@apollo/federation-internals 2.4.9 → 2.5.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 (84) hide show
  1. package/dist/argumentCompositionStrategies.d.ts +12 -7
  2. package/dist/argumentCompositionStrategies.d.ts.map +1 -1
  3. package/dist/argumentCompositionStrategies.js +26 -7
  4. package/dist/argumentCompositionStrategies.js.map +1 -1
  5. package/dist/authenticatedSpec.d.ts +13 -0
  6. package/dist/authenticatedSpec.d.ts.map +1 -0
  7. package/dist/authenticatedSpec.js +36 -0
  8. package/dist/authenticatedSpec.js.map +1 -0
  9. package/dist/coreSpec.d.ts +6 -5
  10. package/dist/coreSpec.d.ts.map +1 -1
  11. package/dist/coreSpec.js +42 -32
  12. package/dist/coreSpec.js.map +1 -1
  13. package/dist/definitions.d.ts +2 -3
  14. package/dist/definitions.d.ts.map +1 -1
  15. package/dist/definitions.js +12 -7
  16. package/dist/definitions.js.map +1 -1
  17. package/dist/directiveAndTypeSpecification.d.ts +8 -8
  18. package/dist/directiveAndTypeSpecification.d.ts.map +1 -1
  19. package/dist/directiveAndTypeSpecification.js +21 -16
  20. package/dist/directiveAndTypeSpecification.js.map +1 -1
  21. package/dist/error.d.ts +1 -1
  22. package/dist/extractSubgraphsFromSupergraph.d.ts +1 -1
  23. package/dist/extractSubgraphsFromSupergraph.d.ts.map +1 -1
  24. package/dist/extractSubgraphsFromSupergraph.js +450 -295
  25. package/dist/extractSubgraphsFromSupergraph.js.map +1 -1
  26. package/dist/federation.d.ts +10 -5
  27. package/dist/federation.d.ts.map +1 -1
  28. package/dist/federation.js +58 -16
  29. package/dist/federation.js.map +1 -1
  30. package/dist/federationSpec.d.ts +3 -1
  31. package/dist/federationSpec.d.ts.map +1 -1
  32. package/dist/federationSpec.js +12 -3
  33. package/dist/federationSpec.js.map +1 -1
  34. package/dist/inaccessibleSpec.d.ts +1 -1
  35. package/dist/inaccessibleSpec.d.ts.map +1 -1
  36. package/dist/inaccessibleSpec.js +4 -4
  37. package/dist/inaccessibleSpec.js.map +1 -1
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +2 -1
  41. package/dist/index.js.map +1 -1
  42. package/dist/joinSpec.d.ts +19 -17
  43. package/dist/joinSpec.d.ts.map +1 -1
  44. package/dist/joinSpec.js +3 -3
  45. package/dist/joinSpec.js.map +1 -1
  46. package/dist/operations.d.ts +9 -43
  47. package/dist/operations.d.ts.map +1 -1
  48. package/dist/operations.js +44 -97
  49. package/dist/operations.js.map +1 -1
  50. package/dist/requiresScopesSpec.d.ts +16 -0
  51. package/dist/requiresScopesSpec.d.ts.map +1 -0
  52. package/dist/requiresScopesSpec.js +55 -0
  53. package/dist/requiresScopesSpec.js.map +1 -0
  54. package/dist/supergraphs.d.ts +19 -4
  55. package/dist/supergraphs.d.ts.map +1 -1
  56. package/dist/supergraphs.js +40 -14
  57. package/dist/supergraphs.js.map +1 -1
  58. package/dist/tagSpec.d.ts +1 -1
  59. package/dist/tagSpec.d.ts.map +1 -1
  60. package/dist/tagSpec.js +4 -4
  61. package/dist/tagSpec.js.map +1 -1
  62. package/dist/utils.d.ts +1 -0
  63. package/dist/utils.d.ts.map +1 -1
  64. package/dist/utils.js +11 -1
  65. package/dist/utils.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/argumentCompositionStrategies.ts +32 -9
  68. package/src/authenticatedSpec.ts +62 -0
  69. package/src/coreSpec.ts +57 -35
  70. package/src/definitions.ts +22 -9
  71. package/src/directiveAndTypeSpecification.ts +25 -24
  72. package/src/error.ts +2 -2
  73. package/src/extractSubgraphsFromSupergraph.ts +647 -393
  74. package/src/federation.ts +95 -16
  75. package/src/federationSpec.ts +13 -5
  76. package/src/inaccessibleSpec.ts +4 -4
  77. package/src/index.ts +2 -1
  78. package/src/joinSpec.ts +23 -13
  79. package/src/operations.ts +62 -182
  80. package/src/precompute.ts +1 -1
  81. package/src/requiresScopesSpec.ts +76 -0
  82. package/src/supergraphs.ts +64 -16
  83. package/src/tagSpec.ts +4 -4
  84. package/src/utils.ts +10 -0
