@theguild/federation-composition 0.2.0 → 0.3.0-alpha-20231213155016-bf63afd

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.
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.sortSDL = exports.stripFederationFromSupergraph = void 0;
7
+ const graphql_1 = require("graphql");
8
+ const lodash_sortby_1 = __importDefault(require("lodash.sortby"));
9
+ const printer_js_1 = require("./printer.js");
10
+ function stripFederationFromSupergraph(supergraph) {
11
+ function remove() {
12
+ return null;
13
+ }
14
+ return (0, graphql_1.visit)(supergraph, {
15
+ DirectiveDefinition: remove,
16
+ Directive: remove,
17
+ SchemaDefinition: remove,
18
+ SchemaExtension: remove,
19
+ EnumTypeDefinition: node => {
20
+ if (node.name.value === 'core__Purpose' ||
21
+ node.name.value === 'join__Graph' ||
22
+ node.name.value === 'link__Purpose') {
23
+ return null;
24
+ }
25
+ return node;
26
+ },
27
+ ScalarTypeDefinition: node => {
28
+ if (node.name.value === '_FieldSet' ||
29
+ node.name.value === 'link__Import' ||
30
+ node.name.value === 'join__FieldSet') {
31
+ return null;
32
+ }
33
+ return node;
34
+ },
35
+ });
36
+ }
37
+ exports.stripFederationFromSupergraph = stripFederationFromSupergraph;
38
+ function sortSDL(doc) {
39
+ try {
40
+ return (0, graphql_1.visit)(doc, {
41
+ Document(node) {
42
+ return {
43
+ ...node,
44
+ definitions: sortNodes(node.definitions),
45
+ };
46
+ },
47
+ SchemaDefinition(node) {
48
+ return {
49
+ ...node,
50
+ directives: sortNodes(node.directives),
51
+ };
52
+ },
53
+ ScalarTypeDefinition(node) {
54
+ return {
55
+ ...node,
56
+ directives: sortNodes(node.directives),
57
+ };
58
+ },
59
+ ObjectTypeDefinition(node) {
60
+ return {
61
+ ...node,
62
+ directives: sortNodes(node.directives),
63
+ fields: sortNodes(node.fields),
64
+ };
65
+ },
66
+ InterfaceTypeDefinition(node) {
67
+ return {
68
+ ...node,
69
+ directives: sortNodes(node.directives),
70
+ fields: sortNodes(node.fields),
71
+ };
72
+ },
73
+ EnumTypeDefinition(node) {
74
+ return {
75
+ ...node,
76
+ directives: sortNodes(node.directives),
77
+ values: sortNodes(node.values),
78
+ };
79
+ },
80
+ EnumValueDefinition(node) {
81
+ return {
82
+ ...node,
83
+ directives: sortNodes(node.directives),
84
+ };
85
+ },
86
+ UnionTypeDefinition(node) {
87
+ return {
88
+ ...node,
89
+ types: sortNodes(node.types),
90
+ directives: sortNodes(node.directives),
91
+ };
92
+ },
93
+ FieldDefinition(node) {
94
+ return {
95
+ ...node,
96
+ directives: sortNodes(node.directives),
97
+ };
98
+ },
99
+ DirectiveDefinition(node) {
100
+ return {
101
+ ...node,
102
+ locations: sortNodes(node.locations),
103
+ };
104
+ },
105
+ Directive(node) {
106
+ for (const arg of node.arguments ?? []) {
107
+ if (['requires', 'provides'].includes(arg.name.value) && arg.value.kind === graphql_1.Kind.STRING) {
108
+ const parsedFields = parseFields(arg.value.value);
109
+ if (parsedFields) {
110
+ const printed = (0, graphql_1.stripIgnoredCharacters)((0, printer_js_1.print)(parsedFields));
111
+ arg.value.value = printed.replace(/^\{/, '').replace(/\}$/, '');
112
+ }
113
+ }
114
+ }
115
+ return {
116
+ ...node,
117
+ arguments: sortNodes(node.arguments),
118
+ };
119
+ },
120
+ StringValue(node) {
121
+ return {
122
+ ...node,
123
+ value: node.value.trim(),
124
+ };
125
+ },
126
+ });
127
+ }
128
+ catch (error) {
129
+ console.log('Failed to parse', doc.loc?.source.name);
130
+ throw error;
131
+ }
132
+ }
133
+ exports.sortSDL = sortSDL;
134
+ function parseFields(fields) {
135
+ const parsed = (0, graphql_1.parse)(fields.trim().startsWith(`{`) ? `query ${fields}` : `query { ${fields} }`).definitions.find(d => d.kind === graphql_1.Kind.OPERATION_DEFINITION);
136
+ return parsed?.selectionSet;
137
+ }
138
+ function valueNodeToString(node) {
139
+ if ('name' in node) {
140
+ return node.name.value;
141
+ }
142
+ if ('value' in node) {
143
+ return node.value.toString();
144
+ }
145
+ if (node.kind === graphql_1.Kind.LIST) {
146
+ return node.values.map(valueNodeToString).join(',');
147
+ }
148
+ if (node.kind === graphql_1.Kind.OBJECT) {
149
+ return 'OBJECT';
150
+ }
151
+ return 'NULL';
152
+ }
153
+ function sortNodes(nodes) {
154
+ if (nodes) {
155
+ if (nodes.length === 0) {
156
+ return [];
157
+ }
158
+ if (isOfKindList(nodes, graphql_1.Kind.NAMED_TYPE)) {
159
+ return (0, lodash_sortby_1.default)(nodes, 'name.value');
160
+ }
161
+ if (isOfKindList(nodes, graphql_1.Kind.DIRECTIVE)) {
162
+ return (0, lodash_sortby_1.default)(nodes, n => {
163
+ const args = n.arguments
164
+ ?.map(a => a.name.value + valueNodeToString(a.value))
165
+ .sort()
166
+ .join(';') ?? '';
167
+ return n.name.value + args;
168
+ });
169
+ }
170
+ if (isOfKindList(nodes, graphql_1.Kind.VARIABLE_DEFINITION)) {
171
+ return (0, lodash_sortby_1.default)(nodes, 'variable.name.value');
172
+ }
173
+ if (isOfKindList(nodes, graphql_1.Kind.ARGUMENT)) {
174
+ return (0, lodash_sortby_1.default)(nodes, 'name.value');
175
+ }
176
+ if (isOfKindList(nodes, graphql_1.Kind.ENUM_VALUE_DEFINITION)) {
177
+ return (0, lodash_sortby_1.default)(nodes, 'name.value');
178
+ }
179
+ if (isOfKindList(nodes, [graphql_1.Kind.FIELD, graphql_1.Kind.FRAGMENT_SPREAD, graphql_1.Kind.INLINE_FRAGMENT])) {
180
+ return (0, lodash_sortby_1.default)(nodes, 'kind', 'name.value');
181
+ }
182
+ if (isOfKindList(nodes, graphql_1.Kind.NAME)) {
183
+ return (0, lodash_sortby_1.default)(nodes, 'value');
184
+ }
185
+ return (0, lodash_sortby_1.default)(nodes, 'kind', 'name.value');
186
+ }
187
+ return;
188
+ }
189
+ function isOfKindList(nodes, kind) {
190
+ return typeof kind === 'string' ? nodes[0].kind === kind : kind.includes(nodes[0].kind);
191
+ }
package/cjs/index.js CHANGED
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.transformSupergraphToPublicSchema = void 0;
17
+ exports.sortSDL = exports.transformSupergraphToPublicSchema = void 0;
18
18
  __exportStar(require("./compose.js"), exports);
