diff --git a/composition-js/src/genHintDoc.ts b/composition-js/src/genHintDoc.ts index 24fcd80d9..bc6780932 100644 --- a/composition-js/src/genHintDoc.ts +++ b/composition-js/src/genHintDoc.ts @@ -2,20 +2,20 @@ import { assert, MultiMap } from '@apollo/federation-internals'; import { HintCodeDefinition, HintLevel, HINTS } from './hints'; const header = `--- -title: Federation Hints -sidebar_title: Hints +title: Composition hints --- -When you successfully [compose](./federated-types/composition) the schemas provided by your [subgraphs](./subgraphs/) into a **supergraph schema**, "hints" may provide additional information about the composition. Hints are first and foremost informative and don't necessarily correspond to a problem to be fixed. +When you successfully [compose](./federated-types/composition) the schemas provided by your [subgraphs](./subgraphs/) into a supergraph schema, the composition process might output **hints** that provide additional information about the result. Hints are primarily informative and _do not_ necessarily indicate that a problem needs to be fixed. Hints are categorized under the following levels: -1. WARN: indicates a situation that may be expected but is usually temporary and should be double-checked. Typically, composition might have had to ignore some elements from some subgraph when creating the supergraph. -2. INFO: information that may hint at some improvements or highlight noteworthy resolution made by composition but can otherwise be ignored. -3. DEBUG: lower-level information that gives insights into the composition but of lesser importance/impact. + +* \`WARN\`: Indicates a situation that might be expected but is usually temporary and should be double-checked. Typically, composition might have needed to ignore some elements from some subgraph when creating the supergraph. +* \`INFO\`: Suggests a potentially helpful improvement or highlights a noteworthy resolution made by composition. Can otherwise be ignored. +* \`DEBUG\`: Lower-level information that provides insight into the composition. These hints are of lesser importance/impact. Note that hints are first and foremost informative and don't necessarily correspond to a problem to be fixed. -This document lists the hints that can be generated for each level, with a description of why they are generated. +This document lists the hints that can be generated for each level, with a description of why each is generated. `; function makeMarkdownArray( @@ -26,7 +26,7 @@ function makeMarkdownArray( let out = '| ' + headers.join(' | ') + ' |\n'; out += '|' + headers.map(_ => '---').join('|') + '|\n'; for (const row of rows) { - assert(row.length <= columns, `Row [${row}] has too columns (expect ${columns} but got ${row.length})`); + assert(row.length <= columns, `Row [${row}] has too few columns (expect ${columns} but got ${row.length})`); const frow = row.length === columns ? row : row.concat(new Array(columns - row.length).fill('')); @@ -54,9 +54,7 @@ const sortRowsByCode = (r1: string[], r2: string[]) => r1[0].localeCompare(r2[0] rows.sort(sortRowsByCode); -const hintsSectionHeader = `## Hints - -The following hints might be generated during composition:`; +const hintsSectionHeader = `The following hints might be generated during composition:`; const hintsByLevel = []; @@ -68,16 +66,16 @@ for (const level of [HintLevel.WARN, HintLevel.INFO, HintLevel.DEBUG]) { } const rows = defs.map(def => [ - '`' + levelName + '`', '`' + def.code + '`', def.description, + '`' + levelName + '`', ]); - hintsByLevel.push(`### ${levelName}` + hintsByLevel.push(`## \`${levelName}\`` + '\n\n' - + makeMarkdownArray( - [ 'Level', 'Code', 'Description' ], - rows, - )); + + '
\n\n' + + makeMarkdownArray([ 'Code', 'Description', 'Level' ], rows) + + '\n
' + ); } console.log( @@ -85,4 +83,3 @@ console.log( + hintsSectionHeader + '\n\n' + hintsByLevel.join('\n\n') ); - diff --git a/docs/source/config.json b/docs/source/config.json index e08bdb8a0..ba2f24d49 100644 --- a/docs/source/config.json +++ b/docs/source/config.json @@ -64,6 +64,7 @@ }, "Debugging & Metrics": { "Error codes": "/errors", + "Composition hints": "/hints", "Federated trace data": "/metrics", "OpenTelemetry": "/opentelemetry" }, diff --git a/docs/source/errors.md b/docs/source/errors.md index 0087faea2..6fcb2f38d 100644 --- a/docs/source/errors.md +++ b/docs/source/errors.md @@ -16,6 +16,8 @@ If Apollo Gateway encounters an error, composition fails. This document lists su The following errors might be raised during composition: +
+ | Code | Description | Since | Comment | |---|---|---|---| | `DEFAULT_VALUE_USES_INACCESSIBLE` | An element is marked as @inaccessible but is used in the default value of an element visible in the API schema. | 2.0.0 | | @@ -25,20 +27,20 @@ The following errors might be raised during composition: | `EMPTY_MERGED_INPUT_TYPE` | An input object type has no field common to all the subgraphs that define the type. Merging that type would result in an invalid empty input object type. | 2.0.0 | | | `ENUM_VALUE_MISMATCH` | An enum type that is used as both an input and output type has a value that is not defined in all the subgraphs that define the enum type. | 2.0.0 | | | `EXTENSION_WITH_NO_BASE` | A subgraph is attempting to `extend` a type that is not originally defined in any known subgraph. | 0.x | | -| `EXTERNAL_ARGUMENT_DEFAULT_MISMATCH` | An `@external` field declares an argument with a default that is incompatible with the corresponding argument in the declaration(s) of that field in other subgtaphs. | 2.0.0 | | +| `EXTERNAL_ARGUMENT_DEFAULT_MISMATCH` | An `@external` field declares an argument with a default that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs. | 2.0.0 | | | `EXTERNAL_ARGUMENT_MISSING` | An `@external` field is missing some arguments present in the declaration(s) of that field in other subgraphs. | 2.0.0 | | -| `EXTERNAL_ARGUMENT_TYPE_MISMATCH` | An `@external` field declares an argument with a type that is incompatible with the corresponding argument in the declaration(s) of that field in other subgtaphs. | 2.0.0 | | +| `EXTERNAL_ARGUMENT_TYPE_MISMATCH` | An `@external` field declares an argument with a type that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs. | 2.0.0 | | | `EXTERNAL_MISSING_ON_BASE` | A field is marked as `@external` in a subgraph but with no non-external declaration in any other subgraph. | 0.x | | | `EXTERNAL_ON_INTERFACE` | The field of an interface type is marked with `@external`: as external is about marking field not resolved by the subgraph and as interface field are not resolved (only implementations of those fields are), an "external" interface field is nonsensical | 2.0.0 | | | `EXTERNAL_TYPE_MISMATCH` | An `@external` field has a type that is incompatible with the declaration(s) of that field in other subgraphs. | 0.x | | -| `EXTERNAL_UNUSED` | An `@external` field is not being used by any instance of `@key`, `@requires`, `@provides` or to satisfy an interface implememtation. | 0.x | | +| `EXTERNAL_UNUSED` | An `@external` field is not being used by any instance of `@key`, `@requires`, `@provides` or to satisfy an interface implementation. | 0.x | | | `FIELD_ARGUMENT_DEFAULT_MISMATCH` | An argument (of a field/directive) has a default value that is incompatible with that of other declarations of that same argument in other subgraphs. | 2.0.0 | | | `FIELD_ARGUMENT_TYPE_MISMATCH` | An argument (of a field/directive) has a type that is incompatible with that of other declarations of that same argument in other subgraphs. | 2.0.0 | Replaces: `VALUE_TYPE_INPUT_VALUE_MISMATCH` | | `FIELD_TYPE_MISMATCH` | A field has a type that is incompatible with other declarations of that field in other subgraphs. | 2.0.0 | Replaces: `VALUE_TYPE_FIELD_TYPE_MISMATCH` | | `IMPLEMENTED_BY_INACCESSIBLE` | An element is marked as @inaccessible but implements an element visible in the API schema. | 2.0.0 | | | `INPUT_FIELD_DEFAULT_MISMATCH` | An input field has a default value that is incompatible with other declarations of that field in other subgraphs. | 2.0.0 | | | `INTERFACE_FIELD_IMPLEM_TYPE_MISMATCH` | For an interface field, some of its concrete implementations have @external or @requires and there is difference in those implementations return type (which is currently not supported; see https://github.com/apollographql/federation/issues/1257) | 2.0.0 | | -| `INTERFACE_FIELD_NO_IMPLEM` | After subgraph merging, an implemenation is missing a field of one of the interface it implements (which can happen for valid subgraphs). | 2.0.0 | | +| `INTERFACE_FIELD_NO_IMPLEM` | After subgraph merging, an implementation is missing a field of one of the interface it implements (which can happen for valid subgraphs). | 2.0.0 | | | `INVALID_FIELD_SHARING` | A field that is non-shareable in at least one subgraph is resolved by multiple subgraphs. | 2.0.0 | | | `INVALID_GRAPHQL` | A schema is invalid GraphQL: it violates one of the rule of the specification. | 2.0.0 | | | `INVALID_LINK_DIRECTIVE_USAGE` | An application of the @link directive is invalid/does not respect the specification. | 2.0.0 | | @@ -78,14 +80,17 @@ The following errors might be raised during composition: | `SATISFIABILITY_ERROR` | Subgraphs can be merged, but the resulting supergraph API would have queries that cannot be satisfied by those subgraphs. | 2.0.0 | | | `TYPE_DEFINITION_INVALID` | A built-in or federation type has an invalid definition in the schema. | 2.0.0 | | | `TYPE_KIND_MISMATCH` | A type has the same name in different subgraphs, but a different kind. For instance, one definition is an object type but another is an interface. | 2.0.0 | Replaces: `VALUE_TYPE_KIND_MISMATCH`, `EXTENSION_OF_WRONG_KIND`, `ENUM_MISMATCH_TYPE` | -| `TYPE_WITH_ONLY_UNUSED_EXTERNAL` | A federation 1 schema has a composite type comprised only of unused external fields. Note that this error can _only_ be raised for federation 1 schema as federation 2 schema do not allow unused external fields (and errors with code EXTERNAL_UNUSED will be raised in that case). But when federation 1 schema are automatically migrated to federation 2 ones, unused external fields are automaticaly removed, and in rare case this can leave a type empty. If that happens, an error with this code will be raised | 2.0.0 | | +| `TYPE_WITH_ONLY_UNUSED_EXTERNAL` | A federation 1 schema has a composite type comprised only of unused external fields. Note that this error can _only_ be raised for federation 1 schema as federation 2 schema do not allow unused external fields (and errors with code EXTERNAL_UNUSED will be raised in that case). But when federation 1 schema are automatically migrated to federation 2 ones, unused external fields are automatically removed, and in rare case this can leave a type empty. If that happens, an error with this code will be raised | 2.0.0 | | | `UNKNOWN_FEDERATION_LINK_VERSION` | The version of federation in a @link directive on the schema is unknown. | 2.0.0 | | +
## Removed codes The following error codes have been removed and are no longer generated by the most recent version of the `@apollo/gateway` library: +
+ | Removed Code | Comment | |---|---| | `DUPLICATE_ENUM_DEFINITION` | As duplicate enum definitions is invalid GraphQL, this will now be an error with code `INVALID_GRAPHQL` | @@ -93,7 +98,7 @@ The following error codes have been removed and are no longer generated by the m | `DUPLICATE_SCALAR_DEFINITION` | As duplicate scalar definitions is invalid GraphQL, this will now be an error with code `INVALID_GRAPHQL` | | `ENUM_MISMATCH` | Subgraph definitions for an enum are now merged by composition | | `EXTERNAL_USED_ON_BASE` | As there is not type ownership anymore, there is also no particular limitation as to where a field can be external. | -| `KEY_FIELDS_MISSING_EXTERNAL` | Using `@external` for key fields is now decouraged, unless the field is truly meant to be external. | +| `KEY_FIELDS_MISSING_EXTERNAL` | Using `@external` for key fields is now discouraged, unless the field is truly meant to be external. | | `KEY_FIELDS_MISSING_ON_BASE` | Keys can now use any field from any other subgraph. | | `KEY_MISSING_ON_BASE` | Each subgraph is now free to declare a key only if it needs it. | | `KEY_NOT_SPECIFIED` | Each subgraph can declare key independently of any other subgraph. | @@ -102,7 +107,8 @@ The following error codes have been removed and are no longer generated by the m | `PROVIDES_NOT_ON_ENTITY` | @provides can now be used on any type. | | `REQUIRES_FIELDS_MISSING_ON_BASE` | Fields in @requires can now be from any subgraph. | | `REQUIRES_USED_ON_BASE` | As there is not type ownership anymore, there is also no particular limitation as to which subgraph can use a @requires. | -| `RESERVED_FIELD_USED` | This error was previously not correctly enforced: the _service and _entities, if present, were overriden; this is still the case | +| `RESERVED_FIELD_USED` | This error was previously not correctly enforced: the _service and _entities, if present, were overridden; this is still the case | | `VALUE_TYPE_NO_ENTITY` | There is no strong different between entity and value types in the model (they are just usage pattern) and a type can have keys in one subgraph but not another. | | `VALUE_TYPE_UNION_TYPES_MISMATCH` | Subgraph definitions for an union are now merged by composition | +
diff --git a/docs/source/hints.md b/docs/source/hints.md index f68157972..ca5328d7c 100644 --- a/docs/source/hints.md +++ b/docs/source/hints.md @@ -1,60 +1,67 @@ --- -title: Federation Hints -sidebar_title: Hints +title: Composition hints --- -When you successfully [compose](./federated-types/composition) the schemas provided by your [subgraphs](./subgraphs/) into a **supergraph schema**, "hints" may provide additional information about the composition. Hints are first and foremost informative and don't necessarily correspond to a problem to be fixed. +When you successfully [compose](./federated-types/composition) the schemas provided by your [subgraphs](./subgraphs/) into a supergraph schema, the composition process might output **hints** that provide additional information about the result. Hints are primarily informative and _do not_ necessarily indicate that a problem needs to be fixed. Hints are categorized under the following levels: -1. WARN: indicates a situation that may be expected but is usually temporary and should be double-checked. Typically, composition might have had to ignore some elements from some subgraph when creating the supergraph. -2. INFO: information that may hint at some improvements or highlight noteworthy resolution made by composition but can otherwise be ignored. -3. DEBUG: lower-level information that gives insights into the composition but of lesser importance/impact. -Note that hints are first and foremost informative and don't necessarily correspond to a problem to be fixed. +* `WARN`: Indicates a situation that might be expected but is usually temporary and should be double-checked. Typically, composition might have needed to ignore some elements from some subgraph when creating the supergraph. +* `INFO`: Suggests a potentially helpful improvement or highlights a noteworthy resolution made by composition. Can otherwise be ignored. +* `DEBUG`: Lower-level information that provides insight into the composition. These hints are of lesser importance/impact. -This document lists the hints that can be generated for each level, with a description of why they are generated. +Note that hints are first and foremost informative and don't necessarily correspond to a problem to be fixed. +This document lists the hints that can be generated for each level, with a description of why each is generated. -## Hints The following hints might be generated during composition: -### WARN +## `WARN` + +
-| Level | Code | Description | +| Code | Description | Level | |---|---|---| -| `WARN` | `INCONSISTENT_DEFAULT_VALUE_PRESENCE` | Indicates that an argument definition (of a field/input field/directive definition) has a default value in only some of the subgraphs that define the argument. | -| `WARN` | `INCONSISTENT_INPUT_OBJECT_FIELD` | Indicates that a field of an input object type definition is only defined in a subset of the subgraphs that declare the input object. | -| `WARN` | `INCONSISTENT_ENUM_VALUE_FOR_INPUT_ENUM` | Indicates that a value of an enum type definition (that is only used as an Input type) has not been merged into the supergraph because it is defined in only a subset of the subgraphs that declare the enum | -| `WARN` | `INCONSISTENT_EXECUTABLE_DIRECTIVE_PRESENCE` | Indicates that an executable directive definition is declared in only some of the subgraphs. | -| `WARN` | `NO_EXECUTABLE_DIRECTIVE_INTERSECTION` | Indicates that, for an executable directive definition, no location for it appears in all subgraphs. | -| `WARN` | `INCONSISTENT_EXECUTABLE_DIRECTIVE_REPEATABLE` | Indicates that an executable directive definition is marked repeatable in only a subset of the subgraphs (and will not be repeatable in the supergraph). | -| `WARN` | `INCONSISTENT_EXECUTABLE_DIRECTIVE_LOCATIONS` | Indicates that an executiable directive definition is declared with inconsistent locations across subgraphs (and will use the intersection of all locations in the supergraph). | -| `WARN` | `INCONSISTENT_DESCRIPTION` | Indicates that an element has a description in more than one subgraph, and the descriptions are not equal. | -| `WARN` | `INCONSISTENT_ARGUMENT_PRESENCE` | Indicates that an optional argument (of a field or directive definition) is not present in all subgraphs and will not be part of the supergraph. | -| `WARN` | `FROM_SUBGRAPH_DOES_NOT_EXIST` | Source subgraph specified by @override directive does not exist | +| `INCONSISTENT_DEFAULT_VALUE_PRESENCE` | Indicates that an argument definition (of a field/input field/directive definition) has a default value in only some of the subgraphs that define the argument. | `WARN` | +| `INCONSISTENT_INPUT_OBJECT_FIELD` | Indicates that a field of an input object type definition is only defined in a subset of the subgraphs that declare the input object. | `WARN` | +| `INCONSISTENT_ENUM_VALUE_FOR_INPUT_ENUM` | Indicates that a value of an enum type definition (that is only used as an Input type) has not been merged into the supergraph because it is defined in only a subset of the subgraphs that declare the enum | `WARN` | +| `INCONSISTENT_EXECUTABLE_DIRECTIVE_PRESENCE` | Indicates that an executable directive definition is declared in only some of the subgraphs. | `WARN` | +| `NO_EXECUTABLE_DIRECTIVE_INTERSECTION` | Indicates that, for an executable directive definition, no location for it appears in all subgraphs. | `WARN` | +| `INCONSISTENT_EXECUTABLE_DIRECTIVE_REPEATABLE` | Indicates that an executable directive definition is marked repeatable in only a subset of the subgraphs (and will not be repeatable in the supergraph). | `WARN` | +| `INCONSISTENT_EXECUTABLE_DIRECTIVE_LOCATIONS` | Indicates that an executiable directive definition is declared with inconsistent locations across subgraphs (and will use the intersection of all locations in the supergraph). | `WARN` | +| `INCONSISTENT_DESCRIPTION` | Indicates that an element has a description in more than one subgraph, and the descriptions are not equal. | `WARN` | +| `INCONSISTENT_ARGUMENT_PRESENCE` | Indicates that an optional argument (of a field or directive definition) is not present in all subgraphs and will not be part of the supergraph. | `WARN` | +| `FROM_SUBGRAPH_DOES_NOT_EXIST` | Source subgraph specified by @override directive does not exist | `WARN` | +
-### INFO +## `INFO` -| Level | Code | Description | +
+ +| Code | Description | Level | |---|---|---| -| `INFO` | `INCONSISTENT_BUT_COMPATIBLE_FIELD_TYPE` | Indicates that a field does not have the exact same types in all subgraphs, but that the types are "compatible" (2 types are compatible if one is a non-nullable version of the other, a list version, a subtype, or a combination of the former). | -| `INFO` | `INCONSISTENT_BUT_COMPATIBLE_ARGUMENT_TYPE` | Indicates that an argument type (of a field/input field/directive definition) does not have the exact same type in all subgraphs, but that the types are "compatible" (two types are compatible if one is a non-nullable version of the other, a list version, a subtype, or a combination of the former). | -| `INFO` | `INCONSISTENT_ENTITY` | Indicates that an object is declared as an entity (has a `@key`) in only some of the subgraphs in which the object is defined. | -| `INFO` | `OVERRIDDEN_FIELD_CAN_BE_REMOVED` | Field has been overridden by another subgraph. Consider removing. | -| `INFO` | `OVERRIDE_DIRECTIVE_CAN_BE_REMOVED` | Field with @override directive no longer exists in source subgraph, the directive can be safely removed | +| `INCONSISTENT_BUT_COMPATIBLE_FIELD_TYPE` | Indicates that a field does not have the exact same types in all subgraphs, but that the types are "compatible" (2 types are compatible if one is a non-nullable version of the other, a list version, a subtype, or a combination of the former). | `INFO` | +| `INCONSISTENT_BUT_COMPATIBLE_ARGUMENT_TYPE` | Indicates that an argument type (of a field/input field/directive definition) does not have the exact same type in all subgraphs, but that the types are "compatible" (two types are compatible if one is a non-nullable version of the other, a list version, a subtype, or a combination of the former). | `INFO` | +| `INCONSISTENT_ENTITY` | Indicates that an object is declared as an entity (has a `@key`) in only some of the subgraphs in which the object is defined. | `INFO` | +| `OVERRIDDEN_FIELD_CAN_BE_REMOVED` | Field has been overridden by another subgraph. Consider removing. | `INFO` | +| `OVERRIDE_DIRECTIVE_CAN_BE_REMOVED` | Field with @override directive no longer exists in source subgraph, the directive can be safely removed | `INFO` | +
-### DEBUG +## `DEBUG` -| Level | Code | Description | -|---|---|---| -| `DEBUG` | `INCONSISTENT_OBJECT_VALUE_TYPE_FIELD` | Indicates that a field of an object "value type" (has no `@key` in any subgraph) is not defined in all the subgraphs that declare the type. | -| `DEBUG` | `INCONSISTENT_INTERFACE_VALUE_TYPE_FIELD` | Indicates that a field of an interface "value type" (has no `@key` in any subgraph) is not defined in all the subgraphs that declare the type. | -| `DEBUG` | `INCONSISTENT_UNION_MEMBER` | Indicates that a member of a union type definition is only defined in a subset of the subgraphs that declare the union. | -| `DEBUG` | `INCONSISTENT_ENUM_VALUE_FOR_OUTPUT_ENUM` | Indicates that a value of an enum type definition (that is only used as an Output type, or is unused) has been merged in the supergraph but is defined in only a subset of the subgraphs that declare the enum | -| `DEBUG` | `INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_REPEATABLE` | Indicates that a type system directive definition is marked repeatable in only a subset of the subgraphs that declare the directive (and will be repeatable in the supergraph). | -| `DEBUG` | `INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_LOCATIONS` | Indicates that a type system directive definition is declared with inconsistent locations across subgraphs (and will use the union of all locations in the supergraph). | -| `DEBUG` | `UNUSED_ENUM_TYPE` | Indicates that an enum type is defined in some subgraphs but is unused (no field/argument references it). All the values from subgraphs defining that enum will be included in the supergraph. | +
+| Code | Description | Level | +|---|---|---| +| `INCONSISTENT_OBJECT_VALUE_TYPE_FIELD` | Indicates that a field of an object "value type" (has no `@key` in any subgraph) is not defined in all the subgraphs that declare the type. | `DEBUG` | +| `INCONSISTENT_INTERFACE_VALUE_TYPE_FIELD` | Indicates that a field of an interface "value type" (has no `@key` in any subgraph) is not defined in all the subgraphs that declare the type. | `DEBUG` | +| `INCONSISTENT_UNION_MEMBER` | Indicates that a member of a union type definition is only defined in a subset of the subgraphs that declare the union. | `DEBUG` | +| `INCONSISTENT_ENUM_VALUE_FOR_OUTPUT_ENUM` | Indicates that a value of an enum type definition (that is only used as an Output type, or is unused) has been merged in the supergraph but is defined in only a subset of the subgraphs that declare the enum | `DEBUG` | +| `INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_REPEATABLE` | Indicates that a type system directive definition is marked repeatable in only a subset of the subgraphs that declare the directive (and will be repeatable in the supergraph). | `DEBUG` | +| `INCONSISTENT_TYPE_SYSTEM_DIRECTIVE_LOCATIONS` | Indicates that a type system directive definition is declared with inconsistent locations across subgraphs (and will use the union of all locations in the supergraph). | `DEBUG` | +| `UNUSED_ENUM_TYPE` | Indicates that an enum type is defined in some subgraphs but is unused (no field/argument references it). All the values from subgraphs defining that enum will be included in the supergraph. | `DEBUG` | + +
diff --git a/internals-js/src/error.ts b/internals-js/src/error.ts index 657e3ce86..b410a2587 100644 --- a/internals-js/src/error.ts +++ b/internals-js/src/error.ts @@ -183,7 +183,7 @@ const REQUIRES_UNSUPPORTED_ON_INTERFACE = DIRECTIVE_UNSUPPORTED_ON_INTERFACE.cre const EXTERNAL_UNUSED = makeCodeDefinition( 'EXTERNAL_UNUSED', - 'An `@external` field is not being used by any instance of `@key`, `@requires`, `@provides` or to satisfy an interface implememtation.', + 'An `@external` field is not being used by any instance of `@key`, `@requires`, `@provides` or to satisfy an interface implementation.', { addedIn: FED1_CODE }, ); @@ -191,7 +191,7 @@ const TYPE_WITH_ONLY_UNUSED_EXTERNAL = makeCodeDefinition( 'TYPE_WITH_ONLY_UNUSED_EXTERNAL', 'A federation 1 schema has a composite type comprised only of unused external fields.' + ` Note that this error can _only_ be raised for federation 1 schema as federation 2 schema do not allow unused external fields (and errors with code ${EXTERNAL_UNUSED.code} will be raised in that case).` - + ' But when federation 1 schema are automatically migrated to federation 2 ones, unused external fields are automaticaly removed, and in rare case this can leave a type empty. If that happens, an error with this code will be raised', + + ' But when federation 1 schema are automatically migrated to federation 2 ones, unused external fields are automatically removed, and in rare case this can leave a type empty. If that happens, an error with this code will be raised', ); const PROVIDES_ON_NON_OBJECT_FIELD = makeCodeDefinition( @@ -245,7 +245,7 @@ const NO_QUERIES = makeCodeDefinition( const INTERFACE_FIELD_NO_IMPLEM = makeCodeDefinition( 'INTERFACE_FIELD_NO_IMPLEM', - 'After subgraph merging, an implemenation is missing a field of one of the interface it implements (which can happen for valid subgraphs).' + 'After subgraph merging, an implementation is missing a field of one of the interface it implements (which can happen for valid subgraphs).' ); const TYPE_KIND_MISMATCH = makeCodeDefinition( @@ -267,12 +267,12 @@ const EXTERNAL_ARGUMENT_MISSING = makeCodeDefinition( const EXTERNAL_ARGUMENT_TYPE_MISMATCH = makeCodeDefinition( 'EXTERNAL_ARGUMENT_TYPE_MISMATCH', - 'An `@external` field declares an argument with a type that is incompatible with the corresponding argument in the declaration(s) of that field in other subgtaphs.', + 'An `@external` field declares an argument with a type that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs.', ); const EXTERNAL_ARGUMENT_DEFAULT_MISMATCH = makeCodeDefinition( 'EXTERNAL_ARGUMENT_DEFAULT_MISMATCH', - 'An `@external` field declares an argument with a default that is incompatible with the corresponding argument in the declaration(s) of that field in other subgtaphs.', + 'An `@external` field declares an argument with a default that is incompatible with the corresponding argument in the declaration(s) of that field in other subgraphs.', ); const EXTERNAL_ON_INTERFACE = makeCodeDefinition( @@ -510,7 +510,7 @@ const codeDefByCode = Object.values(ERRORS).reduce((obj: {[code: string]: ErrorC */ export const REMOVED_ERRORS = [ ['KEY_FIELDS_MISSING_ON_BASE', 'Keys can now use any field from any other subgraph.'], - ['KEY_FIELDS_MISSING_EXTERNAL', 'Using `@external` for key fields is now decouraged, unless the field is truly meant to be external.'], + ['KEY_FIELDS_MISSING_EXTERNAL', 'Using `@external` for key fields is now discouraged, unless the field is truly meant to be external.'], ['KEY_MISSING_ON_BASE', 'Each subgraph is now free to declare a key only if it needs it.'], ['MULTIPLE_KEYS_ON_EXTENSION', 'Every subgraph can have multiple keys, as necessary.'], ['KEY_NOT_SPECIFIED', 'Each subgraph can declare key independently of any other subgraph.'], @@ -528,5 +528,5 @@ export const REMOVED_ERRORS = [ ['VALUE_TYPE_NO_ENTITY', 'There is no strong different between entity and value types in the model (they are just usage pattern) and a type can have keys in one subgraph but not another.'], ['VALUE_TYPE_UNION_TYPES_MISMATCH', 'Subgraph definitions for an union are now merged by composition'], ['PROVIDES_FIELDS_SELECT_INVALID_TYPE', '@provides can now be used on field of interface, union and list types'], - ['RESERVED_FIELD_USED', 'This error was previously not correctly enforced: the _service and _entities, if present, were overriden; this is still the case'], + ['RESERVED_FIELD_USED', 'This error was previously not correctly enforced: the _service and _entities, if present, were overridden; this is still the case'], ]; diff --git a/internals-js/src/genErrorCodeDoc.ts b/internals-js/src/genErrorCodeDoc.ts index 9da542dae..c35c23b39 100644 --- a/internals-js/src/genErrorCodeDoc.ts +++ b/internals-js/src/genErrorCodeDoc.ts @@ -47,10 +47,13 @@ const errorsSection = `## Errors The following errors might be raised during composition: -` + makeMarkdownArray( +
+ +${makeMarkdownArray( [ 'Code', 'Description', 'Since', 'Comment' ], rows -); +)} +
`; const removedErrors = REMOVED_ERRORS .map(([code, comment]) => ['`' + code + '`', comment]) @@ -60,7 +63,10 @@ const removedSection = `## Removed codes The following error codes have been removed and are no longer generated by the most recent version of the \`@apollo/gateway\` library: -` + makeMarkdownArray(['Removed Code', 'Comment'], removedErrors); +
+ +${makeMarkdownArray(['Removed Code', 'Comment'], removedErrors)} +
`; console.log( header + '\n\n' diff --git a/package-lock.json b/package-lock.json index 2ee94fa23..314de6de9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "prettier": "2.6.2", "strip-indent": "3.0.0", "ts-jest": "27.1.4", + "ts-node": "^10.7.0", "typescript": "4.6.3", "winston": "3.7.2", "winston-transport": "4.5.0" @@ -1589,6 +1590,27 @@ "node": ">=0.1.90" } }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@dabh/diagnostics": { "version": "2.0.2", "dev": true, @@ -1616,6 +1638,32 @@ "cosmiconfig": ">=6" } }, + "node_modules/@endemolshinegroup/cosmiconfig-typescript-loader/node_modules/ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.0.5", "dev": true, @@ -4100,6 +4148,30 @@ "node": ">= 10" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, "node_modules/@types/accepts": { "version": "1.3.5", "dev": true, @@ -17820,28 +17892,55 @@ "license": "MIT" }, "node_modules/ts-node": { - "version": "9.1.1", - "dev": true, - "license": "MIT", - "dependencies": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" }, "bin": { "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" }, - "engines": { - "node": ">=10.0.0" - }, "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" } }, "node_modules/tslib": { @@ -18255,6 +18354,12 @@ "license": "MIT", "peer": true }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -19874,6 +19979,21 @@ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "dev": true }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, "@dabh/diagnostics": { "version": "2.0.2", "dev": true, @@ -19891,6 +20011,22 @@ "make-error": "^1", "ts-node": "^9", "tslib": "^2" + }, + "dependencies": { + "ts-node": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } + } } }, "@eslint/eslintrc": { @@ -21734,6 +21870,30 @@ "version": "2.0.0", "dev": true }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, "@types/accepts": { "version": "1.3.5", "dev": true, @@ -31107,15 +31267,32 @@ "dev": true }, "ts-node": { - "version": "9.1.1", - "dev": true, - "requires": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", + "v8-compile-cache-lib": "^3.0.0", "yn": "3.1.1" + }, + "dependencies": { + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + } } }, "tslib": { @@ -31384,6 +31561,12 @@ "dev": true, "peer": true }, + "v8-compile-cache-lib": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", + "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", + "dev": true + }, "v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", diff --git a/package.json b/package.json index 0c816ad8d..813fd363f 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,9 @@ "codegen": "graphql-codegen --config codegen.yml", "codegen:check": "npm run codegen && git diff --exit-code", "lint": "eslint . --ext .ts", - "error-code-doc": "node ./internals-js/dist/genErrorCodeDoc.js > ./docs/source/errors.md", + "error-code-doc": "ts-node ./internals-js/src/genErrorCodeDoc.ts > ./docs/source/errors.md", "error-code-doc:check": "npm run error-code-doc && git diff --exit-code", - "hints-doc": "node ./composition-js/dist/genHintDoc.js > ./docs/source/hints.md", + "hints-doc": "ts-node ./composition-js/src/genHintDoc.ts > ./docs/source/hints.md", "hints-doc:check": "npm run hints-doc && git diff --exit-code" }, "engines": { @@ -77,6 +77,7 @@ "prettier": "2.6.2", "strip-indent": "3.0.0", "ts-jest": "27.1.4", + "ts-node": "^10.7.0", "typescript": "4.6.3", "winston": "3.7.2", "winston-transport": "4.5.0"