UNPKG

2.98 kBJavaScriptView Raw
1import { oldVisit } from '@graphql-codegen/plugin-helpers';
2import { parse, visit, TypeInfo, visitWithTypeInfo, getNamedType, isIntrospectionType, printIntrospectionSchema, isObjectType, } from 'graphql';
3import { TsVisitor } from './visitor.js';
4import { TsIntrospectionVisitor } from './introspection-visitor.js';
5import { transformSchemaAST } from '@graphql-codegen/schema-ast';
6export * from './typescript-variables-to-object.js';
7export * from './visitor.js';
8export * from './config.js';
9export * from './introspection-visitor.js';
10export const plugin = (schema, documents, config) => {
11 const { schema: _schema, ast } = transformSchemaAST(schema, config);
12 const visitor = new TsVisitor(_schema, config);
13 const visitorResult = oldVisit(ast, { leave: visitor });
14 const introspectionDefinitions = includeIntrospectionTypesDefinitions(_schema, documents, config);
15 const scalars = visitor.scalarsDefinition;
16 const directiveArgumentAndInputFieldMappings = visitor.directiveArgumentAndInputFieldMappingsDefinition;
17 return {
18 prepend: [
19 ...visitor.getEnumsImports(),
20 ...visitor.getDirectiveArgumentAndInputFieldMappingsImports(),
21 ...visitor.getScalarsImports(),
22 ...visitor.getWrapperDefinitions(),
23 ].filter(Boolean),
24 content: [
25 scalars,
26 directiveArgumentAndInputFieldMappings,
27 ...visitorResult.definitions,
28 ...introspectionDefinitions,
29 ]
30 .filter(Boolean)
31 .join('\n'),
32 };
33};
34export function includeIntrospectionTypesDefinitions(schema, documents, config) {
35 const typeInfo = new TypeInfo(schema);
36 const usedTypes = [];
37 const documentsVisitor = visitWithTypeInfo(typeInfo, {
38 Field() {
39 const type = getNamedType(typeInfo.getType());
40 if (type && isIntrospectionType(type) && !usedTypes.includes(type)) {
41 usedTypes.push(type);
42 }
43 },
44 });
45 documents.forEach(doc => visit(doc.document, documentsVisitor));
46 const typesToInclude = [];
47 usedTypes.forEach(type => {
48 collectTypes(type);
49 });
50 const visitor = new TsIntrospectionVisitor(schema, config, typesToInclude);
51 const result = oldVisit(parse(printIntrospectionSchema(schema)), { leave: visitor });
52 // recursively go through each `usedTypes` and their children and collect all used types
53 // we don't care about Interfaces, Unions and others, but Objects and Enums
54 function collectTypes(type) {
55 if (typesToInclude.includes(type)) {
56 return;
57 }
58 typesToInclude.push(type);
59 if (isObjectType(type)) {
60 const fields = type.getFields();
61 Object.keys(fields).forEach(key => {
62 const field = fields[key];
63 const type = getNamedType(field.type);
64 collectTypes(type);
65 });
66 }
67 }
68 return result.definitions;
69}