@khanacademy/graphql-flow 1.1.2 → 2.0.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/.babelrc +1 -1
- package/.eslintrc.js +0 -1
- package/.github/workflows/changeset-release.yml +1 -1
- package/CHANGELOG.md +16 -0
- package/dist/cli/config.js +2 -4
- package/dist/cli/run.js +1 -2
- package/dist/enums.js +8 -9
- package/dist/generateResponseType.js +33 -41
- package/dist/generateTypeFiles.js +13 -35
- package/dist/generateVariablesType.js +15 -31
- package/dist/index.js +11 -17
- package/dist/parser/parse.js +10 -8
- package/dist/parser/resolve.js +11 -8
- package/dist/parser/utils.js +36 -0
- package/dist/schemaFromIntrospectionData.js +1 -2
- package/dist/types.js +1 -2
- package/dist/utils.js +43 -3
- package/package.json +8 -7
- package/{src/cli/schema.json → schema.json} +3 -0
- package/{dist/__test__/generateTypeFileContents.test.js → src/__test__/generateTypeFileContents.test.ts} +38 -41
- package/{dist/__test__/graphql-flow.test.js → src/__test__/graphql-flow.test.ts} +232 -235
- package/src/__test__/{processPragmas.test.js → processPragmas.test.ts} +0 -1
- package/{dist/cli/__test__/config.test.js → src/cli/__test__/config.test.ts} +5 -6
- package/{dist/cli/config.js.flow → src/cli/config.ts} +6 -11
- package/src/cli/{run.js → run.ts} +5 -4
- package/src/{enums.js → enums.ts} +20 -22
- package/{dist/generateResponseType.js.flow → src/generateResponseType.ts} +167 -182
- package/src/{generateTypeFiles.js → generateTypeFiles.ts} +24 -40
- package/src/{generateVariablesType.js → generateVariablesType.ts} +34 -44
- package/{dist/index.js.flow → src/index.ts} +33 -24
- package/{dist/parser/__test__/parse.test.js → src/parser/__test__/parse.test.ts} +12 -11
- package/{dist/parser/parse.js.flow → src/parser/parse.ts} +69 -48
- package/{dist/parser/resolve.js.flow → src/parser/resolve.ts} +25 -19
- package/src/parser/utils.ts +24 -0
- package/{dist/schemaFromIntrospectionData.js.flow → src/schemaFromIntrospectionData.ts} +1 -4
- package/src/types.ts +97 -0
- package/src/utils.ts +73 -0
- package/tools/{find-files-with-gql.js → find-files-with-gql.ts} +2 -3
- package/tsconfig.json +110 -0
- package/types/flow-to-ts.d.ts +1 -0
- package/dist/__test__/example-schema.graphql +0 -67
- package/dist/__test__/processPragmas.test.js +0 -76
- package/dist/cli/config.js.map +0 -1
- package/dist/cli/run.js.flow +0 -236
- package/dist/cli/run.js.map +0 -1
- package/dist/cli/schema.json +0 -94
- package/dist/enums.js.flow +0 -98
- package/dist/enums.js.map +0 -1
- package/dist/generateResponseType.js.map +0 -1
- package/dist/generateTypeFiles.js.flow +0 -197
- package/dist/generateTypeFiles.js.map +0 -1
- package/dist/generateVariablesType.js.flow +0 -156
- package/dist/generateVariablesType.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/parser/parse.js.map +0 -1
- package/dist/parser/resolve.js.map +0 -1
- package/dist/schemaFromIntrospectionData.js.map +0 -1
- package/dist/types.js.flow +0 -87
- package/dist/types.js.map +0 -1
- package/dist/utils.js.flow +0 -50
- package/dist/utils.js.map +0 -1
- package/flow-typed/npm/@babel/types_vx.x.x.js +0 -5331
- package/flow-typed/npm/jest_v23.x.x.js +0 -1155
- package/flow-typed/overrides.js +0 -435
- package/src/__test__/generateTypeFileContents.test.js +0 -157
- package/src/__test__/graphql-flow.test.js +0 -639
- package/src/cli/__test__/config.test.js +0 -120
- package/src/cli/config.js +0 -84
- package/src/generateResponseType.js +0 -583
- package/src/index.js +0 -159
- package/src/parser/__test__/parse.test.js +0 -249
- package/src/parser/parse.js +0 -414
- package/src/parser/resolve.js +0 -117
- package/src/schemaFromIntrospectionData.js +0 -68
- package/src/types.js +0 -87
- package/src/utils.js +0 -50
package/.babelrc
CHANGED
package/.eslintrc.js
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @khanacademy/graphql-flow
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 38eb544: Generate TypeScript directly and only TypeScript
|
|
8
|
+
|
|
9
|
+
### Minor Changes
|
|
10
|
+
|
|
11
|
+
- 2933c91: Migrate to TypeScript
|
|
12
|
+
|
|
13
|
+
## 1.2.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- e1e9fde: Add --omitFileExtensions option
|
|
18
|
+
|
|
3
19
|
## 1.1.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/cli/config.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.validateOrThrow = exports.loadConfigFile = exports.getSchemas = exports.
|
|
|
7
7
|
|
|
8
8
|
var _schemaFromIntrospectionData = require("../schemaFromIntrospectionData");
|
|
9
9
|
|
|
10
|
-
var _schema = _interopRequireDefault(require("
|
|
10
|
+
var _schema = _interopRequireDefault(require("../../schema.json"));
|
|
11
11
|
|
|
12
12
|
var _fs = _interopRequireDefault(require("fs"));
|
|
13
13
|
|
|
@@ -33,7 +33,6 @@ const validateOrThrow = (value, jsonSchema) => {
|
|
|
33
33
|
exports.validateOrThrow = validateOrThrow;
|
|
34
34
|
|
|
35
35
|
const loadConfigFile = configFile => {
|
|
36
|
-
// $FlowIgnore
|
|
37
36
|
const data = require(configFile); // eslint-disable-line flowtype-errors/uncovered
|
|
38
37
|
|
|
39
38
|
|
|
@@ -96,5 +95,4 @@ const findApplicableConfig = (path, configs) => {
|
|
|
96
95
|
});
|
|
97
96
|
};
|
|
98
97
|
|
|
99
|
-
exports.findApplicableConfig = findApplicableConfig;
|
|
100
|
-
//# sourceMappingURL=config.js.map
|
|
98
|
+
exports.findApplicableConfig = findApplicableConfig;
|
package/dist/cli/run.js
CHANGED
package/dist/enums.js
CHANGED
|
@@ -17,14 +17,14 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
17
17
|
* Both input & output types can have enums & scalars.
|
|
18
18
|
*/
|
|
19
19
|
const experimentalEnumTypeToFlow = (ctx, enumConfig, description) => {
|
|
20
|
-
const enumDeclaration = babelTypes.
|
|
21
|
-
babelTypes.identifier(enumConfig.name),
|
|
20
|
+
const enumDeclaration = babelTypes.tsEnumDeclaration( // pass id into generic type annotation
|
|
21
|
+
babelTypes.identifier(enumConfig.name), enumConfig.enumValues.map(v => babelTypes.tsEnumMember(babelTypes.identifier(v.name), babelTypes.stringLiteral(v.name))));
|
|
22
22
|
|
|
23
23
|
if (ctx.experimentalEnumsMap) {
|
|
24
24
|
ctx.experimentalEnumsMap[enumConfig.name] = enumDeclaration;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
return (0, _utils.maybeAddDescriptionComment)(description, babelTypes.
|
|
27
|
+
return (0, _utils.maybeAddDescriptionComment)(description, babelTypes.tsTypeReference(enumDeclaration.id));
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
exports.experimentalEnumTypeToFlow = experimentalEnumTypeToFlow;
|
|
@@ -37,7 +37,7 @@ const enumTypeToFlow = (ctx, name) => {
|
|
|
37
37
|
combinedDescription = enumConfig.description + '\n\n' + combinedDescription;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
return ctx.experimentalEnumsMap ? experimentalEnumTypeToFlow(ctx, enumConfig, combinedDescription) : (0, _utils.maybeAddDescriptionComment)(combinedDescription, babelTypes.
|
|
40
|
+
return ctx.experimentalEnumsMap ? experimentalEnumTypeToFlow(ctx, enumConfig, combinedDescription) : (0, _utils.maybeAddDescriptionComment)(combinedDescription, babelTypes.tsUnionType(enumConfig.enumValues.map(n => babelTypes.tsLiteralType(babelTypes.stringLiteral(n.name)))));
|
|
41
41
|
};
|
|
42
42
|
|
|
43
43
|
exports.enumTypeToFlow = enumTypeToFlow;
|
|
@@ -54,18 +54,17 @@ exports.builtinScalars = builtinScalars;
|
|
|
54
54
|
|
|
55
55
|
const scalarTypeToFlow = (ctx, name) => {
|
|
56
56
|
if (builtinScalars[name]) {
|
|
57
|
-
return babelTypes.
|
|
57
|
+
return babelTypes.tsTypeReference(babelTypes.identifier(builtinScalars[name]));
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
const underlyingType = ctx.scalars[name];
|
|
61
61
|
|
|
62
62
|
if (underlyingType != null) {
|
|
63
|
-
return babelTypes.
|
|
63
|
+
return babelTypes.tsTypeReference(babelTypes.identifier(underlyingType));
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
ctx.errors.push(`Unexpected scalar '${name}'! Please add it to the "scalars" argument at the callsite of 'generateFlowTypes()'.`);
|
|
67
|
-
return babelTypes.
|
|
67
|
+
return babelTypes.tsTypeReference(babelTypes.identifier(`UNKNOWN_SCALAR["${name}"]`));
|
|
68
68
|
};
|
|
69
69
|
|
|
70
|
-
exports.scalarTypeToFlow = scalarTypeToFlow;
|
|
71
|
-
//# sourceMappingURL=enums.js.map
|
|
70
|
+
exports.scalarTypeToFlow = scalarTypeToFlow;
|
|
@@ -30,29 +30,21 @@ const generateResponseType = (schema, query, ctx) => {
|
|
|
30
30
|
exports.generateResponseType = generateResponseType;
|
|
31
31
|
|
|
32
32
|
const sortedObjectTypeAnnotation = (ctx, properties) => {
|
|
33
|
-
const obj =
|
|
34
|
-
if (a.type === '
|
|
33
|
+
const obj = (0, _utils.objectTypeFromProperties)(properties.sort((a, b) => {
|
|
34
|
+
if (a.type === 'TSPropertySignature' && b.type === 'TSPropertySignature') {
|
|
35
35
|
const aName = a.key.type === 'Identifier' ? a.key.name : '';
|
|
36
36
|
const bName = b.key.type === 'Identifier' ? b.key.name : '';
|
|
37
37
|
return aName < bName ? -1 : 1;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return 0;
|
|
41
|
-
})
|
|
42
|
-
/* indexers */
|
|
43
|
-
, undefined
|
|
44
|
-
/* callProperties */
|
|
45
|
-
, undefined
|
|
46
|
-
/* internalSlots */
|
|
47
|
-
, true
|
|
48
|
-
/* exact */
|
|
49
|
-
);
|
|
41
|
+
}));
|
|
50
42
|
const name = ctx.path.join('_');
|
|
51
43
|
const isTopLevelType = ctx.path.length <= 1;
|
|
52
44
|
|
|
53
45
|
if (ctx.allObjectTypes != null && !isTopLevelType) {
|
|
54
46
|
ctx.allObjectTypes[name] = obj;
|
|
55
|
-
return babelTypes.
|
|
47
|
+
return babelTypes.tsTypeReference(babelTypes.identifier(name));
|
|
56
48
|
} else {
|
|
57
49
|
return obj;
|
|
58
50
|
}
|
|
@@ -84,7 +76,7 @@ const _typeToFlow = (ctx, type, selection) => {
|
|
|
84
76
|
}
|
|
85
77
|
|
|
86
78
|
if (type.kind === 'LIST') {
|
|
87
|
-
return babelTypes.
|
|
79
|
+
return babelTypes.tsTypeReference(ctx.readOnlyArray ? babelTypes.identifier('ReadonlyArray') : babelTypes.identifier('Array'), babelTypes.tsTypeParameterInstantiation([typeToFlow(ctx, type.ofType, selection)]));
|
|
88
80
|
}
|
|
89
81
|
|
|
90
82
|
if (type.kind === 'UNION') {
|
|
@@ -92,7 +84,7 @@ const _typeToFlow = (ctx, type, selection) => {
|
|
|
92
84
|
|
|
93
85
|
if (!selection.selectionSet) {
|
|
94
86
|
console.log('no selection set', selection);
|
|
95
|
-
return babelTypes.
|
|
87
|
+
return babelTypes.tsAnyKeyword();
|
|
96
88
|
}
|
|
97
89
|
|
|
98
90
|
return unionOrInterfaceToFlow(ctx, union, selection.selectionSet.selections);
|
|
@@ -101,7 +93,7 @@ const _typeToFlow = (ctx, type, selection) => {
|
|
|
101
93
|
if (type.kind === 'INTERFACE') {
|
|
102
94
|
if (!selection.selectionSet) {
|
|
103
95
|
console.log('no selection set', selection);
|
|
104
|
-
return babelTypes.
|
|
96
|
+
return babelTypes.tsAnyKeyword();
|
|
105
97
|
}
|
|
106
98
|
|
|
107
99
|
return unionOrInterfaceToFlow(ctx, ctx.schema.interfacesByName[type.name], selection.selectionSet.selections);
|
|
@@ -113,21 +105,21 @@ const _typeToFlow = (ctx, type, selection) => {
|
|
|
113
105
|
|
|
114
106
|
if (type.kind !== 'OBJECT') {
|
|
115
107
|
console.log('not object', type);
|
|
116
|
-
return babelTypes.
|
|
108
|
+
return babelTypes.tsAnyKeyword();
|
|
117
109
|
}
|
|
118
110
|
|
|
119
111
|
const tname = type.name;
|
|
120
112
|
|
|
121
113
|
if (!ctx.schema.typesByName[tname]) {
|
|
122
114
|
console.log('unknown referenced type', tname);
|
|
123
|
-
return babelTypes.
|
|
115
|
+
return babelTypes.tsAnyKeyword();
|
|
124
116
|
}
|
|
125
117
|
|
|
126
118
|
const childType = ctx.schema.typesByName[tname];
|
|
127
119
|
|
|
128
120
|
if (!selection.selectionSet) {
|
|
129
121
|
console.log('no selection set', selection);
|
|
130
|
-
return babelTypes.
|
|
122
|
+
return babelTypes.tsAnyKeyword();
|
|
131
123
|
}
|
|
132
124
|
|
|
133
125
|
return (0, _utils.maybeAddDescriptionComment)(childType.description, querySelectionToObjectType(ctx, selection.selectionSet.selections, childType, tname));
|
|
@@ -146,7 +138,7 @@ const typeToFlow = (ctx, type, selection) => {
|
|
|
146
138
|
|
|
147
139
|
const inner = _typeToFlow(ctx, type, selection);
|
|
148
140
|
|
|
149
|
-
const result =
|
|
141
|
+
const result = (0, _utils.nullableType)(inner);
|
|
150
142
|
return (0, _utils.transferLeadingComments)(inner, result);
|
|
151
143
|
};
|
|
152
144
|
|
|
@@ -158,8 +150,10 @@ const ensureOnlyOneTypenameProperty = properties => {
|
|
|
158
150
|
// The apollo-utilities "addTypeName" utility will add it
|
|
159
151
|
// even if it's already specified :( so we have to filter out
|
|
160
152
|
// the extra one here.
|
|
161
|
-
if (type.type === '
|
|
162
|
-
|
|
153
|
+
if (type.type === 'TSPropertySignature' && type.key.type === "Identifier" && type.key.name === '__typename') {
|
|
154
|
+
var _type$typeAnnotation;
|
|
155
|
+
|
|
156
|
+
const name = ((_type$typeAnnotation = type.typeAnnotation) === null || _type$typeAnnotation === void 0 ? void 0 : _type$typeAnnotation.typeAnnotation.type) === 'TSLiteralType' && type.typeAnnotation.typeAnnotation.literal.type === 'StringLiteral' ? type.typeAnnotation.typeAnnotation.literal.value : 'INVALID';
|
|
163
157
|
|
|
164
158
|
if (seenTypeName) {
|
|
165
159
|
if (name !== seenTypeName) {
|
|
@@ -181,7 +175,7 @@ const querySelectionToObjectType = (ctx, selections, type, typeName) => {
|
|
|
181
175
|
};
|
|
182
176
|
|
|
183
177
|
const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
|
|
184
|
-
return
|
|
178
|
+
return selections.flatMap(selection => {
|
|
185
179
|
switch (selection.kind) {
|
|
186
180
|
case 'InlineFragment':
|
|
187
181
|
{
|
|
@@ -199,7 +193,7 @@ const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
|
|
|
199
193
|
case 'FragmentSpread':
|
|
200
194
|
if (!ctx.fragments[selection.name.value]) {
|
|
201
195
|
ctx.errors.push(`No fragment named '${selection.name.value}'. Did you forget to include it in the template literal?`);
|
|
202
|
-
return [babelTypes.
|
|
196
|
+
return [babelTypes.tsPropertySignature(babelTypes.identifier(selection.name.value), babelTypes.tsTypeAnnotation(babelTypes.tsTypeReference(babelTypes.identifier(`UNKNOWN_FRAGMENT`))))];
|
|
203
197
|
}
|
|
204
198
|
|
|
205
199
|
return objectPropertiesToFlow(ctx, type, typeName, ctx.fragments[selection.name.value].selectionSet.selections);
|
|
@@ -209,25 +203,25 @@ const objectPropertiesToFlow = (ctx, type, typeName, selections) => {
|
|
|
209
203
|
const alias = selection.alias ? selection.alias.value : name;
|
|
210
204
|
|
|
211
205
|
if (name === '__typename') {
|
|
212
|
-
return [babelTypes.
|
|
206
|
+
return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsLiteralType(babelTypes.stringLiteral(typeName))))];
|
|
213
207
|
}
|
|
214
208
|
|
|
215
209
|
if (!type.fieldsByName[name]) {
|
|
216
210
|
ctx.errors.push(`Unknown field '${name}' for type '${typeName}'`);
|
|
217
|
-
return babelTypes.
|
|
211
|
+
return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsTypeReference(babelTypes.identifier(`UNKNOWN_FIELD["${name}"]`))))];
|
|
218
212
|
}
|
|
219
213
|
|
|
220
214
|
const typeField = type.fieldsByName[name];
|
|
221
|
-
return [(0, _utils.maybeAddDescriptionComment)(typeField.description, (0, _utils.liftLeadingPropertyComments)(babelTypes.
|
|
215
|
+
return [(0, _utils.maybeAddDescriptionComment)(typeField.description, (0, _utils.liftLeadingPropertyComments)(babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(typeToFlow({ ...ctx,
|
|
222
216
|
path: ctx.path.concat([alias])
|
|
223
|
-
}, typeField.type, selection))))];
|
|
217
|
+
}, typeField.type, selection)))))];
|
|
224
218
|
|
|
225
219
|
default:
|
|
226
|
-
ctx.errors.push( //
|
|
220
|
+
ctx.errors.push( // @ts-expect-error: `selection` is `never` here
|
|
227
221
|
`Unsupported selection kind '${selection.kind}'`);
|
|
228
222
|
return [];
|
|
229
223
|
}
|
|
230
|
-
})
|
|
224
|
+
});
|
|
231
225
|
};
|
|
232
226
|
|
|
233
227
|
exports.objectPropertiesToFlow = objectPropertiesToFlow;
|
|
@@ -248,11 +242,10 @@ const unionOrInterfaceToFlow = (ctx, type, selections) => {
|
|
|
248
242
|
|
|
249
243
|
if (allFields) {
|
|
250
244
|
const sharedAttributes = selectedAttributes[0].attributes.slice();
|
|
251
|
-
const typeNameIndex = selectedAttributes[0].attributes.findIndex(x => x.type === '
|
|
245
|
+
const typeNameIndex = selectedAttributes[0].attributes.findIndex(x => x.type === 'TSPropertySignature' && x.key.type === 'Identifier' && x.key.name === '__typename');
|
|
252
246
|
|
|
253
247
|
if (typeNameIndex !== -1) {
|
|
254
|
-
sharedAttributes[typeNameIndex] = babelTypes.
|
|
255
|
-
attrs.attributes[typeNameIndex].value)));
|
|
248
|
+
sharedAttributes[typeNameIndex] = babelTypes.tsPropertySignature(babelTypes.identifier('__typename'), babelTypes.tsTypeAnnotation(babelTypes.tsUnionType(selectedAttributes.map(attrs => attrs.attributes[typeNameIndex].typeAnnotation.typeAnnotation))));
|
|
256
249
|
}
|
|
257
250
|
|
|
258
251
|
return sortedObjectTypeAnnotation(ctx, sharedAttributes);
|
|
@@ -293,7 +286,7 @@ const unionOrInterfaceToFlow = (ctx, type, selections) => {
|
|
|
293
286
|
*/
|
|
294
287
|
|
|
295
288
|
|
|
296
|
-
const result = babelTypes.
|
|
289
|
+
const result = babelTypes.tsUnionType(selectedAttributes.map(({
|
|
297
290
|
typeName,
|
|
298
291
|
attributes
|
|
299
292
|
}) => sortedObjectTypeAnnotation({ ...ctx,
|
|
@@ -303,7 +296,7 @@ const unionOrInterfaceToFlow = (ctx, type, selections) => {
|
|
|
303
296
|
|
|
304
297
|
if (ctx.allObjectTypes && ctx.path.length > 1) {
|
|
305
298
|
ctx.allObjectTypes[name] = result;
|
|
306
|
-
return babelTypes.
|
|
299
|
+
return babelTypes.tsTypeReference(babelTypes.identifier(name));
|
|
307
300
|
}
|
|
308
301
|
|
|
309
302
|
return result;
|
|
@@ -314,7 +307,7 @@ exports.unionOrInterfaceToFlow = unionOrInterfaceToFlow;
|
|
|
314
307
|
const unionOrInterfaceSelection = (config, type, possible, selection) => {
|
|
315
308
|
if (selection.kind === 'Field' && selection.name.value === '__typename') {
|
|
316
309
|
const alias = selection.alias ? selection.alias.value : selection.name.value;
|
|
317
|
-
return [babelTypes.
|
|
310
|
+
return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsLiteralType(babelTypes.stringLiteral(possible.name))))];
|
|
318
311
|
}
|
|
319
312
|
|
|
320
313
|
if (selection.kind === 'Field' && type.kind !== 'UNION') {
|
|
@@ -324,13 +317,13 @@ const unionOrInterfaceSelection = (config, type, possible, selection) => {
|
|
|
324
317
|
|
|
325
318
|
if (!type.fieldsByName[name]) {
|
|
326
319
|
config.errors.push('Unknown field: ' + name + ' on type ' + type.name + ' for possible ' + possible.name);
|
|
327
|
-
return [babelTypes.
|
|
320
|
+
return [babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(babelTypes.tsTypeReference(babelTypes.identifier(`UNKNOWN_FIELD`))))];
|
|
328
321
|
}
|
|
329
322
|
|
|
330
323
|
const typeField = type.fieldsByName[name];
|
|
331
|
-
return [(0, _utils.liftLeadingPropertyComments)(babelTypes.
|
|
324
|
+
return [(0, _utils.liftLeadingPropertyComments)(babelTypes.tsPropertySignature(babelTypes.identifier(alias), babelTypes.tsTypeAnnotation(typeToFlow({ ...config,
|
|
332
325
|
path: config.path.concat([name])
|
|
333
|
-
}, typeField.type, selection)))];
|
|
326
|
+
}, typeField.type, selection))))];
|
|
334
327
|
}
|
|
335
328
|
|
|
336
329
|
if (selection.kind === 'FragmentSpread') {
|
|
@@ -343,7 +336,7 @@ const unionOrInterfaceSelection = (config, type, possible, selection) => {
|
|
|
343
336
|
const typeName = fragment.typeCondition.name.value;
|
|
344
337
|
|
|
345
338
|
if (config.schema.interfacesByName[typeName] && config.schema.interfacesByName[typeName].possibleTypesByName[possible.name] || typeName === possible.name) {
|
|
346
|
-
return
|
|
339
|
+
return fragment.selectionSet.selections.flatMap(selection => unionOrInterfaceSelection(config, config.schema.typesByName[possible.name], possible, selection));
|
|
347
340
|
} else {
|
|
348
341
|
return [];
|
|
349
342
|
}
|
|
@@ -373,5 +366,4 @@ Try using an inline fragment "... on SomeType {}".`);
|
|
|
373
366
|
}
|
|
374
367
|
|
|
375
368
|
return objectPropertiesToFlow(config, config.schema.typesByName[possible.name], possible.name, selection.selectionSet.selections);
|
|
376
|
-
};
|
|
377
|
-
//# sourceMappingURL=generateResponseType.js.map
|
|
369
|
+
};
|
|
@@ -11,14 +11,9 @@ var _path = _interopRequireDefault(require("path"));
|
|
|
11
11
|
|
|
12
12
|
var _ = require(".");
|
|
13
13
|
|
|
14
|
-
var _convert = require("@khanacademy/flow-to-ts/dist/convert.bundle");
|
|
15
|
-
|
|
16
14
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
const indexPrelude = regenerateCommand => `// @flow
|
|
20
|
-
//
|
|
21
|
-
// AUTOGENERATED
|
|
16
|
+
const indexPrelude = regenerateCommand => `// AUTOGENERATED
|
|
22
17
|
// NOTE: New response types are added to this file automatically.
|
|
23
18
|
// Outdated response types can be removed manually as they are deprecated.
|
|
24
19
|
//${regenerateCommand ? ' To regenerate, run ' + regenerateCommand : ''}
|
|
@@ -29,27 +24,19 @@ const indexPrelude = regenerateCommand => `// @flow
|
|
|
29
24
|
exports.indexPrelude = indexPrelude;
|
|
30
25
|
|
|
31
26
|
const generateTypeFileContents = (fileName, schema, document, options, generatedDir, indexContents) => {
|
|
32
|
-
const files = {}; /// Write export for __generated__/index.
|
|
27
|
+
const files = {}; /// Write export for __generated__/index.ts if it doesn't exist
|
|
33
28
|
|
|
34
29
|
const addToIndex = (filePath, typeName) => {
|
|
35
|
-
if (options.typeScript) {
|
|
30
|
+
if (options.typeScript || options.omitFileExtensions) {
|
|
36
31
|
// Typescript doesn't like file extensions
|
|
37
|
-
filePath = filePath.replace(/\.
|
|
32
|
+
filePath = filePath.replace(/\.ts$/, '');
|
|
38
33
|
}
|
|
39
34
|
|
|
40
|
-
const newLine = `export type {${typeName}} from './${_path.default.basename(filePath)}';`;
|
|
35
|
+
const newLine = `export type {${typeName}} from './${_path.default.basename(filePath)}';`; // We match the entire new line to avoid issues that can arise from
|
|
36
|
+
// prefix matches.
|
|
41
37
|
|
|
42
|
-
if (indexContents.indexOf(
|
|
38
|
+
if (indexContents.indexOf(newLine) === -1) {
|
|
43
39
|
indexContents += newLine + '\n';
|
|
44
|
-
} else {
|
|
45
|
-
const lines = indexContents.split('\n').map(line => {
|
|
46
|
-
if (line.includes('./' + _path.default.basename(filePath))) {
|
|
47
|
-
return newLine;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return line;
|
|
51
|
-
});
|
|
52
|
-
indexContents = lines.join('\n');
|
|
53
40
|
}
|
|
54
41
|
};
|
|
55
42
|
|
|
@@ -64,11 +51,11 @@ const generateTypeFileContents = (fileName, schema, document, options, generated
|
|
|
64
51
|
}) => {
|
|
65
52
|
// We write all generated files to a `__generated__` subdir to keep
|
|
66
53
|
// things tidy.
|
|
67
|
-
const targetFileName = options.typeFileName ? options.typeFileName.replace('[operationName]', name) : `${name}.
|
|
54
|
+
const targetFileName = options.typeFileName ? options.typeFileName.replace('[operationName]', name) : `${name}.ts`;
|
|
68
55
|
|
|
69
56
|
const targetPath = _path.default.join(generatedDir, targetFileName);
|
|
70
57
|
|
|
71
|
-
let fileContents =
|
|
58
|
+
let fileContents = `// AUTOGENERATED -- DO NOT EDIT\n` + `// Generated for operation '${name}' in file '../${_path.default.basename(fileName)}'\n` + (options.regenerateCommand ? `// To regenerate, run '${options.regenerateCommand}'.\n` : '') + code;
|
|
72
59
|
|
|
73
60
|
if (options.splitTypes && !isFragment) {
|
|
74
61
|
fileContents += `\nexport type ${name} = ${typeName}['response'];\n` + `export type ${name}Variables = ${typeName}['variables'];\n`;
|
|
@@ -116,7 +103,7 @@ const getGeneratedDir = (fileName, options) => {
|
|
|
116
103
|
const generateTypeFiles = (fileName, schema, document, options) => {
|
|
117
104
|
const generatedDir = getGeneratedDir(fileName, options);
|
|
118
105
|
|
|
119
|
-
const indexFile = _path.default.join(generatedDir, 'index
|
|
106
|
+
const indexFile = _path.default.join(generatedDir, 'index.ts');
|
|
120
107
|
|
|
121
108
|
if (!_fs.default.existsSync(generatedDir)) {
|
|
122
109
|
_fs.default.mkdirSync(generatedDir, {
|
|
@@ -135,16 +122,8 @@ const generateTypeFiles = (fileName, schema, document, options) => {
|
|
|
135
122
|
|
|
136
123
|
_fs.default.writeFileSync(indexFile, indexContents);
|
|
137
124
|
|
|
138
|
-
Object.keys(files).forEach(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (options.typeScript) {
|
|
142
|
-
// eslint-disable-next-line flowtype-errors/uncovered
|
|
143
|
-
files[key] = (0, _convert.convert)(files[key]).replace(`variables: {}`, `variables: Record<never, never>`);
|
|
144
|
-
fname = key.replace(/\.js$/, '.ts');
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
_fs.default.writeFileSync(fname, files[key]);
|
|
125
|
+
Object.keys(files).forEach(fname => {
|
|
126
|
+
_fs.default.writeFileSync(fname, files[fname]);
|
|
148
127
|
});
|
|
149
128
|
|
|
150
129
|
_fs.default.writeFileSync(indexFile, indexContents);
|
|
@@ -175,5 +154,4 @@ const processPragmas = (generateConfig, crawlConfig, rawSource) => {
|
|
|
175
154
|
}
|
|
176
155
|
};
|
|
177
156
|
|
|
178
|
-
exports.processPragmas = processPragmas;
|
|
179
|
-
//# sourceMappingURL=generateTypeFiles.js.map
|
|
157
|
+
exports.processPragmas = processPragmas;
|
|
@@ -19,31 +19,24 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
19
19
|
|
|
20
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
21
|
|
|
22
|
+
// eslint-disable-line flowtype-errors/uncovered
|
|
22
23
|
const inputObjectToFlow = (ctx, name) => {
|
|
23
24
|
const inputObject = ctx.schema.inputObjectsByName[name];
|
|
24
25
|
|
|
25
26
|
if (!inputObject) {
|
|
26
27
|
ctx.errors.push(`Unknown input object ${name}`);
|
|
27
|
-
return babelTypes.
|
|
28
|
+
return babelTypes.tsLiteralType(babelTypes.stringLiteral(`Unknown input object ${name}`));
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
return (0, _utils.maybeAddDescriptionComment)(inputObject.description,
|
|
31
|
-
/* indexers */
|
|
32
|
-
, undefined
|
|
33
|
-
/* callProperties */
|
|
34
|
-
, undefined
|
|
35
|
-
/* internalSlots */
|
|
36
|
-
, true
|
|
37
|
-
/* exact */
|
|
38
|
-
));
|
|
31
|
+
return (0, _utils.maybeAddDescriptionComment)(inputObject.description, (0, _utils.objectTypeFromProperties)(inputObject.inputFields.map(vbl => (0, _utils.maybeAddDescriptionComment)(vbl.description, maybeOptionalObjectTypeProperty(vbl.name, inputRefToFlow(ctx, vbl.type))))));
|
|
39
32
|
};
|
|
40
33
|
|
|
41
34
|
exports.inputObjectToFlow = inputObjectToFlow;
|
|
42
35
|
|
|
43
36
|
const maybeOptionalObjectTypeProperty = (name, type) => {
|
|
44
|
-
const prop = (0, _utils.liftLeadingPropertyComments)(babelTypes.
|
|
37
|
+
const prop = (0, _utils.liftLeadingPropertyComments)(babelTypes.tsPropertySignature(babelTypes.identifier(name), babelTypes.tsTypeAnnotation(type)));
|
|
45
38
|
|
|
46
|
-
if (
|
|
39
|
+
if ((0, _utils.isnNullableType)(type)) {
|
|
47
40
|
prop.optional = true;
|
|
48
41
|
}
|
|
49
42
|
|
|
@@ -59,7 +52,7 @@ const inputRefToFlow = (ctx, inputRef) => {
|
|
|
59
52
|
|
|
60
53
|
const result = _inputRefToFlow(ctx, inputRef);
|
|
61
54
|
|
|
62
|
-
return (0, _utils.transferLeadingComments)(result,
|
|
55
|
+
return (0, _utils.transferLeadingComments)(result, (0, _utils.nullableType)(result));
|
|
63
56
|
};
|
|
64
57
|
|
|
65
58
|
exports.inputRefToFlow = inputRefToFlow;
|
|
@@ -78,10 +71,10 @@ const _inputRefToFlow = (ctx, inputRef) => {
|
|
|
78
71
|
}
|
|
79
72
|
|
|
80
73
|
if (inputRef.kind === 'LIST') {
|
|
81
|
-
return babelTypes.
|
|
74
|
+
return babelTypes.tsTypeReference(babelTypes.identifier('ReadonlyArray'), babelTypes.tsTypeParameterInstantiation([inputRefToFlow(ctx, inputRef.ofType)]));
|
|
82
75
|
}
|
|
83
76
|
|
|
84
|
-
return babelTypes.
|
|
77
|
+
return babelTypes.tsLiteralType(babelTypes.stringLiteral(JSON.stringify(inputRef)));
|
|
85
78
|
};
|
|
86
79
|
|
|
87
80
|
const variableToFlow = (ctx, type) => {
|
|
@@ -91,7 +84,7 @@ const variableToFlow = (ctx, type) => {
|
|
|
91
84
|
|
|
92
85
|
const result = _variableToFlow(ctx, type);
|
|
93
86
|
|
|
94
|
-
return (0, _utils.transferLeadingComments)(result,
|
|
87
|
+
return (0, _utils.transferLeadingComments)(result, (0, _utils.nullableType)(result));
|
|
95
88
|
};
|
|
96
89
|
|
|
97
90
|
const _variableToFlow = (ctx, type) => {
|
|
@@ -107,33 +100,24 @@ const _variableToFlow = (ctx, type) => {
|
|
|
107
100
|
const customScalarType = ctx.scalars[type.name.value];
|
|
108
101
|
|
|
109
102
|
if (customScalarType) {
|
|
110
|
-
return babelTypes.
|
|
103
|
+
return babelTypes.tsTypeReference(babelTypes.identifier(customScalarType));
|
|
111
104
|
}
|
|
112
105
|
|
|
113
106
|
return inputObjectToFlow(ctx, type.name.value);
|
|
114
107
|
}
|
|
115
108
|
|
|
116
109
|
if (type.kind === 'ListType') {
|
|
117
|
-
return babelTypes.
|
|
110
|
+
return babelTypes.tsTypeReference(babelTypes.identifier('ReadonlyArray'), babelTypes.tsTypeParameterInstantiation([variableToFlow(ctx, type.type)]));
|
|
118
111
|
}
|
|
119
112
|
|
|
120
|
-
return babelTypes.
|
|
113
|
+
return babelTypes.tsLiteralType(babelTypes.stringLiteral('UNKNOWN' + JSON.stringify(type)));
|
|
121
114
|
};
|
|
122
115
|
|
|
123
116
|
const generateVariablesType = (schema, item, ctx) => {
|
|
124
|
-
const variableObject =
|
|
117
|
+
const variableObject = (0, _utils.objectTypeFromProperties)((item.variableDefinitions || []).map(vbl => {
|
|
125
118
|
return maybeOptionalObjectTypeProperty(vbl.variable.name.value, variableToFlow(ctx, vbl.type));
|
|
126
|
-
})
|
|
127
|
-
/* indexers */
|
|
128
|
-
, undefined
|
|
129
|
-
/* callProperties */
|
|
130
|
-
, undefined
|
|
131
|
-
/* internalSlots */
|
|
132
|
-
, true
|
|
133
|
-
/* exact */
|
|
134
|
-
);
|
|
119
|
+
}));
|
|
135
120
|
return (0, _generator.default)(variableObject).code; // eslint-disable-line flowtype-errors/uncovered
|
|
136
121
|
};
|
|
137
122
|
|
|
138
|
-
exports.generateVariablesType = generateVariablesType;
|
|
139
|
-
//# sourceMappingURL=generateVariablesType.js.map
|
|
123
|
+
exports.generateVariablesType = generateVariablesType;
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.documentToFlowTypes = exports.FlowGenerationError = void 0;
|
|
7
7
|
|
|
8
|
+
var _wonderStuffCore = require("@khanacademy/wonder-stuff-core");
|
|
9
|
+
|
|
8
10
|
var _generator = _interopRequireDefault(require("@babel/generator"));
|
|
9
11
|
|
|
10
12
|
var _generateResponseType = require("./generateResponseType");
|
|
@@ -13,25 +15,16 @@ var _generateVariablesType = require("./generateVariablesType");
|
|
|
13
15
|
|
|
14
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
17
|
|
|
16
|
-
/* eslint-disable no-console */
|
|
17
|
-
|
|
18
|
-
/* flow-uncovered-file */
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* This tool generates flowtype definitions from graphql queries.
|
|
22
|
-
*
|
|
23
|
-
* It relies on `introspection-query.json` existing in this directory,
|
|
24
|
-
* which is produced by running `./tools/graphql-flow/sendIntrospection.js`.
|
|
25
|
-
*/
|
|
26
18
|
// eslint-disable-line flowtype-errors/uncovered
|
|
27
19
|
const optionsToConfig = (schema, definitions, options, errors = []) => {
|
|
28
|
-
var _options$strictNullab, _options$readOnlyArra, _options$scalars, _options$typeScript;
|
|
20
|
+
var _options$strictNullab, _options$readOnlyArra, _options$scalars, _options$typeScript, _options$omitFileExte;
|
|
29
21
|
|
|
30
22
|
const internalOptions = {
|
|
31
23
|
strictNullability: (_options$strictNullab = options === null || options === void 0 ? void 0 : options.strictNullability) !== null && _options$strictNullab !== void 0 ? _options$strictNullab : true,
|
|
32
24
|
readOnlyArray: (_options$readOnlyArra = options === null || options === void 0 ? void 0 : options.readOnlyArray) !== null && _options$readOnlyArra !== void 0 ? _options$readOnlyArra : true,
|
|
33
25
|
scalars: (_options$scalars = options === null || options === void 0 ? void 0 : options.scalars) !== null && _options$scalars !== void 0 ? _options$scalars : {},
|
|
34
|
-
typeScript: (_options$typeScript = options === null || options === void 0 ? void 0 : options.typeScript) !== null && _options$typeScript !== void 0 ? _options$typeScript : false
|
|
26
|
+
typeScript: (_options$typeScript = options === null || options === void 0 ? void 0 : options.typeScript) !== null && _options$typeScript !== void 0 ? _options$typeScript : false,
|
|
27
|
+
omitFileExtensions: (_options$omitFileExte = options === null || options === void 0 ? void 0 : options.omitFileExtensions) !== null && _options$omitFileExte !== void 0 ? _options$omitFileExte : false
|
|
35
28
|
};
|
|
36
29
|
const fragments = {};
|
|
37
30
|
definitions.forEach(def => {
|
|
@@ -47,7 +40,9 @@ const optionsToConfig = (schema, definitions, options, errors = []) => {
|
|
|
47
40
|
path: [],
|
|
48
41
|
experimentalEnumsMap: options !== null && options !== void 0 && options.experimentalEnums ? {} : undefined,
|
|
49
42
|
...internalOptions
|
|
50
|
-
};
|
|
43
|
+
}; // @ts-expect-error: TS2322 - The type 'readonly []' is 'readonly' and cannot be
|
|
44
|
+
// assigned to the mutable type 'string[]'.
|
|
45
|
+
|
|
51
46
|
return config;
|
|
52
47
|
};
|
|
53
48
|
|
|
@@ -97,7 +92,7 @@ const documentToFlowTypes = (document, schema, options) => {
|
|
|
97
92
|
const typeName = `${name}Type`; // TODO(jared): Maybe make this template configurable?
|
|
98
93
|
// We'll see what's required to get webapp on board.
|
|
99
94
|
|
|
100
|
-
const code = `export type ${typeName} = {
|
|
95
|
+
const code = `export type ${typeName} = {\n variables: ${variables},\n response: ${response}\n};`;
|
|
101
96
|
const extraTypes = codegenExtraTypes(types);
|
|
102
97
|
const experimentalEnums = codegenExtraTypes(config.experimentalEnumsMap || {});
|
|
103
98
|
return {
|
|
@@ -108,7 +103,7 @@ const documentToFlowTypes = (document, schema, options) => {
|
|
|
108
103
|
experimentalEnums
|
|
109
104
|
};
|
|
110
105
|
}
|
|
111
|
-
}).filter(
|
|
106
|
+
}).filter(_wonderStuffCore.isTruthy);
|
|
112
107
|
|
|
113
108
|
if (errors.length) {
|
|
114
109
|
throw new FlowGenerationError(errors);
|
|
@@ -126,5 +121,4 @@ function codegenExtraTypes(types) {
|
|
|
126
121
|
extraTypes[k] = (0, _generator.default)(types[k]).code;
|
|
127
122
|
});
|
|
128
123
|
return extraTypes;
|
|
129
|
-
}
|
|
130
|
-
//# sourceMappingURL=index.js.map
|
|
124
|
+
}
|