-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathindex.ts
117 lines (99 loc) · 3.74 KB
/
index.ts
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
114
115
116
117
import * as fs from 'fs';
import * as path from 'path';
import { GraphQLSchema, buildSchema, IntrospectionQuery, BuildSchemaOptions } from 'graphql';
import { GenerateTypescriptOptions, defaultOptions } from './types';
import { TSResolverGenerator, GenerateResolversResult } from './typescriptResolverGenerator';
import { TypeScriptGenerator } from './typescriptGenerator';
import { formatTabSpace, introspectSchema, introspectSchemaViaLocalFile } from './utils';
export { GenerateTypescriptOptions } from './types';
const packageJson = require(path.join(__dirname, '../package.json'));
const jsDoc =
`/**
* This file is auto-generated by ${packageJson.name}
* Please note that any changes in this file may be overwritten
*/
`;
const typeDefsDecoration = [
'/*******************************',
' * *',
' * TYPE DEFS *',
' * *',
' *******************************/'
];
const typeResolversDecoration = [
'/*********************************',
' * *',
' * TYPE RESOLVERS *',
' * *',
' *********************************/'
];
export const generateTSTypesAsString = async (
schema: GraphQLSchema | string,
outputPath: string,
options: GenerateTypescriptOptions,
buildOptions?: BuildSchemaOptions
): Promise<string> => {
const mergedOptions = { ...defaultOptions, ...options };
const getIntrospectResult = async (): Promise<IntrospectionQuery> => {
if (typeof schema !== 'string') {
return introspectSchema(schema);
}
// is is a path to schema folder?
try {
const schemaPath = path.resolve(schema);
const exists = fs.existsSync(schemaPath);
if (exists) {
return introspectSchemaViaLocalFile(schemaPath, buildOptions);
}
} catch {
// fall-through in case the provided string is a graphql definition,
// which can make path.resolve throw error
}
const schemaViaStr = buildSchema(schema, buildOptions);
return introspectSchema(schemaViaStr);
};
const introspectResult = await getIntrospectResult();
const tsGenerator = new TypeScriptGenerator(mergedOptions, introspectResult, outputPath);
const typeDefs = await tsGenerator.generate();
let typeResolvers: GenerateResolversResult = {
body: [],
importHeader: []
};
const tsResolverGenerator = new TSResolverGenerator(mergedOptions, introspectResult);
typeResolvers = await tsResolverGenerator.generate();
let header = [...typeResolvers.importHeader, jsDoc];
let body: string[] = [
...typeDefsDecoration,
...typeDefs,
...typeResolversDecoration,
...typeResolvers.body
];
if (mergedOptions.namespace) {
body = [
// if namespace is under global, it doesn't need to be declared again
`${mergedOptions.global ? '' : 'declare '}namespace ${options.namespace} {`,
...body,
'}'
];
}
if (mergedOptions.global) {
body = [
'export { };',
'',
'declare global {',
...body,
'}'
];
}
const formatted = formatTabSpace([...header, ...body], mergedOptions.tabSpaces);
return formatted.join('\n');
};
export async function generateTypeScriptTypes(
schema: GraphQLSchema | string,
outputPath: string,
options: GenerateTypescriptOptions = defaultOptions,
buildOptions?: BuildSchemaOptions
) {
const content = await generateTSTypesAsString(schema, outputPath, options, buildOptions);
fs.writeFileSync(outputPath, content, 'utf-8');
}