@apollo/federation-internals 2.8.3 → 2.9.0-beta.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.
Files changed (48) hide show
  1. package/dist/argumentCompositionStrategies.d.ts +17 -0
  2. package/dist/argumentCompositionStrategies.d.ts.map +1 -1
  3. package/dist/argumentCompositionStrategies.js +38 -0
  4. package/dist/argumentCompositionStrategies.js.map +1 -1
  5. package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
  6. package/dist/extractSubgraphsFromSupergraph.js +59 -8
  7. package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
  8. package/dist/federation.d.ts +5 -2
  9. package/dist/federation.d.ts.map +1 -1
  10. package/dist/federation.js +16 -2
  11. package/dist/federation.js.map +1 -1
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +1 -0
  15. package/dist/index.js.map +1 -1
  16. package/dist/operations.d.ts +3 -1
  17. package/dist/operations.d.ts.map +1 -1
  18. package/dist/operations.js +26 -5
  19. package/dist/operations.js.map +1 -1
  20. package/dist/schemaUpgrader.d.ts.map +1 -1
  21. package/dist/schemaUpgrader.js +50 -31
  22. package/dist/schemaUpgrader.js.map +1 -1
  23. package/dist/specs/coreSpec.d.ts +1 -0
  24. package/dist/specs/coreSpec.d.ts.map +1 -1
  25. package/dist/specs/coreSpec.js +18 -0
  26. package/dist/specs/coreSpec.js.map +1 -1
  27. package/dist/specs/costSpec.d.ts +17 -0
  28. package/dist/specs/costSpec.d.ts.map +1 -0
  29. package/dist/specs/costSpec.js +49 -0
  30. package/dist/specs/costSpec.js.map +1 -0
  31. package/dist/specs/federationSpec.d.ts +3 -1
  32. package/dist/specs/federationSpec.d.ts.map +1 -1
  33. package/dist/specs/federationSpec.js +8 -1
  34. package/dist/specs/federationSpec.js.map +1 -1
  35. package/dist/supergraphs.d.ts.map +1 -1
  36. package/dist/supergraphs.js +1 -0
  37. package/dist/supergraphs.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/argumentCompositionStrategies.ts +37 -0
  40. package/src/extractSubgraphsFromSupergraph.ts +94 -7
  41. package/src/federation.ts +21 -2
  42. package/src/index.ts +1 -0
  43. package/src/operations.ts +41 -4
  44. package/src/schemaUpgrader.ts +55 -31
  45. package/src/specs/coreSpec.ts +21 -0
  46. package/src/specs/costSpec.ts +60 -0
  47. package/src/specs/federationSpec.ts +9 -1
  48. package/src/supergraphs.ts +1 -0
@@ -39,6 +39,7 @@ exports.ROUTER_SUPPORTED_SUPERGRAPH_FEATURES = new Set([
39
39
  'https://specs.apollo.dev/policy/v0.1',
40
40
  'https://specs.apollo.dev/source/v0.1',
41
41
  'https://specs.apollo.dev/context/v0.1',
42
+ 'https://specs.apollo.dev/cost/v0.1',
42
43
  ]);
43
44
  const coreVersionZeroDotOneUrl = coreSpec_1.FeatureUrl.parse('https://specs.apollo.dev/core/v0.1');
44
45
  function checkFeatureSupport(coreFeatures, supportedFeatures) {
@@ -1 +1 @@
1
- {"version":3,"file":"supergraphs.js","sourceRoot":"","sources":["../src/supergraphs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"supergraphs.js","sourceRoot":"","sources":["../src/supergraphs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apollo/federation-internals",
3
- "version": "2.8.3",
3
+ "version": "2.9.0-beta.0",
4
4
  "description": "Apollo Federation internal utilities",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -59,4 +59,41 @@ export const ARGUMENT_COMPOSITION_STRATEGIES = {
59
59
  return acc.concat(newValues);
60
60
  }, []),
61
61
  },
62
+ NULLABLE_AND: {
63
+ name: 'NULLABLE_AND',
64
+ isTypeSupported: supportFixedTypes((schema: Schema) => [schema.booleanType()]),
65
+ mergeValues: (values: (boolean | null | undefined)[]) => values.reduce((acc, next) => {
66
+ if (acc === null || acc === undefined) {
67
+ return next;
68
+ } else if (next === null || next === undefined) {
69
+ return acc;
70
+ } else {
71
+ return acc && next;
72
+ }
73
+ }, undefined),
74
+ },
75
+ NULLABLE_MAX: {
76
+ name: 'NULLABLE_MAX',
77
+ isTypeSupported: supportFixedTypes((schema: Schema) => [schema.intType(), new NonNullType(schema.intType())]),
78
+ mergeValues: (values: any[]) => values.reduce((a: any, b: any) => a !== undefined && b !== undefined ? Math.max(a, b) : a ?? b, undefined),
79
+ },
80
+ NULLABLE_UNION: {
81
+ name: 'NULLABLE_UNION',
82
+ isTypeSupported: (_: Schema, type: InputType) => ({ valid: isListType(type) }),
83
+ mergeValues: (values: any[]) => {
84
+ if (values.every((v) => v === undefined)) {
85
+ return undefined;
86
+ }
87
+
88
+ const combined = new Set();
89
+ for (const subgraphValues of values) {
90
+ if (Array.isArray(subgraphValues)) {
91
+ for (const value of subgraphValues) {
92
+ combined.add(value);
93
+ }
94
+ }
95
+ }
96
+ return Array.from(combined);
97
+ }
98
+ }
62
99
  }
