@effect-gql/federation 0.1.0 → 1.0.0

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/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # Effect GraphQL
2
+
3
+ A GraphQL framework for Effect-TS that brings full type safety, composability, and functional programming to your GraphQL servers.
4
+
5
+ > **Note:** This is an experimental prototype exploring the integration between Effect Schema, Effect's service system, and GraphQL.
6
+
7
+ ## Features
8
+
9
+ - **Type-Safe End-to-End** - Define schemas once with Effect Schema, get TypeScript types and GraphQL types automatically
10
+ - **Effect-Powered Resolvers** - Resolvers are Effect programs with built-in error handling and service injection
11
+ - **Immutable Builder** - Fluent, pipe-able API for composing schemas from reusable parts
12
+ - **Service Integration** - Use Effect's Layer system for dependency injection
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @effect-gql/core effect graphql
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```typescript
23
+ import { Effect, Layer } from "effect"
24
+ import * as S from "effect/Schema"
25
+ import { GraphQLSchemaBuilder, execute } from "@effect-gql/core"
26
+
27
+ // Define your schema with Effect Schema
28
+ const UserSchema = S.Struct({
29
+ id: S.String,
30
+ name: S.String,
31
+ email: S.String,
32
+ })
33
+
34
+ // Build your GraphQL schema
35
+ const schema = GraphQLSchemaBuilder.empty
36
+ .objectType({ name: "User", schema: UserSchema })
37
+ .query("users", {
38
+ type: S.Array(UserSchema),
39
+ resolve: () => Effect.succeed([
40
+ { id: "1", name: "Alice", email: "alice@example.com" },
41
+ { id: "2", name: "Bob", email: "bob@example.com" },
42
+ ]),
43
+ })
44
+ .query("user", {
45
+ type: UserSchema,
46
+ args: S.Struct({ id: S.String }),
47
+ resolve: (args) => Effect.succeed({
48
+ id: args.id,
49
+ name: "Alice",
50
+ email: "alice@example.com",
51
+ }),
52
+ })
53
+ .buildSchema()
54
+
55
+ // Execute a query
56
+ const result = await Effect.runPromise(
57
+ execute(schema, Layer.empty)(`
58
+ query {
59
+ users { id name email }
60
+ }
61
+ `)
62
+ )
63
+ ```
64
+
65
+ ## Documentation
66
+
67
+ For full documentation, guides, and API reference, visit the [documentation site](https://nrf110.github.io/effect-gql/).
68
+
69
+ ## Development
70
+
71
+ ```bash
72
+ # Install dependencies
73
+ npm install
74
+
75
+ # Build the project
76
+ npm run build
77
+
78
+ # Run tests
79
+ npm test
80
+
81
+ # Development mode with watch
82
+ npm run dev
83
+ ```
84
+
85
+ ## Contributing
86
+
87
+ Contributions are welcome! Here's how you can help:
88
+
89
+ 1. **Report bugs** - Open an issue describing the problem and steps to reproduce
90
+ 2. **Suggest features** - Open an issue describing your idea
91
+ 3. **Submit PRs** - Fork the repo, make your changes, and open a pull request
92
+
93
+ Please ensure your code:
94
+ - Passes all existing tests (`npm test`)
95
+ - Includes tests for new functionality
96
+ - Follows the existing code style
97
+
98
+ ## License
99
+
100
+ MIT
package/index.cjs ADDED
@@ -0,0 +1,618 @@
1
+ 'use strict';
2
+
3
+ var effect = require('effect');
4
+ var S = require('effect/Schema');
5
+ var core = require('@effect-gql/core');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var S__namespace = /*#__PURE__*/_interopNamespace(S);
26
+
27
+ // src/federated-builder.ts
28
+ function parseLiteralToValue(ast) {
29
+ switch (ast.kind) {
30
+ case core.Kind.STRING:
31
+ case core.Kind.BOOLEAN:
32
+ return ast.value;
33
+ case core.Kind.INT:
34
+ return parseInt(ast.value, 10);
35
+ case core.Kind.FLOAT:
36
+ return parseFloat(ast.value);
37
+ case core.Kind.NULL:
38
+ return null;
39
+ case core.Kind.LIST:
40
+ return ast.values.map(parseLiteralToValue);
41
+ case core.Kind.OBJECT: {
42
+ const obj = {};
43
+ for (const field2 of ast.fields) {
44
+ obj[field2.name.value] = parseLiteralToValue(field2.value);
45
+ }
46
+ return obj;
47
+ }
48
+ default:
49
+ return void 0;
50
+ }
51
+ }
52
+ var AnyScalar = new core.GraphQLScalarType({
53
+ name: "_Any",
54
+ description: "The _Any scalar is used to pass representations of entities from external services.",
55
+ serialize: (value) => value,
56
+ parseValue: (value) => value,
57
+ parseLiteral: parseLiteralToValue
58
+ });
59
+ var FieldSetScalar = new core.GraphQLScalarType({
60
+ name: "_FieldSet",
61
+ description: "A string representing a selection of fields.",
62
+ serialize: (value) => value,
63
+ parseValue: (value) => value,
64
+ parseLiteral: (ast) => {
65
+ if (ast.kind === core.Kind.STRING) {
66
+ return ast.value;
67
+ }
68
+ return void 0;
69
+ }
70
+ });
71
+ function createEntityUnion(entities, typeRegistry) {
72
+ const types = Array.from(entities.keys()).map((name) => typeRegistry.get(name)).filter(Boolean);
73
+ if (types.length === 0) {
74
+ throw new Error("At least one entity must be registered to create _Entity union");
75
+ }
76
+ return new core.GraphQLUnionType({
77
+ name: "_Entity",
78
+ description: "Union of all types that have @key directives",
79
+ types: () => types,
80
+ resolveType: (value) => value.__typename
81
+ });
82
+ }
83
+ function createEntitiesResolver(entities) {
84
+ return async (_parent, args, context) => {
85
+ const effects = args.representations.map((representation) => {
86
+ const entityName = representation.__typename;
87
+ const entity2 = entities.get(entityName);
88
+ if (!entity2) {
89
+ return effect.Effect.fail(new Error(`Unknown entity type: ${entityName}`));
90
+ }
91
+ return entity2.resolveReference(representation).pipe(
92
+ effect.Effect.map((result) => {
93
+ if (result !== null && typeof result === "object") {
94
+ return { ...result, __typename: entityName };
95
+ }
96
+ return result;
97
+ }),
98
+ // Catch individual entity resolution errors and return null
99
+ effect.Effect.catchAll(
100
+ (error) => effect.Effect.logError(`Failed to resolve entity ${entityName}`, error).pipe(effect.Effect.as(null))
101
+ )
102
+ );
103
+ });
104
+ return effect.Runtime.runPromise(context.runtime)(effect.Effect.all(effects, { concurrency: "unbounded" }));
105
+ };
106
+ }
107
+ function createServiceType() {
108
+ return new core.GraphQLObjectType({
109
+ name: "_Service",
110
+ description: "Provides SDL for the subgraph schema",
111
+ fields: {
112
+ sdl: {
113
+ type: core.GraphQLString,
114
+ description: "The SDL representing the subgraph schema"
115
+ }
116
+ }
117
+ });
118
+ }
119
+ function createServiceResolver(sdl) {
120
+ return () => ({ sdl });
121
+ }
122
+
123
+ // src/types.ts
124
+ function toDirectiveApplication(directive) {
125
+ switch (directive._tag) {
126
+ case "key":
127
+ return {
128
+ name: "key",
129
+ args: {
130
+ fields: directive.fields,
131
+ ...directive.resolvable !== void 0 ? { resolvable: directive.resolvable } : {}
132
+ }
133
+ };
134
+ case "external":
135
+ return { name: "external" };
136
+ case "requires":
137
+ return { name: "requires", args: { fields: directive.fields } };
138
+ case "provides":
139
+ return { name: "provides", args: { fields: directive.fields } };
140
+ case "shareable":
141
+ return { name: "shareable" };
142
+ case "inaccessible":
143
+ return { name: "inaccessible" };
144
+ case "override":
145
+ return {
146
+ name: "override",
147
+ args: {
148
+ from: directive.from,
149
+ ...directive.label !== void 0 ? { label: directive.label } : {}
150
+ }
151
+ };
152
+ case "interfaceObject":
153
+ return { name: "interfaceObject" };
154
+ case "tag":
155
+ return { name: "tag", args: { name: directive.name } };
156
+ }
157
+ }
158
+
159
+ // src/federated-builder.ts
160
+ var FederatedSchemaBuilder = class _FederatedSchemaBuilder {
161
+ constructor(state) {
162
+ this.state = state;
163
+ }
164
+ pipe() {
165
+ return effect.Pipeable.pipeArguments(this, arguments);
166
+ }
167
+ /**
168
+ * Create an empty federated schema builder
169
+ */
170
+ static empty = new _FederatedSchemaBuilder({
171
+ coreBuilder: core.GraphQLSchemaBuilder.empty,
172
+ entities: /* @__PURE__ */ new Map(),
173
+ version: "2.3"
174
+ });
175
+ /**
176
+ * Create a builder with custom configuration
177
+ */
178
+ static create(config = {}) {
179
+ return new _FederatedSchemaBuilder({
180
+ coreBuilder: core.GraphQLSchemaBuilder.empty,
181
+ entities: /* @__PURE__ */ new Map(),
182
+ version: config.version ?? "2.3"
183
+ });
184
+ }
185
+ /**
186
+ * Create a new builder with updated state
187
+ */
188
+ with(updates) {
189
+ return new _FederatedSchemaBuilder({
190
+ ...this.state,
191
+ ...updates
192
+ });
193
+ }
194
+ /**
195
+ * Get the underlying core builder for advanced usage
196
+ */
197
+ get coreBuilder() {
198
+ return this.state.coreBuilder;
199
+ }
200
+ // ============================================================================
201
+ // Entity Registration
202
+ // ============================================================================
203
+ /**
204
+ * Register an entity type with @key directive(s) and reference resolver.
205
+ *
206
+ * Entities are the core building block of Apollo Federation. They represent
207
+ * types that can be resolved across subgraph boundaries using their key fields.
208
+ *
209
+ * @example
210
+ * ```typescript
211
+ * builder.entity({
212
+ * name: "User",
213
+ * schema: UserSchema,
214
+ * keys: [key({ fields: "id" })],
215
+ * resolveReference: (ref) => UserService.findById(ref.id),
216
+ * })
217
+ * ```
218
+ */
219
+ entity(config) {
220
+ const { name, schema, keys, directives } = config;
221
+ const typeDirectives = [
222
+ // Add @key directives
223
+ ...keys.map(
224
+ (k) => ({
225
+ name: "key",
226
+ args: {
227
+ fields: k.fields,
228
+ ...k.resolvable !== void 0 ? { resolvable: k.resolvable } : {}
229
+ }
230
+ })
231
+ ),
232
+ // Add additional directives
233
+ ...directives?.map(toDirectiveApplication) ?? []
234
+ ];
235
+ const newCoreBuilder = this.state.coreBuilder.objectType({
236
+ name,
237
+ schema,
238
+ directives: typeDirectives
239
+ });
240
+ const newEntities = new Map(this.state.entities);
241
+ newEntities.set(name, config);
242
+ return this.with({
243
+ coreBuilder: newCoreBuilder,
244
+ entities: newEntities
245
+ });
246
+ }
247
+ // ============================================================================
248
+ // Delegate to Core Builder
249
+ // ============================================================================
250
+ /**
251
+ * Add a query field
252
+ */
253
+ query(name, config) {
254
+ return this.with({
255
+ coreBuilder: this.state.coreBuilder.query(name, config)
256
+ });
257
+ }
258
+ /**
259
+ * Add a mutation field
260
+ */
261
+ mutation(name, config) {
262
+ return this.with({
263
+ coreBuilder: this.state.coreBuilder.mutation(name, config)
264
+ });
265
+ }
266
+ /**
267
+ * Add a subscription field
268
+ */
269
+ subscription(name, config) {
270
+ return this.with({
271
+ coreBuilder: this.state.coreBuilder.subscription(name, config)
272
+ });
273
+ }
274
+ /**
275
+ * Register an object type (non-entity)
276
+ */
277
+ objectType(config) {
278
+ return this.with({
279
+ coreBuilder: this.state.coreBuilder.objectType(config)
280
+ });
281
+ }
282
+ /**
283
+ * Register an interface type
284
+ */
285
+ interfaceType(config) {
286
+ return this.with({
287
+ coreBuilder: this.state.coreBuilder.interfaceType(config)
288
+ });
289
+ }
290
+ /**
291
+ * Register an enum type
292
+ */
293
+ enumType(config) {
294
+ return this.with({
295
+ coreBuilder: this.state.coreBuilder.enumType(config)
296
+ });
297
+ }
298
+ /**
299
+ * Register a union type
300
+ */
301
+ unionType(config) {
302
+ return this.with({
303
+ coreBuilder: this.state.coreBuilder.unionType(config)
304
+ });
305
+ }
306
+ /**
307
+ * Register an input type
308
+ */
309
+ inputType(config) {
310
+ return this.with({
311
+ coreBuilder: this.state.coreBuilder.inputType(config)
312
+ });
313
+ }
314
+ /**
315
+ * Add a computed/relational field to an object type
316
+ */
317
+ field(typeName, fieldName, config) {
318
+ return this.with({
319
+ coreBuilder: this.state.coreBuilder.field(
320
+ typeName,
321
+ fieldName,
322
+ config
323
+ )
324
+ });
325
+ }
326
+ // ============================================================================
327
+ // Schema Building
328
+ // ============================================================================
329
+ /**
330
+ * Build the federated GraphQL schema with _entities and _service queries.
331
+ *
332
+ * Returns both the executable schema and the Federation-compliant SDL.
333
+ */
334
+ buildFederatedSchema() {
335
+ let builderForSchema = this.state.coreBuilder;
336
+ const needsPlaceholder = !this.hasQueryFields();
337
+ if (needsPlaceholder) {
338
+ builderForSchema = builderForSchema.query("_placeholder", {
339
+ type: S__namespace.String,
340
+ resolve: () => effect.Effect.succeed("placeholder")
341
+ });
342
+ }
343
+ const baseSchema = builderForSchema.buildSchema();
344
+ const typeRegistry = /* @__PURE__ */ new Map();
345
+ const typeMap = baseSchema.getTypeMap();
346
+ for (const [name, type] of Object.entries(typeMap)) {
347
+ const isObjectType = type.constructor.name === "GraphQLObjectType";
348
+ if (isObjectType && !name.startsWith("__")) {
349
+ typeRegistry.set(name, type);
350
+ }
351
+ }
352
+ const entityUnion = this.state.entities.size > 0 ? createEntityUnion(this.state.entities, typeRegistry) : null;
353
+ const serviceType = createServiceType();
354
+ const federationQueryFields = {};
355
+ if (entityUnion) {
356
+ federationQueryFields._entities = {
357
+ type: new core.GraphQLNonNull(new core.GraphQLList(entityUnion)),
358
+ args: {
359
+ representations: {
360
+ type: new core.GraphQLNonNull(new core.GraphQLList(new core.GraphQLNonNull(AnyScalar)))
361
+ }
362
+ },
363
+ resolve: createEntitiesResolver(this.state.entities)
364
+ };
365
+ }
366
+ const sdl = this.generateFederatedSDL(baseSchema, needsPlaceholder);
367
+ federationQueryFields._service = {
368
+ type: new core.GraphQLNonNull(serviceType),
369
+ resolve: createServiceResolver(sdl)
370
+ };
371
+ const baseQueryType = baseSchema.getQueryType();
372
+ const baseQueryFields = baseQueryType?.getFields() ?? {};
373
+ const queryType = new core.GraphQLObjectType({
374
+ name: "Query",
375
+ fields: () => {
376
+ const fields = {};
377
+ for (const [name, field2] of Object.entries(baseQueryFields)) {
378
+ if (name === "_placeholder") continue;
379
+ fields[name] = {
380
+ type: field2.type,
381
+ args: field2.args.reduce(
382
+ (acc, arg) => {
383
+ acc[arg.name] = {
384
+ type: arg.type,
385
+ description: arg.description,
386
+ defaultValue: arg.defaultValue
387
+ };
388
+ return acc;
389
+ },
390
+ {}
391
+ ),
392
+ description: field2.description,
393
+ resolve: field2.resolve,
394
+ extensions: field2.extensions
395
+ };
396
+ }
397
+ Object.assign(fields, federationQueryFields);
398
+ return fields;
399
+ }
400
+ });
401
+ const types = [AnyScalar, FieldSetScalar, serviceType];
402
+ if (entityUnion) {
403
+ types.push(entityUnion);
404
+ }
405
+ for (const [name, type] of Object.entries(typeMap)) {
406
+ if (!name.startsWith("__") && name !== "Query") {
407
+ types.push(type);
408
+ }
409
+ }
410
+ const schema = new core.GraphQLSchema({
411
+ query: queryType,
412
+ mutation: baseSchema.getMutationType() ?? void 0,
413
+ subscription: baseSchema.getSubscriptionType() ?? void 0,
414
+ types
415
+ });
416
+ return { schema, sdl };
417
+ }
418
+ /**
419
+ * Check if the core builder has any query fields registered
420
+ */
421
+ hasQueryFields() {
422
+ try {
423
+ const schema = this.state.coreBuilder.buildSchema();
424
+ const queryType = schema.getQueryType();
425
+ return queryType !== null && queryType !== void 0;
426
+ } catch {
427
+ return false;
428
+ }
429
+ }
430
+ /**
431
+ * Build a standard (non-federated) schema.
432
+ * Useful for testing or running without a gateway.
433
+ */
434
+ buildSchema() {
435
+ return this.state.coreBuilder.buildSchema();
436
+ }
437
+ // ============================================================================
438
+ // SDL Generation
439
+ // ============================================================================
440
+ /**
441
+ * Generate Federation-compliant SDL with directive annotations.
442
+ */
443
+ generateFederatedSDL(schema, excludePlaceholder = false) {
444
+ const lines = [
445
+ `extend schema @link(url: "https://specs.apollo.dev/federation/v${this.state.version}", import: ["@key", "@shareable", "@external", "@requires", "@provides", "@override", "@inaccessible", "@interfaceObject", "@tag"])`,
446
+ ""
447
+ ];
448
+ let baseSDL = core.printSchema(schema);
449
+ if (excludePlaceholder) {
450
+ baseSDL = baseSDL.replace(/\s*_placeholder:\s*String\n?/g, "");
451
+ }
452
+ const annotatedSDL = this.annotateSDLWithDirectives(baseSDL, schema);
453
+ lines.push(annotatedSDL);
454
+ return lines.join("\n");
455
+ }
456
+ /**
457
+ * Annotate SDL types with their federation directives from extensions.
458
+ */
459
+ annotateSDLWithDirectives(sdl, schema) {
460
+ const typeMap = schema.getTypeMap();
461
+ let result = sdl;
462
+ for (const [typeName, type] of Object.entries(typeMap)) {
463
+ if (typeName.startsWith("__")) continue;
464
+ const directives = type.extensions?.directives;
465
+ if (!directives || directives.length === 0) continue;
466
+ const directiveStr = directives.map(formatDirective).join(" ");
467
+ const typePattern = new RegExp(
468
+ `(type\\s+${typeName}(?:\\s+implements\\s+[^{]+)?)(\\s*\\{)`,
469
+ "g"
470
+ );
471
+ result = result.replace(typePattern, `$1 ${directiveStr}$2`);
472
+ const interfacePattern = new RegExp(`(interface\\s+${typeName})(\\s*\\{)`, "g");
473
+ result = result.replace(interfacePattern, `$1 ${directiveStr}$2`);
474
+ const enumPattern = new RegExp(`(enum\\s+${typeName})(\\s*\\{)`, "g");
475
+ result = result.replace(enumPattern, `$1 ${directiveStr}$2`);
476
+ const unionPattern = new RegExp(`(union\\s+${typeName})(\\s*=)`, "g");
477
+ result = result.replace(unionPattern, `$1 ${directiveStr}$2`);
478
+ const inputPattern = new RegExp(`(input\\s+${typeName})(\\s*\\{)`, "g");
479
+ result = result.replace(inputPattern, `$1 ${directiveStr}$2`);
480
+ }
481
+ for (const [typeName, type] of Object.entries(typeMap)) {
482
+ if (typeName.startsWith("__")) continue;
483
+ if (!(type instanceof core.GraphQLObjectType)) continue;
484
+ const fields = type.getFields();
485
+ for (const [fieldName, field2] of Object.entries(fields)) {
486
+ const fieldDirectives = field2.extensions?.directives;
487
+ if (!fieldDirectives || fieldDirectives.length === 0) continue;
488
+ const directiveStr = fieldDirectives.map(formatDirective).join(" ");
489
+ const typeBlockPattern = new RegExp(
490
+ `(type\\s+${typeName}[^{]*\\{[\\s\\S]*?)(${fieldName}(?:\\([^)]*\\))?:\\s*[^\\n]+?)([\\n}])`,
491
+ "g"
492
+ );
493
+ result = result.replace(typeBlockPattern, `$1$2 ${directiveStr}$3`);
494
+ }
495
+ }
496
+ return result;
497
+ }
498
+ };
499
+ function formatDirective(directive) {
500
+ if (!directive.args || Object.keys(directive.args).length === 0) {
501
+ return `@${directive.name}`;
502
+ }
503
+ const args = Object.entries(directive.args).map(([key2, value]) => {
504
+ if (typeof value === "string") {
505
+ return `${key2}: "${value}"`;
506
+ }
507
+ return `${key2}: ${JSON.stringify(value)}`;
508
+ }).join(", ");
509
+ return `@${directive.name}(${args})`;
510
+ }
511
+
512
+ // src/directives.ts
513
+ var key = (config) => ({
514
+ _tag: "key",
515
+ fields: config.fields,
516
+ resolvable: config.resolvable
517
+ });
518
+ var shareable = () => ({
519
+ _tag: "shareable"
520
+ });
521
+ var inaccessible = () => ({
522
+ _tag: "inaccessible"
523
+ });
524
+ var interfaceObject = () => ({
525
+ _tag: "interfaceObject"
526
+ });
527
+ var tag = (name) => ({
528
+ _tag: "tag",
529
+ name
530
+ });
531
+ var external = () => ({
532
+ _tag: "external"
533
+ });
534
+ var requires = (config) => ({
535
+ _tag: "requires",
536
+ fields: config.fields
537
+ });
538
+ var provides = (config) => ({
539
+ _tag: "provides",
540
+ fields: config.fields
541
+ });
542
+ var override = (config) => ({
543
+ _tag: "override",
544
+ from: config.from,
545
+ label: config.label
546
+ });
547
+ var entity = (config) => (builder) => builder.entity(config);
548
+ var query = (name, config) => (builder) => builder.query(name, config);
549
+ var mutation = (name, config) => (builder) => builder.mutation(name, config);
550
+ var subscription = (name, config) => (builder) => builder.subscription(name, config);
551
+ var objectType = (config) => (builder) => builder.objectType(config);
552
+ var interfaceType = (config) => (builder) => builder.interfaceType(config);
553
+ var enumType = (config) => (builder) => builder.enumType(config);
554
+ var unionType = (config) => (builder) => builder.unionType(config);
555
+ var inputType = (config) => (builder) => builder.inputType(config);
556
+ var field = (typeName, fieldName, config) => (builder) => builder.field(typeName, fieldName, config);
557
+ var externalField = (config) => ({
558
+ type: config.type,
559
+ description: config.description,
560
+ directives: [{ name: "external" }],
561
+ resolve: (parent) => effect.Effect.succeed(parent)
562
+ });
563
+ var requiresField = (config) => ({
564
+ type: config.type,
565
+ description: config.description,
566
+ directives: [{ name: "requires", args: { fields: config.fields } }],
567
+ resolve: config.resolve
568
+ });
569
+ var providesField = (config) => ({
570
+ type: config.type,
571
+ description: config.description,
572
+ directives: [{ name: "provides", args: { fields: config.fields } }],
573
+ resolve: config.resolve
574
+ });
575
+ var overrideField = (config) => ({
576
+ type: config.type,
577
+ description: config.description,
578
+ directives: [
579
+ {
580
+ name: "override",
581
+ args: {
582
+ from: config.from,
583
+ ...config.label !== void 0 ? { label: config.label } : {}
584
+ }
585
+ }
586
+ ],
587
+ resolve: config.resolve
588
+ });
589
+
590
+ exports.AnyScalar = AnyScalar;
591
+ exports.FederatedSchemaBuilder = FederatedSchemaBuilder;
592
+ exports.FieldSetScalar = FieldSetScalar;
593
+ exports.entity = entity;
594
+ exports.enumType = enumType;
595
+ exports.external = external;
596
+ exports.externalField = externalField;
597
+ exports.field = field;
598
+ exports.inaccessible = inaccessible;
599
+ exports.inputType = inputType;
600
+ exports.interfaceObject = interfaceObject;
601
+ exports.interfaceType = interfaceType;
602
+ exports.key = key;
603
+ exports.mutation = mutation;
604
+ exports.objectType = objectType;
605
+ exports.override = override;
606
+ exports.overrideField = overrideField;
607
+ exports.provides = provides;
608
+ exports.providesField = providesField;
609
+ exports.query = query;
610
+ exports.requires = requires;
611
+ exports.requiresField = requiresField;
612
+ exports.shareable = shareable;
613
+ exports.subscription = subscription;
614
+ exports.tag = tag;
615
+ exports.toDirectiveApplication = toDirectiveApplication;
616
+ exports.unionType = unionType;
617
+ //# sourceMappingURL=index.cjs.map
618
+ //# sourceMappingURL=index.cjs.map