19
19
  __exportStar(require("./types.js"), exports);
20
20
  __exportStar(require("./validate.js"), exports);
21
21
  var transform_supergraph_to_public_schema_js_1 = require("./graphql/transform-supergraph-to-public-schema.js");
22
22
  Object.defineProperty(exports, "transformSupergraphToPublicSchema", { enumerable: true, get: function () { return transform_supergraph_to_public_schema_js_1.transformSupergraphToPublicSchema; } });
23
+ var sort_sdl_js_1 = require("./graphql/sort-sdl.js");
24
+ Object.defineProperty(exports, "sortSDL", { enumerable: true, get: function () { return sort_sdl_js_1.sortSDL; } });
@@ -0,0 +1,183 @@
1
+ import { Kind, parse, stripIgnoredCharacters, visit, } from 'graphql';
2
+ import sortBy from 'lodash.sortby';
3
+ import { print } from './printer.js';
4
+ export function stripFederationFromSupergraph(supergraph) {
5
+ function remove() {
6
+ return null;
7
+ }
8
+ return visit(supergraph, {
9
+ DirectiveDefinition: remove,
10
+ Directive: remove,
11
+ SchemaDefinition: remove,
12
+ SchemaExtension: remove,
13
+ EnumTypeDefinition: node => {
14
+ if (node.name.value === 'core__Purpose' ||
15
+ node.name.value === 'join__Graph' ||
16
+ node.name.value === 'link__Purpose') {
17
+ return null;
18
+ }
19
+ return node;
20
+ },
21
+ ScalarTypeDefinition: node => {
22
+ if (node.name.value === '_FieldSet' ||
23
+ node.name.value === 'link__Import' ||
24
+ node.name.value === 'join__FieldSet') {
25
+ return null;
26
+ }
27
+ return node;
28
+ },
29
+ });
30
+ }
31
+ export function sortSDL(doc) {
32
+ try {
33
+ return visit(doc, {
34
+ Document(node) {
35
+ return {
36
+ ...node,
37
+ definitions: sortNodes(node.definitions),
38
+ };
39
+ },
40
+ SchemaDefinition(node) {
41
+ return {
42
+ ...node,
43
+ directives: sortNodes(node.directives),
44
+ };
45
+ },
46
+ ScalarTypeDefinition(node) {
47
+ return {
48
+ ...node,
49
+ directives: sortNodes(node.directives),
50
+ };
51
+ },
52
+ ObjectTypeDefinition(node) {
53
+ return {
54
+ ...node,
55
+ directives: sortNodes(node.directives),
56
+ fields: sortNodes(node.fields),
57
+ };
58
+ },
59
+ InterfaceTypeDefinition(node) {
60
+ return {
61
+ ...node,
62
+ directives: sortNodes(node.directives),
63
+ fields: sortNodes(node.fields),
64
+ };
65
+ },
66
+ EnumTypeDefinition(node) {
67
+ return {
68
+ ...node,
69
+ directives: sortNodes(node.directives),
70
+ values: sortNodes(node.values),
71
+ };
72
+ },
73
+ EnumValueDefinition(node) {
74
+ return {
75
+ ...node,
76
+ directives: sortNodes(node.directives),
77
+ };
78
+ },
79
+ UnionTypeDefinition(node) {
80
+ return {
81
+ ...node,
82
+ types: sortNodes(node.types),
83
+ directives: sortNodes(node.directives),
84
+ };
85
+ },
86
+ FieldDefinition(node) {
87
+ return {
88
+ ...node,
89
+ directives: sortNodes(node.directives),
90
+ };
91
+ },
92
+ DirectiveDefinition(node) {
93
+ return {
94
+ ...node,
95
+ locations: sortNodes(node.locations),
96
+ };
97
+ },
98
+ Directive(node) {
99
+ for (const arg of node.arguments ?? []) {
100
+ if (['requires', 'provides'].includes(arg.name.value) && arg.value.kind === Kind.STRING) {
101
+ const parsedFields = parseFields(arg.value.value);
102
+ if (parsedFields) {
103
+ const printed = stripIgnoredCharacters(print(parsedFields));
104
+ arg.value.value = printed.replace(/^\{/, '').replace(/\}$/, '');
105
+ }
106
+ }
107
+ }
108
+ return {
109
+ ...node,
110
+ arguments: sortNodes(node.arguments),
111
+ };
112
+ },
113
+ StringValue(node) {
114
+ return {
115
+ ...node,
116
+ value: node.value.trim(),
117
+ };
118
+ },
119
+ });
120
+ }
121
+ catch (error) {
122
+ console.log('Failed to parse', doc.loc?.source.name);
123
+ throw error;
124
+ }
125
+ }
126
+ function parseFields(fields) {
127
+ const parsed = parse(fields.trim().startsWith(`{`) ? `query ${fields}` : `query { ${fields} }`).definitions.find(d => d.kind === Kind.OPERATION_DEFINITION);
128
+ return parsed?.selectionSet;
129
+ }
130
+ function valueNodeToString(node) {
131
+ if ('name' in node) {
132
+ return node.name.value;
133
+ }
134
+ if ('value' in node) {
135
+ return node.value.toString();
136
+ }
137
+ if (node.kind === Kind.LIST) {
138
+ return node.values.map(valueNodeToString).join(',');
139
+ }
140
+ if (node.kind === Kind.OBJECT) {
141
+ return 'OBJECT';
142
+ }
143
+ return 'NULL';
144
+ }
145
+ function sortNodes(nodes) {
146
+ if (nodes) {
147
+ if (nodes.length === 0) {
148
+ return [];
149
+ }
150
+ if (isOfKindList(nodes, Kind.NAMED_TYPE)) {
151
+ return sortBy(nodes, 'name.value');
152
+ }
153
+ if (isOfKindList(nodes, Kind.DIRECTIVE)) {
154
+ return sortBy(nodes, n => {
155
+ const args = n.arguments
156
+ ?.map(a => a.name.value + valueNodeToString(a.value))
157
+ .sort()
158
+ .join(';') ?? '';
159
+ return n.name.value + args;
160
+ });
161
+ }
162
+ if (isOfKindList(nodes, Kind.VARIABLE_DEFINITION)) {
163
+ return sortBy(nodes, 'variable.name.value');
164
+ }
165
+ if (isOfKindList(nodes, Kind.ARGUMENT)) {
166
+ return sortBy(nodes, 'name.value');
167
+ }
168
+ if (isOfKindList(nodes, Kind.ENUM_VALUE_DEFINITION)) {
169
+ return sortBy(nodes, 'name.value');
170
+ }
171
+ if (isOfKindList(nodes, [Kind.FIELD, Kind.FRAGMENT_SPREAD, Kind.INLINE_FRAGMENT])) {
172
+ return sortBy(nodes, 'kind', 'name.value');
173
+ }
174
+ if (isOfKindList(nodes, Kind.NAME)) {
175
+ return sortBy(nodes, 'value');
176
+ }
177
+ return sortBy(nodes, 'kind', 'name.value');
178
+ }
179
+ return;
180
+ }
181
+ function isOfKindList(nodes, kind) {
182
+ return typeof kind === 'string' ? nodes[0].kind === kind : kind.includes(nodes[0].kind);
183
+ }
package/esm/index.js CHANGED
@@ -2,3 +2,4 @@ export * from './compose.js';
2
2
  export * from './types.js';
