From 0854ae533987ac97d99eb9f2b762e3a8b92ce920 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Mar 2024 13:39:02 +0000 Subject: [PATCH 01/10] Add top level interface connection to schema --- .../ConcreteEntityOperations.ts | 1 - .../ImplementingEntityOperations.ts | 4 +- .../model-adapters/InterfaceEntityAdapter.ts | 75 ++++++++++--------- .../InterfaceEntityOperations.ts | 11 ++- .../src/schema/make-augmented-schema.ts | 22 +++++- .../schema/resolvers/query/root-connection.ts | 23 +++--- 6 files changed, 82 insertions(+), 54 deletions(-) diff --git a/packages/graphql/src/schema-model/entity/model-adapters/ConcreteEntityOperations.ts b/packages/graphql/src/schema-model/entity/model-adapters/ConcreteEntityOperations.ts index eb78d2cf6e..d70328e2fe 100644 --- a/packages/graphql/src/schema-model/entity/model-adapters/ConcreteEntityOperations.ts +++ b/packages/graphql/src/schema-model/entity/model-adapters/ConcreteEntityOperations.ts @@ -79,7 +79,6 @@ export class ConcreteEntityOperations extends ImplementingEntityOperations) { - for (const [attributeName, attribute] of attributes.entries()) { - const attributeAdapter = new AttributeAdapter(attribute); - this.attributes.set(attributeName, attributeAdapter); - if (attributeAdapter.isConstrainable() && attributeAdapter.isUnique()) { - this.uniqueFieldsKeys.push(attribute.name); - } - } - } - - private initRelationshipDeclarations(relationshipDeclarations: Map) { - for (const [relationshipName, relationshipDeclaration] of relationshipDeclarations.entries()) { - this.relationshipDeclarations.set( - relationshipName, - new RelationshipDeclarationAdapter(relationshipDeclaration, this) - ); - } - } - get operations(): InterfaceEntityOperations { + public get operations(): InterfaceEntityOperations { if (!this._operations) { return new InterfaceEntityOperations(this); } @@ -119,11 +86,11 @@ export class InterfaceEntityAdapter { return upperFirst(this.plural); } - get isReadable(): boolean { + public get isReadable(): boolean { return this.annotations.query === undefined || this.annotations.query.read === true; } - get isAggregable(): boolean { + public get isAggregable(): boolean { return this.annotations.query === undefined || this.annotations.query.aggregate === true; } @@ -156,4 +123,38 @@ export class InterfaceEntityAdapter { public get subscriptionEventPayloadFields(): AttributeAdapter[] { return Array.from(this.attributes.values()).filter((attribute) => attribute.isEventPayloadField()); } + + public findAttribute(name: string): AttributeAdapter | undefined { + return this.attributes.get(name); + } + + public findRelationshipDeclarations(name: string): RelationshipDeclarationAdapter | undefined { + return this.relationshipDeclarations.get(name); + } + + private initConcreteEntities(entities: ConcreteEntity[]) { + for (const entity of entities) { + const entityAdapter = new ConcreteEntityAdapter(entity); + this.concreteEntities.push(entityAdapter); + } + } + + private initAttributes(attributes: Map) { + for (const [attributeName, attribute] of attributes.entries()) { + const attributeAdapter = new AttributeAdapter(attribute); + this.attributes.set(attributeName, attributeAdapter); + if (attributeAdapter.isConstrainable() && attributeAdapter.isUnique()) { + this.uniqueFieldsKeys.push(attribute.name); + } + } + } + + private initRelationshipDeclarations(relationshipDeclarations: Map) { + for (const [relationshipName, relationshipDeclaration] of relationshipDeclarations.entries()) { + this.relationshipDeclarations.set( + relationshipName, + new RelationshipDeclarationAdapter(relationshipDeclaration, this) + ); + } + } } diff --git a/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts b/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts index f39eb56efd..c22f877930 100644 --- a/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts +++ b/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts @@ -17,8 +17,9 @@ * limitations under the License. */ -import type { InterfaceEntityAdapter } from "./InterfaceEntityAdapter"; +import { upperFirst } from "graphql-compose"; import { ImplementingEntityOperations } from "./ImplementingEntityOperations"; +import type { InterfaceEntityAdapter } from "./InterfaceEntityAdapter"; export class InterfaceEntityOperations extends ImplementingEntityOperations { constructor(interfaceEntityAdapter: InterfaceEntityAdapter) { @@ -32,4 +33,12 @@ export class InterfaceEntityOperations extends ImplementingEntityOperations Date: Tue, 5 Mar 2024 09:37:46 +0000 Subject: [PATCH 02/10] WIP add connection fields to interfaces --- .../graphql/src/schema-model/entity/ConcreteEntity.ts | 4 ++-- .../entity/model-adapters/InterfaceEntityOperations.ts | 4 ++++ .../src/translate/queryAST/factory/OperationFactory.ts | 8 ++++++-- .../queryAST/factory/parsers/parse-operation-fields.ts | 2 ++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/graphql/src/schema-model/entity/ConcreteEntity.ts b/packages/graphql/src/schema-model/entity/ConcreteEntity.ts index 5668bfb84e..18d67d5ab8 100644 --- a/packages/graphql/src/schema-model/entity/ConcreteEntity.ts +++ b/packages/graphql/src/schema-model/entity/ConcreteEntity.ts @@ -68,11 +68,11 @@ export class ConcreteEntity implements Entity { } } - isConcreteEntity(): this is ConcreteEntity { + public isConcreteEntity(): this is ConcreteEntity { return true; } - isCompositeEntity(): this is CompositeEntity { + public isCompositeEntity(): this is CompositeEntity { return false; } diff --git a/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts b/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts index c22f877930..f7626e90dd 100644 --- a/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts +++ b/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts @@ -41,4 +41,8 @@ export class InterfaceEntityOperations extends ImplementingEntityOperations Date: Tue, 5 Mar 2024 11:18:41 +0000 Subject: [PATCH 03/10] Generate QueryAST from top level connection with interface --- .../src/schema/make-augmented-schema.ts | 2 +- .../ast/operations/ConnectionReadOperation.ts | 3 +- .../composite/CompositeConnectionPartial.ts | 3 - .../CompositeConnectionReadOperation.ts | 10 +- .../queryAST/factory/OperationFactory.ts | 2 - .../factory/Operations/ConnectionFactory.ts | 108 +++++++++++++----- 6 files changed, 88 insertions(+), 40 deletions(-) diff --git a/packages/graphql/src/schema/make-augmented-schema.ts b/packages/graphql/src/schema/make-augmented-schema.ts index 4839e10ef2..d26f205857 100644 --- a/packages/graphql/src/schema/make-augmented-schema.ts +++ b/packages/graphql/src/schema/make-augmented-schema.ts @@ -53,7 +53,6 @@ import { attributeAdapterToComposeFields, graphqlDirectivesToCompose } from "./t // GraphQL type imports import type { GraphQLToolsResolveMethods } from "graphql-compose/lib/SchemaComposer"; -import { InterfaceEntityAdapter } from "src/schema-model/entity/model-adapters/InterfaceEntityAdapter"; import type { Subgraph } from "../classes/Subgraph"; import { Neo4jGraphQLSubscriptionsCDCEngine } from "../classes/subscription/Neo4jGraphQLSubscriptionsCDCEngine"; import { SHAREABLE } from "../constants"; @@ -68,6 +67,7 @@ import { ConcreteEntity } from "../schema-model/entity/ConcreteEntity"; import { InterfaceEntity } from "../schema-model/entity/InterfaceEntity"; import { UnionEntity } from "../schema-model/entity/UnionEntity"; import { ConcreteEntityAdapter } from "../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +import { InterfaceEntityAdapter } from "../schema-model/entity/model-adapters/InterfaceEntityAdapter"; import { UnionEntityAdapter } from "../schema-model/entity/model-adapters/UnionEntityAdapter"; import { RelationshipDeclarationAdapter } from "../schema-model/relationship/model-adapters/RelationshipDeclarationAdapter"; import type { CypherField, Neo4jFeaturesSettings } from "../types"; diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 2bad210e84..ad65a8d476 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -98,6 +98,7 @@ export class ConnectionReadOperation extends Operation { }); return filterTruthy([ + this.selection, ...this.nodeFields, ...this.edgeFields, ...this.filters, @@ -131,7 +132,7 @@ export class ConnectionReadOperation extends Operation { }); const filtersSubqueries = [...authFilterSubqueries, ...normalFilterSubqueries]; - + const edgesVar = new Cypher.NamedVariable("edges"); const totalCount = new Cypher.NamedVariable("totalCount"); const edgesProjectionVar = new Cypher.Variable(); diff --git a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts index 8c8fd0ecd2..36bed40b36 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts @@ -26,9 +26,6 @@ import type { OperationTranspileResult } from "../operations"; export class CompositeConnectionPartial extends ConnectionReadOperation { public transpile(context: QueryASTContext): OperationTranspileResult { - if (!context.target) throw new Error(); - if (!this.relationship) throw new Error("connection fields are not supported on top level interface"); - // eslint-disable-next-line prefer-const let { selection: clause, nestedContext } = this.selection.apply(context); diff --git a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionReadOperation.ts index a63b705786..9f038f842e 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionReadOperation.ts @@ -36,7 +36,6 @@ export class CompositeConnectionReadOperation extends Operation { constructor(children: CompositeConnectionPartial[]) { super(); - this.children = children; } @@ -48,9 +47,12 @@ export class CompositeConnectionReadOperation extends Operation { const nestedSubqueries = this.children.flatMap((c) => { const subQueryContext = new QueryASTContext({ ...context, returnVariable: edgeVar }); const result = c.transpile(subQueryContext); - if (!hasTarget(context)) throw new Error("No parent node found!"); - const parentNode = context.target; - return result.clauses.map((sq) => Cypher.concat(new Cypher.With(parentNode), sq)); + if (hasTarget(context)) { + const parentNode = context.target; + return result.clauses.map((sq) => Cypher.concat(new Cypher.With(parentNode), sq)); + } else { + return result.clauses; + } }); const union = new Cypher.Union(...nestedSubqueries); diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index db8e034294..e1f67a85ea 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -103,7 +103,6 @@ export class OperationsFactory { varName?: string; reference?: any; }): Operation { - console.log("Create top level"); // Handles deprecated top level fulltext if (context.resolveTree.args.phrase) { if (!context.fulltext) { @@ -135,7 +134,6 @@ export class OperationsFactory { }); } case "CONNECTION": { - // assertIsConcreteEntity(entity); if (!entity) { throw new Error("Entity is required for top level connection read operations"); } diff --git a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts index dad1dfea46..6ad674e615 100644 --- a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts @@ -17,17 +17,20 @@ * limitations under the License. */ +import { mergeDeep } from "@graphql-tools/utils"; import { isObject, isString } from "graphql-compose"; import type { ResolveTree } from "graphql-parse-resolve-info"; import { cursorToOffset } from "graphql-relay"; import { Integer } from "neo4j-driver"; +import type { EntityAdapter } from "../../../../schema-model/entity/EntityAdapter"; import { InterfaceEntity } from "../../../../schema-model/entity/InterfaceEntity"; -import type { ConcreteEntityAdapter } from "../../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; -import type { InterfaceEntityAdapter } from "../../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; +import { ConcreteEntityAdapter } from "../../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +import { InterfaceEntityAdapter } from "../../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; import type { UnionEntityAdapter } from "../../../../schema-model/entity/model-adapters/UnionEntityAdapter"; import type { RelationshipAdapter } from "../../../../schema-model/relationship/model-adapters/RelationshipAdapter"; import type { ConnectionQueryArgs } from "../../../../types"; import type { Neo4jGraphQLTranslationContext } from "../../../../types/neo4j-graphql-translation-context"; +import { filterTruthy } from "../../../../utils/utils"; import { checkEntityAuthentication } from "../../../authorization/check-authentication"; import type { Field } from "../../ast/fields/Field"; import { ConnectionReadOperation } from "../../ast/operations/ConnectionReadOperation"; @@ -62,9 +65,6 @@ export class ConnectionFactory { resolveTree: ResolveTree; context: Neo4jGraphQLTranslationContext; }): CompositeConnectionReadOperation { - if (!relationship) { - throw new Error("Top-Level Connection are currently supported only for concrete entities"); - } const directed = Boolean(resolveTree.args.directed) ?? true; const resolveTreeWhere: Record = this.queryASTFactory.operationsFactory.getWhereArgs(resolveTree); @@ -77,11 +77,19 @@ export class ConnectionFactory { const concreteEntities = getConcreteEntities(target, nodeWhere); const concreteConnectionOperations = concreteEntities.map((concreteEntity: ConcreteEntityAdapter) => { - const selection = new RelationshipSelection({ - relationship, - directed, - targetOverride: concreteEntity, - }); + let selection: EntitySelection; + + if (relationship) { + selection = new RelationshipSelection({ + relationship, + directed, + targetOverride: concreteEntity, + }); + } else { + selection = new NodeSelection({ + target: concreteEntity, + }); + } const connectionPartial = new CompositeConnectionPartial({ relationship, @@ -103,12 +111,16 @@ export class ConnectionFactory { const compositeConnectionOp = new CompositeConnectionReadOperation(concreteConnectionOperations); // These sort fields will be duplicated on nested "CompositeConnectionPartial" - this.hydrateConnectionOperationsASTWithSort({ - entityOrRel: relationship, - resolveTree, - operation: compositeConnectionOp, - context, - }); + + // TODO: this if shouldn't be needed + if (relationship) { + this.hydrateConnectionOperationsASTWithSort({ + entityOrRel: relationship, + resolveTree, + operation: compositeConnectionOp, + context, + }); + } return compositeConnectionOp; } @@ -119,10 +131,18 @@ export class ConnectionFactory { context, }: { relationship?: RelationshipAdapter; - target: ConcreteEntityAdapter; + target: EntityAdapter; resolveTree: ResolveTree; context: Neo4jGraphQLTranslationContext; - }): ConnectionReadOperation { + }): ConnectionReadOperation | CompositeConnectionReadOperation { + if (!(target instanceof ConcreteEntityAdapter)) { + return this.createCompositeConnectionOperationAST({ + relationship, + target, + resolveTree, + context, + }); + } const directed = Boolean(resolveTree.args.directed) ?? true; const resolveTreeWhere: Record = this.queryASTFactory.operationsFactory.getWhereArgs(resolveTree); checkEntityAuthentication({ @@ -239,20 +259,49 @@ export class ConnectionFactory { }): T { // hydrate hydrateConnectionOperationAST is used for both top-level and nested connections. // If the relationship is defined use the RelationshipAdapter to infer the typeNames, if not use the target. + + // Get the abstract types of the interface + const entityInterfaces = filterTruthy( + target.compositeEntities.map((compositeEntity) => { + if (compositeEntity instanceof InterfaceEntity) { + return new InterfaceEntityAdapter(compositeEntity); + } + }) + ); + + const interfacesFields = entityInterfaces.map((interfaceAdapter) => { + return resolveTree.fieldsByTypeName[interfaceAdapter.operations.connectionFieldTypename] ?? {}; + }); + const entityOrRel = relationship ?? target; - const resolveTreeConnectionFields = { + + const concreteProjectionFields = { ...resolveTree.fieldsByTypeName[entityOrRel.operations.connectionFieldTypename], }; + const resolveTreeConnectionFields = mergeDeep[]>([ + ...interfacesFields, + concreteProjectionFields, + ]); + const edgeFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeConnectionFields, "edges"); - const resolveTreeEdgeFields = getFieldsByTypeName( + + const interfacesEdgeFields = entityInterfaces.map((interfaceAdapter) => { + return getFieldsByTypeName(edgeFieldsRaw, `${interfaceAdapter.name}Edge`); + }); + + const concreteEdgeFields = getFieldsByTypeName( edgeFieldsRaw, - entityOrRel.operations.relationshipFieldTypename + entityOrRel.operations.relationshipFieldTypename // Use interface operation ); + const resolveTreeEdgeFields = mergeDeep[]>([ + ...interfacesEdgeFields, + concreteEdgeFields, + ]); + const nodeFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeEdgeFields, "node"); const propertiesFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeEdgeFields, "properties"); - this.hydrateConnectionOperationsASTWithSort({ entityOrRel, resolveTree, @@ -260,13 +309,14 @@ export class ConnectionFactory { context, }); const isTopLevel = !relationship; - const resolveTreeNodeFieldsTypesNames = isTopLevel - ? [target.name] - : [ - target.name, - relationship.target.name, - ...target.compositeEntities.filter((e) => e instanceof InterfaceEntity).map((e) => e.name), - ]; + + const resolveTreeNodeFieldsTypesNames = [ + target.name, + ...target.compositeEntities.filter((e) => e instanceof InterfaceEntity).map((e) => e.name), + ]; + if (!isTopLevel) { + resolveTreeNodeFieldsTypesNames.push(relationship.target.name); + } const resolveTreeNodeFields = getFieldsByTypeName(nodeFieldsRaw, resolveTreeNodeFieldsTypesNames); const nodeFields = this.queryASTFactory.fieldFactory.createFields(target, resolveTreeNodeFields, context); From 1b57ee6a9ade31509eddc8bf621500b7e517ba24 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Mar 2024 11:38:30 +0000 Subject: [PATCH 04/10] Update schema with top level connections --- .../graphql/tests/schema/comments.test.ts | 12 ++ .../schema/connections/interfaces.test.ts | 24 +++ .../tests/schema/directive-preserve.test.ts | 36 +++++ .../schema/directives/customResolver.test.ts | 12 ++ .../tests/schema/directives/default.test.ts | 12 ++ .../schema/directives/filterable.test.ts | 36 +++++ .../tests/schema/directives/private.test.ts | 24 +++ .../directives/relationship-aggregate.test.ts | 24 +++ .../relationship-nested-operations.test.ts | 96 ++++++++++++ .../schema/directives/selectable.test.ts | 24 +++ .../tests/schema/directives/settable.test.ts | 48 ++++++ .../experimental-schema/comments.test.ts | 12 ++ .../declare-relationship.test.ts | 24 +++ .../directive-preserve.test.ts | 36 +++++ .../directives/customResolver.test.ts | 12 ++ .../directives/default.test.ts | 12 ++ .../directives/filterable.test.ts | 36 +++++ .../directives/private.test.ts | 24 +++ .../directives/relationship-aggregate.test.ts | 24 +++ .../relationship-nested-operations.test.ts | 96 ++++++++++++ .../directives/selectable.test.ts | 24 +++ .../directives/settable.test.ts | 48 ++++++ .../experimental-schema/inheritance.test.ts | 12 ++ .../interface-relationships.test.ts | 120 +++++++++++++++ .../experimental-schema/interfaces.test.ts | 24 +++ .../interfaces/aggregations.test.ts | 24 +++ .../interfaces/typename-in.test.ts | 12 ++ .../experimental-schema/issues/2377.test.ts | 12 ++ .../experimental-schema/issues/2993.test.ts | 24 +++ .../schema/experimental-schema/math.test.ts | 12 ++ .../nested-aggregation-on-interface.test.ts | 24 +++ .../schema/experimental-schema/plural.test.ts | 12 ++ .../experimental-schema/subscriptions.test.ts | 24 +++ ...ype-narrowing-declare-relationship.test.ts | 60 ++++++++ .../union-interface-relationship.test.ts | 12 ++ .../graphql/tests/schema/inheritance.test.ts | 12 ++ .../schema/interface-relationships.test.ts | 144 ++++++++++++++++++ .../graphql/tests/schema/interfaces.test.ts | 24 +++ .../graphql/tests/schema/issues/2377.test.ts | 12 ++ .../graphql/tests/schema/issues/2993.test.ts | 12 ++ .../graphql/tests/schema/issues/3439.test.ts | 60 ++++++++ .../graphql/tests/schema/issues/4511.test.ts | 24 +++ .../graphql/tests/schema/issues/4615.test.ts | 12 ++ packages/graphql/tests/schema/math.test.ts | 12 ++ .../tests/schema/subscriptions.test.ts | 24 +++ .../union-interface-relationship.test.ts | 12 ++ 46 files changed, 1416 insertions(+) diff --git a/packages/graphql/tests/schema/comments.test.ts b/packages/graphql/tests/schema/comments.test.ts index f0ba73a51b..26d10c54a7 100644 --- a/packages/graphql/tests/schema/comments.test.ts +++ b/packages/graphql/tests/schema/comments.test.ts @@ -1102,6 +1102,11 @@ describe("Comments", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1144,6 +1149,12 @@ describe("Comments", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1153,6 +1164,7 @@ describe("Comments", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/connections/interfaces.test.ts b/packages/graphql/tests/schema/connections/interfaces.test.ts index b0f7320d92..50db9b4720 100644 --- a/packages/graphql/tests/schema/connections/interfaces.test.ts +++ b/packages/graphql/tests/schema/connections/interfaces.test.ts @@ -117,6 +117,11 @@ describe("Connection with interfaces", () => { movies: CreatureMoviesDisconnectFieldInput } + type CreatureEdge { + cursor: String! + node: Creature! + } + enum CreatureImplementation { Person } @@ -216,6 +221,12 @@ describe("Connection with interfaces", () => { typename_IN: [CreatureImplementation!] } + type CreaturesConnection { + edges: [CreatureEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\" Information about the number of nodes and relationships deleted during a delete mutation \\"\\"\\" @@ -633,6 +644,11 @@ describe("Connection with interfaces", () => { director: [ProductionDirectorDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -694,9 +710,16 @@ describe("Connection with interfaces", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { creatures(options: CreatureOptions, where: CreatureWhere): [Creature!]! creaturesAggregate(where: CreatureWhere): CreatureAggregateSelection! + creaturesConnection(after: String, first: Int, sort: [CreatureSort], where: CreatureWhere): CreaturesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -705,6 +728,7 @@ describe("Connection with interfaces", () => { peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/directive-preserve.test.ts b/packages/graphql/tests/schema/directive-preserve.test.ts index bc19de908b..5959b7800d 100644 --- a/packages/graphql/tests/schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/directive-preserve.test.ts @@ -1668,6 +1668,11 @@ describe("Directive-preserve", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1740,6 +1745,12 @@ describe("Directive-preserve", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1749,6 +1760,7 @@ describe("Directive-preserve", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -2674,6 +2686,11 @@ describe("Directive-preserve", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -2716,6 +2733,12 @@ describe("Directive-preserve", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -2725,6 +2748,7 @@ describe("Directive-preserve", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3675,6 +3699,11 @@ describe("Directive-preserve", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3717,6 +3746,12 @@ describe("Directive-preserve", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3726,6 +3761,7 @@ describe("Directive-preserve", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/directives/customResolver.test.ts b/packages/graphql/tests/schema/directives/customResolver.test.ts index 8ad131d508..7643903764 100644 --- a/packages/graphql/tests/schema/directives/customResolver.test.ts +++ b/packages/graphql/tests/schema/directives/customResolver.test.ts @@ -99,6 +99,7 @@ describe("@customResolver directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -168,6 +169,11 @@ describe("@customResolver directive", () => { customResolver: StringAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -205,6 +211,12 @@ describe("@customResolver directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int diff --git a/packages/graphql/tests/schema/directives/default.test.ts b/packages/graphql/tests/schema/directives/default.test.ts index dc18c596ac..94b4c38c5f 100644 --- a/packages/graphql/tests/schema/directives/default.test.ts +++ b/packages/graphql/tests/schema/directives/default.test.ts @@ -130,6 +130,7 @@ describe("@default directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -215,6 +216,11 @@ describe("@default directive", () => { toBeOverridden: StringAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -263,6 +269,12 @@ describe("@default directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int diff --git a/packages/graphql/tests/schema/directives/filterable.test.ts b/packages/graphql/tests/schema/directives/filterable.test.ts index 2be6460607..e209265676 100644 --- a/packages/graphql/tests/schema/directives/filterable.test.ts +++ b/packages/graphql/tests/schema/directives/filterable.test.ts @@ -7290,6 +7290,12 @@ describe("@filterable directive", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { username: String! } @@ -7307,6 +7313,11 @@ describe("@filterable directive", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + interface PersonEventPayload { username: String! } @@ -7378,6 +7389,7 @@ describe("@filterable directive", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -8122,6 +8134,12 @@ describe("@filterable directive", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { username: String! } @@ -8139,6 +8157,11 @@ describe("@filterable directive", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + interface PersonEventPayload { username: String! } @@ -8210,6 +8233,7 @@ describe("@filterable directive", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -8954,6 +8978,12 @@ describe("@filterable directive", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { username: String! } @@ -8971,6 +9001,11 @@ describe("@filterable directive", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + interface PersonEventPayload { username: String! } @@ -9042,6 +9077,7 @@ describe("@filterable directive", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/directives/private.test.ts b/packages/graphql/tests/schema/directives/private.test.ts index c6bba12dd3..36cb23262b 100644 --- a/packages/graphql/tests/schema/directives/private.test.ts +++ b/packages/graphql/tests/schema/directives/private.test.ts @@ -90,6 +90,7 @@ describe("@private directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -146,6 +147,11 @@ describe("@private directive", () => { id: IDAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -183,6 +189,12 @@ describe("@private directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int @@ -294,6 +306,7 @@ describe("@private directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -358,6 +371,11 @@ describe("@private directive", () => { id: IDAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -395,6 +413,12 @@ describe("@private directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int diff --git a/packages/graphql/tests/schema/directives/relationship-aggregate.test.ts b/packages/graphql/tests/schema/directives/relationship-aggregate.test.ts index cd7d5d80bb..35136c6282 100644 --- a/packages/graphql/tests/schema/directives/relationship-aggregate.test.ts +++ b/packages/graphql/tests/schema/directives/relationship-aggregate.test.ts @@ -1417,6 +1417,12 @@ describe("@relationship directive, aggregate argument", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { password: String! username: String! @@ -1436,6 +1442,11 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { Actor } @@ -1498,6 +1509,7 @@ describe("@relationship directive, aggregate argument", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -1848,6 +1860,12 @@ describe("@relationship directive, aggregate argument", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { password: String! username: String! @@ -1867,6 +1885,11 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { Actor } @@ -1929,6 +1952,7 @@ describe("@relationship directive, aggregate argument", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/directives/relationship-nested-operations.test.ts b/packages/graphql/tests/schema/directives/relationship-nested-operations.test.ts index c29bfc1b57..7d118bb970 100644 --- a/packages/graphql/tests/schema/directives/relationship-nested-operations.test.ts +++ b/packages/graphql/tests/schema/directives/relationship-nested-operations.test.ts @@ -8835,6 +8835,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -8844,6 +8850,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -9017,6 +9028,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -9285,6 +9297,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -9299,6 +9317,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -9472,6 +9495,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -9740,6 +9764,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -9753,6 +9783,11 @@ describe("Relationship nested operations", () => { node: PersonWhere! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -9926,6 +9961,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -10185,6 +10221,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -10194,6 +10236,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -10371,6 +10418,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -10634,6 +10682,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -10643,6 +10697,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -10816,6 +10875,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -11079,6 +11139,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -11088,6 +11154,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -11261,6 +11332,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -11627,6 +11699,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -11645,6 +11723,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -11822,6 +11905,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -12168,6 +12252,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -12182,6 +12272,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -12355,6 +12450,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! diff --git a/packages/graphql/tests/schema/directives/selectable.test.ts b/packages/graphql/tests/schema/directives/selectable.test.ts index f1cb5dad36..c49f4f23cf 100644 --- a/packages/graphql/tests/schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/directives/selectable.test.ts @@ -3057,6 +3057,11 @@ describe("@selectable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3111,6 +3116,12 @@ describe("@selectable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3120,6 +3131,7 @@ describe("@selectable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3586,6 +3598,11 @@ describe("@selectable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3640,6 +3657,12 @@ describe("@selectable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3649,6 +3672,7 @@ describe("@selectable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/directives/settable.test.ts b/packages/graphql/tests/schema/directives/settable.test.ts index aacf70652d..74f23d3d95 100644 --- a/packages/graphql/tests/schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/directives/settable.test.ts @@ -5539,6 +5539,11 @@ describe("@settable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -5593,6 +5598,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -5602,6 +5613,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -6055,6 +6067,11 @@ describe("@settable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -6104,6 +6121,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -6113,6 +6136,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -6826,6 +6850,11 @@ describe("@settable", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -6904,6 +6933,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -6913,6 +6948,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -7794,6 +7830,11 @@ describe("@settable", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -7878,6 +7919,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -7887,6 +7934,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/comments.test.ts b/packages/graphql/tests/schema/experimental-schema/comments.test.ts index d25793a0a6..5cfd763ffa 100644 --- a/packages/graphql/tests/schema/experimental-schema/comments.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/comments.test.ts @@ -1102,6 +1102,11 @@ describe("Comments", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1144,6 +1149,12 @@ describe("Comments", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1153,6 +1164,7 @@ describe("Comments", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/declare-relationship.test.ts b/packages/graphql/tests/schema/experimental-schema/declare-relationship.test.ts index bac30df177..382ed9495d 100644 --- a/packages/graphql/tests/schema/experimental-schema/declare-relationship.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/declare-relationship.test.ts @@ -880,6 +880,11 @@ describe("Declare Relationship", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -922,6 +927,12 @@ describe("Declare Relationship", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -934,11 +945,13 @@ describe("Declare Relationship", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! shows(options: ShowOptions, where: ShowWhere): [Show!]! showsAggregate(where: ShowWhere): ShowAggregateSelection! + showsConnection(after: String, first: Int, sort: [ShowSort], where: ShowWhere): ShowsConnection! } type Series implements Production & Show { @@ -1469,6 +1482,11 @@ describe("Declare Relationship", () => { title: StringAggregateSelection! } + type ShowEdge { + cursor: String! + node: Show! + } + enum ShowImplementation { Movie Series @@ -1536,6 +1554,12 @@ describe("Declare Relationship", () => { typename_IN: [ShowImplementation!] } + type ShowsConnection { + edges: [ShowEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" enum SortDirection { \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts index 0f061abb8f..f9fc307b79 100644 --- a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts @@ -1668,6 +1668,11 @@ describe("Directive-preserve", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1740,6 +1745,12 @@ describe("Directive-preserve", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1749,6 +1760,7 @@ describe("Directive-preserve", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -2674,6 +2686,11 @@ describe("Directive-preserve", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -2716,6 +2733,12 @@ describe("Directive-preserve", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -2725,6 +2748,7 @@ describe("Directive-preserve", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3675,6 +3699,11 @@ describe("Directive-preserve", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3717,6 +3746,12 @@ describe("Directive-preserve", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3726,6 +3761,7 @@ describe("Directive-preserve", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/directives/customResolver.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/customResolver.test.ts index 90a6df424f..9f3b83c97b 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/customResolver.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/customResolver.test.ts @@ -99,6 +99,7 @@ describe("@customResolver directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -168,6 +169,11 @@ describe("@customResolver directive", () => { customResolver: StringAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -205,6 +211,12 @@ describe("@customResolver directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int diff --git a/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts index 237708cbc4..d55e5374a9 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts @@ -130,6 +130,7 @@ describe("@default directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -215,6 +216,11 @@ describe("@default directive", () => { toBeOverridden: StringAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -263,6 +269,12 @@ describe("@default directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int diff --git a/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts index 7d51385cf1..361860dce0 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts @@ -7290,6 +7290,12 @@ describe("@filterable directive", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { username: String! } @@ -7307,6 +7313,11 @@ describe("@filterable directive", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + interface PersonEventPayload { username: String! } @@ -7378,6 +7389,7 @@ describe("@filterable directive", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -8122,6 +8134,12 @@ describe("@filterable directive", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { username: String! } @@ -8139,6 +8157,11 @@ describe("@filterable directive", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + interface PersonEventPayload { username: String! } @@ -8210,6 +8233,7 @@ describe("@filterable directive", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -8954,6 +8978,12 @@ describe("@filterable directive", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { username: String! } @@ -8971,6 +9001,11 @@ describe("@filterable directive", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + interface PersonEventPayload { username: String! } @@ -9042,6 +9077,7 @@ describe("@filterable directive", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts index 2d7f6ceeb0..bf8461a72e 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts @@ -90,6 +90,7 @@ describe("@private directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -154,6 +155,11 @@ describe("@private directive", () => { id: IDAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -191,6 +197,12 @@ describe("@private directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int @@ -314,6 +326,7 @@ describe("@private directive", () => { type Query { userInterfaces(options: UserInterfaceOptions, where: UserInterfaceWhere): [UserInterface!]! userInterfacesAggregate(where: UserInterfaceWhere): UserInterfaceAggregateSelection! + userInterfacesConnection(after: String, first: Int, sort: [UserInterfaceSort], where: UserInterfaceWhere): UserInterfacesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -370,6 +383,11 @@ describe("@private directive", () => { id: IDAggregateSelection! } + type UserInterfaceEdge { + cursor: String! + node: UserInterface! + } + enum UserInterfaceImplementation { User } @@ -407,6 +425,12 @@ describe("@private directive", () => { typename_IN: [UserInterfaceImplementation!] } + type UserInterfacesConnection { + edges: [UserInterfaceEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input UserOptions { limit: Int offset: Int diff --git a/packages/graphql/tests/schema/experimental-schema/directives/relationship-aggregate.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/relationship-aggregate.test.ts index 841cd3c8bd..afd3b90cac 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/relationship-aggregate.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/relationship-aggregate.test.ts @@ -1417,6 +1417,12 @@ describe("@relationship directive, aggregate argument", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { password: String! username: String! @@ -1436,6 +1442,11 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { Actor } @@ -1498,6 +1509,7 @@ describe("@relationship directive, aggregate argument", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -1848,6 +1860,12 @@ describe("@relationship directive, aggregate argument", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { password: String! username: String! @@ -1867,6 +1885,11 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { Actor } @@ -1929,6 +1952,7 @@ describe("@relationship directive, aggregate argument", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/experimental-schema/directives/relationship-nested-operations.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/relationship-nested-operations.test.ts index bdb21ccd63..6d316237f2 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/relationship-nested-operations.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/relationship-nested-operations.test.ts @@ -8835,6 +8835,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -8844,6 +8850,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -9017,6 +9028,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -9285,6 +9297,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -9299,6 +9317,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -9472,6 +9495,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -9740,6 +9764,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -9753,6 +9783,11 @@ describe("Relationship nested operations", () => { node: PersonWhere! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -9926,6 +9961,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -10185,6 +10221,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -10194,6 +10236,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -10371,6 +10418,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -10634,6 +10682,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -10643,6 +10697,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -10816,6 +10875,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -11079,6 +11139,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -11088,6 +11154,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelection! } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -11261,6 +11332,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -11627,6 +11699,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -11645,6 +11723,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -11822,6 +11905,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! @@ -12168,6 +12252,12 @@ describe("Relationship nested operations", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String } @@ -12182,6 +12272,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { PersonOne PersonTwo @@ -12355,6 +12450,7 @@ describe("Relationship nested operations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! personOnes(options: PersonOneOptions, where: PersonOneWhere): [PersonOne!]! personOnesAggregate(where: PersonOneWhere): PersonOneAggregateSelection! personOnesConnection(after: String, first: Int, sort: [PersonOneSort], where: PersonOneWhere): PersonOnesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts index 1c825e0e7d..54b04908cb 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts @@ -3057,6 +3057,11 @@ describe("@selectable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3111,6 +3116,12 @@ describe("@selectable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3120,6 +3131,7 @@ describe("@selectable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3586,6 +3598,11 @@ describe("@selectable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3640,6 +3657,12 @@ describe("@selectable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3649,6 +3672,7 @@ describe("@selectable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts index 8acd4aa7d7..ab2095ae9e 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts @@ -5539,6 +5539,11 @@ describe("@settable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -5593,6 +5598,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -5602,6 +5613,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -6055,6 +6067,11 @@ describe("@settable", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -6104,6 +6121,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -6113,6 +6136,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -6826,6 +6850,11 @@ describe("@settable", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -6904,6 +6933,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -6913,6 +6948,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -7794,6 +7830,11 @@ describe("@settable", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -7878,6 +7919,12 @@ describe("@settable", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -7887,6 +7934,7 @@ describe("@settable", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts index e6cc370bba..10774b1c42 100644 --- a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts @@ -291,6 +291,12 @@ describe("inheritance", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person @customDirectiveInter { friends(options: PersonOptions, where: PersonWhere): [Person!]! @customDirectiveField friendsConnection(after: String, first: Int, sort: [PersonFriendsConnectionSort!], where: PersonFriendsConnectionWhere): PersonFriendsConnection! @@ -322,6 +328,11 @@ describe("inheritance", () => { friends: [PersonFriendsDisconnectFieldInput!] } + type PersonEdge { + cursor: String! + node: Person! + } + input PersonFriendsConnectFieldInput { connect: PersonConnectInput edge: PersonFriendsEdgeCreateInput @@ -484,6 +495,7 @@ describe("inheritance", () => { actorsConnection(after: String, first: Int, sort: [ActorSort], where: ActorWhere): ActorsConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts b/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts index 403cb27b26..a044afa437 100644 --- a/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts @@ -423,6 +423,11 @@ describe("Interface Relationships", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -465,6 +470,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -474,6 +485,7 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -1627,6 +1639,11 @@ describe("Interface Relationships", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1699,6 +1716,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1711,6 +1734,7 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3202,6 +3226,11 @@ describe("Interface Relationships", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3274,6 +3303,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3286,6 +3321,7 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3908,6 +3944,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + type Interface1Edge { + cursor: String! + node: Interface1! + } + enum Interface1Implementation { Type1Interface1 Type2Interface1 @@ -4021,6 +4062,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface1Implementation!] } + type Interface1sConnection { + edges: [Interface1Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Interface2 { field2: String } @@ -4039,6 +4086,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + type Interface2Edge { + cursor: String! + node: Interface2! + } + enum Interface2Implementation { Type1Interface2 Type2Interface2 @@ -4081,6 +4133,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface2Implementation!] } + type Interface2sConnection { + edges: [Interface2Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Mutation { createType1Interface1s(input: [Type1Interface1CreateInput!]!): CreateType1Interface1sMutationResponse! createType1Interface2s(input: [Type1Interface2CreateInput!]!): CreateType1Interface2sMutationResponse! @@ -4110,8 +4168,10 @@ describe("Interface Relationships", () => { type Query { interface1s(options: Interface1Options, where: Interface1Where): [Interface1!]! interface1sAggregate(where: Interface1Where): Interface1AggregateSelection! + interface1sConnection(after: String, first: Int, sort: [Interface1Sort], where: Interface1Where): Interface1sConnection! interface2s(options: Interface2Options, where: Interface2Where): [Interface2!]! interface2sAggregate(where: Interface2Where): Interface2AggregateSelection! + interface2sConnection(after: String, first: Int, sort: [Interface2Sort], where: Interface2Where): Interface2sConnection! type1Interface1s(options: Type1Interface1Options, where: Type1Interface1Where): [Type1Interface1!]! type1Interface1sAggregate(where: Type1Interface1Where): Type1Interface1AggregateSelection! type1Interface1sConnection(after: String, first: Int, sort: [Type1Interface1Sort], where: Type1Interface1Where): Type1Interface1sConnection! @@ -4887,6 +4947,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + type Interface1Edge { + cursor: String! + node: Interface1! + } + enum Interface1Implementation { Type1Interface1 Type2Interface1 @@ -5045,6 +5110,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface1Implementation!] } + type Interface1sConnection { + edges: [Interface1Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Interface2 { field2: String } @@ -5063,6 +5134,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + type Interface2Edge { + cursor: String! + node: Interface2! + } + enum Interface2Implementation { Type1Interface2 Type2Interface2 @@ -5105,6 +5181,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface2Implementation!] } + type Interface2sConnection { + edges: [Interface2Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Mutation { createType1Interface1s(input: [Type1Interface1CreateInput!]!): CreateType1Interface1sMutationResponse! createType1Interface2s(input: [Type1Interface2CreateInput!]!): CreateType1Interface2sMutationResponse! @@ -5171,8 +5253,10 @@ describe("Interface Relationships", () => { type Query { interface1s(options: Interface1Options, where: Interface1Where): [Interface1!]! interface1sAggregate(where: Interface1Where): Interface1AggregateSelection! + interface1sConnection(after: String, first: Int, sort: [Interface1Sort], where: Interface1Where): Interface1sConnection! interface2s(options: Interface2Options, where: Interface2Where): [Interface2!]! interface2sAggregate(where: Interface2Where): Interface2AggregateSelection! + interface2sConnection(after: String, first: Int, sort: [Interface2Sort], where: Interface2Where): Interface2sConnection! type1Interface1s(options: Type1Interface1Options, where: Type1Interface1Where): [Type1Interface1!]! type1Interface1sAggregate(where: Type1Interface1Where): Type1Interface1AggregateSelection! type1Interface1sConnection(after: String, first: Int, sort: [Type1Interface1Sort], where: Type1Interface1Where): Type1Interface1sConnection! @@ -5970,6 +6054,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + type Interface1Edge { + cursor: String! + node: Interface1! + } + enum Interface1Implementation { Type1Interface1 Type2Interface1 @@ -6144,6 +6233,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface1Implementation!] } + type Interface1sConnection { + edges: [Interface1Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Interface2 { field2: String } @@ -6162,6 +6257,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + type Interface2Edge { + cursor: String! + node: Interface2! + } + enum Interface2Implementation { Type1Interface2 Type2Interface2 @@ -6204,6 +6304,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface2Implementation!] } + type Interface2sConnection { + edges: [Interface2Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Mutation { createType1Interface1s(input: [Type1Interface1CreateInput!]!): CreateType1Interface1sMutationResponse! createType1Interface2s(input: [Type1Interface2CreateInput!]!): CreateType1Interface2sMutationResponse! @@ -6233,8 +6339,10 @@ describe("Interface Relationships", () => { type Query { interface1s(options: Interface1Options, where: Interface1Where): [Interface1!]! interface1sAggregate(where: Interface1Where): Interface1AggregateSelection! + interface1sConnection(after: String, first: Int, sort: [Interface1Sort], where: Interface1Where): Interface1sConnection! interface2s(options: Interface2Options, where: Interface2Where): [Interface2!]! interface2sAggregate(where: Interface2Where): Interface2AggregateSelection! + interface2sConnection(after: String, first: Int, sort: [Interface2Sort], where: Interface2Where): Interface2sConnection! type1Interface1s(options: Type1Interface1Options, where: Type1Interface1Where): [Type1Interface1!]! type1Interface1sAggregate(where: Type1Interface1Where): Type1Interface1AggregateSelection! type1Interface1sConnection(after: String, first: Int, sort: [Type1Interface1Sort], where: Type1Interface1Where): Type1Interface1sConnection! @@ -7495,6 +7603,11 @@ describe("Interface Relationships", () => { creator: ContentCreatorDisconnectFieldInput } + type ContentEdge { + cursor: String! + node: Content! + } + enum ContentImplementation { Comment Post @@ -7555,6 +7668,12 @@ describe("Interface Relationships", () => { typename_IN: [ContentImplementation!] } + type ContentsConnection { + edges: [ContentEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type CreateCommentsMutationResponse { comments: [Comment!]! info: CreateInfo! @@ -7985,6 +8104,7 @@ describe("Interface Relationships", () => { commentsConnection(after: String, first: Int, sort: [CommentSort], where: CommentWhere): CommentsConnection! contents(options: ContentOptions, where: ContentWhere): [Content!]! contentsAggregate(where: ContentWhere): ContentAggregateSelection! + contentsConnection(after: String, first: Int, sort: [ContentSort], where: ContentWhere): ContentsConnection! posts(options: PostOptions, where: PostWhere): [Post!]! postsAggregate(where: PostWhere): PostAggregateSelection! postsConnection(after: String, first: Int, sort: [PostSort], where: PostWhere): PostsConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts index 47d2180ccc..af0022082f 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts @@ -193,6 +193,11 @@ describe("Interfaces", () => { id: IDAggregateSelection! } + type MovieNodeEdge { + cursor: String! + node: MovieNode! + } + enum MovieNodeImplementation { Movie } @@ -311,6 +316,12 @@ describe("Interfaces", () => { typename_IN: [MovieNodeImplementation!] } + type MovieNodesConnection { + edges: [MovieNodeEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input MovieOptions { limit: Int offset: Int @@ -404,6 +415,7 @@ describe("Interfaces", () => { type Query { movieNodes(options: MovieNodeOptions, where: MovieNodeWhere): [MovieNode!]! movieNodesAggregate(where: MovieNodeWhere): MovieNodeAggregateSelection! + movieNodesConnection(after: String, first: Int, sort: [MovieNodeSort], where: MovieNodeWhere): MovieNodesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -608,6 +620,11 @@ describe("Interfaces", () => { id: IDAggregateSelection! } + type MovieNodeEdge { + cursor: String! + node: MovieNode! + } + enum MovieNodeImplementation { Movie } @@ -726,6 +743,12 @@ describe("Interfaces", () => { typename_IN: [MovieNodeImplementation!] } + type MovieNodesConnection { + edges: [MovieNodeEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input MovieOptions { limit: Int offset: Int @@ -819,6 +842,7 @@ describe("Interfaces", () => { type Query { movieNodes(options: MovieNodeOptions, where: MovieNodeWhere): [MovieNode!]! movieNodesAggregate(where: MovieNodeWhere): MovieNodeAggregateSelection! + movieNodesConnection(after: String, first: Int, sort: [MovieNodeSort], where: MovieNodeWhere): MovieNodesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts index 9a67009f39..f0d9592a38 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts @@ -199,6 +199,11 @@ describe("Interface Top Level Aggregations", () => { title: StringAggregateSelection! } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie } @@ -245,12 +250,19 @@ describe("Interface Top Level Aggregations", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" @@ -714,6 +726,11 @@ describe("Interface Top Level Aggregations", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -770,6 +787,12 @@ describe("Interface Top Level Aggregations", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -779,6 +802,7 @@ describe("Interface Top Level Aggregations", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces/typename-in.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces/typename-in.test.ts index 0dce5f4b32..1765c15a8f 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces/typename-in.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces/typename-in.test.ts @@ -400,6 +400,11 @@ describe("typename_IN", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -456,6 +461,12 @@ describe("typename_IN", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -465,6 +476,7 @@ describe("typename_IN", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts index 694726b30f..379109223a 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts @@ -143,6 +143,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { type Query { resourceEntities(options: ResourceEntityOptions, where: ResourceEntityWhere): [ResourceEntity!]! resourceEntitiesAggregate(where: ResourceEntityWhere): ResourceEntityAggregateSelection! + resourceEntitiesConnection(after: String, first: Int, sort: [ResourceEntitySort], where: ResourceEntityWhere): ResourceEntitiesConnection! resources(options: ResourceOptions, where: ResourceWhere): [Resource!]! resourcesAggregate(where: ResourceWhere): ResourceAggregateSelection! resourcesConnection(after: String, first: Int, sort: [ResourceSort], where: ResourceWhere): ResourcesConnection! @@ -373,6 +374,12 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { node: Resource! } + type ResourceEntitiesConnection { + edges: [ResourceEntityEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface ResourceEntity { id: ID! name: String @@ -389,6 +396,11 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { name: StringAggregateSelection! } + type ResourceEntityEdge { + cursor: String! + node: ResourceEntity! + } + enum ResourceEntityImplementation { Resource } diff --git a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts index e770ab000b..cf9ee31284 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts @@ -149,6 +149,11 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { User: UserCreateInput } + type ProfileEdge { + cursor: String! + node: Profile! + } + enum ProfileImplementation { User } @@ -202,9 +207,16 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { userName_STARTS_WITH: String } + type ProfilesConnection { + edges: [ProfileEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { profiles(options: ProfileOptions, where: ProfileWhere): [Profile!]! profilesAggregate(where: ProfileWhere): ProfileAggregateSelection! + profilesConnection(after: String, first: Int, sort: [ProfileSort], where: ProfileWhere): ProfilesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! @@ -555,6 +567,11 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { User: UserCreateInput } + type ProfileEdge { + cursor: String! + node: Profile! + } + enum ProfileImplementation { User } @@ -607,9 +624,16 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { userName_STARTS_WITH: String } + type ProfilesConnection { + edges: [ProfileEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { profiles(options: ProfileOptions, where: ProfileWhere): [Profile!]! profilesAggregate(where: ProfileWhere): ProfileAggregateSelection! + profilesConnection(after: String, first: Int, sort: [ProfileSort], where: ProfileWhere): ProfilesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/math.test.ts b/packages/graphql/tests/schema/experimental-schema/math.test.ts index 860f445663..7345fb1c6e 100644 --- a/packages/graphql/tests/schema/experimental-schema/math.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/math.test.ts @@ -1649,6 +1649,11 @@ describe("Algebraic", () => { Movie: MovieCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie } @@ -1690,6 +1695,12 @@ describe("Algebraic", () => { viewers_NOT_IN: [Int!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! @@ -1699,6 +1710,7 @@ describe("Algebraic", () => { peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/experimental-schema/nested-aggregation-on-interface.test.ts b/packages/graphql/tests/schema/experimental-schema/nested-aggregation-on-interface.test.ts index b85071ae15..41b486b3d0 100644 --- a/packages/graphql/tests/schema/experimental-schema/nested-aggregation-on-interface.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/nested-aggregation-on-interface.test.ts @@ -434,6 +434,11 @@ describe("nested aggregation on interface", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -490,6 +495,12 @@ describe("nested aggregation on interface", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -499,6 +510,7 @@ describe("nested aggregation on interface", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -1052,6 +1064,11 @@ describe("nested aggregation on interface", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1108,6 +1125,12 @@ describe("nested aggregation on interface", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1117,6 +1140,7 @@ describe("nested aggregation on interface", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/plural.test.ts b/packages/graphql/tests/schema/experimental-schema/plural.test.ts index 4b6d391a15..f5900b1caa 100644 --- a/packages/graphql/tests/schema/experimental-schema/plural.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/plural.test.ts @@ -58,6 +58,11 @@ describe("Plural option", () => { name: StringAggregateSelection! } + type AnimalEdge { + cursor: String! + node: Animal! + } + enum AnimalImplementation { Dog } @@ -95,6 +100,12 @@ describe("Plural option", () => { typename_IN: [AnimalImplementation!] } + type AnimalesConnection { + edges: [AnimalEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Cat { queenOf: String } @@ -285,6 +296,7 @@ describe("Plural option", () => { type Query { animales(options: AnimalOptions, where: AnimalWhere): [Animal!]! animalesAggregate(where: AnimalWhere): AnimalAggregateSelection! + animalesConnection(after: String, first: Int, sort: [AnimalSort], where: AnimalWhere): AnimalesConnection! cats(options: CatOptions, where: CatWhere): [Cat!]! catsAggregate(where: CatWhere): CatAggregateSelection! catsConnection(after: String, first: Int, sort: [CatSort], where: CatWhere): CatsConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts index 34ace4cda9..94479471ed 100644 --- a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts @@ -5767,6 +5767,11 @@ describe("Subscriptions", () => { movies: CreatureMoviesDisconnectFieldInput } + type CreatureEdge { + cursor: String! + node: Creature! + } + enum CreatureImplementation { Person } @@ -5844,6 +5849,12 @@ describe("Subscriptions", () => { typename_IN: [CreatureImplementation!] } + type CreaturesConnection { + edges: [CreatureEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\" Information about the number of nodes and relationships deleted during a delete mutation \\"\\"\\" @@ -6276,6 +6287,11 @@ describe("Subscriptions", () => { director: ProductionDirectorDisconnectFieldInput } + type ProductionEdge { + cursor: String! + node: Production! + } + interface ProductionEventPayload { id: ID } @@ -6342,9 +6358,16 @@ describe("Subscriptions", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { creatures(options: CreatureOptions, where: CreatureWhere): [Creature!]! creaturesAggregate(where: CreatureWhere): CreatureAggregateSelection! + creaturesConnection(after: String, first: Int, where: CreatureWhere): CreaturesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -6353,6 +6376,7 @@ describe("Subscriptions", () => { peopleConnection(after: String, first: Int, where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/type-narrowing-declare-relationship.test.ts b/packages/graphql/tests/schema/experimental-schema/type-narrowing-declare-relationship.test.ts index 9c418ba9f9..3b3d088682 100644 --- a/packages/graphql/tests/schema/experimental-schema/type-narrowing-declare-relationship.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/type-narrowing-declare-relationship.test.ts @@ -961,6 +961,12 @@ describe("Declare Relationship", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { name: String! } @@ -979,6 +985,11 @@ describe("Declare Relationship", () => { UntrainedPerson: UntrainedPersonCreateInput } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { Actor UntrainedPerson @@ -1150,6 +1161,11 @@ describe("Declare Relationship", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { AmatureProduction Movie @@ -1211,6 +1227,12 @@ describe("Declare Relationship", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1223,8 +1245,10 @@ describe("Declare Relationship", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! untrainedPeople(options: UntrainedPersonOptions, where: UntrainedPersonWhere): [UntrainedPerson!]! untrainedPeopleAggregate(where: UntrainedPersonWhere): UntrainedPersonAggregateSelection! untrainedPeopleConnection(after: String, first: Int, sort: [UntrainedPersonSort], where: UntrainedPersonWhere): UntrainedPeopleConnection! @@ -2511,6 +2535,12 @@ describe("Declare Relationship", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person { actedIn(options: ProductionOptions, where: ProductionWhere): [Production!]! actedInConnection(after: String, first: Int, sort: [PersonActedInConnectionSort!], where: PersonActedInConnectionWhere): PersonActedInConnection! @@ -2595,6 +2625,11 @@ describe("Declare Relationship", () => { actedIn: [PersonActedInDisconnectFieldInput!] } + type PersonEdge { + cursor: String! + node: Person! + } + enum PersonImplementation { Actor UntrainedPerson @@ -2727,6 +2762,11 @@ describe("Declare Relationship", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { AmatureProduction Movie @@ -2783,6 +2823,12 @@ describe("Declare Relationship", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -2795,8 +2841,10 @@ describe("Declare Relationship", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! untrainedPeople(options: UntrainedPersonOptions, where: UntrainedPersonWhere): [UntrainedPerson!]! untrainedPeopleAggregate(where: UntrainedPersonWhere): UntrainedPersonAggregateSelection! untrainedPeopleConnection(after: String, first: Int, sort: [UntrainedPersonSort], where: UntrainedPersonWhere): UntrainedPeopleConnection! @@ -4168,6 +4216,11 @@ describe("Declare Relationship", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -4240,6 +4293,12 @@ describe("Declare Relationship", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -4252,6 +4311,7 @@ describe("Declare Relationship", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/experimental-schema/union-interface-relationship.test.ts b/packages/graphql/tests/schema/experimental-schema/union-interface-relationship.test.ts index 6283c890f9..e4a0fa05b1 100644 --- a/packages/graphql/tests/schema/experimental-schema/union-interface-relationship.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/union-interface-relationship.test.ts @@ -1690,6 +1690,7 @@ describe("Union Interface Relationships", () => { peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! reviewers(options: ReviewerOptions, where: ReviewerWhere): [Reviewer!]! reviewersAggregate(where: ReviewerWhere): ReviewerAggregateSelection! + reviewersConnection(after: String, first: Int, sort: [ReviewerSort], where: ReviewerWhere): ReviewersConnection! } \\"\\"\\"Input type for options that can be specified on a query operation.\\"\\"\\" @@ -1786,6 +1787,11 @@ describe("Union Interface Relationships", () => { Person: PersonCreateInput } + type ReviewerEdge { + cursor: String! + node: Reviewer! + } + enum ReviewerImplementation { Influencer Person @@ -1840,6 +1846,12 @@ describe("Union Interface Relationships", () => { typename_IN: [ReviewerImplementation!] } + type ReviewersConnection { + edges: [ReviewerEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" enum SortDirection { \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/inheritance.test.ts b/packages/graphql/tests/schema/inheritance.test.ts index 5a285d010a..cc9222a535 100644 --- a/packages/graphql/tests/schema/inheritance.test.ts +++ b/packages/graphql/tests/schema/inheritance.test.ts @@ -291,6 +291,12 @@ describe("inheritance", () => { startCursor: String } + type PeopleConnection { + edges: [PersonEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Person @customDirectiveInter { friends(options: PersonOptions, where: PersonWhere): [Person!]! @customDirectiveField friendsConnection(after: String, first: Int, sort: [PersonFriendsConnectionSort!], where: PersonFriendsConnectionWhere): PersonFriendsConnection! @@ -322,6 +328,11 @@ describe("inheritance", () => { friends: [PersonFriendsDisconnectFieldInput!] } + type PersonEdge { + cursor: String! + node: Person! + } + input PersonFriendsConnectFieldInput { connect: PersonConnectInput edge: PersonFriendsEdgeCreateInput @@ -484,6 +495,7 @@ describe("inheritance", () => { actorsConnection(after: String, first: Int, sort: [ActorSort], where: ActorWhere): ActorsConnection! people(options: PersonOptions, where: PersonWhere): [Person!]! peopleAggregate(where: PersonWhere): PersonAggregateSelection! + peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/interface-relationships.test.ts b/packages/graphql/tests/schema/interface-relationships.test.ts index 12af8e5ce6..10f1efa75d 100644 --- a/packages/graphql/tests/schema/interface-relationships.test.ts +++ b/packages/graphql/tests/schema/interface-relationships.test.ts @@ -423,6 +423,11 @@ describe("Interface Relationships", () => { Series: SeriesCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -465,6 +470,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -474,6 +485,7 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -1627,6 +1639,11 @@ describe("Interface Relationships", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -1699,6 +1716,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -1711,6 +1734,7 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3202,6 +3226,11 @@ describe("Interface Relationships", () => { actors: [ProductionActorsDisconnectFieldInput!] } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -3274,6 +3303,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -3286,6 +3321,7 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -3908,6 +3944,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + type Interface1Edge { + cursor: String! + node: Interface1! + } + enum Interface1Implementation { Type1Interface1 Type2Interface1 @@ -4021,6 +4062,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface1Implementation!] } + type Interface1sConnection { + edges: [Interface1Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Interface2 { field2: String } @@ -4039,6 +4086,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + type Interface2Edge { + cursor: String! + node: Interface2! + } + enum Interface2Implementation { Type1Interface2 Type2Interface2 @@ -4081,6 +4133,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface2Implementation!] } + type Interface2sConnection { + edges: [Interface2Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Mutation { createType1Interface1s(input: [Type1Interface1CreateInput!]!): CreateType1Interface1sMutationResponse! createType1Interface2s(input: [Type1Interface2CreateInput!]!): CreateType1Interface2sMutationResponse! @@ -4110,8 +4168,10 @@ describe("Interface Relationships", () => { type Query { interface1s(options: Interface1Options, where: Interface1Where): [Interface1!]! interface1sAggregate(where: Interface1Where): Interface1AggregateSelection! + interface1sConnection(after: String, first: Int, sort: [Interface1Sort], where: Interface1Where): Interface1sConnection! interface2s(options: Interface2Options, where: Interface2Where): [Interface2!]! interface2sAggregate(where: Interface2Where): Interface2AggregateSelection! + interface2sConnection(after: String, first: Int, sort: [Interface2Sort], where: Interface2Where): Interface2sConnection! type1Interface1s(options: Type1Interface1Options, where: Type1Interface1Where): [Type1Interface1!]! type1Interface1sAggregate(where: Type1Interface1Where): Type1Interface1AggregateSelection! type1Interface1sConnection(after: String, first: Int, sort: [Type1Interface1Sort], where: Type1Interface1Where): Type1Interface1sConnection! @@ -4887,6 +4947,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + type Interface1Edge { + cursor: String! + node: Interface1! + } + enum Interface1Implementation { Type1Interface1 Type2Interface1 @@ -5045,6 +5110,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface1Implementation!] } + type Interface1sConnection { + edges: [Interface1Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Interface2 { field2: String } @@ -5063,6 +5134,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + type Interface2Edge { + cursor: String! + node: Interface2! + } + enum Interface2Implementation { Type1Interface2 Type2Interface2 @@ -5105,6 +5181,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface2Implementation!] } + type Interface2sConnection { + edges: [Interface2Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Mutation { createType1Interface1s(input: [Type1Interface1CreateInput!]!): CreateType1Interface1sMutationResponse! createType1Interface2s(input: [Type1Interface2CreateInput!]!): CreateType1Interface2sMutationResponse! @@ -5171,8 +5253,10 @@ describe("Interface Relationships", () => { type Query { interface1s(options: Interface1Options, where: Interface1Where): [Interface1!]! interface1sAggregate(where: Interface1Where): Interface1AggregateSelection! + interface1sConnection(after: String, first: Int, sort: [Interface1Sort], where: Interface1Where): Interface1sConnection! interface2s(options: Interface2Options, where: Interface2Where): [Interface2!]! interface2sAggregate(where: Interface2Where): Interface2AggregateSelection! + interface2sConnection(after: String, first: Int, sort: [Interface2Sort], where: Interface2Where): Interface2sConnection! type1Interface1s(options: Type1Interface1Options, where: Type1Interface1Where): [Type1Interface1!]! type1Interface1sAggregate(where: Type1Interface1Where): Type1Interface1AggregateSelection! type1Interface1sConnection(after: String, first: Int, sort: [Type1Interface1Sort], where: Type1Interface1Where): Type1Interface1sConnection! @@ -5970,6 +6054,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + type Interface1Edge { + cursor: String! + node: Interface1! + } + enum Interface1Implementation { Type1Interface1 Type2Interface1 @@ -6144,6 +6233,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface1Implementation!] } + type Interface1sConnection { + edges: [Interface1Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface Interface2 { field2: String } @@ -6162,6 +6257,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + type Interface2Edge { + cursor: String! + node: Interface2! + } + enum Interface2Implementation { Type1Interface2 Type2Interface2 @@ -6204,6 +6304,12 @@ describe("Interface Relationships", () => { typename_IN: [Interface2Implementation!] } + type Interface2sConnection { + edges: [Interface2Edge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Mutation { createType1Interface1s(input: [Type1Interface1CreateInput!]!): CreateType1Interface1sMutationResponse! createType1Interface2s(input: [Type1Interface2CreateInput!]!): CreateType1Interface2sMutationResponse! @@ -6233,8 +6339,10 @@ describe("Interface Relationships", () => { type Query { interface1s(options: Interface1Options, where: Interface1Where): [Interface1!]! interface1sAggregate(where: Interface1Where): Interface1AggregateSelection! + interface1sConnection(after: String, first: Int, sort: [Interface1Sort], where: Interface1Where): Interface1sConnection! interface2s(options: Interface2Options, where: Interface2Where): [Interface2!]! interface2sAggregate(where: Interface2Where): Interface2AggregateSelection! + interface2sConnection(after: String, first: Int, sort: [Interface2Sort], where: Interface2Where): Interface2sConnection! type1Interface1s(options: Type1Interface1Options, where: Type1Interface1Where): [Type1Interface1!]! type1Interface1sAggregate(where: Type1Interface1Where): Type1Interface1AggregateSelection! type1Interface1sConnection(after: String, first: Int, sort: [Type1Interface1Sort], where: Type1Interface1Where): Type1Interface1sConnection! @@ -7495,6 +7603,11 @@ describe("Interface Relationships", () => { creator: ContentCreatorDisconnectFieldInput } + type ContentEdge { + cursor: String! + node: Content! + } + enum ContentImplementation { Comment Post @@ -7555,6 +7668,12 @@ describe("Interface Relationships", () => { typename_IN: [ContentImplementation!] } + type ContentsConnection { + edges: [ContentEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type CreateCommentsMutationResponse { comments: [Comment!]! info: CreateInfo! @@ -7985,6 +8104,7 @@ describe("Interface Relationships", () => { commentsConnection(after: String, first: Int, sort: [CommentSort], where: CommentWhere): CommentsConnection! contents(options: ContentOptions, where: ContentWhere): [Content!]! contentsAggregate(where: ContentWhere): ContentAggregateSelection! + contentsConnection(after: String, first: Int, sort: [ContentSort], where: ContentWhere): ContentsConnection! posts(options: PostOptions, where: PostWhere): [Post!]! postsAggregate(where: PostWhere): PostAggregateSelection! postsConnection(after: String, first: Int, sort: [PostSort], where: PostWhere): PostsConnection! @@ -8818,6 +8938,11 @@ describe("Interface Relationships", () => { title: StringAggregateSelection! } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie Series @@ -8856,6 +8981,12 @@ describe("Interface Relationships", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { actors(options: ActorOptions, where: ActorWhere): [Actor!]! actorsAggregate(where: ActorWhere): ActorAggregateSelection! @@ -8865,11 +8996,13 @@ describe("Interface Relationships", () => { moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! shows(options: ShowOptions, where: ShowWhere): [Show!]! showsAggregate(where: ShowWhere): ShowAggregateSelection! + showsConnection(after: String, first: Int, sort: [ShowSort], where: ShowWhere): ShowsConnection! } type Series implements Production & Show { @@ -9318,6 +9451,11 @@ describe("Interface Relationships", () => { actors: [ShowActorsDisconnectFieldInput!] } + type ShowEdge { + cursor: String! + node: Show! + } + enum ShowImplementation { Movie Series @@ -9390,6 +9528,12 @@ describe("Interface Relationships", () => { typename_IN: [ShowImplementation!] } + type ShowsConnection { + edges: [ShowEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" enum SortDirection { \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/interfaces.test.ts b/packages/graphql/tests/schema/interfaces.test.ts index 7d984c0b6a..0a7db89cf8 100644 --- a/packages/graphql/tests/schema/interfaces.test.ts +++ b/packages/graphql/tests/schema/interfaces.test.ts @@ -193,6 +193,11 @@ describe("Interfaces", () => { id: IDAggregateSelection! } + type MovieNodeEdge { + cursor: String! + node: MovieNode! + } + enum MovieNodeImplementation { Movie } @@ -311,6 +316,12 @@ describe("Interfaces", () => { typename_IN: [MovieNodeImplementation!] } + type MovieNodesConnection { + edges: [MovieNodeEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input MovieOptions { limit: Int offset: Int @@ -404,6 +415,7 @@ describe("Interfaces", () => { type Query { movieNodes(options: MovieNodeOptions, where: MovieNodeWhere): [MovieNode!]! movieNodesAggregate(where: MovieNodeWhere): MovieNodeAggregateSelection! + movieNodesConnection(after: String, first: Int, sort: [MovieNodeSort], where: MovieNodeWhere): MovieNodesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -608,6 +620,11 @@ describe("Interfaces", () => { id: IDAggregateSelection! } + type MovieNodeEdge { + cursor: String! + node: MovieNode! + } + enum MovieNodeImplementation { Movie } @@ -726,6 +743,12 @@ describe("Interfaces", () => { typename_IN: [MovieNodeImplementation!] } + type MovieNodesConnection { + edges: [MovieNodeEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + input MovieOptions { limit: Int offset: Int @@ -819,6 +842,7 @@ describe("Interfaces", () => { type Query { movieNodes(options: MovieNodeOptions, where: MovieNodeWhere): [MovieNode!]! movieNodesAggregate(where: MovieNodeWhere): MovieNodeAggregateSelection! + movieNodesConnection(after: String, first: Int, sort: [MovieNodeSort], where: MovieNodeWhere): MovieNodesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! diff --git a/packages/graphql/tests/schema/issues/2377.test.ts b/packages/graphql/tests/schema/issues/2377.test.ts index 5649669973..cd4e858c1c 100644 --- a/packages/graphql/tests/schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/issues/2377.test.ts @@ -143,6 +143,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { type Query { resourceEntities(options: ResourceEntityOptions, where: ResourceEntityWhere): [ResourceEntity!]! resourceEntitiesAggregate(where: ResourceEntityWhere): ResourceEntityAggregateSelection! + resourceEntitiesConnection(after: String, first: Int, sort: [ResourceEntitySort], where: ResourceEntityWhere): ResourceEntitiesConnection! resources(options: ResourceOptions, where: ResourceWhere): [Resource!]! resourcesAggregate(where: ResourceWhere): ResourceAggregateSelection! resourcesConnection(after: String, first: Int, sort: [ResourceSort], where: ResourceWhere): ResourcesConnection! @@ -373,6 +374,12 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { node: Resource! } + type ResourceEntitiesConnection { + edges: [ResourceEntityEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface ResourceEntity { id: ID! name: String @@ -389,6 +396,11 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { name: StringAggregateSelection! } + type ResourceEntityEdge { + cursor: String! + node: ResourceEntity! + } + enum ResourceEntityImplementation { Resource } diff --git a/packages/graphql/tests/schema/issues/2993.test.ts b/packages/graphql/tests/schema/issues/2993.test.ts index e2e911b574..7dd0d7f715 100644 --- a/packages/graphql/tests/schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/issues/2993.test.ts @@ -149,6 +149,11 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { User: UserCreateInput } + type ProfileEdge { + cursor: String! + node: Profile! + } + enum ProfileImplementation { User } @@ -202,9 +207,16 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { userName_STARTS_WITH: String } + type ProfilesConnection { + edges: [ProfileEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { profiles(options: ProfileOptions, where: ProfileWhere): [Profile!]! profilesAggregate(where: ProfileWhere): ProfileAggregateSelection! + profilesConnection(after: String, first: Int, sort: [ProfileSort], where: ProfileWhere): ProfilesConnection! users(options: UserOptions, where: UserWhere): [User!]! usersAggregate(where: UserWhere): UserAggregateSelection! usersConnection(after: String, first: Int, sort: [UserSort], where: UserWhere): UsersConnection! diff --git a/packages/graphql/tests/schema/issues/3439.test.ts b/packages/graphql/tests/schema/issues/3439.test.ts index e5bcffb22f..09e394e8d2 100644 --- a/packages/graphql/tests/schema/issues/3439.test.ts +++ b/packages/graphql/tests/schema/issues/3439.test.ts @@ -393,6 +393,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { id: StringAggregateSelection! } + type INodeEdge { + cursor: String! + node: INode! + } + enum INodeImplementation { Movie Series @@ -431,6 +436,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { typename_IN: [INodeImplementation!] } + type INodesConnection { + edges: [INodeEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + interface IProduct { genre: Genre! id: String! @@ -452,6 +463,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { Series: SeriesCreateInput } + type IProductEdge { + cursor: String! + node: IProduct! + } + interface IProductEventPayload { id: String! name: String! @@ -538,6 +554,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { typename_IN: [IProductImplementation!] } + type IProductsConnection { + edges: [IProductEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Movie implements INode & IProduct { genre(directed: Boolean = true, options: GenreOptions, where: GenreWhere): Genre! genreAggregate(directed: Boolean = true, where: GenreWhere): MovieGenreGenreAggregationSelection @@ -904,8 +926,10 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! iNodes(options: INodeOptions, where: INodeWhere): [INode!]! iNodesAggregate(where: INodeWhere): INodeAggregateSelection! + iNodesConnection(after: String, first: Int, sort: [INodeSort], where: INodeWhere): INodesConnection! iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! iProductsAggregate(where: IProductWhere): IProductAggregateSelection! + iProductsConnection(after: String, first: Int, sort: [IProductSort], where: IProductWhere): IProductsConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -1689,6 +1713,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { Series: SeriesCreateInput } + type IProductEdge { + cursor: String! + node: IProduct! + } + interface IProductEventPayload { id: String! name: String! @@ -1775,6 +1804,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { typename_IN: [IProductImplementation!] } + type IProductsConnection { + edges: [IProductEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Movie implements IProduct { genre(directed: Boolean = true, options: GenreOptions, where: GenreWhere): Genre! genreAggregate(directed: Boolean = true, where: GenreWhere): MovieGenreGenreAggregationSelection @@ -2141,6 +2176,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! iProductsAggregate(where: IProductWhere): IProductAggregateSelection! + iProductsConnection(after: String, first: Int, sort: [IProductSort], where: IProductWhere): IProductsConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -2948,6 +2984,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genre: IProductGenreDisconnectFieldInput } + type IProductEdge { + cursor: String! + node: IProduct! + } + interface IProductEventPayload { id: String! name: String! @@ -3238,6 +3279,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { typename_IN: [IProductImplementation!] } + type IProductsConnection { + edges: [IProductEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type IntAggregateSelection { average: Float max: Int @@ -3671,6 +3718,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! iProductsAggregate(where: IProductWhere): IProductAggregateSelection! + iProductsConnection(after: String, first: Int, sort: [IProductSort], where: IProductWhere): IProductsConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -4550,6 +4598,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genre: IProductGenreDisconnectInput } + type IProductEdge { + cursor: String! + node: IProduct! + } + interface IProductEventPayload { id: String! name: String! @@ -4848,6 +4901,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { typename_IN: [IProductImplementation!] } + type IProductsConnection { + edges: [IProductEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type IntAggregateSelection { average: Float max: Int @@ -5266,6 +5325,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! iProductsAggregate(where: IProductWhere): IProductAggregateSelection! + iProductsConnection(after: String, first: Int, sort: [IProductSort], where: IProductWhere): IProductsConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! diff --git a/packages/graphql/tests/schema/issues/4511.test.ts b/packages/graphql/tests/schema/issues/4511.test.ts index d811eed385..983ce4f136 100644 --- a/packages/graphql/tests/schema/issues/4511.test.ts +++ b/packages/graphql/tests/schema/issues/4511.test.ts @@ -116,6 +116,11 @@ describe("https://github.com/neo4j/graphql/issues/4511", () => { movies: CreatureMoviesDisconnectFieldInput } + type CreatureEdge { + cursor: String! + node: Creature! + } + enum CreatureImplementation { Person } @@ -193,6 +198,12 @@ describe("https://github.com/neo4j/graphql/issues/4511", () => { typename_IN: [CreatureImplementation!] } + type CreaturesConnection { + edges: [CreatureEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\" Information about the number of nodes and relationships deleted during a delete mutation \\"\\"\\" @@ -625,6 +636,11 @@ describe("https://github.com/neo4j/graphql/issues/4511", () => { director: ProductionDirectorDisconnectFieldInput } + type ProductionEdge { + cursor: String! + node: Production! + } + interface ProductionEventPayload { id: ID } @@ -691,9 +707,16 @@ describe("https://github.com/neo4j/graphql/issues/4511", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { creatures(options: CreatureOptions, where: CreatureWhere): [Creature!]! creaturesAggregate(where: CreatureWhere): CreatureAggregateSelection! + creaturesConnection(after: String, first: Int, where: CreatureWhere): CreaturesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -702,6 +725,7 @@ describe("https://github.com/neo4j/graphql/issues/4511", () => { peopleConnection(after: String, first: Int, where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/issues/4615.test.ts b/packages/graphql/tests/schema/issues/4615.test.ts index 2f1d0bdb90..b11d86e2a3 100644 --- a/packages/graphql/tests/schema/issues/4615.test.ts +++ b/packages/graphql/tests/schema/issues/4615.test.ts @@ -636,6 +636,7 @@ describe("https://github.com/neo4j/graphql/issues/4615", () => { seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! shows(options: ShowOptions, where: ShowWhere): [Show!]! showsAggregate(where: ShowWhere): ShowAggregateSelection! + showsConnection(after: String, first: Int, sort: [ShowSort], where: ShowWhere): ShowsConnection! } type Series implements Show { @@ -1064,6 +1065,11 @@ describe("https://github.com/neo4j/graphql/issues/4615", () => { actors: [ShowActorsDisconnectFieldInput!] } + type ShowEdge { + cursor: String! + node: Show! + } + enum ShowImplementation { Movie Series @@ -1136,6 +1142,12 @@ describe("https://github.com/neo4j/graphql/issues/4615", () => { typename_IN: [ShowImplementation!] } + type ShowsConnection { + edges: [ShowEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" enum SortDirection { \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/math.test.ts b/packages/graphql/tests/schema/math.test.ts index 5e19c4417a..02879a7912 100644 --- a/packages/graphql/tests/schema/math.test.ts +++ b/packages/graphql/tests/schema/math.test.ts @@ -1649,6 +1649,11 @@ describe("Algebraic", () => { Movie: MovieCreateInput } + type ProductionEdge { + cursor: String! + node: Production! + } + enum ProductionImplementation { Movie } @@ -1690,6 +1695,12 @@ describe("Algebraic", () => { viewers_NOT_IN: [Int!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! @@ -1699,6 +1710,7 @@ describe("Algebraic", () => { peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/subscriptions.test.ts b/packages/graphql/tests/schema/subscriptions.test.ts index 31ac387f53..79a95ad8c0 100644 --- a/packages/graphql/tests/schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/subscriptions.test.ts @@ -5767,6 +5767,11 @@ describe("Subscriptions", () => { movies: CreatureMoviesDisconnectFieldInput } + type CreatureEdge { + cursor: String! + node: Creature! + } + enum CreatureImplementation { Person } @@ -5844,6 +5849,12 @@ describe("Subscriptions", () => { typename_IN: [CreatureImplementation!] } + type CreaturesConnection { + edges: [CreatureEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\" Information about the number of nodes and relationships deleted during a delete mutation \\"\\"\\" @@ -6276,6 +6287,11 @@ describe("Subscriptions", () => { director: ProductionDirectorDisconnectFieldInput } + type ProductionEdge { + cursor: String! + node: Production! + } + interface ProductionEventPayload { id: ID } @@ -6342,9 +6358,16 @@ describe("Subscriptions", () => { typename_IN: [ProductionImplementation!] } + type ProductionsConnection { + edges: [ProductionEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + type Query { creatures(options: CreatureOptions, where: CreatureWhere): [Creature!]! creaturesAggregate(where: CreatureWhere): CreatureAggregateSelection! + creaturesConnection(after: String, first: Int, where: CreatureWhere): CreaturesConnection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -6353,6 +6376,7 @@ describe("Subscriptions", () => { peopleConnection(after: String, first: Int, where: PersonWhere): PeopleConnection! productions(options: ProductionOptions, where: ProductionWhere): [Production!]! productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! + productionsConnection(after: String, first: Int, sort: [ProductionSort], where: ProductionWhere): ProductionsConnection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! diff --git a/packages/graphql/tests/schema/union-interface-relationship.test.ts b/packages/graphql/tests/schema/union-interface-relationship.test.ts index 144055ceff..564e0d528c 100644 --- a/packages/graphql/tests/schema/union-interface-relationship.test.ts +++ b/packages/graphql/tests/schema/union-interface-relationship.test.ts @@ -1690,6 +1690,7 @@ describe("Union Interface Relationships", () => { peopleConnection(after: String, first: Int, sort: [PersonSort], where: PersonWhere): PeopleConnection! reviewers(options: ReviewerOptions, where: ReviewerWhere): [Reviewer!]! reviewersAggregate(where: ReviewerWhere): ReviewerAggregateSelection! + reviewersConnection(after: String, first: Int, sort: [ReviewerSort], where: ReviewerWhere): ReviewersConnection! } \\"\\"\\"Input type for options that can be specified on a query operation.\\"\\"\\" @@ -1786,6 +1787,11 @@ describe("Union Interface Relationships", () => { Person: PersonCreateInput } + type ReviewerEdge { + cursor: String! + node: Reviewer! + } + enum ReviewerImplementation { Influencer Person @@ -1840,6 +1846,12 @@ describe("Union Interface Relationships", () => { typename_IN: [ReviewerImplementation!] } + type ReviewersConnection { + edges: [ReviewerEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" enum SortDirection { \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" From 7ea3d928e1711a9bb4effdd213b0a163f86ccba9 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Mar 2024 15:57:00 +0000 Subject: [PATCH 05/10] Add tests on top level interface connection --- .../factory/Operations/ConnectionFactory.ts | 22 +- .../factory/SortAndPaginationFactory.ts | 28 +- .../queryAST/utils/is-relationship-entity.ts | 25 ++ .../interfaces-top-level.int.test.ts | 287 ++++++++++++++++++ 4 files changed, 346 insertions(+), 16 deletions(-) create mode 100644 packages/graphql/src/translate/queryAST/utils/is-relationship-entity.ts create mode 100644 packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts diff --git a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts index 6ad674e615..7d7e5e3b09 100644 --- a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts @@ -40,8 +40,8 @@ import type { EntitySelection } from "../../ast/selection/EntitySelection"; import { NodeSelection } from "../../ast/selection/NodeSelection"; import { RelationshipSelection } from "../../ast/selection/RelationshipSelection"; import { getConcreteEntities } from "../../utils/get-concrete-entities"; -import { isConcreteEntity } from "../../utils/is-concrete-entity"; import { isInterfaceEntity } from "../../utils/is-interface-entity"; +import { isRelationshipEntity } from "../../utils/is-relationship-entity"; import { isUnionEntity } from "../../utils/is-union-entity"; import type { QueryASTFactory } from "../QueryASTFactory"; import { findFieldsByNameInFieldsByTypeNameField } from "../parsers/find-fields-by-name-in-fields-by-type-name-field"; @@ -113,14 +113,14 @@ export class ConnectionFactory { // These sort fields will be duplicated on nested "CompositeConnectionPartial" // TODO: this if shouldn't be needed - if (relationship) { - this.hydrateConnectionOperationsASTWithSort({ - entityOrRel: relationship, - resolveTree, - operation: compositeConnectionOp, - context, - }); - } + // if (relationship) { + this.hydrateConnectionOperationsASTWithSort({ + entityOrRel: relationship ?? target, + resolveTree, + operation: compositeConnectionOp, + context, + }); + // } return compositeConnectionOp; } @@ -183,13 +183,13 @@ export class ConnectionFactory { operation, context, }: { - entityOrRel: ConcreteEntityAdapter | RelationshipAdapter; + entityOrRel: EntityAdapter | RelationshipAdapter; resolveTree: ResolveTree; operation: T; context: Neo4jGraphQLTranslationContext; }): T { let options: Pick | undefined; - const target = isConcreteEntity(entityOrRel) ? entityOrRel : entityOrRel.target; + const target = isRelationshipEntity(entityOrRel) ? entityOrRel.target : entityOrRel; if (!isUnionEntity(target)) { options = this.queryASTFactory.operationsFactory.getConnectionOptions(target, resolveTree.args); } else { diff --git a/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts b/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts index c6f63da118..02197fb162 100644 --- a/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts @@ -20,7 +20,6 @@ import type Cypher from "@neo4j/cypher-builder"; import { SCORE_FIELD } from "../../../graphql/directives/fulltext"; import type { EntityAdapter } from "../../../schema-model/entity/EntityAdapter"; -import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; import { RelationshipAdapter } from "../../../schema-model/relationship/model-adapters/RelationshipAdapter"; import type { ConnectionSortArg, GraphQLOptionsArg, GraphQLSortArg, NestedGraphQLSortArg } from "../../../types"; import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context"; @@ -31,6 +30,7 @@ import { FulltextScoreSort } from "../ast/sort/FulltextScoreSort"; import { PropertySort } from "../ast/sort/PropertySort"; import type { Sort } from "../ast/sort/Sort"; import { isConcreteEntity } from "../utils/is-concrete-entity"; +import { isRelationshipEntity } from "../utils/is-relationship-entity"; import { isUnionEntity } from "../utils/is-union-entity"; import type { QueryASTFactory } from "./QueryASTFactory"; @@ -52,7 +52,7 @@ export class SortAndPaginationFactory { public createConnectionSortFields( options: ConnectionSortArg, - entityOrRel: ConcreteEntityAdapter | RelationshipAdapter, + entityOrRel: EntityAdapter | RelationshipAdapter, context: Neo4jGraphQLTranslationContext ): { edge: Sort[]; node: Sort[] } { if (isConcreteEntity(entityOrRel)) { @@ -66,14 +66,32 @@ export class SortAndPaginationFactory { node: nodeSortFields, }; } + if (isRelationshipEntity(entityOrRel)) { + const nodeSortFields = this.createPropertySort({ + optionArg: options.node ?? {}, + entity: entityOrRel.target, + context, + }); + const edgeSortFields = this.createPropertySort({ + optionArg: options.edge || {}, + entity: entityOrRel, + context, + }); + return { + edge: edgeSortFields, + node: nodeSortFields, + }; + } + // Is union or interface + const nodeSortFields = this.createPropertySort({ optionArg: options.node ?? {}, - entity: entityOrRel.target, + entity: entityOrRel, context, }); - const edgeSortFields = this.createPropertySort({ optionArg: options.edge || {}, entity: entityOrRel, context }); + return { - edge: edgeSortFields, + edge: [], node: nodeSortFields, }; } diff --git a/packages/graphql/src/translate/queryAST/utils/is-relationship-entity.ts b/packages/graphql/src/translate/queryAST/utils/is-relationship-entity.ts new file mode 100644 index 0000000000..c7ee57c364 --- /dev/null +++ b/packages/graphql/src/translate/queryAST/utils/is-relationship-entity.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { EntityAdapter } from "../../../schema-model/entity/EntityAdapter"; +import { RelationshipAdapter } from "../../../schema-model/relationship/model-adapters/RelationshipAdapter"; + +export function isRelationshipEntity(entity: EntityAdapter | RelationshipAdapter): entity is RelationshipAdapter { + return entity instanceof RelationshipAdapter; +} diff --git a/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts b/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts new file mode 100644 index 0000000000..23534e8bbc --- /dev/null +++ b/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts @@ -0,0 +1,287 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { GraphQLSchema } from "graphql"; +import { graphql } from "graphql"; +import type { Driver } from "neo4j-driver"; +import { Neo4jGraphQL } from "../../../src"; +import { cleanNodes } from "../../utils/clean-nodes"; +import { UniqueType } from "../../utils/graphql-types"; +import Neo4jHelper from "../neo4j"; + +describe("Interfaces top level connections", () => { + const Series = new UniqueType("Series"); + const Season = new UniqueType("Season"); + const ProgrammeItem = new UniqueType("ProgrammeItem"); + + let schema: GraphQLSchema; + let driver: Driver; + let neo4j: Neo4jHelper; + + async function graphqlQuery(query: string) { + return graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues(), + }); + } + + beforeAll(async () => { + neo4j = new Neo4jHelper(); + driver = await neo4j.getDriver(); + + const typeDefs = /* GraphQL */ ` + interface Show { + title: String! + actors: [Actor!]! @declareRelationship + } + + type Movie implements Show { + title: String! + cost: Float + runtime: Int + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Series implements Show { + title: String! + episodes: Int + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Actor { + name: String! + actedIn: [Show!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + + type ActedIn @relationshipProperties { + screenTime: Int + } + `; + const neoGraphql = new Neo4jGraphQL({ typeDefs, driver }); + schema = await neoGraphql.getSchema(); + + await neo4j.run(` + CREATE (m1:Movie {title: "The Matrix", cost: 24}) + CREATE (:Movie {title: "The Godfather", cost: 20}) + CREATE (:Series {title: "The Matrix Series", episodes: 4}) + CREATE (s1:Series {title: "Avatar", episodes: 9}) + + CREATE(a:Actor {name: "Arthur Dent"}) + CREATE(a)-[:ACTED_IN {screenTime: 10}]->(m1) + CREATE(a)-[:ACTED_IN {screenTime: 20}]->(s1) + `); + }); + + afterEach(async () => { + await cleanNodes(driver, [Series, Season, ProgrammeItem]); + }); + + afterAll(async () => { + await driver.close(); + }); + + test("Top level connection page info", async () => { + const query = /* GraphQL */ ` + query { + showsConnection { + pageInfo { + endCursor + hasNextPage + hasPreviousPage + startCursor + } + totalCount + } + } + `; + const queryResults = await graphqlQuery(query); + expect(queryResults.errors).toBeUndefined(); + expect(queryResults.data).toEqual({ + showsConnection: { + pageInfo: { + endCursor: expect.toBeString(), + hasNextPage: false, + hasPreviousPage: false, + startCursor: expect.toBeString(), + }, + totalCount: 4, + }, + }); + }); + + test("Top level connection with filter", async () => { + const query = /* GraphQL */ ` + query { + showsConnection(where: { title_CONTAINS: "The Matrix" }) { + edges { + node { + title + ... on Movie { + cost + } + } + } + } + } + `; + const queryResults = await graphqlQuery(query); + expect(queryResults.errors).toBeUndefined(); + expect(queryResults.data).toEqual({ + showsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + title: "The Matrix Series", + }, + }, + { + node: { + title: "The Matrix", + cost: 24, + }, + }, + ]), + }, + }); + }); + + test("Top level connection with limit", async () => { + const query = /* GraphQL */ ` + query { + showsConnection(where: { title_CONTAINS: "The Matrix" }, first: 1) { + edges { + node { + title + ... on Movie { + cost + } + } + } + } + } + `; + const queryResults = await graphqlQuery(query); + expect(queryResults.errors).toBeUndefined(); + expect(queryResults.data).toEqual({ + showsConnection: { + edges: expect.toBeArrayOfSize(1), + }, + }); + }); + + test("Top level connection with sort and limit DESC", async () => { + const query = /* GraphQL */ ` + query { + showsConnection(where: { title_CONTAINS: "The" }, first: 2, sort: { title: DESC }) { + edges { + node { + title + ... on Movie { + cost + } + } + } + } + } + `; + const queryResults = await graphqlQuery(query); + expect(queryResults.errors).toBeUndefined(); + expect(queryResults.data).toEqual({ + showsConnection: { + edges: [ + { + node: { + title: "The Matrix Series", + }, + }, + { + node: { title: "The Matrix", cost: 24 }, + }, + ], + }, + }); + }); + + test("Top level connection with nested connection", async () => { + const query = /* GraphQL */ ` + query { + showsConnection { + edges { + node { + title + actorsConnection { + edges { + node { + name + } + properties { + ... on ActedIn { + screenTime + } + } + } + } + } + } + } + } + `; + const queryResults = await graphqlQuery(query); + expect(queryResults.errors).toBeUndefined(); + expect(queryResults.data).toEqual({ + showsConnection: { + edges: expect.toIncludeSameMembers([ + { + node: { + title: "The Matrix Series", + actorsConnection: { + edges: [], + }, + }, + }, + { + node: { + title: "The Matrix", + actorsConnection: { + edges: [{ node: { name: "Arthur Dent" }, properties: { screenTime: 10 } }], + }, + }, + }, + { + node: { + title: "Avatar", + actorsConnection: { + edges: [{ node: { name: "Arthur Dent" }, properties: { screenTime: 20 } }], + }, + }, + }, + { + node: { + title: "The Godfather", + actorsConnection: { + edges: [], + }, + }, + }, + ]), + }, + }); + }); +}); From c198de3cfa0d17e574bb261ccca65de45d350013 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Mar 2024 15:59:48 +0000 Subject: [PATCH 06/10] Add changeset on top level interfaces connection --- .changeset/honest-pumpkins-roll.md | 40 ++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .changeset/honest-pumpkins-roll.md diff --git a/.changeset/honest-pumpkins-roll.md b/.changeset/honest-pumpkins-roll.md new file mode 100644 index 0000000000..9e45b0a1ba --- /dev/null +++ b/.changeset/honest-pumpkins-roll.md @@ -0,0 +1,40 @@ +--- +"@neo4j/graphql": minor +--- + +Support for top-level connection query on interfaces. For example: + +_Typedefs_ + +```graphql +interface Show { + title: String! +} + +type Movie implements Show { + title: String! + cost: Float +} + +type Series implements Show { + title: String! + episodes: Int +} +``` + +_Query_ + +```graphql +query { + showsConnection(where: { title_CONTAINS: "The Matrix" }) { + edges { + node { + title + ... on Movie { + cost + } + } + } + } +} +``` From aa6c3462d870c0ba343fd7bf6239861e3b7a54fa Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Mar 2024 16:08:46 +0000 Subject: [PATCH 07/10] Improve sortAndPaginationFactory --- packages/graphql/src/schema/make-augmented-schema.ts | 2 -- .../queryAST/factory/Operations/ConnectionFactory.ts | 3 --- .../queryAST/factory/SortAndPaginationFactory.ts | 12 ------------ 3 files changed, 17 deletions(-) diff --git a/packages/graphql/src/schema/make-augmented-schema.ts b/packages/graphql/src/schema/make-augmented-schema.ts index d26f205857..f8fe552807 100644 --- a/packages/graphql/src/schema/make-augmented-schema.ts +++ b/packages/graphql/src/schema/make-augmented-schema.ts @@ -555,7 +555,6 @@ function generateObjectType({ graphqlDirectivesToCompose(propagatedDirectives) ); - // FOR CONCRETE composer.Query.addFields({ [concreteEntityAdapter.operations.rootTypeFieldNames.connection]: rootConnectionResolver({ composer, @@ -695,7 +694,6 @@ function generateInterfaceObjectType({ graphqlDirectivesToCompose(propagatedDirectives) ); - // FOR CONCRETE composer.Query.addFields({ [interfaceEntityAdapter.operations.rootTypeFieldNames.connection]: rootConnectionResolver({ composer, diff --git a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts index 7d7e5e3b09..f87c9d7076 100644 --- a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts @@ -112,15 +112,12 @@ export class ConnectionFactory { // These sort fields will be duplicated on nested "CompositeConnectionPartial" - // TODO: this if shouldn't be needed - // if (relationship) { this.hydrateConnectionOperationsASTWithSort({ entityOrRel: relationship ?? target, resolveTree, operation: compositeConnectionOp, context, }); - // } return compositeConnectionOp; } diff --git a/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts b/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts index 02197fb162..b9a5678483 100644 --- a/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/SortAndPaginationFactory.ts @@ -55,17 +55,6 @@ export class SortAndPaginationFactory { entityOrRel: EntityAdapter | RelationshipAdapter, context: Neo4jGraphQLTranslationContext ): { edge: Sort[]; node: Sort[] } { - if (isConcreteEntity(entityOrRel)) { - const nodeSortFields = this.createPropertySort({ - optionArg: options.node ?? {}, - entity: entityOrRel, - context, - }); - return { - edge: [], - node: nodeSortFields, - }; - } if (isRelationshipEntity(entityOrRel)) { const nodeSortFields = this.createPropertySort({ optionArg: options.node ?? {}, @@ -82,7 +71,6 @@ export class SortAndPaginationFactory { node: nodeSortFields, }; } - // Is union or interface const nodeSortFields = this.createPropertySort({ optionArg: options.node ?? {}, From 33cac47910f1749454e6e008d0d301ba5cb1a8f1 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Mar 2024 17:27:43 +0000 Subject: [PATCH 08/10] Minor improvements to connection factory --- .../factory/Operations/ConnectionFactory.ts | 165 +++++++++--------- .../queryAST/utils/get-entity-interfaces.ts | 37 ++++ 2 files changed, 120 insertions(+), 82 deletions(-) create mode 100644 packages/graphql/src/translate/queryAST/utils/get-entity-interfaces.ts diff --git a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts index f87c9d7076..e809dc27f0 100644 --- a/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/Operations/ConnectionFactory.ts @@ -25,12 +25,11 @@ import { Integer } from "neo4j-driver"; import type { EntityAdapter } from "../../../../schema-model/entity/EntityAdapter"; import { InterfaceEntity } from "../../../../schema-model/entity/InterfaceEntity"; import { ConcreteEntityAdapter } from "../../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; -import { InterfaceEntityAdapter } from "../../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; +import type { InterfaceEntityAdapter } from "../../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; import type { UnionEntityAdapter } from "../../../../schema-model/entity/model-adapters/UnionEntityAdapter"; import type { RelationshipAdapter } from "../../../../schema-model/relationship/model-adapters/RelationshipAdapter"; import type { ConnectionQueryArgs } from "../../../../types"; import type { Neo4jGraphQLTranslationContext } from "../../../../types/neo4j-graphql-translation-context"; -import { filterTruthy } from "../../../../utils/utils"; import { checkEntityAuthentication } from "../../../authorization/check-authentication"; import type { Field } from "../../ast/fields/Field"; import { ConnectionReadOperation } from "../../ast/operations/ConnectionReadOperation"; @@ -40,6 +39,7 @@ import type { EntitySelection } from "../../ast/selection/EntitySelection"; import { NodeSelection } from "../../ast/selection/NodeSelection"; import { RelationshipSelection } from "../../ast/selection/RelationshipSelection"; import { getConcreteEntities } from "../../utils/get-concrete-entities"; +import { getEntityInterfaces } from "../../utils/get-entity-interfaces"; import { isInterfaceEntity } from "../../utils/is-interface-entity"; import { isRelationshipEntity } from "../../utils/is-relationship-entity"; import { isUnionEntity } from "../../utils/is-union-entity"; @@ -239,6 +239,57 @@ export class ConnectionFactory { return topLevelConnectionResolveTree; } + public splitConnectionFields(rawFields: Record): { + node: ResolveTree | undefined; + edge: ResolveTree | undefined; + fields: Record; + } { + let nodeField: ResolveTree | undefined; + let edgeField: ResolveTree | undefined; + + const fields: Record = {}; + + Object.entries(rawFields).forEach(([key, field]) => { + if (field.name === "node") { + nodeField = field; + } else if (field.name === "edge") { + edgeField = field; + } else { + fields[key] = field; + } + }); + + return { + node: nodeField, + edge: edgeField, + fields, + }; + } + + public getConnectionOptions( + entity: ConcreteEntityAdapter | InterfaceEntityAdapter, + options: Record + ): Pick | undefined { + const limitDirective = entity.annotations.limit; + + let limit: Integer | number | undefined = options?.first ?? limitDirective?.default ?? limitDirective?.max; + if (limit instanceof Integer) { + limit = limit.toNumber(); + } + const maxLimit = limitDirective?.max; + if (limit !== undefined && maxLimit !== undefined) { + limit = Math.min(limit, maxLimit); + } + + if (limit === undefined && options.after === undefined && options.sort === undefined) return undefined; + + return { + first: limit, + after: options.after, + sort: options.sort, + }; + } + private hydrateConnectionOperationAST({ relationship, target, @@ -254,49 +305,14 @@ export class ConnectionFactory { operation: T; whereArgs: Record; }): T { - // hydrate hydrateConnectionOperationAST is used for both top-level and nested connections. - // If the relationship is defined use the RelationshipAdapter to infer the typeNames, if not use the target. - - // Get the abstract types of the interface - const entityInterfaces = filterTruthy( - target.compositeEntities.map((compositeEntity) => { - if (compositeEntity instanceof InterfaceEntity) { - return new InterfaceEntityAdapter(compositeEntity); - } - }) - ); - - const interfacesFields = entityInterfaces.map((interfaceAdapter) => { - return resolveTree.fieldsByTypeName[interfaceAdapter.operations.connectionFieldTypename] ?? {}; - }); - const entityOrRel = relationship ?? target; - const concreteProjectionFields = { - ...resolveTree.fieldsByTypeName[entityOrRel.operations.connectionFieldTypename], - }; - - const resolveTreeConnectionFields = mergeDeep[]>([ - ...interfacesFields, - concreteProjectionFields, - ]); - - const edgeFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeConnectionFields, "edges"); - - const interfacesEdgeFields = entityInterfaces.map((interfaceAdapter) => { - return getFieldsByTypeName(edgeFieldsRaw, `${interfaceAdapter.name}Edge`); + const resolveTreeEdgeFields = this.parseConnectionFields({ + entityOrRel, + target, + resolveTree, }); - const concreteEdgeFields = getFieldsByTypeName( - edgeFieldsRaw, - entityOrRel.operations.relationshipFieldTypename // Use interface operation - ); - - const resolveTreeEdgeFields = mergeDeep[]>([ - ...interfacesEdgeFields, - concreteEdgeFields, - ]); - const nodeFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeEdgeFields, "node"); const propertiesFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeEdgeFields, "properties"); this.hydrateConnectionOperationsASTWithSort({ @@ -350,54 +366,39 @@ export class ConnectionFactory { return operation; } - public splitConnectionFields(rawFields: Record): { - node: ResolveTree | undefined; - edge: ResolveTree | undefined; - fields: Record; - } { - let nodeField: ResolveTree | undefined; - let edgeField: ResolveTree | undefined; - - const fields: Record = {}; + private parseConnectionFields({ + target, + resolveTree, + entityOrRel, + }: { + entityOrRel: RelationshipAdapter | ConcreteEntityAdapter; + target: ConcreteEntityAdapter; + resolveTree: ResolveTree; + }): Record { + // Get interfaces of the entity + const entityInterfaces = getEntityInterfaces(target); - Object.entries(rawFields).forEach(([key, field]) => { - if (field.name === "node") { - nodeField = field; - } else if (field.name === "edge") { - edgeField = field; - } else { - fields[key] = field; - } + const interfacesFields = entityInterfaces.map((interfaceAdapter) => { + return resolveTree.fieldsByTypeName[interfaceAdapter.operations.connectionFieldTypename] ?? {}; }); - return { - node: nodeField, - edge: edgeField, - fields, + const concreteProjectionFields = { + ...resolveTree.fieldsByTypeName[entityOrRel.operations.connectionFieldTypename], }; - } - public getConnectionOptions( - entity: ConcreteEntityAdapter | InterfaceEntityAdapter, - options: Record - ): Pick | undefined { - const limitDirective = entity.annotations.limit; + const resolveTreeConnectionFields: Record = mergeDeep[]>([ + ...interfacesFields, + concreteProjectionFields, + ]); - let limit: Integer | number | undefined = options?.first ?? limitDirective?.default ?? limitDirective?.max; - if (limit instanceof Integer) { - limit = limit.toNumber(); - } - const maxLimit = limitDirective?.max; - if (limit !== undefined && maxLimit !== undefined) { - limit = Math.min(limit, maxLimit); - } + const edgeFieldsRaw = findFieldsByNameInFieldsByTypeNameField(resolveTreeConnectionFields, "edges"); - if (limit === undefined && options.after === undefined && options.sort === undefined) return undefined; + const interfacesEdgeFields = entityInterfaces.map((interfaceAdapter) => { + return getFieldsByTypeName(edgeFieldsRaw, `${interfaceAdapter.name}Edge`); + }); - return { - first: limit, - after: options.after, - sort: options.sort, - }; + const concreteEdgeFields = getFieldsByTypeName(edgeFieldsRaw, entityOrRel.operations.relationshipFieldTypename); + + return mergeDeep([...interfacesEdgeFields, concreteEdgeFields]); } } diff --git a/packages/graphql/src/translate/queryAST/utils/get-entity-interfaces.ts b/packages/graphql/src/translate/queryAST/utils/get-entity-interfaces.ts new file mode 100644 index 0000000000..3d63af12c2 --- /dev/null +++ b/packages/graphql/src/translate/queryAST/utils/get-entity-interfaces.ts @@ -0,0 +1,37 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { InterfaceEntity } from "../../../schema-model/entity/InterfaceEntity"; +import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +import { InterfaceEntityAdapter } from "../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; +import { filterTruthy } from "../../../utils/utils"; + +/** + * Return all the interfaces the provided concrete entity inherits + * Note that this functions accepts and returns Adapters, not the raw entities + */ +export function getEntityInterfaces(entity: ConcreteEntityAdapter): InterfaceEntityAdapter[] { + return filterTruthy( + entity.compositeEntities.map((compositeEntity) => { + if (compositeEntity instanceof InterfaceEntity) { + return new InterfaceEntityAdapter(compositeEntity); + } + }) + ); +} From 579e7515b65426eb02e154690fb498a16bca232d Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Mar 2024 17:35:50 +0000 Subject: [PATCH 09/10] Add unique type to interfaces top level tests --- .../interfaces-top-level.int.test.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts b/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts index 23534e8bbc..006c97516f 100644 --- a/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts +++ b/packages/graphql/tests/integration/connections/interfaces-top-level.int.test.ts @@ -26,9 +26,9 @@ import { UniqueType } from "../../utils/graphql-types"; import Neo4jHelper from "../neo4j"; describe("Interfaces top level connections", () => { + const Movie = new UniqueType("Movie"); const Series = new UniqueType("Series"); - const Season = new UniqueType("Season"); - const ProgrammeItem = new UniqueType("ProgrammeItem"); + const Actor = new UniqueType("Actor"); let schema: GraphQLSchema; let driver: Driver; @@ -49,23 +49,23 @@ describe("Interfaces top level connections", () => { const typeDefs = /* GraphQL */ ` interface Show { title: String! - actors: [Actor!]! @declareRelationship + actors: [${Actor}!]! @declareRelationship } - type Movie implements Show { + type ${Movie} implements Show { title: String! cost: Float runtime: Int - actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + actors: [${Actor}!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } - type Series implements Show { + type ${Series} implements Show { title: String! episodes: Int - actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + actors: [${Actor}!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } - type Actor { + type ${Actor} { name: String! actedIn: [Show!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") } @@ -78,19 +78,19 @@ describe("Interfaces top level connections", () => { schema = await neoGraphql.getSchema(); await neo4j.run(` - CREATE (m1:Movie {title: "The Matrix", cost: 24}) - CREATE (:Movie {title: "The Godfather", cost: 20}) - CREATE (:Series {title: "The Matrix Series", episodes: 4}) - CREATE (s1:Series {title: "Avatar", episodes: 9}) + CREATE (m1:${Movie} {title: "The Matrix", cost: 24}) + CREATE (:${Movie} {title: "The Godfather", cost: 20}) + CREATE (:${Series} {title: "The Matrix Series", episodes: 4}) + CREATE (s1:${Series} {title: "Avatar", episodes: 9}) - CREATE(a:Actor {name: "Arthur Dent"}) + CREATE(a:${Actor} {name: "Arthur Dent"}) CREATE(a)-[:ACTED_IN {screenTime: 10}]->(m1) CREATE(a)-[:ACTED_IN {screenTime: 20}]->(s1) `); }); afterEach(async () => { - await cleanNodes(driver, [Series, Season, ProgrammeItem]); + await cleanNodes(driver, [Series, Movie, Actor]); }); afterAll(async () => { @@ -133,7 +133,7 @@ describe("Interfaces top level connections", () => { edges { node { title - ... on Movie { + ... on ${Movie} { cost } } @@ -169,7 +169,7 @@ describe("Interfaces top level connections", () => { edges { node { title - ... on Movie { + ... on ${Movie} { cost } } @@ -193,7 +193,7 @@ describe("Interfaces top level connections", () => { edges { node { title - ... on Movie { + ... on ${Movie} { cost } } From 7fcd0aa9131d4ae7594e10df422eb05f3e6fbc94 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 6 Mar 2024 10:56:56 +0000 Subject: [PATCH 10/10] Add tck tests on top level connection with interfaces --- .../connections/top-level-interfaces.test.ts | 157 ++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 packages/graphql/tests/tck/connections/top-level-interfaces.test.ts diff --git a/packages/graphql/tests/tck/connections/top-level-interfaces.test.ts b/packages/graphql/tests/tck/connections/top-level-interfaces.test.ts new file mode 100644 index 0000000000..4d67635f1b --- /dev/null +++ b/packages/graphql/tests/tck/connections/top-level-interfaces.test.ts @@ -0,0 +1,157 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Neo4jGraphQL } from "../../../src"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; + +describe("Top level interface connections", () => { + let typeDefs: string; + let neoSchema: Neo4jGraphQL; + + beforeAll(() => { + typeDefs = /* GraphQL */ ` + interface Show { + title: String! + actors: [Actor!]! @declareRelationship + } + + type Movie implements Show { + title: String! + cost: Float + runtime: Int + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Series implements Show { + title: String! + episodes: Int + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Actor { + name: String! + actedIn: [Show!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + + type ActedIn @relationshipProperties { + screenTime: Int + } + `; + + neoSchema = new Neo4jGraphQL({ + typeDefs, + }); + }); + + test("Top level connection", async () => { + const query = /* GraphQL */ ` + query { + showsConnection(where: { title: "The Matrix" }) { + edges { + node { + title + ... on Movie { + cost + } + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + MATCH (this0:Movie) + WHERE this0.title = $param0 + WITH { node: { __resolveType: \\"Movie\\", __id: id(this0), cost: this0.cost, title: this0.title } } AS edge + RETURN edge + UNION + MATCH (this1:Series) + WHERE this1.title = $param1 + WITH { node: { __resolveType: \\"Series\\", __id: id(this1), title: this1.title } } AS edge + RETURN edge + } + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + RETURN { edges: edges, totalCount: totalCount } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Matrix\\", + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + test("Top level connection with limit", async () => { + const query = /* GraphQL */ ` + query { + showsConnection(where: { title: "The Matrix" }, first: 2) { + edges { + node { + title + ... on Movie { + cost + } + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + MATCH (this0:Movie) + WHERE this0.title = $param0 + WITH { node: { __resolveType: \\"Movie\\", __id: id(this0), cost: this0.cost, title: this0.title } } AS edge + RETURN edge + UNION + MATCH (this1:Series) + WHERE this1.title = $param1 + WITH { node: { __resolveType: \\"Series\\", __id: id(this1), title: this1.title } } AS edge + RETURN edge + } + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge + LIMIT $param2 + RETURN collect(edge) AS var2 + } + RETURN { edges: var2, totalCount: totalCount } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Matrix\\", + \\"param1\\": \\"The Matrix\\", + \\"param2\\": { + \\"low\\": 2, + \\"high\\": 0 + } + }" + `); + }); +});