-
Notifications
You must be signed in to change notification settings - Fork 192
Expand file tree
/
Copy pathbase-plugin.ts
More file actions
113 lines (99 loc) · 3.11 KB
/
base-plugin.ts
File metadata and controls
113 lines (99 loc) · 3.11 KB
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
112
113
import { GraphQLSchema } from 'graphql';
import { Types } from '@graphql-codegen/plugin-helpers';
import { ScalaBaseVisitor } from './base-visitor';
import { ScalaPluginCommonRawConfig } from './config';
export type BasePluginFunction<TRawConfig extends ScalaPluginCommonRawConfig> = (
schema: GraphQLSchema,
documents: Types.DocumentFile[],
config: TRawConfig,
info: { outputFile?: string },
) => Types.PluginOutput;
export const createBasePlugin = <
TRawConfig extends ScalaPluginCommonRawConfig,
TVisitor extends ScalaBaseVisitor<TRawConfig, any>,
>(
createVisitor: (
schema: GraphQLSchema,
config: TRawConfig,
outputFileInfo: { outputFile?: string },
) => TVisitor,
): BasePluginFunction<TRawConfig> => {
return (
schema: GraphQLSchema,
_: Types.DocumentFile[],
config: TRawConfig,
info: { outputFile?: string },
): Types.PluginOutput => {
if (!config.packageName && info.outputFile) {
const parts = info.outputFile.split('/');
parts.pop();
if (parts.length > 0) {
config = {
...config,
packageName: parts.join('.'),
};
}
}
const visitor = createVisitor(schema, config, { outputFile: info.outputFile });
const typeNames = Object.keys(schema.getTypeMap()).filter(
typeName => !typeName.startsWith('__'),
);
const header = [
visitor.getPackage(),
'',
visitor.getImports(),
'',
'getTypeClassDefinitions' in visitor ? (visitor as any).getTypeClassDefinitions() : '',
]
.filter(Boolean)
.join('\n');
const schemaScalarTypeNames = typeNames.filter(typeName => {
const type = schema.getTypeMap()[typeName];
return type.astNode?.kind === 'ScalarTypeDefinition';
});
const customScalarDefinitions: string[] = [];
if (config.scalars) {
Object.keys(config.scalars).forEach(scalarName => {
if (typeof config.scalars[scalarName] === 'string') {
const scalarType = config.scalars[scalarName];
customScalarDefinitions.push(`type ${scalarName} = ${scalarType}`);
}
});
}
const defaultScalars = visitor.generateCustomScalars
? visitor.generateCustomScalars([
...schemaScalarTypeNames,
...Object.keys(config.scalars || {}),
])
: [];
const contentFragments = typeNames.map(typeName => {
const type = schema.getTypeMap()[typeName];
if (
type.astNode?.kind === 'ScalarTypeDefinition' &&
config.scalars &&
typeof config.scalars[typeName] === 'string'
) {
return '';
}
const astNodeKind = type.astNode?.kind as string | undefined;
if (astNodeKind && astNodeKind in visitor) {
const handler = (visitor as any)[astNodeKind];
if (typeof handler === 'function') {
return handler.call(visitor, type.astNode);
}
}
return '';
});
const content = [
header,
...customScalarDefinitions,
...defaultScalars,
...contentFragments.filter(Boolean),
].join('\n\n');
return {
content,
prepend: [],
append: [],
};
};
};