3
3
  export * from './validate.js';
4
4
  export { transformSupergraphToPublicSchema } from './graphql/transform-supergraph-to-public-schema.js';
5
+ export { sortSDL } from './graphql/sort-sdl.js';
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@theguild/federation-composition",
3
- "version": "0.2.0",
3
+ "version": "0.3.0-alpha-20231213155016-bf63afd",
4
4
  "description": "Open Source Composition library for Apollo Federation",
5
5
  "peerDependencies": {
6
6
  "graphql": "^16.0.0"
7
7
  },
8
8
  "dependencies": {
9
9
  "constant-case": "^3.0.0",
10
- "json5": "^2.2.0"
10
+ "json5": "^2.2.0",
11
+ "lodash.sortby": "^4.7.0"
11
12
  },
12
13
  "repository": {
13
14
  "type": "git",
@@ -0,0 +1,4 @@
1
+ import { DocumentNode } from 'graphql';
2
+ export declare function stripFederationFromSupergraph(supergraph: DocumentNode): DocumentNode;
3
+ export declare function sortSDL(doc: DocumentNode): DocumentNode;
4
+ //# sourceMappingURL=sort-sdl.d.ts.map
@@ -0,0 +1,4 @@
1
+ import { DocumentNode } from 'graphql';
2
+ export declare function stripFederationFromSupergraph(supergraph: DocumentNode): DocumentNode;
3
+ export declare function sortSDL(doc: DocumentNode): DocumentNode;
4
+ //# sourceMappingURL=sort-sdl.d.ts.map
@@ -2,4 +2,5 @@ export * from './compose.cjs';
2
2
  export * from './types.cjs';
3
3
  export * from './validate.cjs';
4
4
  export { transformSupergraphToPublicSchema } from './graphql/transform-supergraph-to-public-schema.cjs';
5
+ export { sortSDL } from './graphql/sort-sdl.cjs';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -2,4 +2,5 @@ export * from './compose.js';
2
2
  export * from './types.js';
3
3
  export * from './validate.js';
4
4
  export { transformSupergraphToPublicSchema } from './graphql/transform-supergraph-to-public-schema.js';
5
+ export { sortSDL } from './graphql/sort-sdl.js';
5
6
  //# sourceMappingURL=index.d.ts.map