@graphql-codegen/java-apollo-android 2.2.14 → 2.3.0-alpha-2fbcdb6d3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/base-java-visitor.js +114 -0
- package/cjs/custom-type-class.js +69 -0
- package/cjs/field-arguments.js +36 -0
- package/cjs/file-type.js +10 -0
- package/cjs/imports.js +45 -0
- package/cjs/index.js +5 -0
- package/cjs/input-type-visitor.js +187 -0
- package/cjs/operation-visitor.js +780 -0
- package/cjs/package.json +1 -0
- package/cjs/plugin.js +48 -0
- package/cjs/preset.js +95 -0
- package/cjs/types.js +2 -0
- package/cjs/visitor-config.js +2 -0
- package/esm/base-java-visitor.js +110 -0
- package/esm/custom-type-class.js +65 -0
- package/esm/field-arguments.js +32 -0
- package/esm/file-type.js +7 -0
- package/esm/imports.js +42 -0
- package/esm/index.js +2 -0
- package/esm/input-type-visitor.js +183 -0
- package/{index.mjs → esm/operation-visitor.js} +8 -565
- package/esm/plugin.js +44 -0
- package/esm/preset.js +92 -0
- package/esm/types.js +1 -0
- package/esm/visitor-config.js +1 -0
- package/package.json +23 -16
- package/{base-java-visitor.d.ts → typings/base-java-visitor.d.ts} +3 -3
- package/{custom-type-class.d.ts → typings/custom-type-class.d.ts} +3 -3
- package/{field-arguments.d.ts → typings/field-arguments.d.ts} +1 -1
- package/{file-type.d.ts → typings/file-type.d.ts} +0 -0
- package/{imports.d.ts → typings/imports.d.ts} +0 -0
- package/typings/index.d.ts +2 -0
- package/{input-type-visitor.d.ts → typings/input-type-visitor.d.ts} +3 -3
- package/{operation-visitor.d.ts → typings/operation-visitor.d.ts} +3 -3
- package/{plugin.d.ts → typings/plugin.d.ts} +1 -1
- package/{preset.d.ts → typings/preset.d.ts} +0 -0
- package/{types.d.ts → typings/types.d.ts} +0 -0
- package/{visitor-config.d.ts → typings/visitor-config.d.ts} +0 -0
- package/index.d.ts +0 -2
- package/index.js +0 -1339
|
@@ -1,372 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { BaseJavaVisitor, SCALAR_TO_WRITER_METHOD } from './base-java-visitor.js';
|
|
2
|
+
import { indent, indentMultiline, getBaseTypeNode } from '@graphql-codegen/visitor-plugin-common';
|
|
3
|
+
import { buildPackageNameFromPath, JavaDeclarationBlock } from '@graphql-codegen/java-common';
|
|
4
|
+
import { getBaseType } from '@graphql-codegen/plugin-helpers';
|
|
5
|
+
import { print, Kind, isNonNullType, isScalarType, isEnumType, isUnionType, isInterfaceType, isObjectType, isInputObjectType, GraphQLString, isListType, } from 'graphql';
|
|
6
|
+
import { Imports } from './imports.js';
|
|
5
7
|
import { createHash } from 'crypto';
|
|
6
8
|
import pluralize from 'pluralize';
|
|
9
|
+
import { visitFieldArguments } from './field-arguments.js';
|
|
7
10
|
import { camelCase, pascalCase } from 'change-case-all';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const Imports = {
|
|
11
|
-
// Primitives
|
|
12
|
-
String: 'java.lang.String',
|
|
13
|
-
Boolean: 'java.lang.Boolean',
|
|
14
|
-
Integer: 'java.lang.Integer',
|
|
15
|
-
Object: 'java.lang.Object',
|
|
16
|
-
Float: 'java.lang.Float',
|
|
17
|
-
Long: 'java.lang.Long',
|
|
18
|
-
// Java Base
|
|
19
|
-
Class: 'java.lang.Class',
|
|
20
|
-
Arrays: 'java.util.Arrays',
|
|
21
|
-
List: 'java.util.List',
|
|
22
|
-
IOException: 'java.io.IOException',
|
|
23
|
-
Collections: 'java.util.Collections',
|
|
24
|
-
LinkedHashMap: 'java.util.LinkedHashMap',
|
|
25
|
-
Map: 'java.util.Map',
|
|
26
|
-
// Annotations
|
|
27
|
-
Nonnull: 'javax.annotation.Nonnull',
|
|
28
|
-
Nullable: 'javax.annotation.Nullable',
|
|
29
|
-
Override: 'java.lang.Override',
|
|
30
|
-
Generated: 'javax.annotation.Generated',
|
|
31
|
-
// Apollo Android
|
|
32
|
-
ScalarType: 'com.apollographql.apollo.api.ScalarType',
|
|
33
|
-
GraphqlFragment: 'com.apollographql.apollo.api.GraphqlFragment',
|
|
34
|
-
Operation: 'com.apollographql.apollo.api.Operation',
|
|
35
|
-
OperationName: 'com.apollographql.apollo.api.OperationName',
|
|
36
|
-
Mutation: 'com.apollographql.apollo.api.Mutation',
|
|
37
|
-
Query: 'com.apollographql.apollo.api.Query',
|
|
38
|
-
Subscription: 'com.apollographql.apollo.api.Subscription',
|
|
39
|
-
ResponseField: 'com.apollographql.apollo.api.ResponseField',
|
|
40
|
-
ResponseFieldMapper: 'com.apollographql.apollo.api.ResponseFieldMapper',
|
|
41
|
-
ResponseFieldMarshaller: 'com.apollographql.apollo.api.ResponseFieldMarshaller',
|
|
42
|
-
ResponseReader: 'com.apollographql.apollo.api.ResponseReader',
|
|
43
|
-
ResponseWriter: 'com.apollographql.apollo.api.ResponseWriter',
|
|
44
|
-
FragmentResponseFieldMapper: 'com.apollographql.apollo.api.FragmentResponseFieldMapper',
|
|
45
|
-
UnmodifiableMapBuilder: 'com.apollographql.apollo.api.internal.UnmodifiableMapBuilder',
|
|
46
|
-
Utils: 'com.apollographql.apollo.api.internal.Utils',
|
|
47
|
-
InputType: 'com.apollographql.apollo.api.InputType',
|
|
48
|
-
Input: 'com.apollographql.apollo.api.Input',
|
|
49
|
-
InputFieldMarshaller: 'com.apollographql.apollo.api.InputFieldMarshaller',
|
|
50
|
-
InputFieldWriter: 'com.apollographql.apollo.api.InputFieldWriter',
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
const SCALAR_TO_WRITER_METHOD = {
|
|
54
|
-
ID: 'writeString',
|
|
55
|
-
String: 'writeString',
|
|
56
|
-
Int: 'writeInt',
|
|
57
|
-
Boolean: 'writeBoolean',
|
|
58
|
-
Float: 'writeDouble',
|
|
59
|
-
};
|
|
60
|
-
function isTypeNode(type) {
|
|
61
|
-
return type && !!type.kind;
|
|
62
|
-
}
|
|
63
|
-
class BaseJavaVisitor extends BaseVisitor {
|
|
64
|
-
constructor(_schema, rawConfig, additionalConfig) {
|
|
65
|
-
super(rawConfig, {
|
|
66
|
-
...additionalConfig,
|
|
67
|
-
scalars: buildScalars(_schema, { ID: 'String' }, JAVA_SCALARS),
|
|
68
|
-
});
|
|
69
|
-
this._schema = _schema;
|
|
70
|
-
this._imports = new Set();
|
|
71
|
-
}
|
|
72
|
-
getPackage() {
|
|
73
|
-
return '';
|
|
74
|
-
}
|
|
75
|
-
additionalContent() {
|
|
76
|
-
return '';
|
|
77
|
-
}
|
|
78
|
-
getImports() {
|
|
79
|
-
return Array.from(this._imports).map(imp => `import ${imp};`);
|
|
80
|
-
}
|
|
81
|
-
getImplementingTypes(node) {
|
|
82
|
-
const allTypesMap = this._schema.getTypeMap();
|
|
83
|
-
const implementingTypes = [];
|
|
84
|
-
for (const graphqlType of Object.values(allTypesMap)) {
|
|
85
|
-
if (graphqlType instanceof GraphQLObjectType) {
|
|
86
|
-
const allInterfaces = graphqlType.getInterfaces();
|
|
87
|
-
if (allInterfaces.find(int => int.name === node.name)) {
|
|
88
|
-
implementingTypes.push(graphqlType.name);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return implementingTypes;
|
|
93
|
-
}
|
|
94
|
-
transformType(type) {
|
|
95
|
-
let schemaType;
|
|
96
|
-
let isNonNull;
|
|
97
|
-
if (isTypeNode(type)) {
|
|
98
|
-
const baseTypeNode = getBaseTypeNode(type);
|
|
99
|
-
schemaType = this._schema.getType(baseTypeNode.name.value);
|
|
100
|
-
isNonNull = type.kind === Kind.NON_NULL_TYPE;
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
schemaType = this._schema.getType(getBaseType(type).name);
|
|
104
|
-
isNonNull = isNonNullType(type);
|
|
105
|
-
}
|
|
106
|
-
const javaType = this.getJavaClass(schemaType);
|
|
107
|
-
const annotation = isNonNull ? 'Nonnull' : 'Nullable';
|
|
108
|
-
const typeToUse = isTypeNode(type)
|
|
109
|
-
? this.getListTypeNodeWrapped(javaType, type)
|
|
110
|
-
: this.getListTypeWrapped(javaType, type);
|
|
111
|
-
return {
|
|
112
|
-
baseType: schemaType.name,
|
|
113
|
-
javaType,
|
|
114
|
-
isNonNull,
|
|
115
|
-
annotation,
|
|
116
|
-
typeToUse,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
// Replaces a GraphQL type with a Java class
|
|
120
|
-
getJavaClass(schemaType) {
|
|
121
|
-
let typeToUse = schemaType.name;
|
|
122
|
-
if (isScalarType(schemaType)) {
|
|
123
|
-
const scalar = this.scalars[schemaType.name] || 'Object';
|
|
124
|
-
if (Imports[scalar]) {
|
|
125
|
-
this._imports.add(Imports[scalar]);
|
|
126
|
-
}
|
|
127
|
-
typeToUse = scalar;
|
|
128
|
-
}
|
|
129
|
-
else if (isInputObjectType(schemaType)) {
|
|
130
|
-
// Make sure to import it if it's in use
|
|
131
|
-
this._imports.add(`${this.config.typePackage}.${schemaType.name}`);
|
|
132
|
-
}
|
|
133
|
-
return typeToUse;
|
|
134
|
-
}
|
|
135
|
-
getListTypeWrapped(toWrap, type) {
|
|
136
|
-
if (isNonNullType(type)) {
|
|
137
|
-
return this.getListTypeWrapped(toWrap, type.ofType);
|
|
138
|
-
}
|
|
139
|
-
if (isListType(type)) {
|
|
140
|
-
const child = this.getListTypeWrapped(toWrap, type.ofType);
|
|
141
|
-
this._imports.add(Imports.List);
|
|
142
|
-
return `List<${child}>`;
|
|
143
|
-
}
|
|
144
|
-
return toWrap;
|
|
145
|
-
}
|
|
146
|
-
getListTypeNodeWrapped(toWrap, type) {
|
|
147
|
-
if (type.kind === Kind.NON_NULL_TYPE) {
|
|
148
|
-
return this.getListTypeNodeWrapped(toWrap, type.type);
|
|
149
|
-
}
|
|
150
|
-
if (type.kind === Kind.LIST_TYPE) {
|
|
151
|
-
const child = this.getListTypeNodeWrapped(toWrap, type.type);
|
|
152
|
-
this._imports.add(Imports.List);
|
|
153
|
-
return `List<${child}>`;
|
|
154
|
-
}
|
|
155
|
-
return toWrap;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
class InputTypeVisitor extends BaseJavaVisitor {
|
|
160
|
-
constructor(_schema, rawConfig) {
|
|
161
|
-
super(_schema, rawConfig, {
|
|
162
|
-
typePackage: rawConfig.typePackage || 'type',
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
getPackage() {
|
|
166
|
-
return this.config.typePackage;
|
|
167
|
-
}
|
|
168
|
-
addInputMembers(cls, fields) {
|
|
169
|
-
fields.forEach(field => {
|
|
170
|
-
const type = this.transformType(field.type);
|
|
171
|
-
const actualType = type.isNonNull ? type.typeToUse : `Input<${type.typeToUse}>`;
|
|
172
|
-
const annotations = type.isNonNull ? [type.annotation] : [];
|
|
173
|
-
this._imports.add(Imports[type.annotation]);
|
|
174
|
-
cls.addClassMember(field.name.value, actualType, null, annotations, 'private', { final: true });
|
|
175
|
-
cls.addClassMethod(field.name.value, actualType, `return this.${field.name.value};`, [], [type.annotation], 'public');
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
addInputCtor(cls, className, fields) {
|
|
179
|
-
const impl = fields.map(field => `this.${field.name.value} = ${field.name.value};`).join('\n');
|
|
180
|
-
cls.addClassMethod(className, null, impl, fields.map(f => {
|
|
181
|
-
const type = this.transformType(f.type);
|
|
182
|
-
const actualType = type.isNonNull ? type.typeToUse : `Input<${type.typeToUse}>`;
|
|
183
|
-
this._imports.add(Imports[type.annotation]);
|
|
184
|
-
return {
|
|
185
|
-
name: f.name.value,
|
|
186
|
-
type: actualType,
|
|
187
|
-
annotations: type.isNonNull ? [type.annotation] : [],
|
|
188
|
-
};
|
|
189
|
-
}), [], 'public');
|
|
190
|
-
}
|
|
191
|
-
getFieldWriterCall(field, listItemCall = false) {
|
|
192
|
-
const baseType = getBaseTypeNode(field.type);
|
|
193
|
-
const schemaType = this._schema.getType(baseType.name.value);
|
|
194
|
-
const isNonNull = field.type.kind === Kind.NON_NULL_TYPE;
|
|
195
|
-
let writerMethod = null;
|
|
196
|
-
if (isScalarType(schemaType)) {
|
|
197
|
-
writerMethod = SCALAR_TO_WRITER_METHOD[schemaType.name] || 'writeCustom';
|
|
198
|
-
}
|
|
199
|
-
else if (isInputObjectType(schemaType)) {
|
|
200
|
-
return listItemCall
|
|
201
|
-
? `writeObject($item.marshaller())`
|
|
202
|
-
: `writeObject("${field.name.value}", ${field.name.value}.value != null ? ${field.name.value}.value.marshaller() : null)`;
|
|
203
|
-
}
|
|
204
|
-
else if (isEnumType(schemaType)) {
|
|
205
|
-
writerMethod = 'writeString';
|
|
206
|
-
}
|
|
207
|
-
return listItemCall
|
|
208
|
-
? `${writerMethod}($item)`
|
|
209
|
-
: `${writerMethod}("${field.name.value}", ${field.name.value}${isNonNull ? '' : '.value'})`;
|
|
210
|
-
}
|
|
211
|
-
getFieldWithTypePrefix(field, wrapWith = null, applyNullable = false) {
|
|
212
|
-
this._imports.add(Imports.Input);
|
|
213
|
-
const typeToUse = this.getJavaClass(this._schema.getType(getBaseTypeNode(field.type).name.value));
|
|
214
|
-
const isNonNull = field.type.kind === Kind.NON_NULL_TYPE;
|
|
215
|
-
const name = field.kind === Kind.INPUT_VALUE_DEFINITION ? field.name.value : field.variable.name.value;
|
|
216
|
-
if (isNonNull) {
|
|
217
|
-
this._imports.add(Imports.Nonnull);
|
|
218
|
-
return `@Nonnull ${typeToUse} ${name}`;
|
|
219
|
-
}
|
|
220
|
-
if (wrapWith) {
|
|
221
|
-
return typeof wrapWith === 'function' ? `${wrapWith(typeToUse)} ${name}` : `${wrapWith}<${typeToUse}> ${name}`;
|
|
222
|
-
}
|
|
223
|
-
if (applyNullable) {
|
|
224
|
-
this._imports.add(Imports.Nullable);
|
|
225
|
-
}
|
|
226
|
-
return `${applyNullable ? '@Nullable ' : ''}${typeToUse} ${name}`;
|
|
227
|
-
}
|
|
228
|
-
buildFieldsMarshaller(field) {
|
|
229
|
-
const isNonNull = field.type.kind === Kind.NON_NULL_TYPE;
|
|
230
|
-
const isArray = field.type.kind === Kind.LIST_TYPE ||
|
|
231
|
-
(field.type.kind === Kind.NON_NULL_TYPE && field.type.type.kind === Kind.LIST_TYPE);
|
|
232
|
-
const call = this.getFieldWriterCall(field, isArray);
|
|
233
|
-
const baseTypeNode = getBaseTypeNode(field.type);
|
|
234
|
-
const listItemType = this.getJavaClass(this._schema.getType(baseTypeNode.name.value));
|
|
235
|
-
let result = '';
|
|
236
|
-
// TODO: Refactor
|
|
237
|
-
if (isArray) {
|
|
238
|
-
result = `writer.writeList("${field.name.value}", ${field.name.value}.value != null ? new InputFieldWriter.ListWriter() {
|
|
239
|
-
@Override
|
|
240
|
-
public void write(InputFieldWriter.ListItemWriter listItemWriter) throws IOException {
|
|
241
|
-
for (${listItemType} $item : ${field.name.value}.value) {
|
|
242
|
-
listItemWriter.${call};
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
} : null);`;
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
result = indent(`writer.${call};`);
|
|
249
|
-
}
|
|
250
|
-
if (isNonNull) {
|
|
251
|
-
return result;
|
|
252
|
-
}
|
|
253
|
-
return indentMultiline(`if(${field.name.value}.defined) {
|
|
254
|
-
${indentMultiline(result)}
|
|
255
|
-
}`);
|
|
256
|
-
}
|
|
257
|
-
buildMarshallerOverride(fields) {
|
|
258
|
-
this._imports.add(Imports.Override);
|
|
259
|
-
this._imports.add(Imports.IOException);
|
|
260
|
-
this._imports.add(Imports.InputFieldWriter);
|
|
261
|
-
this._imports.add(Imports.InputFieldMarshaller);
|
|
262
|
-
const allMarshallers = fields.map(field => indentMultiline(this.buildFieldsMarshaller(field), 2));
|
|
263
|
-
return indentMultiline(`@Override
|
|
264
|
-
public InputFieldMarshaller marshaller() {
|
|
265
|
-
return new InputFieldMarshaller() {
|
|
266
|
-
@Override
|
|
267
|
-
public void marshal(InputFieldWriter writer) throws IOException {
|
|
268
|
-
${allMarshallers.join('\n')}
|
|
269
|
-
}
|
|
270
|
-
};
|
|
271
|
-
}`);
|
|
272
|
-
}
|
|
273
|
-
buildBuilderNestedClass(className, fields) {
|
|
274
|
-
const builderClassName = 'Builder';
|
|
275
|
-
const privateFields = fields
|
|
276
|
-
.map(field => {
|
|
277
|
-
const isArray = field.type.kind === Kind.LIST_TYPE ||
|
|
278
|
-
(field.type.kind === Kind.NON_NULL_TYPE && field.type.type.kind === Kind.LIST_TYPE);
|
|
279
|
-
const fieldType = this.getFieldWithTypePrefix(field, v => (!isArray ? `Input<${v}>` : `Input<List<${v}>>`));
|
|
280
|
-
const isNonNull = field.type.kind === Kind.NON_NULL_TYPE;
|
|
281
|
-
return `private ${fieldType}${isNonNull ? '' : ' = Input.absent()'};`;
|
|
282
|
-
})
|
|
283
|
-
.map(s => indent(s));
|
|
284
|
-
const setters = fields
|
|
285
|
-
.map(field => {
|
|
286
|
-
const isArray = field.type.kind === Kind.LIST_TYPE ||
|
|
287
|
-
(field.type.kind === Kind.NON_NULL_TYPE && field.type.type.kind === Kind.LIST_TYPE);
|
|
288
|
-
const fieldType = this.getFieldWithTypePrefix(field, isArray ? 'List' : null);
|
|
289
|
-
const isNonNull = field.type.kind === Kind.NON_NULL_TYPE;
|
|
290
|
-
return `\npublic ${builderClassName} ${field.name.value}(${isNonNull ? '' : '@Nullable '}${fieldType}) {
|
|
291
|
-
this.${field.name.value} = ${isNonNull ? field.name.value : `Input.fromNullable(${field.name.value})`};
|
|
292
|
-
return this;
|
|
293
|
-
}`;
|
|
294
|
-
})
|
|
295
|
-
.map(s => indentMultiline(s));
|
|
296
|
-
const nonNullFields = fields
|
|
297
|
-
.filter(f => f.type.kind === Kind.NON_NULL_TYPE)
|
|
298
|
-
.map(nnField => {
|
|
299
|
-
this._imports.add(Imports.Utils);
|
|
300
|
-
return indent(`Utils.checkNotNull(${nnField.name.value}, "${nnField.name.value} == null");`, 1);
|
|
301
|
-
});
|
|
302
|
-
const ctor = '\n' + indent(`${builderClassName}() {}`);
|
|
303
|
-
const buildFn = indentMultiline(`public ${className} build() {
|
|
304
|
-
${nonNullFields.join('\n')}
|
|
305
|
-
return new ${className}(${fields.map(f => f.name.value).join(', ')});
|
|
306
|
-
}`);
|
|
307
|
-
const body = [...privateFields, ctor, ...setters, '', buildFn].join('\n');
|
|
308
|
-
return indentMultiline(new JavaDeclarationBlock()
|
|
309
|
-
.withName(builderClassName)
|
|
310
|
-
.access('public')
|
|
311
|
-
.final()
|
|
312
|
-
.static()
|
|
313
|
-
.withBlock(body)
|
|
314
|
-
.asKind('class').string);
|
|
315
|
-
}
|
|
316
|
-
InputObjectTypeDefinition(node) {
|
|
317
|
-
const className = node.name.value;
|
|
318
|
-
this._imports.add(Imports.InputType);
|
|
319
|
-
this._imports.add(Imports.Generated);
|
|
320
|
-
const cls = new JavaDeclarationBlock()
|
|
321
|
-
.annotate([`Generated("Apollo GraphQL")`])
|
|
322
|
-
.access('public')
|
|
323
|
-
.final()
|
|
324
|
-
.asKind('class')
|
|
325
|
-
.withName(className)
|
|
326
|
-
.implements(['InputType']);
|
|
327
|
-
this.addInputMembers(cls, node.fields);
|
|
328
|
-
this.addInputCtor(cls, className, node.fields);
|
|
329
|
-
cls.addClassMethod('builder', 'Builder', 'return new Builder();', [], [], 'public', { static: true });
|
|
330
|
-
const marshallerOverride = this.buildMarshallerOverride(node.fields);
|
|
331
|
-
const builderClass = this.buildBuilderNestedClass(className, node.fields);
|
|
332
|
-
const classBlock = [marshallerOverride, '', builderClass].join('\n');
|
|
333
|
-
cls.withBlock(classBlock);
|
|
334
|
-
return cls.string;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
function visitFieldArguments(selection, imports) {
|
|
339
|
-
if (!selection.arguments || selection.arguments.length === 0) {
|
|
340
|
-
return 'null';
|
|
341
|
-
}
|
|
342
|
-
imports.add(Imports.UnmodifiableMapBuilder);
|
|
343
|
-
imports.add(Imports.String);
|
|
344
|
-
imports.add(Imports.Object);
|
|
345
|
-
return oldVisit(selection, {
|
|
346
|
-
leave: {
|
|
347
|
-
Field: (node) => {
|
|
348
|
-
return (`new UnmodifiableMapBuilder<String, Object>(${node.arguments.length})` + node.arguments.join('') + '.build()');
|
|
349
|
-
},
|
|
350
|
-
Argument: (node) => {
|
|
351
|
-
return `.put("${node.name.value}", ${node.value})`;
|
|
352
|
-
},
|
|
353
|
-
ObjectValue: (node) => {
|
|
354
|
-
return `new UnmodifiableMapBuilder<String, Object>(${node.fields.length})` + node.fields.join('') + '.build()';
|
|
355
|
-
},
|
|
356
|
-
ObjectField: (node) => {
|
|
357
|
-
return `.put("${node.name.value}", ${node.value})`;
|
|
358
|
-
},
|
|
359
|
-
Variable: (node) => {
|
|
360
|
-
return `new UnmodifiableMapBuilder<String, Object>(2).put("kind", "Variable").put("variableName", "${node.name.value}").build()`;
|
|
361
|
-
},
|
|
362
|
-
StringValue: (node) => `"${node.value}"`,
|
|
363
|
-
IntValue: (node) => `"${node.value}"`,
|
|
364
|
-
FloatValue: (node) => `"${node.value}"`,
|
|
365
|
-
},
|
|
366
|
-
});
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
class OperationVisitor extends BaseJavaVisitor {
|
|
11
|
+
export class OperationVisitor extends BaseJavaVisitor {
|
|
370
12
|
constructor(_schema, rawConfig, _availableFragments) {
|
|
371
13
|
super(_schema, rawConfig, {
|
|
372
14
|
package: rawConfig.package || buildPackageNameFromPath(process.cwd()),
|
|
@@ -1131,202 +773,3 @@ ${variables
|
|
|
1131
773
|
return cls;
|
|
1132
774
|
}
|
|
1133
775
|
}
|
|
1134
|
-
|
|
1135
|
-
var FileType;
|
|
1136
|
-
(function (FileType) {
|
|
1137
|
-
FileType[FileType["INPUT_TYPE"] = 0] = "INPUT_TYPE";
|
|
1138
|
-
FileType[FileType["OPERATION"] = 1] = "OPERATION";
|
|
1139
|
-
FileType[FileType["FRAGMENT"] = 2] = "FRAGMENT";
|
|
1140
|
-
FileType[FileType["CUSTOM_TYPES"] = 3] = "CUSTOM_TYPES";
|
|
1141
|
-
})(FileType || (FileType = {}));
|
|
1142
|
-
|
|
1143
|
-
const filteredScalars = ['String', 'Float', 'Int', 'Boolean'];
|
|
1144
|
-
class CustomTypeClassVisitor extends BaseJavaVisitor {
|
|
1145
|
-
constructor(schema, rawConfig) {
|
|
1146
|
-
super(schema, rawConfig, {
|
|
1147
|
-
typePackage: rawConfig.typePackage || 'type',
|
|
1148
|
-
});
|
|
1149
|
-
}
|
|
1150
|
-
extract(name) {
|
|
1151
|
-
const lastIndex = name.lastIndexOf('.');
|
|
1152
|
-
if (lastIndex === -1) {
|
|
1153
|
-
return {
|
|
1154
|
-
className: name,
|
|
1155
|
-
importFrom: Imports[name] || null,
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
return {
|
|
1159
|
-
className: name.substring(lastIndex + 1),
|
|
1160
|
-
importFrom: name,
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
additionalContent() {
|
|
1164
|
-
this._imports.add(Imports.ScalarType);
|
|
1165
|
-
this._imports.add(Imports.Class);
|
|
1166
|
-
this._imports.add(Imports.Override);
|
|
1167
|
-
this._imports.add(Imports.Generated);
|
|
1168
|
-
const allTypes = this._schema.getTypeMap();
|
|
1169
|
-
const enumValues = Object.keys(allTypes)
|
|
1170
|
-
.filter(t => isScalarType(allTypes[t]) && !filteredScalars.includes(t))
|
|
1171
|
-
.map(t => allTypes[t])
|
|
1172
|
-
.map(scalarType => {
|
|
1173
|
-
const uppercaseName = scalarType.name.toUpperCase();
|
|
1174
|
-
const javaType = this.extract(this.scalars[scalarType.name] || 'String');
|
|
1175
|
-
if (javaType.importFrom) {
|
|
1176
|
-
this._imports.add(javaType.importFrom);
|
|
1177
|
-
}
|
|
1178
|
-
return indentMultiline(`${uppercaseName} {
|
|
1179
|
-
@Override
|
|
1180
|
-
public String typeName() {
|
|
1181
|
-
return "${scalarType.name}";
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
@Override
|
|
1185
|
-
public Class javaType() {
|
|
1186
|
-
return ${javaType.className}.class;
|
|
1187
|
-
}
|
|
1188
|
-
}`);
|
|
1189
|
-
})
|
|
1190
|
-
.join(',\n\n');
|
|
1191
|
-
return new JavaDeclarationBlock()
|
|
1192
|
-
.annotate([`Generated("Apollo GraphQL")`])
|
|
1193
|
-
.access('public')
|
|
1194
|
-
.asKind('enum')
|
|
1195
|
-
.withName('CustomType')
|
|
1196
|
-
.implements(['ScalarType'])
|
|
1197
|
-
.withBlock(enumValues).string;
|
|
1198
|
-
}
|
|
1199
|
-
getPackage() {
|
|
1200
|
-
return this.config.typePackage;
|
|
1201
|
-
}
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
const plugin = (schema, documents, config) => {
|
|
1205
|
-
const allAst = concatAST(documents.map(v => v.document));
|
|
1206
|
-
const allFragments = [
|
|
1207
|
-
...allAst.definitions.filter(d => d.kind === Kind.FRAGMENT_DEFINITION).map(fragmentDef => ({
|
|
1208
|
-
node: fragmentDef,
|
|
1209
|
-
name: fragmentDef.name.value,
|
|
1210
|
-
onType: fragmentDef.typeCondition.name.value,
|
|
1211
|
-
isExternal: false,
|
|
1212
|
-
})),
|
|
1213
|
-
...(config.externalFragments || []),
|
|
1214
|
-
];
|
|
1215
|
-
let visitor;
|
|
1216
|
-
switch (config.fileType) {
|
|
1217
|
-
case FileType.FRAGMENT:
|
|
1218
|
-
case FileType.OPERATION: {
|
|
1219
|
-
visitor = new OperationVisitor(schema, config, allFragments);
|
|
1220
|
-
break;
|
|
1221
|
-
}
|
|
1222
|
-
case FileType.INPUT_TYPE: {
|
|
1223
|
-
visitor = new InputTypeVisitor(schema, config);
|
|
1224
|
-
break;
|
|
1225
|
-
}
|
|
1226
|
-
case FileType.CUSTOM_TYPES: {
|
|
1227
|
-
visitor = new CustomTypeClassVisitor(schema, config);
|
|
1228
|
-
break;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
if (!visitor) {
|
|
1232
|
-
return { content: '' };
|
|
1233
|
-
}
|
|
1234
|
-
const visitResult = oldVisit(allAst, visitor);
|
|
1235
|
-
const additionalContent = visitor.additionalContent();
|
|
1236
|
-
const imports = visitor.getImports();
|
|
1237
|
-
return {
|
|
1238
|
-
prepend: [`package ${visitor.getPackage()};\n`, ...imports],
|
|
1239
|
-
content: '\n' + [...visitResult.definitions.filter(a => a && typeof a === 'string'), additionalContent].join('\n'),
|
|
1240
|
-
};
|
|
1241
|
-
};
|
|
1242
|
-
|
|
1243
|
-
const packageNameToDirectory = (packageName) => {
|
|
1244
|
-
return `./${packageName.split('.').join('/')}/`;
|
|
1245
|
-
};
|
|
1246
|
-
const preset = {
|
|
1247
|
-
buildGeneratesSection: options => {
|
|
1248
|
-
const outDir = options.baseOutputDir;
|
|
1249
|
-
const inputTypesAst = [];
|
|
1250
|
-
visit(options.schema, {
|
|
1251
|
-
InputObjectTypeDefinition: {
|
|
1252
|
-
enter(node) {
|
|
1253
|
-
inputTypesAst.push(node);
|
|
1254
|
-
},
|
|
1255
|
-
},
|
|
1256
|
-
});
|
|
1257
|
-
const inputTypesDocumentNode = { kind: Kind.DOCUMENT, definitions: inputTypesAst };
|
|
1258
|
-
const allAst = concatAST(options.documents.map(v => v.document));
|
|
1259
|
-
const operationsAst = allAst.definitions.filter(d => d.kind === Kind.OPERATION_DEFINITION);
|
|
1260
|
-
const fragments = allAst.definitions.filter(d => d.kind === Kind.FRAGMENT_DEFINITION);
|
|
1261
|
-
const externalFragments = fragments.map(frag => ({
|
|
1262
|
-
isExternal: true,
|
|
1263
|
-
importFrom: frag.name.value,
|
|
1264
|
-
name: frag.name.value,
|
|
1265
|
-
onType: frag.typeCondition.name.value,
|
|
1266
|
-
node: frag,
|
|
1267
|
-
}));
|
|
1268
|
-
return [
|
|
1269
|
-
{
|
|
1270
|
-
filename: join(outDir, packageNameToDirectory(options.config.typePackage), 'CustomType.java'),
|
|
1271
|
-
plugins: options.plugins,
|
|
1272
|
-
pluginMap: options.pluginMap,
|
|
1273
|
-
config: {
|
|
1274
|
-
...options.config,
|
|
1275
|
-
fileType: FileType.CUSTOM_TYPES,
|
|
1276
|
-
},
|
|
1277
|
-
schema: options.schema,
|
|
1278
|
-
documents: [],
|
|
1279
|
-
},
|
|
1280
|
-
...inputTypesDocumentNode.definitions.map((ast) => {
|
|
1281
|
-
const document = { kind: Kind.DOCUMENT, definitions: [ast] };
|
|
1282
|
-
return {
|
|
1283
|
-
filename: join(outDir, packageNameToDirectory(options.config.typePackage), ast.name.value + '.java'),
|
|
1284
|
-
plugins: options.plugins,
|
|
1285
|
-
pluginMap: options.pluginMap,
|
|
1286
|
-
config: {
|
|
1287
|
-
...options.config,
|
|
1288
|
-
fileType: FileType.INPUT_TYPE,
|
|
1289
|
-
skipDocumentsValidation: true,
|
|
1290
|
-
},
|
|
1291
|
-
schema: options.schema,
|
|
1292
|
-
documents: [{ document, location: '' }],
|
|
1293
|
-
};
|
|
1294
|
-
}),
|
|
1295
|
-
...operationsAst.map((ast) => {
|
|
1296
|
-
const fileName = ast.name.value.toLowerCase().endsWith(ast.operation)
|
|
1297
|
-
? ast.name.value
|
|
1298
|
-
: `${ast.name.value}${pascalCase(ast.operation)}`;
|
|
1299
|
-
const document = { kind: Kind.DOCUMENT, definitions: [ast] };
|
|
1300
|
-
return {
|
|
1301
|
-
filename: join(outDir, packageNameToDirectory(options.config.package), fileName + '.java'),
|
|
1302
|
-
plugins: options.plugins,
|
|
1303
|
-
pluginMap: options.pluginMap,
|
|
1304
|
-
config: {
|
|
1305
|
-
...options.config,
|
|
1306
|
-
fileType: FileType.OPERATION,
|
|
1307
|
-
externalFragments,
|
|
1308
|
-
},
|
|
1309
|
-
schema: options.schema,
|
|
1310
|
-
documents: [{ document, location: '' }],
|
|
1311
|
-
};
|
|
1312
|
-
}),
|
|
1313
|
-
...fragments.map((ast) => {
|
|
1314
|
-
const document = { kind: Kind.DOCUMENT, definitions: [ast] };
|
|
1315
|
-
return {
|
|
1316
|
-
filename: join(outDir, packageNameToDirectory(options.config.fragmentPackage), ast.name.value + '.java'),
|
|
1317
|
-
plugins: options.plugins,
|
|
1318
|
-
pluginMap: options.pluginMap,
|
|
1319
|
-
config: {
|
|
1320
|
-
...options.config,
|
|
1321
|
-
fileType: FileType.FRAGMENT,
|
|
1322
|
-
externalFragments,
|
|
1323
|
-
},
|
|
1324
|
-
schema: options.schema,
|
|
1325
|
-
documents: [{ document, location: '' }],
|
|
1326
|
-
};
|
|
1327
|
-
}),
|
|
1328
|
-
];
|
|
1329
|
-
},
|
|
1330
|
-
};
|
|
1331
|
-
|
|
1332
|
-
export { plugin, preset };
|
package/esm/plugin.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { oldVisit } from '@graphql-codegen/plugin-helpers';
|
|
2
|
+
import { concatAST, Kind } from 'graphql';
|
|
3
|
+
import { InputTypeVisitor } from './input-type-visitor.js';
|
|
4
|
+
import { OperationVisitor } from './operation-visitor.js';
|
|
5
|
+
import { FileType } from './file-type.js';
|
|
6
|
+
import { CustomTypeClassVisitor } from './custom-type-class.js';
|
|
7
|
+
export const plugin = (schema, documents, config) => {
|
|
8
|
+
const allAst = concatAST(documents.map(v => v.document));
|
|
9
|
+
const allFragments = [
|
|
10
|
+
...allAst.definitions.filter(d => d.kind === Kind.FRAGMENT_DEFINITION).map(fragmentDef => ({
|
|
11
|
+
node: fragmentDef,
|
|
12
|
+
name: fragmentDef.name.value,
|
|
13
|
+
onType: fragmentDef.typeCondition.name.value,
|
|
14
|
+
isExternal: false,
|
|
15
|
+
})),
|
|
16
|
+
...(config.externalFragments || []),
|
|
17
|
+
];
|
|
18
|
+
let visitor;
|
|
19
|
+
switch (config.fileType) {
|
|
20
|
+
case FileType.FRAGMENT:
|
|
21
|
+
case FileType.OPERATION: {
|
|
22
|
+
visitor = new OperationVisitor(schema, config, allFragments);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
case FileType.INPUT_TYPE: {
|
|
26
|
+
visitor = new InputTypeVisitor(schema, config);
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case FileType.CUSTOM_TYPES: {
|
|
30
|
+
visitor = new CustomTypeClassVisitor(schema, config);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!visitor) {
|
|
35
|
+
return { content: '' };
|
|
36
|
+
}
|
|
37
|
+
const visitResult = oldVisit(allAst, visitor);
|
|
38
|
+
const additionalContent = visitor.additionalContent();
|
|
39
|
+
const imports = visitor.getImports();
|
|
40
|
+
return {
|
|
41
|
+
prepend: [`package ${visitor.getPackage()};\n`, ...imports],
|
|
42
|
+
content: '\n' + [...visitResult.definitions.filter(a => a && typeof a === 'string'), additionalContent].join('\n'),
|
|
43
|
+
};
|
|
44
|
+
};
|