1 | "use strict";
|
2 | var __importStar = (this && this.__importStar) || function (mod) {
|
3 | if (mod && mod.__esModule) return mod;
|
4 | var result = {};
|
5 | if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
|
6 | result["default"] = mod;
|
7 | return result;
|
8 | };
|
9 | Object.defineProperty(exports, "__esModule", { value: true });
|
10 | const t = __importStar(require("@babel/types"));
|
11 | const graphql_1 = require("graphql");
|
12 | const graphql_tool_utilities_1 = require("graphql-tool-utilities");
|
13 | const utilities_1 = require("../utilities");
|
14 | function tsInterfaceBodyForObjectField({ fields = [] }, graphQLType, stack, context, requiresTypename = false) {
|
15 | const { schema } = context.ast;
|
16 | const isRootType = !Array.isArray(graphQLType) &&
|
17 | (graphQLType === schema.getQueryType() ||
|
18 | graphQLType === schema.getMutationType() ||
|
19 | graphQLType === schema.getSubscriptionType());
|
20 | const uniqueFields = fields.filter((field) => {
|
21 | if (stack.hasSeenField(field)) {
|
22 | return false;
|
23 | }
|
24 | stack.sawField(field);
|
25 | return true;
|
26 | });
|
27 | const typenameField = {
|
28 | fieldName: '__typename',
|
29 | responseName: '__typename',
|
30 | type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString),
|
31 | isConditional: false,
|
32 | };
|
33 | const typename = ((context.options.addTypename && !isRootType) || requiresTypename) &&
|
34 | !stack.hasSeenField(typenameField)
|
35 | ? tsPropertyForField(typenameField, graphQLType, stack, context, requiresTypename)
|
36 | : null;
|
37 | const body = uniqueFields.map((field) => tsPropertyForField(field, graphQLType, stack, context, requiresTypename));
|
38 | return t.tsInterfaceBody(typename ? [typename, ...body] : body);
|
39 | }
|
40 | exports.tsInterfaceBodyForObjectField = tsInterfaceBodyForObjectField;
|
41 | function tsTypeForInlineFragment(inlineFragment, _graphQLType, stack, context, requiresTypename = false) {
|
42 | const { typeCondition } = inlineFragment;
|
43 | const interfaceDeclaration = t.tsInterfaceDeclaration(t.identifier(stack.name), null, null, tsInterfaceBodyForObjectField(inlineFragment, typeCondition, stack, context, requiresTypename));
|
44 | return context.export(interfaceDeclaration);
|
45 | }
|
46 | function tsTypeForObjectField(field, graphQLType, stack, context) {
|
47 | const { inlineFragments = [] } = field;
|
48 | const possibleTypes = graphql_1.isInterfaceType(graphQLType) || graphql_1.isUnionType(graphQLType)
|
49 | ? context.ast.schema.getPossibleTypes(graphQLType)
|
50 | : [];
|
51 | if (inlineFragments.length) {
|
52 | const fragmentTypes = [...inlineFragments].map((inlineFragment) => tsTypeForInlineFragment(inlineFragment, graphQLType, stack.fragment(inlineFragment.typeCondition), context, context.options.partial));
|
53 | const typesCoveredByInlineFragments = new Set([...inlineFragments].reduce((types, inlineFragment) => [...types, ...inlineFragment.possibleTypes], []));
|
54 | const missingPossibleTypes = possibleTypes.filter((possibleType) => {
|
55 | return !typesCoveredByInlineFragments.has(possibleType);
|
56 | });
|
57 | const otherStack = stack.fragment();
|
58 | const otherTypeInterface = t.tsInterfaceDeclaration(t.identifier(otherStack.name), null, null, tsInterfaceBodyForObjectField(field, missingPossibleTypes, otherStack, context, context.options.partial));
|
59 | const otherType = context.export(otherTypeInterface);
|
60 | return t.tsUnionType([...fragmentTypes, otherType]);
|
61 | }
|
62 | else if (possibleTypes.length === 1) {
|
63 |
|
64 |
|
65 |
|
66 |
|
67 | const otherStack = stack.fragment();
|
68 | const otherTypeInterface = t.tsInterfaceDeclaration(t.identifier(otherStack.name), null, null, tsInterfaceBodyForObjectField({ fields: [] }, [], otherStack, context, context.options.partial));
|
69 | const interfaceStack = stack.fragment(possibleTypes[0]);
|
70 | const interfaceDeclaration = t.tsInterfaceDeclaration(t.identifier(interfaceStack.name), null, null, tsInterfaceBodyForObjectField(field, graphQLType, interfaceStack, context));
|
71 | return t.tsUnionType([
|
72 | context.export(interfaceDeclaration),
|
73 | context.export(otherTypeInterface),
|
74 | ]);
|
75 | }
|
76 | const interfaceDeclaration = t.tsInterfaceDeclaration(t.identifier(stack.name), null, null, tsInterfaceBodyForObjectField(field, graphQLType, stack, context));
|
77 | return context.export(interfaceDeclaration);
|
78 | }
|
79 | function tsTypenameForGraphQLType(type) {
|
80 | return t.tsLiteralType(t.stringLiteral(type.name));
|
81 | }
|
82 | function tsPropertyForField(field, parentType, stack, context, isRequiredTypename = false) {
|
83 | if (field.fieldName === '__typename' && parentType) {
|
84 | const optional = !isRequiredTypename &&
|
85 | (context.options.partial ||
|
86 | field.isConditional ||
|
87 | !graphql_1.isNonNullType(field.type));
|
88 | const parentTypes = Array.isArray(parentType) ? parentType : [parentType];
|
89 | const allPossibleTypes = parentTypes.reduce((all, type) => [
|
90 | ...all,
|
91 | ...(graphql_1.isAbstractType(type)
|
92 | ? context.ast.schema.getPossibleTypes(type)
|
93 | : [type]),
|
94 | ], []);
|
95 | let typename;
|
96 | if (allPossibleTypes.length === 0) {
|
97 | typename = t.tsLiteralType(t.stringLiteral(''));
|
98 | }
|
99 | else if (allPossibleTypes.length > 1) {
|
100 | typename = t.tsUnionType(allPossibleTypes.map(tsTypenameForGraphQLType));
|
101 | }
|
102 | else {
|
103 | typename = tsTypenameForGraphQLType(allPossibleTypes[0]);
|
104 | }
|
105 | const typenameProperty = t.tsPropertySignature(t.identifier(field.responseName), optional
|
106 | ? t.tsTypeAnnotation(t.tsUnionType([typename, t.tsNullKeyword()]))
|
107 | : t.tsTypeAnnotation(typename));
|
108 | typenameProperty.optional = optional;
|
109 | return typenameProperty;
|
110 | }
|
111 | const property = t.tsPropertySignature(t.identifier(field.responseName), t.tsTypeAnnotation(tsTypeForGraphQLType(field.type, field, stack, context)));
|
112 | property.optional =
|
113 | context.options.partial ||
|
114 | field.isConditional ||
|
115 | !graphql_1.isNonNullType(field.type);
|
116 | return property;
|
117 | }
|
118 | function tsTypeForGraphQLType(graphQLType, field, stack, context) {
|
119 | let type;
|
120 | const forceNullable = context.options.partial ||
|
121 | (field.isConditional && graphQLType === field.type);
|
122 | const isNonNull = !forceNullable && graphql_1.isNonNullType(graphQLType);
|
123 | const unwrappedGraphQLType = graphql_1.isNonNullType(graphQLType)
|
124 | ? graphQLType.ofType
|
125 | : graphQLType;
|
126 | if (graphql_1.isScalarType(unwrappedGraphQLType)) {
|
127 | if (utilities_1.scalarTypeMap.hasOwnProperty(unwrappedGraphQLType.name)) {
|
128 | type = utilities_1.scalarTypeMap[unwrappedGraphQLType.name];
|
129 | }
|
130 | else {
|
131 | context.file.import(unwrappedGraphQLType.name);
|
132 | type = t.tsTypeReference(t.identifier(unwrappedGraphQLType.name));
|
133 | }
|
134 | }
|
135 | else if (graphql_1.isEnumType(unwrappedGraphQLType)) {
|
136 | context.file.import(unwrappedGraphQLType.name);
|
137 | type = t.tsTypeReference(t.identifier(unwrappedGraphQLType.name));
|
138 | }
|
139 | else if (graphql_1.isListType(unwrappedGraphQLType)) {
|
140 | const { ofType } = unwrappedGraphQLType;
|
141 | const arrayType = tsTypeForGraphQLType(ofType, field, stack, context);
|
142 | type = t.tsArrayType(t.isTSUnionType(arrayType) ? t.tsParenthesizedType(arrayType) : arrayType);
|
143 | }
|
144 | else if (graphql_1.isObjectType(unwrappedGraphQLType) ||
|
145 | graphql_1.isInterfaceType(unwrappedGraphQLType) ||
|
146 | graphql_1.isUnionType(unwrappedGraphQLType)) {
|
147 | type = tsTypeForObjectField(field, unwrappedGraphQLType, stack.nested(field, unwrappedGraphQLType), context);
|
148 | }
|
149 | else {
|
150 | type = t.tsAnyKeyword();
|
151 | }
|
152 | return isNonNull ? type : t.tsUnionType([type, t.tsNullKeyword()]);
|
153 | }
|
154 | function variablesInterface(variables, context) {
|
155 | return t.tsInterfaceDeclaration(t.identifier('Variables'), null, null, t.tsInterfaceBody(variables
|
156 | .filter(graphql_tool_utilities_1.isTypedVariable)
|
157 | .map((variable) => tsPropertyForVariable(variable, context))));
|
158 | }
|
159 | exports.variablesInterface = variablesInterface;
|
160 | function tsPropertyForVariable({ name, type }, context) {
|
161 | const property = t.tsPropertySignature(t.identifier(name), t.tsTypeAnnotation(tsTypeForGraphQLInputType(type, context)));
|
162 | property.optional = !graphql_1.isNonNullType(type);
|
163 | return property;
|
164 | }
|
165 | function tsTypeForGraphQLInputType(graphQLType, context) {
|
166 | let type;
|
167 | const unwrappedGraphQLType = graphql_1.isNonNullType(graphQLType)
|
168 | ? graphQLType.ofType
|
169 | : graphQLType;
|
170 | if (graphql_1.isScalarType(unwrappedGraphQLType)) {
|
171 | if (utilities_1.scalarTypeMap.hasOwnProperty(unwrappedGraphQLType.name)) {
|
172 | type = utilities_1.scalarTypeMap[unwrappedGraphQLType.name];
|
173 | }
|
174 | else {
|
175 | context.file.import(unwrappedGraphQLType.name);
|
176 | type = t.tsTypeReference(t.identifier(unwrappedGraphQLType.name));
|
177 | }
|
178 | }
|
179 | else if (graphql_1.isEnumType(unwrappedGraphQLType) ||
|
180 | graphql_1.isInputObjectType(unwrappedGraphQLType)) {
|
181 | context.file.import(unwrappedGraphQLType.name);
|
182 | type = t.tsTypeReference(t.identifier(unwrappedGraphQLType.name));
|
183 | }
|
184 | else {
|
185 | const { ofType } = unwrappedGraphQLType;
|
186 | const arrayType = tsTypeForGraphQLInputType(ofType, context);
|
187 | type = t.tsArrayType(graphql_1.isNonNullType(ofType) ? arrayType : t.tsParenthesizedType(arrayType));
|
188 | }
|
189 | return graphql_1.isNonNullType(graphQLType)
|
190 | ? type
|
191 | : t.tsUnionType([type, t.tsNullKeyword()]);
|
192 | }
|