UNPKG

5.49 kBJavaScriptView Raw
1"use strict";
2// This file is copied from `apollographql/federation`. The only difference is
3// that it has a hack to not remove federation specific properties.
4// https://github.com/apollographql/federation/blob/main/subgraph-js/src/schema-helper/transformSchema.ts
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.transformSchema = void 0;
7const graphql_1 = require("graphql");
8function transformSchema(schema, transformType) {
9 const typeMap = Object.create(null);
10 for (const oldType of Object.values(schema.getTypeMap())) {
11 if ((0, graphql_1.isIntrospectionType)(oldType))
12 continue;
13 const result = transformType(oldType);
14 // Returning `null` removes the type.
15 if (result === null)
16 continue;
17 // Returning `undefined` keeps the old type.
18 const newType = result || oldType;
19 typeMap[newType.name] = recreateNamedType(newType);
20 }
21 const schemaConfig = schema.toConfig();
22 return new graphql_1.GraphQLSchema({
23 ...schemaConfig,
24 types: Object.values(typeMap),
25 query: replaceMaybeType(schemaConfig.query),
26 mutation: replaceMaybeType(schemaConfig.mutation),
27 subscription: replaceMaybeType(schemaConfig.subscription),
28 directives: replaceDirectives([...schemaConfig.directives]),
29 });
30 function recreateNamedType(type) {
31 if ((0, graphql_1.isObjectType)(type)) {
32 const config = type.toConfig();
33 const objectType = new graphql_1.GraphQLObjectType({
34 ...config,
35 interfaces: () => config.interfaces.map(replaceNamedType),
36 fields: () => replaceFields(config.fields),
37 });
38 if (type.extensions?.apollo?.subgraph?.resolveReference) {
39 objectType.extensions = {
40 ...objectType.extensions,
41 apollo: {
42 ...objectType.extensions.apollo,
43 subgraph: {
44 ...objectType.extensions.apollo.subgraph,
45 resolveReference: type.extensions.apollo.subgraph.resolveReference,
46 },
47 },
48 };
49 /**
50 * Backcompat for old versions of @apollo/subgraph which didn't use
51 * `extensions` This can be removed when support for @apollo/subgraph <
52 * 0.4.2 is dropped Reference:
53 * https://github.com/apollographql/federation/pull/1747
54 */
55 // @ts-expect-error (explanation above)
56 }
57 else if (type.resolveReference) {
58 // @ts-expect-error (explanation above)
59 objectType.resolveReference = type.resolveReference;
60 }
61 return objectType;
62 }
63 else if ((0, graphql_1.isInterfaceType)(type)) {
64 const config = type.toConfig();
65 return new graphql_1.GraphQLInterfaceType({
66 ...config,
67 interfaces: () => config.interfaces.map(replaceNamedType),
68 fields: () => replaceFields(config.fields),
69 });
70 }
71 else if ((0, graphql_1.isUnionType)(type)) {
72 const config = type.toConfig();
73 return new graphql_1.GraphQLUnionType({
74 ...config,
75 types: () => config.types.map(replaceNamedType),
76 });
77 }
78 else if ((0, graphql_1.isInputObjectType)(type)) {
79 const config = type.toConfig();
80 return new graphql_1.GraphQLInputObjectType({
81 ...config,
82 fields: () => replaceInputFields(config.fields),
83 });
84 }
85 return type;
86 }
87 function replaceType(type) {
88 if ((0, graphql_1.isListType)(type)) {
89 return new graphql_1.GraphQLList(replaceType(type.ofType));
90 }
91 else if ((0, graphql_1.isNonNullType)(type)) {
92 return new graphql_1.GraphQLNonNull(replaceType(type.ofType));
93 }
94 return replaceNamedType(type);
95 }
96 function replaceNamedType(type) {
97 const newType = typeMap[type.name];
98 return newType ? newType : type;
99 }
100 function replaceMaybeType(type) {
101 return type ? replaceNamedType(type) : undefined;
102 }
103 function replaceFields(fieldsMap) {
104 return mapValues(fieldsMap, (field) => ({
105 ...field,
106 type: replaceType(field.type),
107 args: field.args ? replaceArgs(field.args) : undefined,
108 }));
109 }
110 function replaceInputFields(fieldsMap) {
111 return mapValues(fieldsMap, (field) => ({
112 ...field,
113 type: replaceType(field.type),
114 }));
115 }
116 function replaceArgs(args) {
117 return mapValues(args, (arg) => ({
118 ...arg,
119 type: replaceType(arg.type),
120 }));
121 }
122 function replaceDirectives(directives) {
123 return directives.map((directive) => {
124 const config = directive.toConfig();
125 return new graphql_1.GraphQLDirective({
126 ...config,
127 args: replaceArgs(config.args),
128 });
129 });
130 }
131}
132exports.transformSchema = transformSchema;
133function mapValues(object, callback) {
134 const result = Object.create(null);
135 for (const [key, value] of Object.entries(object)) {
136 result[key] = callback(value);
137 }
138 return result;
139}