/
plugin.ts
111 lines (104 loc) · 3.51 KB
/
plugin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { oldVisit, PluginFunction, Types } from '@graphql-codegen/plugin-helpers';
import { GraphQLSchema, concatAST, Kind, FragmentDefinitionNode } from 'graphql';
import { RawConfig, LoadedFragment } from '@graphql-codegen/visitor-plugin-common';
import { InputTypeVisitor } from './input-type-visitor';
import { BaseJavaVisitor } from './base-java-visitor';
import { OperationVisitor } from './operation-visitor';
import { FileType } from './file-type';
import { CustomTypeClassVisitor } from './custom-type-class';
/**
* @description This plugin and presets creates generated mappers and parsers for a complete type-safe GraphQL requests, for developers that uses Apollo Android runtime.
*/
export interface JavaApolloAndroidPluginConfig extends RawConfig {
/**
* @description Customize the Java package name for the generated operations. The default package name will be generated according to the output file path.
*
* @exampleMarkdown
* ```yml
* generates:
* ./app/src/main/java/:
* preset: java-apollo-android
* config:
* package: 'com.my.package.generated.graphql'
* plugins:
* - java-apollo-android
* ```
*/
package?: string;
/**
* @description Customize the Java package name for the types generated based on input types.
*
* @exampleMarkdown
* ```yml
* generates:
* ./app/src/main/java/:
* preset: java-apollo-android
* config:
* typePackage: 'com.my.package.generated.graphql'
* plugins:
* - java-apollo-android
* ```
*/
typePackage?: string;
/**
* @description Customize the Java package name for the fragments generated classes.
*
* @exampleMarkdown
* ```yml
* generates:
* ./app/src/main/java/:
* preset: java-apollo-android
* config:
* fragmentPackage: 'com.my.package.generated.graphql'
* plugins:
* - java-apollo-android
* ```
*/
fragmentPackage?: string;
// This is an internal configuration, that allow the preset to communicate with the plugin.
fileType: FileType;
}
export const plugin: PluginFunction<JavaApolloAndroidPluginConfig, Types.ComplexPluginOutput> = (
schema: GraphQLSchema,
documents: Types.DocumentFile[],
config: JavaApolloAndroidPluginConfig
) => {
const allAst = concatAST(documents.map(v => v.document));
const allFragments: LoadedFragment[] = [
...(allAst.definitions.filter(d => d.kind === Kind.FRAGMENT_DEFINITION) as FragmentDefinitionNode[]).map(
fragmentDef => ({
node: fragmentDef,
name: fragmentDef.name.value,
onType: fragmentDef.typeCondition.name.value,
isExternal: false,
})
),
...(config.externalFragments || []),
];
let visitor: BaseJavaVisitor;
switch (config.fileType) {
case FileType.FRAGMENT:
case FileType.OPERATION: {
visitor = new OperationVisitor(schema, config, allFragments);
break;
}
case FileType.INPUT_TYPE: {
visitor = new InputTypeVisitor(schema, config);
break;
}
case FileType.CUSTOM_TYPES: {
visitor = new CustomTypeClassVisitor(schema, config);
break;
}
}
if (!visitor) {
return { content: '' };
}
const visitResult = oldVisit(allAst, visitor as any);
const additionalContent = visitor.additionalContent();
const imports = visitor.getImports();
return {
prepend: [`package ${visitor.getPackage()};\n`, ...imports],
content: '\n' + [...visitResult.definitions.filter(a => a && typeof a === 'string'), additionalContent].join('\n'),
};
};