forked from nestjs/graphql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphql-schema.builder.ts
More file actions
125 lines (119 loc) · 3.84 KB
/
graphql-schema.builder.ts
File metadata and controls
125 lines (119 loc) · 3.84 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
114
115
116
117
118
119
120
121
122
123
124
125
import { Injectable } from '@nestjs/common';
import { loadPackage } from '@nestjs/common/utils/load-package.util';
import { isString } from '@nestjs/common/utils/shared.utils';
import {
GraphQLSchema,
lexicographicSortSchema,
specifiedDirectives,
} from 'graphql';
import { printSchema } from '@apollo/federation';
import { resolve } from 'path';
import { GRAPHQL_SDL_FILE_HEADER } from './graphql.constants';
import { GqlModuleOptions } from './interfaces';
import { BuildSchemaOptions } from './interfaces/build-schema-options.interface';
import { GraphQLSchemaFactory } from './schema-builder/graphql-schema.factory';
import { FileSystemHelper } from './schema-builder/helpers/file-system.helper';
import { ScalarsExplorerService } from './services';
@Injectable()
export class GraphQLSchemaBuilder {
constructor(
private readonly scalarsExplorerService: ScalarsExplorerService,
private readonly gqlSchemaFactory: GraphQLSchemaFactory,
private readonly fileSystemHelper: FileSystemHelper,
) {}
async build(
autoSchemaFile: string | boolean,
options: GqlModuleOptions,
resolvers: Function[],
): Promise<any> {
const scalarsMap = this.scalarsExplorerService.getScalarsMap();
try {
const buildSchemaOptions = options.buildSchemaOptions || {};
return await this.buildSchema(
resolvers,
autoSchemaFile,
{
...buildSchemaOptions,
scalarsMap,
schemaDirectives: options.schemaDirectives,
schemaTransforms: options.schemaTransforms,
},
options.sortSchema,
options.transformAutoSchemaFile && options.transformSchema,
);
} catch (err) {
if (err && err.details) {
console.error(err.details);
}
throw err;
}
}
async buildFederatedSchema(
autoSchemaFile: string | boolean,
options: GqlModuleOptions,
resolvers: Function[],
) {
const scalarsMap = this.scalarsExplorerService.getScalarsMap();
try {
const buildSchemaOptions = options.buildSchemaOptions || {};
return await this.buildSchema(
resolvers,
autoSchemaFile,
{
...buildSchemaOptions,
directives: [
...specifiedDirectives,
...this.loadFederationDirectives(),
...((buildSchemaOptions && buildSchemaOptions.directives) || []),
],
scalarsMap,
schemaDirectives: options.schemaDirectives,
skipCheck: true,
},
options.sortSchema,
options.transformAutoSchemaFile && options.transformSchema,
);
} catch (err) {
if (err && err.details) {
console.error(err.details);
}
throw err;
}
}
private async buildSchema(
resolvers: Function[],
autoSchemaFile: boolean | string,
options: BuildSchemaOptions = {},
sortSchema?: boolean,
transformSchema?: (
schema: GraphQLSchema,
) => GraphQLSchema | Promise<GraphQLSchema>,
): Promise<GraphQLSchema> {
const schema = await this.gqlSchemaFactory.create(resolvers, options);
if (typeof autoSchemaFile !== 'boolean') {
const filename = isString(autoSchemaFile)
? autoSchemaFile
: resolve(process.cwd(), 'schema.gql');
const transformedSchema = transformSchema
? await transformSchema(schema)
: schema;
const fileContent =
GRAPHQL_SDL_FILE_HEADER +
printSchema(
sortSchema
? lexicographicSortSchema(transformedSchema)
: transformedSchema,
);
await this.fileSystemHelper.writeFile(filename, fileContent);
}
return schema;
}
private loadFederationDirectives() {
const { federationDirectives } = loadPackage(
'@apollo/federation/dist/directives',
'SchemaBuilder',
() => require('@apollo/federation/dist/directives'),
);
return federationDirectives;
}
}