Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 38 additions & 38 deletions composition-go/index.global.js

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions composition/src/router-configuration/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { FieldName, TypeName } from '../types/types';

export type NatsEventType = 'subscribe' | 'publish' | 'request';

export type KafkaEventType = 'subscribe' | 'publish';
Expand Down Expand Up @@ -72,20 +74,21 @@ export type FieldSetConditionDataParams = {
};

export type RequiredFieldConfiguration = {
fieldName: string;
fieldName: FieldName;
selectionSet: string;
conditions?: Array<FieldSetConditionData>;
disableEntityResolver?: boolean;
};

export type ConfigurationData = {
fieldNames: Set<string>;
fieldNames: Set<FieldName>;
isRootNode: boolean;
typeName: string;
entityInterfaceConcreteTypeNames?: Set<string>;
typeName: TypeName;
entityInterfaceConcreteTypeNames?: Set<TypeName>;
events?: EventConfiguration[];
externalFieldNames?: Set<string>;
externalFieldNames?: Set<FieldName>;
isInterfaceObject?: boolean;
protectedFieldNames?: Array<FieldName>;
provides?: RequiredFieldConfiguration[];
keys?: RequiredFieldConfiguration[];
requires?: RequiredFieldConfiguration[];
Expand Down
3 changes: 2 additions & 1 deletion composition/src/router-configuration/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ConfigurationData, FieldSetConditionData, FieldSetConditionDataParams } from './types';
import { FieldName } from '../types/types';