@@ -3,10 +3,11 @@ import { ErrCoreCheckFailed, FeatureUrl, FeatureVersion } from "./coreSpec";
3
3
  import { CoreFeatures, Schema, sourceASTs } from "./definitions";
4
4
  import { joinIdentity, JoinSpecDefinition, JOIN_VERSIONS } from "./joinSpec";
5
5
  import { buildSchema, buildSchemaFromAST } from "./buildSchema";
6
- import { extractSubgraphsNamesAndUrlsFromSupergraph } from "./extractSubgraphsFromSupergraph";
6
+ import { extractSubgraphsNamesAndUrlsFromSupergraph, extractSubgraphsFromSupergraph } from "./extractSubgraphsFromSupergraph";
7
7
  import { ERRORS } from "./error";
8
+ import { Subgraphs } from ".";
8
9
 
9
- const SUPPORTED_FEATURES = new Set([
10
+ export const DEFAULT_SUPPORTED_SUPERGRAPH_FEATURES = new Set([
10
11
  'https://specs.apollo.dev/core/v0.1',
11
12
  'https://specs.apollo.dev/core/v0.2',
12
13
  'https://specs.apollo.dev/join/v0.1',
@@ -21,24 +22,12 @@ const SUPPORTED_FEATURES = new Set([
21
22
 
22
23
  const coreVersionZeroDotOneUrl = FeatureUrl.parse('https://specs.apollo.dev/core/v0.1');
23
24
 
24
- export function buildSupergraphSchema(supergraphSdl: string | DocumentNode): [Schema, {name: string, url: string}[]] {
25
- // We delay validation because `checkFeatureSupport` gives slightly more useful errors if, say, 'for' is used with core v0.1.
26
- const schema = typeof supergraphSdl === 'string'
27
- ? buildSchema(supergraphSdl, { validate: false })
28
- : buildSchemaFromAST(supergraphSdl, { validate: false });
29
-
30
- const [coreFeatures] = validateSupergraph(schema);
31
- checkFeatureSupport(coreFeatures);
32
- schema.validate();
33
- return [schema, extractSubgraphsNamesAndUrlsFromSupergraph(schema)];
34
- }
35
-
36
25
  /**
37
26
  * Checks that only our hard-coded list of features are part of the provided schema, and that if
38
27
  * the schema uses core v0.1, then it doesn't use the 'for' (purpose) argument.
39
28
  * Throws if that is not true.
40
29
  */
41
- function checkFeatureSupport(coreFeatures: CoreFeatures) {
30
+ function checkFeatureSupport(coreFeatures: CoreFeatures, supportedFeatures: Set<string>) {
42
31
  const errors: GraphQLError[] = [];
43
32
  const coreItself = coreFeatures.coreItself;
44
33
  if (coreItself.url.equals(coreVersionZeroDotOneUrl)) {
@@ -56,7 +45,7 @@ function checkFeatureSupport(coreFeatures: CoreFeatures) {
56
45
 
57
46
  for (const feature of coreFeatures.allFeatures()) {
58
47
  if (feature.url.equals(coreVersionZeroDotOneUrl) || feature.purpose === 'EXECUTION' || feature.purpose === 'SECURITY') {
59
- if (!SUPPORTED_FEATURES.has(feature.url.base.toString())) {
48
+ if (!supportedFeatures.has(feature.url.base.toString())) {
60
49
  errors.push(ERRORS.UNSUPPORTED_LINKED_FEATURE.err(
61
50
  `feature ${feature.url} is for: ${feature.purpose} but is unsupported`,
62
51
  { nodes: feature.directive.sourceAST },
@@ -89,3 +78,62 @@ export function validateSupergraph(supergraph: Schema): [CoreFeatures, JoinSpecD
89
78
  export function isFed1Supergraph(supergraph: Schema): boolean {
90
79
  return validateSupergraph(supergraph)[1].version.equals(new FeatureVersion(0, 1));
91
80
  }
81
+
82
+ export class Supergraph {
83
+ private readonly containedSubgraphs: readonly {name: string, url: string}[];
84
+ // Lazily computed as that requires a bit of work.
85
+ private _subgraphs?: Subgraphs;
86
+
87
+ constructor(
88
+ readonly schema: Schema,
89
+ supportedFeatures: Set<string> | null = DEFAULT_SUPPORTED_SUPERGRAPH_FEATURES,
90
+ private readonly shouldValidate: boolean = true,
91
+ ) {
92
+ const [coreFeatures] = validateSupergraph(schema);
93
+
94
+ if (supportedFeatures !== null) {
95
+ checkFeatureSupport(coreFeatures, supportedFeatures);
96
+ }
97
+
98
+ if (shouldValidate) {
99
+ schema.validate();
100
+ } else {
101
+ schema.assumeValid();
102
+ }
103
+
104
+ this.containedSubgraphs = extractSubgraphsNamesAndUrlsFromSupergraph(schema);
105
+ }
106
+
107
+ static build(supergraphSdl: string | DocumentNode, options?: { supportedFeatures?: Set<string>, validateSupergraph?: boolean }) {
108
+ // We delay validation because `checkFeatureSupport` in the constructor gives slightly more useful errors if, say, 'for' is used with core v0.1.
109
+ const schema = typeof supergraphSdl === 'string'
110
+ ? buildSchema(supergraphSdl, { validate: false })
111
+ : buildSchemaFromAST(supergraphSdl, { validate: false });
112
+
113
+ return new Supergraph(schema, options?.supportedFeatures, options?.validateSupergraph);
114
+ }
115
+
116
+ /**
117
+ * The list of names/urls of the subgraphs contained in this subgraph.
118
+ *
119
+ * Note that this is a subset of what `this.subgraphs()` returns, but contrarily to that method, this method does not do a full extraction of the
120
+ * subgraphs schema.
121
+ */
122
+ subgraphsMetadata(): readonly {name: string, url: string}[] {
123
+ return this.containedSubgraphs;
124
+ }
125
+
126
+ subgraphs(): Subgraphs {
127
+ if (!this._subgraphs) {
128
+ // Note that `extractSubgraphsFromSupergraph` redo a little bit of work we're already one, like validating
129
+ // the supergraph. We could refactor things to avoid it, but it's completely negligible in practice so we
130
+ // can leave that to "some day, maybe".
131
+ this._subgraphs = extractSubgraphsFromSupergraph(this.schema, this.shouldValidate);
132
+ }
133
+ return this._subgraphs;
134
+ }
135
+
136
+ apiSchema(): Schema {
137
+ return this.schema.toAPISchema();
138
+ }
139
+ }
package/src/tagSpec.ts CHANGED
@@ -13,8 +13,8 @@ export class TagSpecDefinition extends FeatureDefinition {
13
13
  public readonly tagDirectiveSpec: DirectiveSpecification;
14
14
  private readonly printedTagDefinition: string;
15
15
 
16
- constructor(version: FeatureVersion) {
17
- super(new FeatureUrl(tagIdentity, 'tag', version));
16
+ constructor(version: FeatureVersion, minimumFederationVersion?: FeatureVersion) {
17
+ super(new FeatureUrl(tagIdentity, 'tag', version), minimumFederationVersion);
18
18
  this.tagLocations = [
19
19
  DirectiveLocation.FIELD_DEFINITION,
20
20
  DirectiveLocation.OBJECT,
@@ -43,7 +43,7 @@ export class TagSpecDefinition extends FeatureDefinition {
43
43
  repeatable: true,
44
44
  args: [{ name: 'name', type: (schema) => new NonNullType(schema.stringType()) }],
45
45
  composes: true,
46
- supergraphSpecification: () => TAG_VERSIONS.latest(),
46
+ supergraphSpecification: (fedVersion) => TAG_VERSIONS.getMinimumRequiredVersion(fedVersion),
47
47
  });
48
48
  this.registerDirective(this.tagDirectiveSpec);
49
49
  }
@@ -77,6 +77,6 @@ export class TagSpecDefinition extends FeatureDefinition {
77
77
  export const TAG_VERSIONS = new FeatureDefinitions<TagSpecDefinition>(tagIdentity)
78
78
  .add(new TagSpecDefinition(new FeatureVersion(0, 1)))
79
79
  .add(new TagSpecDefinition(new FeatureVersion(0, 2)))
80
- .add(new TagSpecDefinition(new FeatureVersion(0, 3)));
80
+ .add(new TagSpecDefinition(new FeatureVersion(0, 3), new FeatureVersion(2, 0)));
81
81
 
82
82
  registerKnownFeature(TAG_VERSIONS);
package/src/utils.ts CHANGED
@@ -431,3 +431,13 @@ export function isNonEmptyArray<T>(array: T[]): array is NonEmptyArray<T> {
431
431
  return array.length > 0;
432
432
  }
433
433
 
434
+ // We can switch to `Array.prototype.findLast` when we drop support for Node 16
435
+ export function findLast<T>(array: T[], predicate: (t: T) => boolean): T | undefined {
436
+ for (let i = array.length - 1; i >= 0; i--) {
437
+ const t = array[i];
438
+ if (predicate(t)) {
439
+ return t;
440
+ }
441
+ }
442
+ return undefined;
443
+ }