Skip to content

Commit

Permalink
chore: refactor override, shareable, external
Browse files Browse the repository at this point in the history
  • Loading branch information
Aenimus committed Feb 17, 2024
1 parent 55e7adf commit 6bb1fad
Show file tree
Hide file tree
Showing 24 changed files with 1,168 additions and 1,121 deletions.
483 changes: 182 additions & 301 deletions composition-go/index.global.js

Large diffs are not rendered by default.

12 changes: 5 additions & 7 deletions composition/src/ast/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {
ArgumentNode,
ConstDirectiveNode,
DocumentNode,
EnumTypeDefinitionNode,
EnumTypeExtensionNode,
FieldDefinitionNode,
FieldNode,
InputObjectTypeDefinitionNode,
Expand All @@ -15,10 +17,13 @@ import {
ObjectTypeExtensionNode,
OperationTypeNode,
parse,
ScalarTypeDefinitionNode,
ScalarTypeExtensionNode,
SchemaDefinitionNode,
SchemaExtensionNode,
SelectionSetNode,
StringValueNode,
UnionTypeDefinitionNode,
UnionTypeExtensionNode,
} from 'graphql';
import {
Expand Down Expand Up @@ -54,13 +59,6 @@ import {
UNION_UPPER,
} from '../utils/string-constants';
import { duplicateInterfaceError, unexpectedKindFatalError } from '../errors/errors';
import {
EnumTypeDefinitionNode,
EnumTypeExtensionNode,
ScalarTypeDefinitionNode,
ScalarTypeExtensionNode,
UnionTypeDefinitionNode,
} from 'graphql/index';
import { DirectiveContainer, EXECUTABLE_DIRECTIVE_LOCATIONS, NodeContainer } from '../federation/utils';

export function isObjectLikeNodeEntity(node: ObjectLikeTypeNode): boolean {
Expand Down
41 changes: 8 additions & 33 deletions composition/src/errors/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export function noBaseTypeExtensionError(typeName: string): Error {

export function noDefinedUnionMembersError(unionTypeName: string, extension = false): Error {
return new Error(
`The union ` + (extension ? 'extension' : '') + ` "${unionTypeName}" must define at least one union member.`
`The union ` + (extension ? 'extension' : '') + ` "${unionTypeName}" must define at least one union member.`,
);
}

Expand Down Expand Up @@ -214,8 +214,10 @@ export function shareableFieldDefinitionsError(parent: ObjectContainer, children
}

export function undefinedDirectiveErrorMessage(directiveName: string, hostPath: string): string {
return `The directive "${directiveName}" is declared on "${hostPath}",` +
` but the directive is not defined in the schema.`;
return (
`The directive "${directiveName}" is declared on "${hostPath}",` +
` but the directive is not defined in the schema.`
);
}

export function undefinedEntityKeyErrorMessage(fieldName: string, objectName: string): string {
Expand Down Expand Up @@ -289,9 +291,7 @@ export function invalidUnionError(unionName: string): Error {
}

export function duplicateUnionMemberError(memberTypeName: string, unionTypeName: string): Error {
return new Error(
`Member "${memberTypeName}" must only be defined on union "${unionTypeName}" once.`
)
return new Error(`Member "${memberTypeName}" must only be defined on union "${unionTypeName}" once.`);
}

export const invalidDeprecatedDirectiveError = new Error(`
Expand Down Expand Up @@ -379,29 +379,6 @@ export function invalidKeyDirectiveArgumentErrorMessage(directiveKind: Kind): st
return ` The required argument named "fields" must be type "String" and not type "${directiveKind}".`;
}

export function invalidGraphQLNameErrorMessage(type: string, name: string): string {
return (
` The ${type} "${name}" is an invalid GraphQL name:\n` +
` GraphQL names must match the following regex: /[_a-zA-Z][_a-zA-Z0-9]*/`
);
}

export const invalidOpeningBraceErrorMessage: string = ` Unexpected brace opening:\n Received an opening brace "{" before the parent value was defined.`;

export const invalidClosingBraceErrorMessage: string = ` Unexpected brace closure:\n Received a closing brace "}" before any nested values were defined.`;

export const invalidNestingClosureErrorMessage: string = ` Unexpected brace closure:\n Received a closing brace "}" before its corresponding opening brace "{" was defined.`;

export const invalidNestingErrorMessage: string = ` Invalid nesting:\n A nested key was terminated without a closing brace "}".`;

export function invalidEntityKeyError(parentTypeName: string, entityKey: string, errorMessage: string): Error {
return new Error(
`The directive "key" declared on the object "${parentTypeName}"` +
` with the "fields" argument value of "${entityKey}" is invalid for the following reason:\n` +
errorMessage,
);
}

export function invalidKeyDirectivesError(parentTypeName: string, errorMessages: string[]): Error {
return new Error(
`The entity "${parentTypeName}" defines the following invalid "key" directive` +
Expand Down Expand Up @@ -887,10 +864,8 @@ export function allFieldDefinitionsAreInaccessibleError(typeString: string, type
);
}

export function equivalentSourceAndTargetOverrideError(subgraphName: string, hostPath: string): Error {
return new Error(
`Cannot override field "${hostPath}" because the source and target subgraph names are both "${subgraphName}"`,
);
export function equivalentSourceAndTargetOverrideErrorMessage(subgraphName: string, hostPath: string): string {
return `Cannot override field "${hostPath}" because the source and target subgraph names are both "${subgraphName}"`;
}

export function undefinedEntityInterfaceImplementationsError(
Expand Down
30 changes: 17 additions & 13 deletions composition/src/federation/federation-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ import {
DirectiveMap,
EnumValueContainer,
ExtensionContainer,
FederationFieldData,
FederationResultContainer,
FieldContainer,
InputValueContainer,
InterfaceContainer,
isFieldInaccessible,
Expand Down Expand Up @@ -140,8 +140,8 @@ import {
EntityContainer,
EntityContainerByTypeName,
EntityInterfaceFederationData,
generateAuthenticatedDirective,
generateRequiresScopesDirective,
generateSimpleDirective,
getAllMutualEntries,
getEntriesNotInHashSet,
getOrThrowError,
Expand Down Expand Up @@ -488,7 +488,7 @@ export class FederationFactory {
}
}

isShareabilityOfAllFieldInstancesValid(fieldContainer: FieldContainer) {
isShareabilityOfAllFieldInstancesValid(fieldContainer: FederationFieldData) {
let shareableFields = 0;
let unshareableFields = 0;
for (const [subgraphName, isShareable] of fieldContainer.subgraphsByShareable) {
Expand Down Expand Up @@ -678,7 +678,7 @@ export class FederationFactory {
}
this.parents.set(parentTypeName, {
directives: this.extractPersistedDirectives(node.directives || [], newPersistedDirectivesContainer()),
fields: new Map<string, FieldContainer>(),
fields: new Map<string, FederationFieldData>(),
interfaces: extractInterfaces(node, new Set<string>()),
kind: Kind.INTERFACE_TYPE_DEFINITION,
node: interfaceTypeDefinitionNodeToMutable({
Expand Down Expand Up @@ -740,7 +740,7 @@ export class FederationFactory {
}
this.parents.set(parentTypeName, {
directives: this.extractPersistedDirectives(node.directives || [], newPersistedDirectivesContainer()),
fields: new Map<string, FieldContainer>(),
fields: new Map<string, FederationFieldData>(),
interfaces: extractInterfaces(node, new Set<string>()),
kind: node.kind,
node: interfaceTypeDefinitionNodeToMutable(node),
Expand Down Expand Up @@ -771,7 +771,7 @@ export class FederationFactory {
}
this.parents.set(parentTypeName, {
directives: this.extractPersistedDirectives(node.directives || [], newPersistedDirectivesContainer()),
fields: new Map<string, FieldContainer>(),
fields: new Map<string, FederationFieldData>(),
interfaces: extractInterfaces(node, new Set<string>()),
isRootType: this.isParentRootType,
kind: node.kind,
Expand Down Expand Up @@ -816,7 +816,7 @@ export class FederationFactory {
const interfaces = extractInterfaces(node, new Set<string>());
this.extensions.set(this.parentTypeName, {
directives: this.extractPersistedDirectives(node.directives || [], newPersistedDirectivesContainer()),
fields: new Map<string, FieldContainer>(),
fields: new Map<string, FederationFieldData>(),
interfaces,
isRootType: this.isParentRootType,
kind: Kind.OBJECT_TYPE_EXTENSION,
Expand Down Expand Up @@ -954,7 +954,7 @@ export class FederationFactory {
}

mergeArguments(
container: FieldContainer | DirectiveContainer,
container: FederationFieldData | DirectiveContainer,
args: MutableInputValueDefinitionNode[],
errors: InvalidRequiredArgument[],
argumentNames?: string[],
Expand Down Expand Up @@ -1012,7 +1012,7 @@ export class FederationFactory {
definitions.push(directiveContainer.node);
}

pushAuthorizationDirectives(fieldContainer: FieldContainer, parentTypeName: string) {
pushAuthorizationDirectives(fieldContainer: FederationFieldData, parentTypeName: string) {
const authorizationData = this.authorizationDataByParentTypeName.get(parentTypeName);
if (!authorizationData) {
return;
Expand All @@ -1024,7 +1024,7 @@ export class FederationFactory {
return;
}
if (fieldAuthorizationData.requiresAuthentication) {
fieldContainer.directives.directives.set(AUTHENTICATED, [generateAuthenticatedDirective()]);
fieldContainer.directives.directives.set(AUTHENTICATED, [generateSimpleDirective(AUTHENTICATED)]);
}
if (fieldAuthorizationData.requiredScopes.length > 0) {
fieldContainer.directives.directives.set(REQUIRES_SCOPES, [
Expand All @@ -1033,7 +1033,7 @@ export class FederationFactory {
}
}

getMergedFieldDefinitionNode(fieldContainer: FieldContainer, parentTypeName: string): FieldDefinitionNode {
getMergedFieldDefinitionNode(fieldContainer: FederationFieldData, parentTypeName: string): FieldDefinitionNode {
this.pushAuthorizationDirectives(fieldContainer, parentTypeName);
pushPersistedDirectivesAndGetNode(fieldContainer);
if (fieldContainer.arguments.size < 1) {
Expand Down Expand Up @@ -1174,7 +1174,7 @@ export class FederationFactory {
return false;
}

isFieldExternalInAllMutualSubgraphs(subgraphs: Set<string>, fieldContainer: FieldContainer): boolean {
isFieldExternalInAllMutualSubgraphs(subgraphs: Set<string>, fieldContainer: FederationFieldData): boolean {
const mutualSubgraphs = getAllMutualEntries(subgraphs, fieldContainer.subgraphNames);
if (mutualSubgraphs.size < 1) {
return false;
Expand Down Expand Up @@ -1463,7 +1463,11 @@ export class FederationFactory {
const fieldPath = `${parentTypeName}.${fieldName}`;
const fieldContainer = parentContainer.fieldDataByFieldName.get(fieldName);
// undefined if the field does not exist on the parent
if (!fieldContainer || fieldContainer.argumentDataByArgumentName.size || definedFields[currentDepth].has(fieldName)) {
if (
!fieldContainer ||
fieldContainer.argumentDataByArgumentName.size ||
definedFields[currentDepth].has(fieldName)
) {
shouldAddKeyFieldSet = false;
return BREAK;
}
Expand Down
11 changes: 5 additions & 6 deletions composition/src/federation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
SUBSCRIPTION_UPPER,
} from '../utils/string-constants';
import { SubgraphConfig } from '../subgraph/subgraph';
import { AuthorizationData } from '../utils/utils';

export type FederationResultContainer = {
errors?: Error[];
Expand Down Expand Up @@ -117,7 +116,7 @@ export type EnumValueContainer = {

export type EnumValueMap = Map<string, EnumValueContainer>;

export type FieldContainer = {
export type FederationFieldData = {
arguments: ArgumentMap;
directives: PersistedDirectivesContainer;
isShareable: boolean;
Expand All @@ -128,7 +127,7 @@ export type FieldContainer = {
subgraphsByShareable: Map<string, boolean>;
};

export type FieldMap = Map<string, FieldContainer>;
export type FieldMap = Map<string, FederationFieldData>;

export type InputValueContainer = {
appearances: number;
Expand Down Expand Up @@ -189,7 +188,7 @@ export type UnionContainer = {
node: MutableUnionTypeDefinitionNode;
};

export type ChildContainer = FieldContainer | InputValueContainer | EnumValueContainer;
export type ChildContainer = FederationFieldData | InputValueContainer | EnumValueContainer;

export type ParentContainer =
| EnumContainer
Expand All @@ -204,6 +203,6 @@ export type ExtensionContainer = ObjectExtensionContainer;
export type ParentMap = Map<string, ParentContainer>;
export type ObjectLikeContainer = ObjectContainer | InterfaceContainer;

export function isFieldInaccessible(fieldContainer: FieldContainer): boolean {
return fieldContainer.directives.directives.has(INACCESSIBLE);
export function isFieldInaccessible(fieldData: FederationFieldData): boolean {
return fieldData.directives.directives.has(INACCESSIBLE);
}
9 changes: 7 additions & 2 deletions composition/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ export * from './errors/errors';
export * from './federation/federation-factory';
export * from './federation/utils';
export * from './normalization/normalization-factory';
export * from './normalization/utils';
export * from './normalization/walkers';
export * from './router-configuration/router-configuration';
export * from './subgraph/subgraph';
export * from './schema-building/ast';
export * from './schema-building/type-definition-data';
export * from './schema-building/type-extension-data';
export * from './schema-building/type-merging';
export * from './utils/utils';
export * from './schema-building/utils';
export * from './subgraph/subgraph';
export * from './utils/utils';
export * from './warnings/warnings';
Loading

0 comments on commit 6bb1fad

Please sign in to comment.