export function newFieldSetConditionData({
fieldCoordinatesPath,
Expand All @@ -12,7 +13,7 @@ export function newFieldSetConditionData({

export function newConfigurationData(isEntity: boolean, renamedTypeName: string): ConfigurationData {
return {
fieldNames: new Set<string>(),
fieldNames: new Set<FieldName>(),
isRootNode: isEntity,
typeName: renamedTypeName,
};
Expand Down
1 change: 1 addition & 0 deletions composition/src/schema-building/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ export type ObjectDefinitionData = {
name: string;
node: MutableObjectNode;
persistedDirectivesData: PersistedDirectivesData;
protectedFieldNames: Set<FieldName>;
renamedTypeName: string;
subgraphNames: Set<string>;
description?: StringValueNode;
Expand Down
4 changes: 2 additions & 2 deletions composition/src/schema-building/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ export function isParentDataRootType(parentData: ParentDefinitionData): boolean
return parentData.isRootType;
}

export function isParentDataInterfaceType(parentData: ParentDefinitionData): boolean {
return parentData.kind === Kind.INTERFACE_TYPE_DEFINITION;
export function isInterfaceDefinitionData(data: ParentDefinitionData): data is InterfaceDefinitionData {
return data.kind === Kind.INTERFACE_TYPE_DEFINITION;
}

export function setParentDataExtensionType(existingData: ParentDefinitionData, incomingData: ParentDefinitionData) {
Expand Down
5 changes: 3 additions & 2 deletions composition/src/subgraph/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ParentDefinitionData,
PersistedDirectiveDefinitionData,
} from '../schema-building/types';
import { TypeName } from '../types/types';

export type Subgraph = {
definitions: DocumentNode;
Expand All @@ -14,9 +15,9 @@ export type Subgraph = {
};

export type SubgraphConfig = {
configurationDataByTypeName: Map<string, ConfigurationData>;
configurationDataByTypeName: Map<TypeName, ConfigurationData>;
isVersionTwo: boolean;
parentDefinitionDataByTypeName: Map<string, ParentDefinitionData>;
parentDefinitionDataByTypeName: Map<TypeName, ParentDefinitionData>;
schema: GraphQLSchema;
};

Expand Down
3 changes: 2 additions & 1 deletion composition/src/utils/string-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export const PARENT_DEFINITION_DATA = 'parentDefinitionDataByTypeName';
export const PARENT_DEFINITION_DATA_MAP = 'parentDefinitionDataByParentTypeName';
export const PARENT_EXTENSION_DATA_MAP = 'parentExtensionDataByParentTypeName';
export const PERIOD = '.';
export const PROTECTED = 'openfed__protected';
export const PROVIDER_ID = 'providerId';
export const PROVIDES = 'provides';
export const PUBLISH = 'publish';
Expand Down Expand Up @@ -165,7 +166,7 @@ export const EXECUTABLE_DIRECTIVE_LOCATIONS = new Set<string>([
export const ROOT_TYPE_NAMES = new Set<string>([MUTATION, QUERY, SUBSCRIPTION]);
export const AUTHORIZATION_DIRECTIVES = new Set<string>([AUTHENTICATED, REQUIRES_SCOPES]);
export const PERSISTED_CLIENT_DIRECTIVES = new Set<string>([DEPRECATED]);
export const INHERITABLE_DIRECTIVE_NAMES = new Set<string>([EXTERNAL, SHAREABLE]);
export const INHERITABLE_DIRECTIVE_NAMES = new Set<string>([EXTERNAL, PROTECTED, SHAREABLE]);
export const IGNORED_FIELDS = new Set<string>([ENTITIES_FIELD, SERVICE_FIELD]);

export const INPUT_NODE_KINDS = new Set<Kind>([
Expand Down
3 changes: 2 additions & 1 deletion composition/src/v1/federation/federation-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ import {
InvalidRequiredInputValueData,
} from '../../utils/types';
import { FederateSubgraphsContractV1Params, FederateSubgraphsWithContractsV1Params, FederationParams } from './types';
import { ContractName, FieldCoords, SubgraphName, TypeName } from '../../types/types';
import { ContractName, FieldCoords, FieldName, SubgraphName, TypeName } from '../../types/types';

export class FederationFactory {
authorizationDataByParentTypeName: Map<string, AuthorizationData>;
Expand Down Expand Up @@ -1132,6 +1132,7 @@ export class FederationFactory {
kind: sourceData.kind,
name: stringToNameNode(sourceData.renamedTypeName || sourceData.name),
},
protectedFieldNames: new Set<FieldName>(),
renamedTypeName: sourceData.renamedTypeName,
Comment thread
ysmolski marked this conversation as resolved.
Outdated
subgraphNames: new Set(sourceData.subgraphNames),
};
Expand Down
12 changes: 12 additions & 0 deletions composition/src/v1/normalization/directive-definition-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
KEY_DEFINITION,
LINK_DEFINITION,
OVERRIDE_DEFINITION,
PROTECTED_DEFINITION,
PROVIDES_DEFINITION,
REQUIRED_FIELDSET_TYPE_NODE,
REQUIRED_STRING_TYPE_NODE,
Expand Down Expand Up @@ -98,6 +99,7 @@ import {
CHANNELS,
EDFS_REDIS_PUBLISH,
EDFS_REDIS_SUBSCRIBE,
PROTECTED,
} from '../../utils/string-constants';

export const AUTHENTICATED_DEFINITION_DATA: DirectiveDefinitionData = {
Expand Down Expand Up @@ -439,6 +441,16 @@ export const NATS_SUBSCRIBE_DEFINITION_DATA: DirectiveDefinitionData = {
requiredArgumentNames: new Set<string>([SUBJECTS]),
};

export const PROTECTED_DEFINITION_DATA: DirectiveDefinitionData = {
argumentTypeNodeByArgumentName: new Map<string, ArgumentData>(),
isRepeatable: true,
locations: new Set<string>([FIELD_DEFINITION_UPPER, OBJECT_UPPER]),
name: PROTECTED,
node: PROTECTED_DEFINITION,
optionalArgumentNames: new Set<string>(),
requiredArgumentNames: new Set<string>(),
};

export const REDIS_PUBLISH_DEFINITION_DATA: DirectiveDefinitionData = {
argumentTypeNodeByArgumentName: new Map<string, ArgumentData>([
[
Expand Down
30 changes: 25 additions & 5 deletions composition/src/v1/normalization/normalization-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import {
LINK_IMPORT_DEFINITION,
LINK_PURPOSE_DEFINITION,
MAX_OR_SCOPES,
PROTECTED_DEFINITION,
SCOPE_SCALAR_DEFINITION,
SUBSCRIPTION_FIELD_CONDITION_DEFINITION,
SUBSCRIPTION_FILTER_CONDITION_DEFINITION,
Expand Down Expand Up @@ -303,6 +304,7 @@ import {
OPERATION_TO_DEFAULT,
OVERRIDE,
PROPAGATE,
PROTECTED,
PROVIDER_ID,
PROVIDER_TYPE_KAFKA,
PROVIDER_TYPE_NATS,
Expand Down Expand Up @@ -356,6 +358,7 @@ import {
} from './types';
import { newConfigurationData, newFieldSetConditionData } from '../../router-configuration/utils';
import { ImplementationErrors, InvalidFieldImplementation } from '../../utils/types';
import { FieldName } from '../../types/types';

export function normalizeSubgraphFromString(subgraphSDL: string, noLocation = true): NormalizationResult {
const { error, documentNode } = safeParse(subgraphSDL, noLocation);
Expand Down Expand Up @@ -397,6 +400,7 @@ export class NormalizationFactory {
invalidRepeatedDirectiveNameByCoords = new Map<string, Set<string>>();
isCurrentParentExtension = false;
isParentObjectExternal = false;
isParentObjectProtected = false;
isParentObjectShareable = false;
isSubgraphEventDrivenGraph = false;
isSubgraphVersionTwo = false;
Expand Down Expand Up @@ -555,14 +559,18 @@ export class NormalizationFactory {
fieldDirectivesByDirectiveName: Map<string, Array<ConstDirectiveNode>>,
inheritedDirectiveNames: Set<string>,
) {
if (this.isParentObjectShareable && !fieldDirectivesByDirectiveName.has(SHAREABLE)) {
fieldDirectivesByDirectiveName.set(SHAREABLE, [generateSimpleDirective(SHAREABLE)]);
inheritedDirectiveNames.add(SHAREABLE);
}
if (this.isParentObjectExternal && !fieldDirectivesByDirectiveName.has(EXTERNAL)) {
fieldDirectivesByDirectiveName.set(EXTERNAL, [generateSimpleDirective(EXTERNAL)]);
inheritedDirectiveNames.add(EXTERNAL);
}
if (this.isParentObjectProtected && !fieldDirectivesByDirectiveName.has(PROTECTED)) {
fieldDirectivesByDirectiveName.set(PROTECTED, [generateSimpleDirective(PROTECTED)]);
inheritedDirectiveNames.add(PROTECTED);
}
if (this.isParentObjectShareable && !fieldDirectivesByDirectiveName.has(SHAREABLE)) {
fieldDirectivesByDirectiveName.set(SHAREABLE, [generateSimpleDirective(SHAREABLE)]);
inheritedDirectiveNames.add(SHAREABLE);
}
return fieldDirectivesByDirectiveName;
}

Expand Down Expand Up @@ -591,6 +599,7 @@ export class NormalizationFactory {
continue;
}
this.isParentObjectExternal ||= directiveName === EXTERNAL;
this.isParentObjectProtected ||= directiveName === PROTECTED;
this.isParentObjectShareable ||= directiveName === SHAREABLE;
}
Comment thread
ysmolski marked this conversation as resolved.
Comment thread
ysmolski marked this conversation as resolved.
return directivesByDirectiveName;
Expand Down Expand Up @@ -1251,7 +1260,7 @@ export class NormalizationFactory {
const parentData = this.parentDefinitionDataByTypeName.get(typeName);
const directivesByDirectiveName = this.extractDirectives(
node,
parentData?.directivesByDirectiveName || new Map<string, ConstDirectiveNode[]>(),
parentData?.directivesByDirectiveName ?? new Map<string, ConstDirectiveNode[]>(),
);
const isRootType = this.isTypeNameRootType(typeName);
const extensionType = this.getNodeExtensionType(isRealExtension, directivesByDirectiveName, isRootType);
Expand Down Expand Up @@ -1290,6 +1299,7 @@ export class NormalizationFactory {
name: typeName,
node: getMutableObjectNode(node.name),
persistedDirectivesData: newPersistedDirectivesData(),
protectedFieldNames: new Set<FieldName>(),
renamedTypeName: this.getRenamedRootTypeName(typeName),
subgraphNames: new Set<string>([this.subgraphName]),
description: formatDescription('description' in node ? node.description : undefined),
Expand Down Expand Up @@ -2874,6 +2884,10 @@ export class NormalizationFactory {
definitions.push(LINK_PURPOSE_DEFINITION);
}

if (this.referencedDirectiveNames.has(PROTECTED)) {
definitions.push(PROTECTED_DEFINITION);
}

Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
if (invalidEventsDirectiveDataByRootFieldPath.size > 0) {
errorMessages.push(invalidRootTypeFieldEventsDirectivesErrorMessage(invalidEventsDirectiveDataByRootFieldPath));
}
Expand Down Expand Up @@ -3327,6 +3341,9 @@ export class NormalizationFactory {
if (this.referencedDirectiveNames.has(CONFIGURE_CHILD_DESCRIPTIONS)) {
definitions.push(CONFIGURE_CHILD_DESCRIPTIONS_DEFINITION);
}
if (this.referencedDirectiveNames.has(PROTECTED)) {
definitions.push(PROTECTED_DEFINITION);
}
for (const directiveDefinition of this.customDirectiveDefinitions.values()) {
definitions.push(directiveDefinition);
}
Expand Down Expand Up @@ -3459,6 +3476,9 @@ export class NormalizationFactory {
if (parentData.fieldDataByName.size < 1 && !isNodeQuery(parentTypeName, operationTypeNode)) {
this.errors.push(noFieldDefinitionsError(kindToNodeType(parentData.kind), parentTypeName));
}
if (isObject && parentData.protectedFieldNames.size > 0) {
configurationData.protectedFieldNames = [...parentData.protectedFieldNames];
}
break;
case Kind.SCALAR_TYPE_DEFINITION:
if (parentData.extensionType === ExtensionType.REAL) {
Expand Down
3 changes: 3 additions & 0 deletions composition/src/v1/normalization/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import {
SPECIFIED_BY_DEFINITION_DATA,
SUBSCRIPTION_FILTER_DEFINITION_DATA,
TAG_DEFINITION_DATA,
PROTECTED_DEFINITION_DATA,
} from './directive-definition-data';
import {
AUTHENTICATED,
Expand All @@ -70,6 +71,7 @@ import {
LINK,
OVERRIDE,
PERIOD,
PROTECTED,
PROVIDES,
QUERY,
REQUIRES,
Expand Down Expand Up @@ -404,6 +406,7 @@ export function initializeDirectiveDefinitionDatas(): Map<string, DirectiveDefin
[LINK, LINK_DEFINITION_DATA],
[OVERRIDE, OVERRIDE_DEFINITION_DATA],
[PROVIDES, PROVIDES_DEFINITION_DATA],
[PROTECTED, PROTECTED_DEFINITION_DATA],
[REQUIRES, REQUIRES_DEFINITION_DATA],
[REQUIRES_SCOPES, REQUIRES_SCOPES_DEFINITION_DATA],
[SHAREABLE, SHAREABLE_DEFINITION_DATA],
Expand Down
10 changes: 8 additions & 2 deletions composition/src/v1/normalization/walkers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { EVENT_DIRECTIVE_NAMES } from '../utils/string-constants';
import {
getRenamedRootTypeName,
isParentDataCompositeOutputType,
isParentDataInterfaceType,
isInterfaceDefinitionData,
isTypeNameRootType,
newPersistedDirectivesData,
} from '../../schema-building/utils';
Expand All @@ -39,6 +39,7 @@ import {
EXTERNAL,
IGNORED_FIELDS,
PARENT_DEFINITION_DATA,
PROTECTED,
PROVIDES,
REQUIRES,
SERVICE_OBJECT,
Expand Down Expand Up @@ -362,11 +363,14 @@ export function upsertParentsAndChildren(nf: NormalizationFactory, document: Doc
const directivesByDirectiveName = nf.extractDirectives(node, new Map<string, ConstDirectiveNode[]>());
const inheritedDirectiveNames = new Set<string>();
// Add parent-level shareable and external to the field extraction and repeatable validation
if (!isParentDataInterfaceType(parentData)) {
if (!isInterfaceDefinitionData(parentData)) {
nf.addInheritedDirectivesToFieldData(directivesByDirectiveName, inheritedDirectiveNames);
if (directivesByDirectiveName.has(EXTERNAL)) {
nf.unvalidatedExternalFieldCoords.add(`${nf.originalParentTypeName}.${fieldName}`);
}
if (nf.isParentObjectProtected || directivesByDirectiveName.has(PROTECTED)) {
parentData.protectedFieldNames.add(fieldName);
}
}
const fieldData = nf.addFieldDataByNode(
parentData.fieldDataByName,
Expand Down Expand Up @@ -521,6 +525,7 @@ export function upsertParentsAndChildren(nf: NormalizationFactory, document: Doc
nf.renamedParentTypeName = '';
nf.lastParentNodeKind = Kind.NULL;
nf.isParentObjectExternal = false;
nf.isParentObjectProtected = false;
nf.isParentObjectShareable = false;
},
},
Expand All @@ -546,6 +551,7 @@ export function upsertParentsAndChildren(nf: NormalizationFactory, document: Doc
nf.renamedParentTypeName = '';
nf.lastParentNodeKind = Kind.NULL;
nf.isParentObjectExternal = false;
nf.isParentObjectProtected = false;
nf.isParentObjectShareable = false;
},
},
Expand Down
10 changes: 10 additions & 0 deletions composition/src/v1/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import {
EDFS_REDIS_SUBSCRIBE,
CHANNEL,
CHANNELS,
PROTECTED,
} from '../../utils/string-constants';

export const REQUIRED_STRING_TYPE_NODE: TypeNode = {
Expand Down Expand Up @@ -512,6 +513,7 @@ export const ALL_IN_BUILT_DIRECTIVE_NAMES = new Set<string>([
LINK,
OVERRIDE,
PROVIDES,
PROTECTED,
REQUIRES,
Comment thread
ysmolski marked this conversation as resolved.
Outdated
Comment thread
ysmolski marked this conversation as resolved.
REQUIRES_SCOPES,
SHAREABLE,
Expand Down Expand Up @@ -657,6 +659,14 @@ export const OVERRIDE_DEFINITION: DirectiveDefinitionNode = {
repeatable: false,
};

// directive @openfed__protected repeatable on FIELD_DEFINITION | OBJECT_DEFINITION
export const PROTECTED_DEFINITION: DirectiveDefinitionNode = {
kind: Kind.DIRECTIVE_DEFINITION,
locations: stringArrayToNameNodeArray([FIELD_DEFINITION_UPPER, OBJECT_UPPER]),
name: stringToNameNode(PROTECTED),
repeatable: true,
Comment thread
devsergiy marked this conversation as resolved.
};

Comment thread
ysmolski marked this conversation as resolved.
Outdated
Comment thread
ysmolski marked this conversation as resolved.
// @requiresScopes(scopes: [[openfed__Scope!]!]!) on ENUM | FIELD_DEFINITION | INTERFACE | OBJECT | SCALAR
export const REQUIRES_SCOPES_DEFINITION: MutableDirectiveDefinitionNode = {
arguments: [
Expand Down
4 changes: 0 additions & 4 deletions composition/src/v1/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,10 +437,6 @@ export function isNodeKindObject(kind: Kind) {
return kind === Kind.OBJECT_TYPE_DEFINITION || kind === Kind.OBJECT_TYPE_EXTENSION;
}

export function isInterfaceDefinitionData(data: ParentDefinitionData): data is InterfaceDefinitionData {
return data.kind === Kind.INTERFACE_TYPE_DEFINITION;
}

export function isObjectDefinitionData(data?: ParentDefinitionData): data is ObjectDefinitionData {
if (!data) {
return false;
Expand Down
Loading
Loading