@@ -40,7 +40,7 @@ import { parseSelectionSet } from "./operations";
40
40
  import fs from 'fs';
41
41
  import path from 'path';
42
42
  import { validateStringContainsBoolean } from "./utils";
43
- import { CONTEXT_VERSIONS, ContextSpecDefinition, DirectiveDefinition, errorCauses, isFederationDirectiveDefinedInSchema, printErrors } from ".";
43
+ import { CONTEXT_VERSIONS, ContextSpecDefinition, DirectiveDefinition, FeatureUrl, FederationDirectiveName, SchemaElement, errorCauses, isFederationDirectiveDefinedInSchema, printErrors } from ".";
44
44
 
45
45
  function filteredTypes(
46
46
  supergraph: Schema,
@@ -224,11 +224,13 @@ export function extractSubgraphsFromSupergraph(supergraph: Schema, validateExtra
224
224
  }
225
225
 
226
226
  const types = filteredTypes(supergraph, joinSpec, coreFeatures.coreDefinition);
227
+ const originalDirectiveNames = getApolloDirectiveNames(supergraph);
227
228
  const args: ExtractArguments = {
228
229
  supergraph,
229
230
  subgraphs,
230
231
  joinSpec,
231
232
  filteredTypes: types,
233
+ originalDirectiveNames,
232
234
  getSubgraph,
233
235
  getSubgraphEnumValue,
234
236
  };
@@ -292,6 +294,7 @@ type ExtractArguments = {
292
294
  subgraphs: Subgraphs,
293
295
  joinSpec: JoinSpecDefinition,
294
296
  filteredTypes: NamedType[],
297
+ originalDirectiveNames: Record<string, string>,
295
298
  getSubgraph: (application: Directive<any, { graph?: string }>) => Subgraph | undefined,
296
299
  getSubgraphEnumValue: (subgraphName: string) => string
297
300
  }
@@ -348,7 +351,8 @@ function addAllEmptySubgraphTypes(args: ExtractArguments): TypesInfo {
348
351
  for (const application of typeApplications) {
349
352
  const subgraph = getSubgraph(application);
350
353
  assert(subgraph, () => `Should have found the subgraph for ${application}`);
351
- subgraph.schema.addType(newNamedType(type.kind, type.name));
354
+ const subgraphType = subgraph.schema.addType(newNamedType(type.kind, type.name));
355
+ propagateDemandControlDirectives(type, subgraphType, subgraph, args.originalDirectiveNames);
352
356
  }
353
357
  break;
354
358
  }
@@ -434,6 +438,8 @@ function extractObjOrItfContent(args: ExtractArguments, info: TypeInfo<ObjectTyp
434
438
  const implementsDirective = args.joinSpec.implementsDirective(args.supergraph);
435
439
  assert(implementsDirective, '@join__implements should existing for a fed2 supergraph');
436
440
 
441
+ const originalDirectiveNames = args.originalDirectiveNames;
442
+
437
443
  for (const { type, subgraphsInfo } of info) {
438
444
  const implementsApplications = type.appliedDirectivesOf(implementsDirective);
439
445
  for (const application of implementsApplications) {
@@ -444,13 +450,17 @@ function extractObjOrItfContent(args: ExtractArguments, info: TypeInfo<ObjectTyp
444
450
  subgraphInfo.type.addImplementedInterface(args.interface);
445
451
  }
446
452
 
453
+ for (const { type: subgraphType, subgraph } of subgraphsInfo.values()) {
454
+ propagateDemandControlDirectives(type, subgraphType, subgraph, args.originalDirectiveNames);
455
+ }
456
+
447
457
  for (const field of type.fields()) {
448
458
  const fieldApplications = field.appliedDirectivesOf(fieldDirective);
449
459
  if (fieldApplications.length === 0) {
450
460
  // In fed2 subgraph, no @join__field means that the field is in all the subgraphs in which the type is.
451
461
  const isShareable = isObjectType(type) && subgraphsInfo.size > 1;
452
462
  for (const { type: subgraphType, subgraph } of subgraphsInfo.values()) {
453
- addSubgraphField({ field, type: subgraphType, subgraph, isShareable });
463
+ addSubgraphField({ field, type: subgraphType, subgraph, isShareable, originalDirectiveNames });
454
464
  }
455
465
  } else {
456
466
  const isShareable = isObjectType(type)
@@ -468,15 +478,58 @@ function extractObjOrItfContent(args: ExtractArguments, info: TypeInfo<ObjectTyp
468
478
  }
469
479
 
470
480
  const { type: subgraphType, subgraph } = subgraphsInfo.get(joinFieldArgs.graph)!;
471
- addSubgraphField({ field, type: subgraphType, subgraph, isShareable, joinFieldArgs });
481
+ addSubgraphField({ field, type: subgraphType, subgraph, isShareable, joinFieldArgs, originalDirectiveNames });
472
482
  }
473
483
  }
474
484
  }
475
485
  }
476
486
  }
477
487
 
488
+ /**
489
+ * Builds a map of original name to new name for Apollo feature directives. This is
490
+ * used to handle cases where a directive is renamed via an import statement. For
491
+ * example, importing a directive with a custom name like
492
+ * ```graphql
493
+ * @link(url: "https://specs.apollo.dev/cost/v0.1", import: [{ name: "@cost", as: "@renamedCost" }])
494
+ * ```
495
+ * results in a map entry of `cost -> renamedCost` with the `@` prefix removed.
496
+ *
497
+ * If the directive is imported under its default name, that also results in an entry. So,
498
+ * ```graphql
499
+ * @link(url: "https://specs.apollo.dev/cost/v0.1", import: ["@cost"])
500
+ * ```
501
+ * results in a map entry of `cost -> cost`. This duals as a way to check if a directive
502
+ * is included in the supergraph schema.
503
+ *
504
+ * **Important:** This map does _not_ include directives imported from identities other
505
+ * than `specs.apollo.dev`. This helps us avoid extracting directives to subgraphs
506
+ * when a custom directive's name conflicts with that of a default one.
507
+ */
508
+ function getApolloDirectiveNames(supergraph: Schema): Record<string, string> {
509
+ const originalDirectiveNames: Record<string, string> = {};
510
+ for (const linkDirective of supergraph.schemaDefinition.appliedDirectivesOf("link")) {
511
+ if (linkDirective.arguments().url && linkDirective.arguments().import) {
512
+ const url = FeatureUrl.maybeParse(linkDirective.arguments().url);
513
+ if (!url?.identity.includes("specs.apollo.dev")) {
514
+ continue;
515
+ }
516
+
517
+ for (const importedDirective of linkDirective.arguments().import) {
518
+ if (importedDirective.name && importedDirective.as) {
519
+ originalDirectiveNames[importedDirective.name.replace('@', '')] = importedDirective.as.replace('@', '');
520
+ } else if (typeof importedDirective === 'string') {
521
+ originalDirectiveNames[importedDirective.replace('@', '')] = importedDirective.replace('@', '');
522
+ }
523
+ }
524
+ }
525
+ }
526
+
527
+ return originalDirectiveNames;
528
+ }
529
+
478
530
  function extractInputObjContent(args: ExtractArguments, info: TypeInfo<InputObjectType>[]) {
479
531
  const fieldDirective = args.joinSpec.fieldDirective(args.supergraph);
532
+ const originalDirectiveNames = args.originalDirectiveNames;
480
533
 
481
534
  for (const { type, subgraphsInfo } of info) {
482
535
  for (const field of type.fields()) {
@@ -484,7 +537,7 @@ function extractInputObjContent(args: ExtractArguments, info: TypeInfo<InputObje
484
537
  if (fieldApplications.length === 0) {
485
538
  // In fed2 subgraph, no @join__field means that the field is in all the subgraphs in which the type is.
486
539
  for (const { type: subgraphType, subgraph } of subgraphsInfo.values()) {
487
- addSubgraphInputField({ field, type: subgraphType, subgraph });
540
+ addSubgraphInputField({ field, type: subgraphType, subgraph, originalDirectiveNames });
488
541
  }
489
542
  } else {
490
543
  for (const application of fieldApplications) {
@@ -496,7 +549,7 @@ function extractInputObjContent(args: ExtractArguments, info: TypeInfo<InputObje
496
549
  }
497
550
 
498
551
  const { type: subgraphType, subgraph } = subgraphsInfo.get(args.graph)!;
499
- addSubgraphInputField({ field, type: subgraphType, subgraph, joinFieldArgs: args});
552
+ addSubgraphInputField({ field, type: subgraphType, subgraph, joinFieldArgs: args, originalDirectiveNames });
500
553
  }
501
554
  }
502
555
  }
@@ -506,8 +559,13 @@ function extractInputObjContent(args: ExtractArguments, info: TypeInfo<InputObje
506
559
  function extractEnumTypeContent(args: ExtractArguments, info: TypeInfo<EnumType>[]) {
507
560
  // This was added in join 0.3, so it can genuinely be undefined.
508
561
  const enumValueDirective = args.joinSpec.enumValueDirective(args.supergraph);
562
+ const originalDirectiveNames = args.originalDirectiveNames;
509
563
 
510
564
  for (const { type, subgraphsInfo } of info) {
565
+ for (const { type: subgraphType, subgraph } of subgraphsInfo.values()) {
566
+ propagateDemandControlDirectives(type, subgraphType, subgraph, originalDirectiveNames);
567
+ }
568
+
511
569
  for (const value of type.values) {
512
570
  const enumValueApplications = enumValueDirective ? value.appliedDirectivesOf(enumValueDirective) : [];
513
571
  if (enumValueApplications.length === 0) {
@@ -620,6 +678,24 @@ function maybeDumpSubgraphSchema(subgraph: Subgraph): string {
620
678
  }
621
679
  }
622
680
 
681
+ function propagateDemandControlDirectives(source: SchemaElement<any, any>, dest: SchemaElement<any, any>, subgraph: Subgraph, originalDirectiveNames?: Record<string, string>) {
682
+ const costDirectiveName = originalDirectiveNames?.[FederationDirectiveName.COST];
683
+ if (costDirectiveName) {
684
+ const costDirective = source.appliedDirectivesOf(costDirectiveName).pop();
685
+ if (costDirective) {
686
+ dest.applyDirective(subgraph.metadata().costDirective().name, costDirective.arguments());
687
+ }
688
+ }
689
+
690
+ const listSizeDirectiveName = originalDirectiveNames?.[FederationDirectiveName.LIST_SIZE];
691
+ if (listSizeDirectiveName) {
692
+ const listSizeDirective = source.appliedDirectivesOf(listSizeDirectiveName).pop();
693
+ if (listSizeDirective) {
694
+ dest.applyDirective(subgraph.metadata().listSizeDirective().name, listSizeDirective.arguments());
695
+ }
696
+ }
697
+ }
698
+
623
699
  function errorToString(e: any,): string {
624
700
  const causes = errorCauses(e);
625
701
  return causes ? printErrors(causes) : String(e);
@@ -631,12 +707,14 @@ function addSubgraphField({
631
707
  subgraph,
632
708
  isShareable,
633
709
  joinFieldArgs,
710
+ originalDirectiveNames,
634
711
  }: {
635
712
  field: FieldDefinition<ObjectType | InterfaceType>,
636
713
  type: ObjectType | InterfaceType,
637
714
  subgraph: Subgraph,
638
715
  isShareable: boolean,
639
716
  joinFieldArgs?: JoinFieldDirectiveArguments,
717
+ originalDirectiveNames?: Record<string, string>,
640
718
  }): FieldDefinition<ObjectType | InterfaceType> {
641
719
  const copiedFieldType = joinFieldArgs?.type
642
720
  ? decodeType(joinFieldArgs.type, subgraph.schema, subgraph.name)
@@ -644,7 +722,8 @@ function addSubgraphField({
644
722
 
645
723
  const subgraphField = type.addField(field.name, copiedFieldType);
646
724
  for (const arg of field.arguments()) {
647
- subgraphField.addArgument(arg.name, copyType(arg.type!, subgraph.schema, subgraph.name), arg.defaultValue);
725
+ const argDef = subgraphField.addArgument(arg.name, copyType(arg.type!, subgraph.schema, subgraph.name), arg.defaultValue);
726
+ propagateDemandControlDirectives(arg, argDef, subgraph, originalDirectiveNames)
648
727
  }
649
728
  if (joinFieldArgs?.requires) {
650
729
  subgraphField.applyDirective(subgraph.metadata().requiresDirective(), {'fields': joinFieldArgs.requires});
@@ -689,6 +768,9 @@ function addSubgraphField({
689
768
  if (isShareable && !external && !usedOverridden) {
690
769
  subgraphField.applyDirective(subgraph.metadata().shareableDirective());
691
770
  }
771
+
772
+ propagateDemandControlDirectives(field, subgraphField, subgraph, originalDirectiveNames);
773
+
692
774
  return subgraphField;
693
775
  }
694
776
 
@@ -697,11 +779,13 @@ function addSubgraphInputField({
697
779
  type,
698
780
  subgraph,
699
781
  joinFieldArgs,
782
+ originalDirectiveNames,
700
783
  }: {
701
784
  field: InputFieldDefinition,
702
785
  type: InputObjectType,
703
786
  subgraph: Subgraph,
704
787
  joinFieldArgs?: JoinFieldDirectiveArguments,
788
+ originalDirectiveNames?: Record<string, string>
705
789
  }): InputFieldDefinition {
706
790
  const copiedType = joinFieldArgs?.type
707
791
  ? decodeType(joinFieldArgs?.type, subgraph.schema, subgraph.name)
@@ -709,6 +793,9 @@ function addSubgraphInputField({
709
793
 
710
794
  const inputField = type.addField(field.name, copiedType);
711
795
  inputField.defaultValue = field.defaultValue
796
+
797
+ propagateDemandControlDirectives(field, inputField, subgraph, originalDirectiveNames);
798
+
712
799
  return inputField;
713
800
  }
714
801
 
package/src/federation.ts CHANGED
@@ -100,6 +100,7 @@ import {
100
100
  SourceFieldDirectiveArgs,
101
101
  SourceTypeDirectiveArgs,
102
102
  } from "./specs/sourceSpec";
103
+ import { CostDirectiveArguments, ListSizeDirectiveArguments } from "./specs/costSpec";
103
104
 
104
105
  const linkSpec = LINK_VERSIONS.latest();
105
106
  const tagSpec = TAG_VERSIONS.latest();
@@ -1275,6 +1276,14 @@ export class FederationMetadata {
1275
1276
  return this.getPost20FederationDirective(FederationDirectiveName.CONTEXT);
1276
1277
  }
1277
1278
 
1279
+ costDirective(): Post20FederationDirectiveDefinition<CostDirectiveArguments> {
1280
+ return this.getPost20FederationDirective(FederationDirectiveName.COST);
1281
+ }
1282
+
1283
+ listSizeDirective(): Post20FederationDirectiveDefinition<ListSizeDirectiveArguments> {
1284
+ return this.getPost20FederationDirective(FederationDirectiveName.LIST_SIZE);
1285
+ }
1286
+
1278
1287
  allFederationDirectives(): DirectiveDefinition[] {
1279
1288
  const baseDirectives: DirectiveDefinition[] = [
1280
1289
  this.keyDirective(),
@@ -1338,6 +1347,16 @@ export class FederationMetadata {
1338
1347
  baseDirectives.push(fromContextDirective);
1339
1348
  }
1340
1349
 
1350
+ const costDirective = this.costDirective();
1351
+ if (isFederationDirectiveDefinedInSchema(costDirective)) {
1352
+ baseDirectives.push(costDirective);
1353
+ }
1354
+
1355
+ const listSizeDirective = this.listSizeDirective();
1356
+ if (isFederationDirectiveDefinedInSchema(listSizeDirective)) {
1357
+ baseDirectives.push(listSizeDirective);
1358
+ }
1359
+
1341
1360
  return baseDirectives;
1342
1361
  }
1343
1362
 
@@ -1831,9 +1850,9 @@ export function setSchemaAsFed2Subgraph(schema: Schema, useLatest: boolean = fal
1831
1850
 
1832
1851
  // This is the full @link declaration as added by `asFed2SubgraphDocument`. It's here primarily for uses by tests that print and match
1833
1852
  // subgraph schema to avoid having to update 20+ tests every time we use a new directive or the order of import changes ...
1834
- export const FEDERATION2_LINK_WITH_FULL_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.8", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject", "@authenticated", "@requiresScopes", "@policy", "@sourceAPI", "@sourceType", "@sourceField", "@context", "@fromContext"])';
1853
+ export const FEDERATION2_LINK_WITH_FULL_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject", "@authenticated", "@requiresScopes", "@policy", "@sourceAPI", "@sourceType", "@sourceField", "@context", "@fromContext", "@cost", "@listSize"])';
1835
1854
  // This is the full @link declaration that is added when upgrading fed v1 subgraphs to v2 version. It should only be used by tests.
1836
- export const FEDERATION2_LINK_WITH_AUTO_EXPANDED_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.8", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])';
1855
+ export const FEDERATION2_LINK_WITH_AUTO_EXPANDED_IMPORTS = '@link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])';
1837
1856
 
1838
1857
  // This is the federation @link for tests that go through the SchemaUpgrader.
1839
1858
  export const FEDERATION2_LINK_WITH_AUTO_EXPANDED_IMPORTS_UPGRADED = '@link(url: "https://specs.apollo.dev/federation/v2.4", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])';
package/src/index.ts CHANGED
@@ -25,3 +25,4 @@ export * from './specs/authenticatedSpec';
25
25
  export * from './specs/requiresScopesSpec';
26
26
  export * from './specs/policySpec';
27
27
  export * from './specs/sourceSpec';
28
+ export * from './specs/costSpec';
package/src/operations.ts CHANGED
@@ -56,6 +56,8 @@ import { assert, mapKeys, mapValues, MapWithCachedArrays, MultiMap, SetMultiMap
56
56
  import { argumentsEquals, argumentsFromAST, isValidValue, valueToAST, valueToString } from "./values";
57
57
  import { v1 as uuidv1 } from 'uuid';
58
58
 
59
+ export const DEFAULT_MIN_USAGES_TO_OPTIMIZE = 2;
60
+
59
61
  function validate(condition: any, message: () => string, sourceAST?: ASTNode): asserts condition {
60
62
  if (!condition) {
61
63
  throw ERRORS.INVALID_GRAPHQL.err(message(), { nodes: sourceAST });
@@ -934,25 +936,55 @@ export class Operation extends DirectiveTargetElement<Operation> {
934
936
  this.appliedDirectives,
935
937
  );
936
938
  }
939
+
940
+ private collectUndefinedVariablesFromFragments(fragments: NamedFragments): Variable[] {
941
+ const collector = new VariableCollector();
942
+ for (const namedFragment of fragments.definitions()) {
943
+ namedFragment.selectionSet.usedVariables().forEach(v => {
944
+ if (!this.variableDefinitions.definition(v)) {
945
+ collector.add(v);
946
+ }
947
+ });
948
+ }
949
+ return collector.variables();
950
+ }
937
951
 
938
952
  // Returns a copy of this operation with the provided updated selection set and fragments.
939
- private withUpdatedSelectionSetAndFragments(newSelectionSet: SelectionSet, newFragments: NamedFragments | undefined): Operation {
953
+ private withUpdatedSelectionSetAndFragments(
954
+ newSelectionSet: SelectionSet,
955
+ newFragments: NamedFragments | undefined,
956
+ allAvailableVariables?: VariableDefinitions,
957
+ ): Operation {
940
958
  if (this.selectionSet === newSelectionSet && newFragments === this.fragments) {
941
959
  return this;
942
960
  }
961
+
962
+ let newVariableDefinitions = this.variableDefinitions;
963
+ if (allAvailableVariables && newFragments) {
964
+ const undefinedVariables = this.collectUndefinedVariablesFromFragments(newFragments);
965
+ if (undefinedVariables.length > 0) {
966
+ newVariableDefinitions = new VariableDefinitions();
967
+ newVariableDefinitions.addAll(this.variableDefinitions);
968
+ newVariableDefinitions.addAll(allAvailableVariables.filter(undefinedVariables));
969
+ }
970
+ }
943
971
 
944
972
  return new Operation(
945
973
  this.schema(),
946
974
  this.rootKind,
947
975
  newSelectionSet,
948
- this.variableDefinitions,
976
+ newVariableDefinitions,
949
977
  newFragments,
950
978
  this.name,
951
979
  this.appliedDirectives,
952
980
  );
953
981
  }
954
982
 
955
- optimize(fragments?: NamedFragments, minUsagesToOptimize: number = 2): Operation {
983
+ optimize(
984
+ fragments?: NamedFragments,
985
+ minUsagesToOptimize: number = DEFAULT_MIN_USAGES_TO_OPTIMIZE,
986
+ allAvailableVariables?: VariableDefinitions,
987
+ ): Operation {
956
988
  assert(minUsagesToOptimize >= 1, `Expected 'minUsagesToOptimize' to be at least 1, but got ${minUsagesToOptimize}`)
957
989
  if (!fragments || fragments.isEmpty()) {
958
990
  return this;
@@ -1001,11 +1033,16 @@ export class Operation extends DirectiveTargetElement<Operation> {
1001
1033
  }
1002
1034
  }
1003
1035
 
1004
- return this.withUpdatedSelectionSetAndFragments(optimizedSelection, finalFragments ?? undefined);
1036
+ return this.withUpdatedSelectionSetAndFragments(
1037
+ optimizedSelection,
1038
+ finalFragments ?? undefined,
1039
+ allAvailableVariables,
1040
+ );
1005
1041
  }
1006
1042
 
1007
1043
  generateQueryFragments(): Operation {
1008
1044
  const [minimizedSelectionSet, fragments] = this.selectionSet.minimizeSelectionSet();
1045
+
1009
1046
  return new Operation(
1010
1047
  this.schema(),
1011
1048
  this.rootKind,
@@ -11,6 +11,7 @@ import {
11
11
  Directive,
12
12
  Extension,
13
13
  FieldDefinition,
14
+ InterfaceType,
14
15
  isCompositeType,
15
16
  isInterfaceType,
16
17
  isObjectType,
@@ -230,6 +231,28 @@ export function upgradeSubgraphsIfNecessary(inputs: Subgraphs): UpgradeResult {
230
231
  const subgraphs = new Subgraphs();
231
232
  let errors: GraphQLError[] = [];
232
233
  const subgraphsUsingInterfaceObject = [];
234
+
235
+ // build a data structure to help us do computation only once
236
+ const objectTypeMap = new Map<string, Map<string, [ObjectType | InterfaceType, FederationMetadata]>>();
237
+ for (const subgraph of inputs.values()) {
238
+ for (const t of subgraph.schema.objectTypes()) {
239
+ let entry = objectTypeMap.get(t.name);
240
+ if (!entry) {
241
+ entry = new Map();
242
+ objectTypeMap.set(t.name, entry);
243
+ }
244
+ entry.set(subgraph.name, [t, subgraph.metadata()]);
245
+ }
246
+ for (const t of subgraph.schema.interfaceTypes()) {
247
+ let entry = objectTypeMap.get(t.name);
248
+ if (!entry) {
249
+ entry = new Map();
250
+ objectTypeMap.set(t.name, entry);
251
+ }
252
+ entry.set(subgraph.name, [t, subgraph.metadata()]);
253
+ }
254
+ }
255
+
233
256
  for (const subgraph of inputs.values()) {
234
257
  if (subgraph.isFed2Subgraph()) {
235
258
  subgraphs.add(subgraph);
@@ -237,8 +260,7 @@ export function upgradeSubgraphsIfNecessary(inputs: Subgraphs): UpgradeResult {
237
260
  subgraphsUsingInterfaceObject.push(subgraph.name);
238
261
  }
239
262
  } else {
240
- const otherSubgraphs = inputs.values().filter((s) => s.name !== subgraph.name);
241
- const res = new SchemaUpgrader(subgraph, otherSubgraphs).upgrade();
263
+ const res = new SchemaUpgrader(subgraph, inputs.values(), objectTypeMap).upgrade();
242
264
  if (res.errors) {
243
265
  errors = errors.concat(res.errors);
244
266
  } else {
@@ -291,16 +313,6 @@ function isRootTypeExtension(type: NamedType): boolean {
291
313
  && (type.hasAppliedDirective(metadata.extendsDirective()) || (type.hasExtensionElements() && !type.hasNonExtensionElements()));
292
314
  }
293
315
 
294
- function resolvesField(subgraph: Subgraph, field: FieldDefinition<ObjectType>): boolean {
295
- const metadata = subgraph.metadata();
296
- const t = subgraph.schema.type(field.parent.name);
297
- if (!t || !isObjectType(t)) {
298
- return false;
299
- }
300
- const f = t.field(field.name);
301
- return !!f && (!metadata.isFieldExternal(f) || metadata.isFieldPartiallyExternal(f));
302
- }
303
-
304
316
  function getField(schema: Schema, typeName: string, fieldName: string): FieldDefinition<CompositeType> | undefined {
305
317
  const type = schema.type(typeName);
306
318
  return type && isCompositeType(type) ? type.field(fieldName) : undefined;
@@ -313,7 +325,7 @@ class SchemaUpgrader {
313
325
  private readonly metadata: FederationMetadata;
314
326
  private readonly errors: GraphQLError[] = [];
315
327
 
316
- constructor(private readonly originalSubgraph: Subgraph, private readonly otherSubgraphs: Subgraph[]) {
328
+ constructor(private readonly originalSubgraph: Subgraph, private readonly allSubgraphs: readonly Subgraph[], private readonly objectTypeMap: Map<string, Map<string, [ObjectType | InterfaceType, FederationMetadata]>>) {
317
329
  // Note that as we clone the original schema, the 'sourceAST' values in the elements of the new schema will be those of the original schema
318
330
  // and those won't be updated as we modify the schema to make it fed2-enabled. This is _important_ for us here as this is what ensures that
319
331
  // later merge errors "AST" nodes ends up pointing to the original schema, the one that make sense to the user.
@@ -380,8 +392,9 @@ class SchemaUpgrader {
380
392
  }
381
393
 
382
394
  const extensionAST = firstOf<Extension<any>>(type.extensions().values())?.sourceAST;
383
- for (const subgraph of this.otherSubgraphs) {
384
- const otherType = subgraph.schema.type(type.name);
395
+ const typeInOtherSubgraphs = Array.from(this.objectTypeMap.get(type.name)!.entries()).filter(([subgraphName, _]) => subgraphName !== this.subgraph.name);
396
+ for (let i = 0; i < typeInOtherSubgraphs.length; i += 1) {
397
+ const otherType = typeInOtherSubgraphs[i][1][0];
385
398
  if (otherType && otherType.hasNonExtensionElements()) {
386
399
  return;
387
400
  }
@@ -589,13 +602,12 @@ class SchemaUpgrader {
589
602
  // case territory in the first place, so this is probably good enough (that is, there is
590
603
  // customer schema for which what we do here matter but not that I know of for which it's
591
604
  // not good enough).
592
- for (const other of this.otherSubgraphs) {
593
- const typeInOther = other.schema.type(type.name);
594
- if (!typeInOther) {
595
- continue;
596
- }
597
- assert(isCompositeType(typeInOther), () => `Type ${type} is of kind ${type.kind} in ${this.subgraph.name} but ${typeInOther.kind} in ${other.name}`);
598
- const keysInOther = typeInOther.appliedDirectivesOf(other.metadata().keyDirective());
605
+ const typeInOtherSubgraphs = Array.from(this.objectTypeMap.get(type.name)!.entries()).filter(([subgraphName, _]) => subgraphName !== this.subgraph.name);
606
+
607
+ for (const [otherSubgraphName, v] of typeInOtherSubgraphs) {
608
+ const [typeInOther, metadata] = v;
609
+ assert(isCompositeType(typeInOther), () => `Type ${type} is of kind ${type.kind} in ${this.subgraph.name} but ${typeInOther.kind} in ${otherSubgraphName}`);
610
+ const keysInOther = typeInOther.appliedDirectivesOf(metadata.keyDirective());
599
611
  if (keysInOther.length === 0) {
600
612
  continue;
601
613
  }
@@ -702,7 +714,10 @@ class SchemaUpgrader {
702
714
  // - to every "value type" (in the fed1 sense of non-root type and non-entity) if it is used in any other subgraphs
703
715
  // - to any (non-external) field of an entity/root-type that is not a key field and if another subgraphs resolve it (fully or partially through @provides)
704
716
  for (const type of this.schema.objectTypes()) {
705
- if (type.hasAppliedDirective(keyDirective) || type.isRootType()) {
717
+ if(type.isSubscriptionRootType()) {
718
+ continue;
719
+ }
720
+ if (type.hasAppliedDirective(keyDirective) || (type.isRootType())) {
706
721
  for (const field of type.fields()) {
707
722
  // To know if the field is a "key" field which doesn't need shareable, we rely on whether the field is shareable in the original
708
723
  // schema (the fed1 version), because as fed1 schema will have no @shareable, the key fields will effectively be the only field
@@ -710,17 +725,26 @@ class SchemaUpgrader {
710
725
  if (originalMetadata.isFieldShareable(field)) {
711
726
  continue;
712
727
  }
713
- const otherResolvingSubgraphs = this.otherSubgraphs.filter((s) => resolvesField(s, field));
714
- if (otherResolvingSubgraphs.length > 0 && !field.hasAppliedDirective(shareableDirective)) {
728
+
729
+ const entries = Array.from(this.objectTypeMap.get(type.name)!.entries());
730
+ const typeInOtherSubgraphs = entries.filter(([subgraphName, v]) => {
731
+ if (subgraphName === this.subgraph.name) {
732
+ return false;
733
+ }
734
+ const f = v[0].field(field.name);
735
+ return !!f && (!v[1].isFieldExternal(f) || v[1].isFieldPartiallyExternal(f));
736
+ });
737
+
738
+ if (typeInOtherSubgraphs.length > 0 && !field.hasAppliedDirective(shareableDirective)) {
715
739
  field.applyDirective(shareableDirective);
716
- this.addChange(new ShareableFieldAddition(field.coordinate, otherResolvingSubgraphs.map((s) => s.name)));
740
+ this.addChange(new ShareableFieldAddition(field.coordinate, typeInOtherSubgraphs.map(([s]) => s)));
717
741
  }
718
742
  }
719
743
  } else {
720
- const otherDeclaringSubgraphs = this.otherSubgraphs.filter((s) => s.schema.type(type.name));
721
- if (otherDeclaringSubgraphs.length > 0 && !type.hasAppliedDirective(shareableDirective)) {
744
+ const typeInOtherSubgraphs = Array.from(this.objectTypeMap.get(type.name)!.entries()).filter(([subgraphName, _]) => subgraphName !== this.subgraph.name);
745
+ if (typeInOtherSubgraphs.length > 0 && !type.hasAppliedDirective(shareableDirective)) {
722
746
  type.applyDirective(shareableDirective);
723
- this.addChange(new ShareableTypeAddition(type.coordinate, otherDeclaringSubgraphs.map((s) => s.name)));
747
+ this.addChange(new ShareableTypeAddition(type.coordinate, typeInOtherSubgraphs.map(([s]) => s)));
724
748
  }
725
749
  }
726
750
  }
@@ -739,8 +763,8 @@ class SchemaUpgrader {
739
763
  continue;
740
764
  }
741
765
  if (this.external(element)) {
742
- const tagIsUsedInOtherDefinition = this.otherSubgraphs
743
- .map((s) => getField(s.schema, element.parent.name, element.name))
766
+ const tagIsUsedInOtherDefinition = this.allSubgraphs
767
+ .map((s) => s.name === this.originalSubgraph.name ? undefined : getField(s.schema, element.parent.name, element.name))
744
768
  .filter((f) => !(f && f.hasAppliedDirective('external')))
745
769
  .some((f) => f && f.appliedDirectivesOf('tag').some((d) => valueEquals(application.arguments(), d.arguments())));
746
770
 
@@ -552,6 +552,27 @@ export class CoreSpecDefinition extends FeatureDefinition {
552
552
  return feature.addElementsToSchema(schema);
553
553
  }
554
554
 
555
+ applyFeatureAsLink(schema: Schema, feature: FeatureDefinition, purpose?: CorePurpose, imports?: CoreImport[]): GraphQLError[] {
556
+ const existing = schema.schemaDefinition.appliedDirectivesOf(linkDirectiveDefaultName).find((link) => link.arguments().url === feature.toString());
557
+ if (existing) {
558
+ existing.remove();
559
+ }
560
+
561
+ const coreDirective = this.coreDirective(schema);
562
+ const args: LinkDirectiveArgs = {
563
+ url: feature.toString(),
564
+ import: (existing?.arguments().import ?? []).concat(imports?.map((i) => i.as ? { name: `@${i.name}`, as: `@${i.as}` } : `@${i.name}`)),
565
+ feature: undefined,
566
+ };
567
+
568
+ if (this.supportPurposes() && purpose) {
569
+ args.for = purpose;
570
+ }
571
+
572
+ schema.schemaDefinition.applyDirective(coreDirective, args);
573
+ return feature.addElementsToSchema(schema);
574
+ }
575
+
555
576
  extractFeatureUrl(args: CoreOrLinkDirectiveArgs): FeatureUrl {
556
577
  return FeatureUrl.parse(args[this.urlArgName()]!);
557
578
  }