@trackunit/graphql-build-tools 0.0.15 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## 0.0.16 (2026-06-24)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **graphql-build-tools:** preserve schema directives and drop emptied root types when reconciling root operations ([fdc403007aa](https://github.com/Trackunit/manager/commit/fdc403007aa))
6
+ - **graphql-build-tools:** drop dangling root operation bindings when @hidden empties a root type ([af908369e9f](https://github.com/Trackunit/manager/commit/af908369e9f))
7
+
8
+ ### ❤️ Thank You
9
+
10
+ - Claude Opus 4.8
11
+ - Cursor @cursoragent
12
+ - Kieran Prince
13
+ - Ulrik Jørgensen
14
+
1
15
  ## 0.0.15 (2026-06-23)
2
16
 
3
17
  ### 🩹 Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/graphql-build-tools",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "engines": {
6
6
  "node": ">=24.x"
@@ -0,0 +1,2 @@
1
+ import { GraphQLSchema } from "graphql";
2
+ export declare const reconcileRootOperationTypes: (schema: GraphQLSchema) => GraphQLSchema;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reconcileRootOperationTypes = void 0;
4
+ const graphql_1 = require("graphql");
5
+ /**
6
+ * Per-server @hidden filtering can prune a root operation type (query/mutation/subscription) away while
7
+ * the original explicit `schema {}` block still binds it. `printSchemaWithDirectives` then emits a
8
+ * dangling binding (e.g. `mutation: Mutation` with no `type Mutation`), which fails stitching
9
+ * composition with `Unknown type Mutation.`. A subgraph legitimately having no query or no mutation for
10
+ * a server is fine — only the dangling reference is not.
11
+ *
12
+ * This rebinds each operation to a live, non-empty root type and rewrites the schema-definition AST so it
13
+ * only lists operations whose root type is still live. Schema-level directives / extensions on that AST
14
+ * are preserved (they live nowhere else), and any now-empty root type is dropped from the type map so we
15
+ * never emit an empty `type X {}`. Returns the schema untouched when nothing dangles, keeping the common
16
+ * case byte-for-byte identical.
17
+ */
18
+ const isNonEmptyObjectType = (type) => type !== null && type !== undefined && Object.keys(type.getFields()).length > 0;
19
+ // Operations still bound by the schema-definition AST (what astFromSchema would print).
20
+ const boundOperationsFromAst = (schema) => {
21
+ const operations = new Set();
22
+ const nodes = [schema.astNode, ...schema.extensionASTNodes];
23
+ for (const node of nodes) {
24
+ if (node === null || node === undefined) {
25
+ continue;
26
+ }
27
+ for (const operationType of node.operationTypes ?? []) {
28
+ operations.add(operationType.operation);
29
+ }
30
+ }
31
+ return operations;
32
+ };
33
+ // Keep only the operation bindings whose root type is still live, dropping the dangling ones.
34
+ const liveOperationTypeNodes = (operationTypes, liveOperations) => (operationTypes ?? []).filter(operationType => liveOperations.has(operationType.operation));
35
+ const reconcileRootOperationTypes = (schema) => {
36
+ const config = schema.toConfig();
37
+ const liveQuery = isNonEmptyObjectType(config.query) ? config.query : undefined;
38
+ const liveMutation = isNonEmptyObjectType(config.mutation) ? config.mutation : undefined;
39
+ const liveSubscription = isNonEmptyObjectType(config.subscription) ? config.subscription : undefined;
40
+ const emptiedAnOperation = liveQuery !== config.query || liveMutation !== config.mutation || liveSubscription !== config.subscription;
41
+ const boundOperations = boundOperationsFromAst(schema);
42
+ const hasDanglingBinding = (boundOperations.has(graphql_1.OperationTypeNode.QUERY) && liveQuery === undefined) ||
43
+ (boundOperations.has(graphql_1.OperationTypeNode.MUTATION) && liveMutation === undefined) ||
44
+ (boundOperations.has(graphql_1.OperationTypeNode.SUBSCRIPTION) && liveSubscription === undefined);
45
+ // No emptied root and no dangling binding — leave the output identical.
46
+ if (!emptiedAnOperation && !hasDanglingBinding) {
47
+ return schema;
48
+ }
49
+ const liveOperations = new Set();
50
+ if (liveQuery !== undefined) {
51
+ liveOperations.add(graphql_1.OperationTypeNode.QUERY);
52
+ }
53
+ if (liveMutation !== undefined) {
54
+ liveOperations.add(graphql_1.OperationTypeNode.MUTATION);
55
+ }
56
+ if (liveSubscription !== undefined) {
57
+ liveOperations.add(graphql_1.OperationTypeNode.SUBSCRIPTION);
58
+ }
59
+ // Root types that are no longer live must leave the type map, otherwise an empty `type X {}` is printed.
60
+ const deadRootTypeNames = new Set();
61
+ const markDeadRoot = (original, live) => {
62
+ if (original !== null && original !== undefined && live === undefined) {
63
+ deadRootTypeNames.add(original.name);
64
+ }
65
+ };
66
+ markDeadRoot(config.query, liveQuery);
67
+ markDeadRoot(config.mutation, liveMutation);
68
+ markDeadRoot(config.subscription, liveSubscription);
69
+ const reconciledAstNode = config.astNode === null || config.astNode === undefined
70
+ ? config.astNode
71
+ : { ...config.astNode, operationTypes: liveOperationTypeNodes(config.astNode.operationTypes, liveOperations) };
72
+ return new graphql_1.GraphQLSchema({
73
+ ...config,
74
+ query: liveQuery,
75
+ mutation: liveMutation,
76
+ subscription: liveSubscription,
77
+ // Drop dead roots from the explicit type list. `new GraphQLSchema` re-collects any type still
78
+ // referenced by a live field, so a former root that is also used as a field type survives as a
79
+ // regular type — only the genuinely unreferenced root is removed.
80
+ types: config.types.filter(type => !deadRootTypeNames.has(type.name)),
81
+ // Keep schema-level directives/extensions; only strip operation entries whose root type is gone.
82
+ astNode: reconciledAstNode,
83
+ extensionASTNodes: config.extensionASTNodes.map(node => ({
84
+ ...node,
85
+ operationTypes: liveOperationTypeNodes(node.operationTypes, liveOperations),
86
+ })),
87
+ });
88
+ };
89
+ exports.reconcileRootOperationTypes = reconcileRootOperationTypes;
90
+ //# sourceMappingURL=reconcile-root-operation-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile-root-operation-types.js","sourceRoot":"","sources":["../../../../../../libs/graphql/build-tools/src/transformers/reconcile-root-operation-types.ts"],"names":[],"mappings":"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","sourcesContent":["import { GraphQLSchema, OperationTypeNode, type GraphQLObjectType, type OperationTypeDefinitionNode } from \"graphql\";\n\n/**\n * Per-server @hidden filtering can prune a root operation type (query/mutation/subscription) away while\n * the original explicit `schema {}` block still binds it. `printSchemaWithDirectives` then emits a\n * dangling binding (e.g. `mutation: Mutation` with no `type Mutation`), which fails stitching\n * composition with `Unknown type Mutation.`. A subgraph legitimately having no query or no mutation for\n * a server is fine — only the dangling reference is not.\n *\n * This rebinds each operation to a live, non-empty root type and rewrites the schema-definition AST so it\n * only lists operations whose root type is still live. Schema-level directives / extensions on that AST\n * are preserved (they live nowhere else), and any now-empty root type is dropped from the type map so we\n * never emit an empty `type X {}`. Returns the schema untouched when nothing dangles, keeping the common\n * case byte-for-byte identical.\n */\n\nconst isNonEmptyObjectType = (type: GraphQLObjectType | null | undefined): type is GraphQLObjectType =>\n type !== null && type !== undefined && Object.keys(type.getFields()).length > 0;\n\n// Operations still bound by the schema-definition AST (what astFromSchema would print).\nconst boundOperationsFromAst = (schema: GraphQLSchema): ReadonlySet<OperationTypeNode> => {\n const operations = new Set<OperationTypeNode>();\n const nodes = [schema.astNode, ...schema.extensionASTNodes];\n for (const node of nodes) {\n if (node === null || node === undefined) {\n continue;\n }\n for (const operationType of node.operationTypes ?? []) {\n operations.add(operationType.operation);\n }\n }\n return operations;\n};\n\n// Keep only the operation bindings whose root type is still live, dropping the dangling ones.\nconst liveOperationTypeNodes = (\n operationTypes: ReadonlyArray<OperationTypeDefinitionNode> | undefined,\n liveOperations: ReadonlySet<OperationTypeNode>\n): ReadonlyArray<OperationTypeDefinitionNode> =>\n (operationTypes ?? []).filter(operationType => liveOperations.has(operationType.operation));\n\nexport const reconcileRootOperationTypes = (schema: GraphQLSchema): GraphQLSchema => {\n const config = schema.toConfig();\n\n const liveQuery = isNonEmptyObjectType(config.query) ? config.query : undefined;\n const liveMutation = isNonEmptyObjectType(config.mutation) ? config.mutation : undefined;\n const liveSubscription = isNonEmptyObjectType(config.subscription) ? config.subscription : undefined;\n\n const emptiedAnOperation =\n liveQuery !== config.query || liveMutation !== config.mutation || liveSubscription !== config.subscription;\n\n const boundOperations = boundOperationsFromAst(schema);\n const hasDanglingBinding =\n (boundOperations.has(OperationTypeNode.QUERY) && liveQuery === undefined) ||\n (boundOperations.has(OperationTypeNode.MUTATION) && liveMutation === undefined) ||\n (boundOperations.has(OperationTypeNode.SUBSCRIPTION) && liveSubscription === undefined);\n\n // No emptied root and no dangling binding — leave the output identical.\n if (!emptiedAnOperation && !hasDanglingBinding) {\n return schema;\n }\n\n const liveOperations = new Set<OperationTypeNode>();\n if (liveQuery !== undefined) {\n liveOperations.add(OperationTypeNode.QUERY);\n }\n if (liveMutation !== undefined) {\n liveOperations.add(OperationTypeNode.MUTATION);\n }\n if (liveSubscription !== undefined) {\n liveOperations.add(OperationTypeNode.SUBSCRIPTION);\n }\n\n // Root types that are no longer live must leave the type map, otherwise an empty `type X {}` is printed.\n const deadRootTypeNames = new Set<string>();\n const markDeadRoot = (original: GraphQLObjectType | null | undefined, live: GraphQLObjectType | undefined): void => {\n if (original !== null && original !== undefined && live === undefined) {\n deadRootTypeNames.add(original.name);\n }\n };\n markDeadRoot(config.query, liveQuery);\n markDeadRoot(config.mutation, liveMutation);\n markDeadRoot(config.subscription, liveSubscription);\n\n const reconciledAstNode =\n config.astNode === null || config.astNode === undefined\n ? config.astNode\n : { ...config.astNode, operationTypes: liveOperationTypeNodes(config.astNode.operationTypes, liveOperations) };\n\n return new GraphQLSchema({\n ...config,\n query: liveQuery,\n mutation: liveMutation,\n subscription: liveSubscription,\n // Drop dead roots from the explicit type list. `new GraphQLSchema` re-collects any type still\n // referenced by a live field, so a former root that is also used as a field type survives as a\n // regular type — only the genuinely unreferenced root is removed.\n types: config.types.filter(type => !deadRootTypeNames.has(type.name)),\n // Keep schema-level directives/extensions; only strip operation entries whose root type is gone.\n astNode: reconciledAstNode,\n extensionASTNodes: config.extensionASTNodes.map(node => ({\n ...node,\n operationTypes: liveOperationTypeNodes(node.operationTypes, liveOperations),\n })),\n });\n};\n"]}
@@ -8,6 +8,7 @@ const complexity_directive_1 = require("./complexity-directive");
8
8
  const global_id_transformer_1 = require("./global-id-transformer");
9
9
  const hidden_directive_1 = require("./hidden-directive");
10
10
  const preview_directive_1 = require("./preview-directive");
11
+ const reconcile_root_operation_types_1 = require("./reconcile-root-operation-types");
11
12
  exports.graphqlGatewayNames = ["internal", "public", "report", "v3-mobile"];
12
13
  const applySdlDirectiveTransformers = (schema, gatewayName, { preserveStitchingEntrypoints = false } = {}) => {
13
14
  const { complexityDirectiveTransformer } = (0, complexity_directive_1.complexityDirective)();
@@ -16,7 +17,10 @@ const applySdlDirectiveTransformers = (schema, gatewayName, { preserveStitchingE
16
17
  const { authorizationDirectiveTransformer } = (0, authorization_directive_1.authorizationDirective)();
17
18
  const hiddenSchema = hiddenDirectiveTransformer(schema);
18
19
  const previewSchema = gatewayName === "report" ? hiddenSchema : previewDirectiveTransformer(hiddenSchema);
19
- return authorizationDirectiveTransformer(complexityDirectiveTransformer((0, global_id_transformer_1.globalIdTransformer)(previewSchema)));
20
+ const transformedSchema = authorizationDirectiveTransformer(complexityDirectiveTransformer((0, global_id_transformer_1.globalIdTransformer)(previewSchema)));
21
+ // Drop dangling/empty root operations left when @hidden empties a root type. Complements
22
+ // preserveStitchingEntrypoints, which only rescues roots whose fields carry a stitching directive.
23
+ return (0, reconcile_root_operation_types_1.reconcileRootOperationTypes)(transformedSchema);
20
24
  };
21
25
  exports.applySdlDirectiveTransformers = applySdlDirectiveTransformers;
22
26
  exports.applyDirectiveTransformers = exports.applySdlDirectiveTransformers;
@@ -1 +1 @@
1
- {"version":3,"file":"transformer-chain.js","sourceRoot":"","sources":["../../../../../../libs/graphql/build-tools/src/transformers/transformer-chain.ts"],"names":[],"mappings":";;;AAAA,kDAA6D;AAC7D,gDAAiE;AAEjE,uEAAmE;AACnE,iEAA6D;AAC7D,mEAA8D;AAC9D,yDAAqD;AACrD,2DAAuD;AAE1C,QAAA,mBAAmB,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AAanF,MAAM,6BAA6B,GAAG,CAC3C,MAAqB,EACrB,WAA+B,EAC/B,EAAE,4BAA4B,GAAG,KAAK,KAA2C,EAAE,EACpE,EAAE;IACjB,MAAM,EAAE,8BAA8B,EAAE,GAAG,IAAA,0CAAmB,GAAE,CAAC;IACjE,MAAM,EAAE,2BAA2B,EAAE,GAAG,IAAA,oCAAgB,GAAE,CAAC;IAC3D,MAAM,EAAE,0BAA0B,EAAE,GAAG,IAAA,kCAAe,EAAC,WAAW,EAAE,EAAE,4BAA4B,EAAE,CAAC,CAAC;IACtG,MAAM,EAAE,iCAAiC,EAAE,GAAG,IAAA,gDAAsB,GAAE,CAAC;IACvE,MAAM,YAAY,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,2BAA2B,CAAC,YAAY,CAAC,CAAC;IAE1G,OAAO,iCAAiC,CAAC,8BAA8B,CAAC,IAAA,2CAAmB,EAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAC/G,CAAC,CAAC;AAbW,QAAA,6BAA6B,iCAaxC;AAEW,QAAA,0BAA0B,GAAG,qCAA6B,CAAC;AAEjE,MAAM,yBAAyB,GAAG,CAAC,WAA+B,EAAE,QAAgB,EAAU,EAAE;IACrG,MAAM,MAAM,GAAG,IAAA,6BAAoB,EAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,OAAO,IAAA,iCAAyB,EAC9B,IAAA,qCAA6B,EAAC,MAAM,EAAE,WAAW,EAAE,EAAE,4BAA4B,EAAE,IAAI,EAAE,CAAC,CAC3F,CAAC;AACJ,CAAC,CAAC;AALW,QAAA,yBAAyB,6BAKpC","sourcesContent":["import { makeExecutableSchema } from \"@graphql-tools/schema\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport type { GraphQLSchema } from \"graphql\";\nimport { authorizationDirective } from \"./authorization-directive\";\nimport { complexityDirective } from \"./complexity-directive\";\nimport { globalIdTransformer } from \"./global-id-transformer\";\nimport { hiddenDirective } from \"./hidden-directive\";\nimport { previewDirective } from \"./preview-directive\";\n\nexport const graphqlGatewayNames = [\"internal\", \"public\", \"report\", \"v3-mobile\"] as const;\n\nexport type GraphqlGatewayName = (typeof graphqlGatewayNames)[number];\n\nexport type ApplySdlDirectiveTransformersOptions = {\n /**\n * Keep schema-stitching entry points (@merge / @computed fields) even when they are @hidden.\n * Enabled when rendering a single subgraph's SDL so a pure-stitch subgraph does not collapse to an\n * empty schema. The runtime gateway omits this so those internal fields stay hidden from users.\n */\n readonly preserveStitchingEntrypoints?: boolean;\n};\n\nexport const applySdlDirectiveTransformers = (\n schema: GraphQLSchema,\n gatewayName: GraphqlGatewayName,\n { preserveStitchingEntrypoints = false }: ApplySdlDirectiveTransformersOptions = {}\n): GraphQLSchema => {\n const { complexityDirectiveTransformer } = complexityDirective();\n const { previewDirectiveTransformer } = previewDirective();\n const { hiddenDirectiveTransformer } = hiddenDirective(gatewayName, { preserveStitchingEntrypoints });\n const { authorizationDirectiveTransformer } = authorizationDirective();\n const hiddenSchema = hiddenDirectiveTransformer(schema);\n const previewSchema = gatewayName === \"report\" ? hiddenSchema : previewDirectiveTransformer(hiddenSchema);\n\n return authorizationDirectiveTransformer(complexityDirectiveTransformer(globalIdTransformer(previewSchema)));\n};\n\nexport const applyDirectiveTransformers = applySdlDirectiveTransformers;\n\nexport const buildTransformedSchemaSdl = (gatewayName: GraphqlGatewayName, inputSdl: string): string => {\n const schema = makeExecutableSchema({ typeDefs: inputSdl });\n return printSchemaWithDirectives(\n applySdlDirectiveTransformers(schema, gatewayName, { preserveStitchingEntrypoints: true })\n );\n};\n"]}
1
+ {"version":3,"file":"transformer-chain.js","sourceRoot":"","sources":["../../../../../../libs/graphql/build-tools/src/transformers/transformer-chain.ts"],"names":[],"mappings":";;;AAAA,kDAA6D;AAC7D,gDAAiE;AAEjE,uEAAmE;AACnE,iEAA6D;AAC7D,mEAA8D;AAC9D,yDAAqD;AACrD,2DAAuD;AACvD,qFAA+E;AAElE,QAAA,mBAAmB,GAAG,CAAC,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC;AAanF,MAAM,6BAA6B,GAAG,CAC3C,MAAqB,EACrB,WAA+B,EAC/B,EAAE,4BAA4B,GAAG,KAAK,KAA2C,EAAE,EACpE,EAAE;IACjB,MAAM,EAAE,8BAA8B,EAAE,GAAG,IAAA,0CAAmB,GAAE,CAAC;IACjE,MAAM,EAAE,2BAA2B,EAAE,GAAG,IAAA,oCAAgB,GAAE,CAAC;IAC3D,MAAM,EAAE,0BAA0B,EAAE,GAAG,IAAA,kCAAe,EAAC,WAAW,EAAE,EAAE,4BAA4B,EAAE,CAAC,CAAC;IACtG,MAAM,EAAE,iCAAiC,EAAE,GAAG,IAAA,gDAAsB,GAAE,CAAC;IACvE,MAAM,YAAY,GAAG,0BAA0B,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,2BAA2B,CAAC,YAAY,CAAC,CAAC;IAE1G,MAAM,iBAAiB,GAAG,iCAAiC,CACzD,8BAA8B,CAAC,IAAA,2CAAmB,EAAC,aAAa,CAAC,CAAC,CACnE,CAAC;IAEF,yFAAyF;IACzF,mGAAmG;IACnG,OAAO,IAAA,4DAA2B,EAAC,iBAAiB,CAAC,CAAC;AACxD,CAAC,CAAC;AAnBW,QAAA,6BAA6B,iCAmBxC;AAEW,QAAA,0BAA0B,GAAG,qCAA6B,CAAC;AAEjE,MAAM,yBAAyB,GAAG,CAAC,WAA+B,EAAE,QAAgB,EAAU,EAAE;IACrG,MAAM,MAAM,GAAG,IAAA,6BAAoB,EAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,OAAO,IAAA,iCAAyB,EAC9B,IAAA,qCAA6B,EAAC,MAAM,EAAE,WAAW,EAAE,EAAE,4BAA4B,EAAE,IAAI,EAAE,CAAC,CAC3F,CAAC;AACJ,CAAC,CAAC;AALW,QAAA,yBAAyB,6BAKpC","sourcesContent":["import { makeExecutableSchema } from \"@graphql-tools/schema\";\nimport { printSchemaWithDirectives } from \"@graphql-tools/utils\";\nimport type { GraphQLSchema } from \"graphql\";\nimport { authorizationDirective } from \"./authorization-directive\";\nimport { complexityDirective } from \"./complexity-directive\";\nimport { globalIdTransformer } from \"./global-id-transformer\";\nimport { hiddenDirective } from \"./hidden-directive\";\nimport { previewDirective } from \"./preview-directive\";\nimport { reconcileRootOperationTypes } from \"./reconcile-root-operation-types\";\n\nexport const graphqlGatewayNames = [\"internal\", \"public\", \"report\", \"v3-mobile\"] as const;\n\nexport type GraphqlGatewayName = (typeof graphqlGatewayNames)[number];\n\nexport type ApplySdlDirectiveTransformersOptions = {\n /**\n * Keep schema-stitching entry points (@merge / @computed fields) even when they are @hidden.\n * Enabled when rendering a single subgraph's SDL so a pure-stitch subgraph does not collapse to an\n * empty schema. The runtime gateway omits this so those internal fields stay hidden from users.\n */\n readonly preserveStitchingEntrypoints?: boolean;\n};\n\nexport const applySdlDirectiveTransformers = (\n schema: GraphQLSchema,\n gatewayName: GraphqlGatewayName,\n { preserveStitchingEntrypoints = false }: ApplySdlDirectiveTransformersOptions = {}\n): GraphQLSchema => {\n const { complexityDirectiveTransformer } = complexityDirective();\n const { previewDirectiveTransformer } = previewDirective();\n const { hiddenDirectiveTransformer } = hiddenDirective(gatewayName, { preserveStitchingEntrypoints });\n const { authorizationDirectiveTransformer } = authorizationDirective();\n const hiddenSchema = hiddenDirectiveTransformer(schema);\n const previewSchema = gatewayName === \"report\" ? hiddenSchema : previewDirectiveTransformer(hiddenSchema);\n\n const transformedSchema = authorizationDirectiveTransformer(\n complexityDirectiveTransformer(globalIdTransformer(previewSchema))\n );\n\n // Drop dangling/empty root operations left when @hidden empties a root type. Complements\n // preserveStitchingEntrypoints, which only rescues roots whose fields carry a stitching directive.\n return reconcileRootOperationTypes(transformedSchema);\n};\n\nexport const applyDirectiveTransformers = applySdlDirectiveTransformers;\n\nexport const buildTransformedSchemaSdl = (gatewayName: GraphqlGatewayName, inputSdl: string): string => {\n const schema = makeExecutableSchema({ typeDefs: inputSdl });\n return printSchemaWithDirectives(\n applySdlDirectiveTransformers(schema, gatewayName, { preserveStitchingEntrypoints: true })\n );\n};\n"]}