From 5034630c49bc61488f9fb16ced6e8b614384cbc3 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 30 Nov 2023 15:01:05 +0000 Subject: [PATCH 001/136] Remove _on from interface filters --- .../src/schema/generation/where-input.ts | 16 ++++++---- .../src/schema/make-augmented-schema.ts | 29 +++++++++++++++++-- .../queryAST/factory/OperationFactory.ts | 1 - 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/packages/graphql/src/schema/generation/where-input.ts b/packages/graphql/src/schema/generation/where-input.ts index 5a42fcfbddd..bb37611b947 100644 --- a/packages/graphql/src/schema/generation/where-input.ts +++ b/packages/graphql/src/schema/generation/where-input.ts @@ -60,11 +60,13 @@ export function withWhereInputType({ userDefinedFieldDirectives, features, composer, + experimental, }: { entityAdapter: EntityAdapter | RelationshipAdapter; userDefinedFieldDirectives: Map; features: Neo4jFeaturesSettings | undefined; composer: SchemaComposer; + experimental: boolean; }): InputTypeComposer { if (composer.has(entityAdapter.operations.whereInputTypeName)) { return composer.getITC(entityAdapter.operations.whereInputTypeName); @@ -91,12 +93,14 @@ export function withWhereInputType({ NOT: whereInputType, }); } else if (entityAdapter instanceof InterfaceEntityAdapter) { - const implementationsWhereInputType = makeImplementationsWhereInput({ - interfaceEntityAdapter: entityAdapter, - composer, - }); - // TODO: add interfaces that implement this interface here - whereInputType.addFields({ _on: implementationsWhereInputType }); + if (!experimental) { + const implementationsWhereInputType = makeImplementationsWhereInput({ + interfaceEntityAdapter: entityAdapter, + composer, + }); + // TODO: add interfaces that implement this interface here + whereInputType.addFields({ _on: implementationsWhereInputType }); + } } return whereInputType; } diff --git a/packages/graphql/src/schema/make-augmented-schema.ts b/packages/graphql/src/schema/make-augmented-schema.ts index 7f89e058d74..b93bac37acb 100644 --- a/packages/graphql/src/schema/make-augmented-schema.ts +++ b/packages/graphql/src/schema/make-augmented-schema.ts @@ -229,6 +229,7 @@ function makeAugmentedSchema({ userDefinedDirectivesForInterface, userDefinedFieldDirectivesForNode, features, + experimental, }); seenRelationshipPropertiesInterfaces.add(relationshipAdapter.propertiesTypeName); } @@ -287,7 +288,13 @@ function makeAugmentedSchema({ propagatedDirectives, composer, }); - withWhereInputType({ entityAdapter: concreteEntityAdapter, userDefinedFieldDirectives, features, composer }); + withWhereInputType({ + entityAdapter: concreteEntityAdapter, + userDefinedFieldDirectives, + features, + composer, + experimental, + }); /** * TODO [translation-layer-compatibility] * Need to migrate resolvers, which themselves rely on the translation layer being migrated to the new schema model @@ -412,6 +419,7 @@ function makeAugmentedSchema({ userDefinedFieldDirectives: new Map(), features, composer, + experimental, }); if (experimental) { // strip-out the schema config directives from the union type @@ -455,6 +463,7 @@ function makeAugmentedSchema({ userDefinedFieldDirectives, features, composer, + experimental, }); withOptionsInputType({ entityAdapter: interfaceEntityAdapter, userDefinedFieldDirectives, composer }); if (interfaceEntityAdapter.isReadable) { @@ -652,12 +661,14 @@ function doForRelationshipPropertiesInterface({ userDefinedDirectivesForInterface, userDefinedFieldDirectivesForNode, features, + experimental, }: { composer: SchemaComposer; relationshipAdapter: RelationshipAdapter; userDefinedDirectivesForInterface: Map; userDefinedFieldDirectivesForNode: Map>; features?: Neo4jFeaturesSettings; + experimental: boolean; }) { if (!relationshipAdapter.propertiesTypeName) { return; @@ -674,7 +685,13 @@ function doForRelationshipPropertiesInterface({ }); withSortInputType({ relationshipAdapter, userDefinedFieldDirectives, composer }); withUpdateInputType({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, composer }); - withWhereInputType({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, features, composer }); + withWhereInputType({ + entityAdapter: relationshipAdapter, + userDefinedFieldDirectives, + features, + composer, + experimental, + }); withCreateInputType({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, composer }); } @@ -706,7 +723,13 @@ function doForInterfacesThatAreTargetOfARelationship({ DirectiveNode[] >; withOptionsInputType({ entityAdapter: interfaceEntityAdapter, userDefinedFieldDirectives, composer }); - withWhereInputType({ entityAdapter: interfaceEntityAdapter, userDefinedFieldDirectives, features, composer }); + withWhereInputType({ + entityAdapter: interfaceEntityAdapter, + userDefinedFieldDirectives, + features, + composer, + experimental, + }); withCreateInputType({ entityAdapter: interfaceEntityAdapter, userDefinedFieldDirectives, composer }); withUpdateInputType({ entityAdapter: interfaceEntityAdapter, userDefinedFieldDirectives, composer }); diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index 9e6a5abb308..d6d036f6c73 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -332,7 +332,6 @@ export class OperationsFactory { resolveTree: ResolveTree, context: Neo4jGraphQLTranslationContext ): AggregationOperation | CompositeAggregationOperation { - console.log("createAggregationOperation"); let entity: ConcreteEntityAdapter | InterfaceEntityAdapter; if (entityOrRel instanceof RelationshipAdapter) { entity = entityOrRel.target as ConcreteEntityAdapter; From 7afed26008b0054446a70095416420d0fc2ed4f1 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 30 Nov 2023 15:17:06 +0000 Subject: [PATCH 002/136] Update experimental tests --- .../interfaces-top-level.int.test.ts | 279 +----------------- .../tests/schema/directives/plural.test.ts | 5 - .../experimental-schema/comments.test.ts | 6 - .../directive-preserve.test.ts | 12 - .../directives/default.test.ts | 5 - .../directives/private.test.ts | 5 - .../directives/relationship-aggregate.test.ts | 10 - .../relationship-nested-operations.test.ts | 48 --- .../directives/selectable.test.ts | 12 - .../directives/settable.test.ts | 24 -- .../experimental-schema/inheritance.test.ts | 5 - .../interface-relationships.test.ts | 30 -- .../experimental-schema/interfaces.test.ts | 10 - .../interfaces/aggregations.test.ts | 11 - .../experimental-schema/issues/2377.test.ts | 5 - .../experimental-schema/issues/2993.test.ts | 10 - .../schema/experimental-schema/math.test.ts | 5 - .../nested-aggregation-on-interface.test.ts | 12 - .../union-interface-relationship.test.ts | 6 - .../interface-authorization.test.ts | 191 +----------- .../experimental/interface-pagination.test.ts | 108 +------ .../experimental/interface-top-level.test.ts | 172 +---------- 22 files changed, 8 insertions(+), 963 deletions(-) diff --git a/packages/graphql/tests/integration/experimental/interfaces-top-level.int.test.ts b/packages/graphql/tests/integration/experimental/interfaces-top-level.int.test.ts index 499190b0954..a3153137cad 100644 --- a/packages/graphql/tests/integration/experimental/interfaces-top-level.int.test.ts +++ b/packages/graphql/tests/integration/experimental/interfaces-top-level.int.test.ts @@ -20,11 +20,11 @@ import type { GraphQLSchema } from "graphql"; import { graphql } from "graphql"; import type { Driver } from "neo4j-driver"; -import Neo4j from "../neo4j"; import { Neo4jGraphQL } from "../../../src"; -import { UniqueType } from "../../utils/graphql-types"; -import { createBearerToken } from "../../utils/create-bearer-token"; import { cleanNodes } from "../../utils/clean-nodes"; +import { createBearerToken } from "../../utils/create-bearer-token"; +import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; describe("Top-level interface query fields", () => { const secret = "the-secret"; @@ -201,177 +201,6 @@ describe("Top-level interface query fields", () => { }); }); - test("should return results on top-level simple query on simple interface with filters", async () => { - const neoGraphql = new Neo4jGraphQL({ - typeDefs, - driver, - features: { - authorization: { - key: secret, - }, - }, - experimental: true, - }); - schema = await neoGraphql.getSchema(); - - const query = ` - query { - myOtherInterfaces(where: {_on:{ ${SomeNodeType}: { other: {id: "2"}} } }) { - id - ... on ${SomeNodeType} { - id - other { - id - } - } - } - } - `; - - const token = createBearerToken(secret, {}); - const queryResult = await graphqlQuery(query, token); - expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data).toEqual({ - myOtherInterfaces: expect.toIncludeSameMembers([ - { - id: "1", - other: [ - { - id: "2", - }, - ], - }, - { - id: "10", - other: [ - { - id: "2", - }, - ], - }, - ]), - }); - }); - - test("should return results on top-level simple query on interface target to a relationship with filters", async () => { - const neoGraphql = new Neo4jGraphQL({ - typeDefs, - driver, - features: { - authorization: { - key: secret, - }, - }, - experimental: true, - }); - schema = await neoGraphql.getSchema(); - - const query = ` - query { - myInterfaces(where: { _on: { ${SomeNodeType}: {somethingElse_NOT: "test"}, ${MyOtherImplementationType}: {someField: "bla"} } }) { - id - ... on ${MyOtherImplementationType} { - someField - } - ... on MyOtherInterface { - something - ... on ${SomeNodeType} { - somethingElse - } - } - } - } - `; - - const token = createBearerToken(secret, {}); - const queryResult = await graphqlQuery(query, token); - expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data).toEqual({ - myInterfaces: [ - { - id: "10", - something: "someothernode", - somethingElse: "othertest", - }, - { - id: "4", - someField: "bla", - }, - ], - }); - }); - - test("Type filtering using onType", async () => { - const neoGraphql = new Neo4jGraphQL({ - typeDefs, - driver, - features: { - authorization: { - key: secret, - }, - }, - experimental: true, - }); - schema = await neoGraphql.getSchema(); - - const query = ` - query { - myInterfaces(where: { _on: { ${MyOtherImplementationType}: {} } }) { - id - ... on ${MyOtherImplementationType} { - someField - } - - } - } - `; - - const token = createBearerToken(secret, {}); - const queryResult = await graphqlQuery(query, token); - expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data).toEqual({ - myInterfaces: [ - { - id: "4", - someField: "bla", - }, - ], - }); - }); - - test("Filter overriding using onType", async () => { - const neoGraphql = new Neo4jGraphQL({ - typeDefs, - driver, - features: { - authorization: { - key: secret, - }, - }, - experimental: true, - }); - schema = await neoGraphql.getSchema(); - - const query = ` - query { - myInterfaces(where: { id_STARTS_WITH: "4", _on: { ${MyOtherImplementationType}: {id_STARTS_WITH: "1"} } }) { - id - ... on ${MyOtherImplementationType} { - someField - } - - } - } - `; - - const token = createBearerToken(secret, {}); - const queryResult = await graphqlQuery(query, token); - expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data).toEqual({ - myInterfaces: [], - }); - }); - test("should return results on top-level simple query on simple interface sorted", async () => { const query = ` query { @@ -449,65 +278,6 @@ describe("Top-level interface query fields", () => { }); }); - test("should return results on top-level simple query on interface target to a relationship sorted", async () => { - const query = ` - query { - myInterfaces(where: { _on: { ${SomeNodeType}: {somethingElse_NOT: "test"}, ${MyOtherImplementationType}: {} } }, options: {sort: [{id: ASC}]}) { - id - ... on ${MyOtherImplementationType} { - someField - } - ... on MyOtherInterface { - something - ... on ${SomeNodeType} { - somethingElse - other(options: { sort: [{id: DESC}] }) { - id - } - } - } - } - } - `; - - const session = await neo4j.getSession(); - - try { - await session.run(` - MATCH (s:${SomeNodeType} { id: "10", something:"someothernode",somethingElse:"othertest" }) - CREATE (other:${OtherNodeType} { id: "30" }) - MERGE (s)-[:HAS_OTHER_NODES]->(other) - `); - } finally { - await session.close(); - } - - const token = createBearerToken(secret, {}); - const queryResult = await graphqlQuery(query, token); - expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data).toEqual({ - myInterfaces: [ - { - id: "10", - something: "someothernode", - somethingElse: "othertest", - other: [ - { - id: "30", - }, - { - id: "2", - }, - ], - }, - { - id: "4", - someField: "bla", - }, - ], - }); - }); - describe("add authorization", () => { beforeAll(async () => { typeDefs = @@ -659,49 +429,6 @@ describe("Top-level interface query fields", () => { ]), }); }); - - test("should combine filters with authorization filters", async () => { - const neoGraphql = new Neo4jGraphQL({ - typeDefs, - driver, - features: { - authorization: { - key: secret, - }, - }, - experimental: true, - }); - schema = await neoGraphql.getSchema(); - - const query = ` - query { - myInterfaces(where: { _on: { ${SomeNodeType}: {somethingElse_NOT: "test"}, ${MyOtherImplementationType}: {someField: "bla"} } }) { - id - ... on ${MyOtherImplementationType} { - someField - } - ... on MyOtherInterface { - something - ... on ${SomeNodeType} { - somethingElse - } - } - } - } - `; - - const token = createBearerToken(secret, { roles: ["admin"], jwtAllowedNamesExample: "somenode" }); - const queryResult = await graphqlQuery(query, token); - expect(queryResult.errors).toBeUndefined(); - expect(queryResult.data).toEqual({ - myInterfaces: [ - { - id: "4", - someField: "bla", - }, - ], - }); - }); }); describe("add limit directive", () => { diff --git a/packages/graphql/tests/schema/directives/plural.test.ts b/packages/graphql/tests/schema/directives/plural.test.ts index e907926d717..646d7b95da0 100644 --- a/packages/graphql/tests/schema/directives/plural.test.ts +++ b/packages/graphql/tests/schema/directives/plural.test.ts @@ -1174,10 +1174,6 @@ describe("Plural option", () => { name: StringAggregateSelectionNullable! } - input AnimalImplementationsWhere { - Dog: DogWhere - } - input AnimalOptions { limit: Int offset: Int @@ -1195,7 +1191,6 @@ describe("Plural option", () => { } input AnimalWhere { - _on: AnimalImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/comments.test.ts b/packages/graphql/tests/schema/experimental-schema/comments.test.ts index 38431941397..714da69c3ab 100644 --- a/packages/graphql/tests/schema/experimental-schema/comments.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/comments.test.ts @@ -1103,11 +1103,6 @@ describe("Comments", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -1130,7 +1125,6 @@ describe("Comments", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere title: String title_CONTAINS: String title_ENDS_WITH: String 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 1ea0941410c..653ffe1732c 100644 --- a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts @@ -1541,11 +1541,6 @@ describe("Directive-preserve", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -1568,7 +1563,6 @@ describe("Directive-preserve", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere title: String title_CONTAINS: String title_ENDS_WITH: String @@ -2539,11 +2533,6 @@ describe("Directive-preserve", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -2566,7 +2555,6 @@ describe("Directive-preserve", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere title: String title_CONTAINS: String title_ENDS_WITH: String 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 fc1f133c4f8..73d777631a5 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts @@ -215,10 +215,6 @@ describe("@default directive", () => { toBeOverridden: StringAggregateSelectionNonNullable! } - input UserInterfaceImplementationsWhere { - User: UserWhere - } - input UserInterfaceOptions { limit: Int offset: Int @@ -237,7 +233,6 @@ describe("@default directive", () => { } input UserInterfaceWhere { - _on: UserInterfaceImplementationsWhere fromInterface: String fromInterface_CONTAINS: String fromInterface_ENDS_WITH: String 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 206cfc3ef0d..b9844283400 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts @@ -146,10 +146,6 @@ describe("@private directive", () => { id: IDAggregateSelectionNullable! } - input UserInterfaceImplementationsWhere { - User: UserWhere - } - input UserInterfaceOptions { limit: Int offset: Int @@ -167,7 +163,6 @@ describe("@private directive", () => { } input UserInterfaceWhere { - _on: UserInterfaceImplementationsWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 29149e2ff4c..ba6c3fe3e5f 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 @@ -1450,10 +1450,6 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorUpdateInput } - input PersonImplementationsWhere { - Actor: ActorWhere - } - input PersonOptions { limit: Int offset: Int @@ -1478,7 +1474,6 @@ describe("@relationship directive, aggregate argument", () => { } input PersonWhere { - _on: PersonImplementationsWhere password: String password_CONTAINS: String password_ENDS_WITH: String @@ -1888,10 +1883,6 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorUpdateInput } - input PersonImplementationsWhere { - Actor: ActorWhere - } - input PersonOptions { limit: Int offset: Int @@ -1916,7 +1907,6 @@ describe("@relationship directive, aggregate argument", () => { } input PersonWhere { - _on: PersonImplementationsWhere password: String password_CONTAINS: String password_ENDS_WITH: String 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 e385ee56483..a527d4d6021 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 @@ -8734,11 +8734,6 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -8885,7 +8880,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -9186,11 +9180,6 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -9337,7 +9326,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -9637,11 +9625,6 @@ describe("Relationship nested operations", () => { node: PersonWhere! } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -9788,7 +9771,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10080,11 +10062,6 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoUpdateInput } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -10236,7 +10213,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10527,11 +10503,6 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -10678,7 +10649,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10969,11 +10939,6 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -11120,7 +11085,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -11528,11 +11492,6 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoUpdateInput } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -11684,7 +11643,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -12063,11 +12021,6 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } - input PersonImplementationsWhere { - PersonOne: PersonOneWhere - PersonTwo: PersonTwoWhere - } - type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -12214,7 +12167,6 @@ describe("Relationship nested operations", () => { } input PersonWhere { - _on: PersonImplementationsWhere name: String name_CONTAINS: String name_ENDS_WITH: String 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 8ddaecbc82d..9e5a63e774f 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts @@ -3072,11 +3072,6 @@ describe("@selectable", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -3101,7 +3096,6 @@ describe("@selectable", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere description: String description_CONTAINS: String description_ENDS_WITH: String @@ -3609,11 +3603,6 @@ describe("@selectable", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -3638,7 +3627,6 @@ describe("@selectable", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere description: String description_CONTAINS: String description_ENDS_WITH: String 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 9c398fa7fa5..6e7e02fdf8f 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts @@ -5559,11 +5559,6 @@ describe("@settable", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -5588,7 +5583,6 @@ describe("@settable", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere description: String description_CONTAINS: String description_ENDS_WITH: String @@ -6078,11 +6072,6 @@ describe("@settable", () => { Series: SeriesCreateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -6101,7 +6090,6 @@ describe("@settable", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere description: String description_CONTAINS: String description_ENDS_WITH: String @@ -6860,11 +6848,6 @@ describe("@settable", () => { Series: [SeriesDisconnectInput!] } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -6883,7 +6866,6 @@ describe("@settable", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") @@ -7796,11 +7778,6 @@ describe("@settable", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -7826,7 +7803,6 @@ describe("@settable", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") diff --git a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts index 3c15467c57a..637fc28520a 100644 --- a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts @@ -401,10 +401,6 @@ describe("inheritance", () => { Actor: ActorUpdateInput } - input PersonImplementationsWhere { - Actor: ActorWhere - } - input PersonOptions { limit: Int offset: Int @@ -428,7 +424,6 @@ describe("inheritance", () => { } input PersonWhere { - _on: PersonImplementationsWhere friendsConnection: PersonFriendsConnectionWhere @deprecated(reason: \\"Use \`friendsConnection_SOME\` instead.\\") \\"\\"\\" Return People where all of the related PersonFriendsConnections match this filter 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 da9f2096d89..7b1d5160125 100644 --- a/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts @@ -424,11 +424,6 @@ describe("Interface Relationships", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -451,7 +446,6 @@ describe("Interface Relationships", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere title: String title_CONTAINS: String title_ENDS_WITH: String @@ -1598,11 +1592,6 @@ describe("Interface Relationships", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -1626,7 +1615,6 @@ describe("Interface Relationships", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") @@ -2255,11 +2243,6 @@ describe("Interface Relationships", () => { Type2Interface1: Type2Interface1UpdateInput } - input Interface1ImplementationsWhere { - Type1Interface1: Type1Interface1Where - Type2Interface1: Type2Interface1Where - } - input Interface1Interface2ConnectFieldInput { where: Interface2ConnectWhere } @@ -2340,7 +2323,6 @@ describe("Interface Relationships", () => { } input Interface1Where { - _on: Interface1ImplementationsWhere field1: String field1_CONTAINS: String field1_ENDS_WITH: String @@ -2394,11 +2376,6 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2UpdateInput } - input Interface2ImplementationsWhere { - Type1Interface2: Type1Interface2Where - Type2Interface2: Type2Interface2Where - } - input Interface2Options { limit: Int offset: Int @@ -2421,7 +2398,6 @@ describe("Interface Relationships", () => { } input Interface2Where { - _on: Interface2ImplementationsWhere field2: String field2_CONTAINS: String field2_ENDS_WITH: String @@ -3629,11 +3605,6 @@ describe("Interface Relationships", () => { Post: PostUpdateInput } - input ContentImplementationsWhere { - Comment: CommentWhere - Post: PostWhere - } - input ContentOptions { limit: Int offset: Int @@ -3659,7 +3630,6 @@ describe("Interface Relationships", () => { } input ContentWhere { - _on: ContentImplementationsWhere content: String content_CONTAINS: String content_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts index c89e1dcda29..f2fd4435278 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts @@ -162,10 +162,6 @@ describe("Interfaces", () => { id: IDAggregateSelectionNullable! } - input MovieNodeImplementationsWhere { - Movie: MovieWhere - } - input MovieNodeMoviesConnectFieldInput { connect: [MovieConnectInput!] \\"\\"\\" @@ -247,7 +243,6 @@ describe("Interfaces", () => { } input MovieNodeWhere { - _on: MovieNodeImplementationsWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -526,10 +521,6 @@ describe("Interfaces", () => { id: IDAggregateSelectionNullable! } - input MovieNodeImplementationsWhere { - Movie: MovieWhere - } - input MovieNodeMoviesConnectFieldInput { connect: [MovieConnectInput!] \\"\\"\\" @@ -611,7 +602,6 @@ describe("Interfaces", () => { } input MovieNodeWhere { - _on: MovieNodeImplementationsWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 0d7f166d5fd..caaa12d7833 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts @@ -199,10 +199,6 @@ describe("Interface Top Level Aggregations", () => { title: StringAggregateSelectionNonNullable! } - input ProductionImplementationsWhere { - Movie: MovieWhere - } - input ProductionOptions { limit: Int offset: Int @@ -221,7 +217,6 @@ describe("Interface Top Level Aggregations", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere cost: Float cost_GT: Float cost_GTE: Float @@ -712,11 +707,6 @@ describe("Interface Top Level Aggregations", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -745,7 +735,6 @@ describe("Interface Top Level Aggregations", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere cost: Float cost_GT: Float cost_GTE: Float 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 f58be04674a..d3159548206 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts @@ -388,10 +388,6 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { name: StringAggregateSelectionNullable! } - input ResourceEntityImplementationsWhere { - Resource: ResourceWhere - } - input ResourceEntityOptions { limit: Int offset: Int @@ -411,7 +407,6 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { } input ResourceEntityWhere { - _on: ResourceEntityImplementationsWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 eee73a976bb..1566b4557d1 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts @@ -169,10 +169,6 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { User: UserUpdateInput } - input ProfileImplementationsWhere { - User: UserWhere - } - input ProfileOptions { limit: Int offset: Int @@ -197,7 +193,6 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input ProfileWhere { - _on: ProfileImplementationsWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -595,10 +590,6 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { User: UserUpdateInput } - input ProfileImplementationsWhere { - User: UserWhere - } - input ProfileOptions { limit: Int offset: Int @@ -622,7 +613,6 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input ProfileWhere { - _on: ProfileImplementationsWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID diff --git a/packages/graphql/tests/schema/experimental-schema/math.test.ts b/packages/graphql/tests/schema/experimental-schema/math.test.ts index 6b41ae86e07..a24e91ac530 100644 --- a/packages/graphql/tests/schema/experimental-schema/math.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/math.test.ts @@ -1680,10 +1680,6 @@ describe("Algebraic", () => { Movie: MovieUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - } - input ProductionOptions { limit: Int offset: Int @@ -1708,7 +1704,6 @@ describe("Algebraic", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere viewers: Int viewers_GT: Int viewers_GTE: Int 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 544299be2c8..6127c3054bd 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 @@ -435,11 +435,6 @@ describe("nested aggregation on interface", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -468,7 +463,6 @@ describe("nested aggregation on interface", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere cost: Float cost_GT: Float cost_GTE: Float @@ -1052,11 +1046,6 @@ describe("nested aggregation on interface", () => { Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -1085,7 +1074,6 @@ describe("nested aggregation on interface", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere cost: Float cost_GT: Float cost_GTE: Float 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 d3b19ec768d..259a1b2b309 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 @@ -1832,11 +1832,6 @@ describe("Union Interface Relationships", () => { Person: PersonUpdateInput } - input ReviewerImplementationsWhere { - Influencer: InfluencerWhere - Person: PersonWhere - } - input ReviewerOptions { limit: Int offset: Int @@ -1865,7 +1860,6 @@ describe("Union Interface Relationships", () => { } input ReviewerWhere { - _on: ReviewerImplementationsWhere reputation: Int reputation_GT: Int reputation_GTE: Int diff --git a/packages/graphql/tests/tck/experimental/interface-authorization.test.ts b/packages/graphql/tests/tck/experimental/interface-authorization.test.ts index ce22012a6d5..7d7b60845b6 100644 --- a/packages/graphql/tests/tck/experimental/interface-authorization.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-authorization.test.ts @@ -17,11 +17,11 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../../src"; -import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; import { createBearerToken } from "../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; describe("Interface top level operations with authorization", () => { const secret = "secret"; @@ -389,191 +389,4 @@ describe("Interface top level operations with authorization", () => { }" `); }); - - test("Read interface with filters", async () => { - const query = gql` - { - myOtherInterfaces(where: { _on: { SomeNodeType: { other: { id: "2" } } } }) { - id - ... on SomeNodeType { - id - other { - id - } - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - OPTIONAL MATCH (this0)-[:HAS_OTHER_NODES]->(this1:OtherNodeType) - WITH *, count(this1) AS otherCount - WITH * - WHERE ((otherCount <> 0 AND this1.id = $param0) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.jwtAllowedNamesExample IS NOT NULL AND this0.id = $jwt.jwtAllowedNamesExample) AND ($jwt.roles IS NOT NULL AND $param3 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) - CALL { - WITH this0 - MATCH (this0)-[this2:HAS_OTHER_NODES]->(this3:OtherNodeType) - WITH this3 { .id } AS this3 - RETURN head(collect(this3)) AS var4 - } - WITH this0 { .id, other: var4, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"2\\", - \\"isAuthenticated\\": true, - \\"jwt\\": { - \\"roles\\": [], - \\"jwtAllowedNamesExample\\": \\"Horror\\" - }, - \\"param3\\": \\"admin\\" - }" - `); - }); - - test("Read interface with filters (interface target of a relationship)", async () => { - const query = gql` - { - myInterfaces( - where: { - _on: { - SomeNodeType: { somethingElse_NOT: "test" } - MyOtherImplementationType: { someField: "bla" } - } - } - ) { - id - ... on MyOtherImplementationType { - someField - } - ... on MyOtherInterface { - something - ... on SomeNodeType { - somethingElse - } - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - WHERE (NOT (this0.somethingElse = $param0) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.jwtAllowedNamesExample IS NOT NULL AND this0.id = $jwt.jwtAllowedNamesExample) AND ($jwt.roles IS NOT NULL AND $param3 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) - WITH this0 { .id, .something, .somethingElse, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - UNION - MATCH (this1:MyOtherImplementationType) - WHERE this1.someField = $param4 - WITH this1 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this1) } AS this1 - RETURN this1 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"test\\", - \\"isAuthenticated\\": true, - \\"jwt\\": { - \\"roles\\": [], - \\"jwtAllowedNamesExample\\": \\"Horror\\" - }, - \\"param3\\": \\"admin\\", - \\"param4\\": \\"bla\\" - }" - `); - }); - - test("Type filtering using onType", async () => { - const query = gql` - { - myInterfaces(where: { _on: { MyOtherImplementationType: {} } }) { - id - ... on MyOtherImplementationType { - someField - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:MyOtherImplementationType) - WITH this0 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); - }); - - test("Filter overriding using onType", async () => { - const query = gql` - { - myInterfaces( - where: { id_STARTS_WITH: "4", _on: { MyOtherImplementationType: { id_STARTS_WITH: "1" } } } - ) { - id - ... on MyOtherImplementationType { - someField - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - WHERE (this0.id STARTS WITH $param0 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.jwtAllowedNamesExample IS NOT NULL AND this0.id = $jwt.jwtAllowedNamesExample) AND ($jwt.roles IS NOT NULL AND $param3 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) - WITH this0 { .id, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - UNION - MATCH (this1:MyImplementationType) - WHERE (this1.id STARTS WITH $param4 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.groups IS NOT NULL AND $param5 IN $jwt.groups)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) - WITH this1 { .id, __resolveType: \\"MyImplementationType\\", __id: id(this1) } AS this1 - RETURN this1 AS this - UNION - MATCH (this2:MyOtherImplementationType) - WHERE this2.id STARTS WITH $param6 - WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 - RETURN this2 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"4\\", - \\"isAuthenticated\\": true, - \\"jwt\\": { - \\"roles\\": [], - \\"jwtAllowedNamesExample\\": \\"Horror\\" - }, - \\"param3\\": \\"admin\\", - \\"param4\\": \\"4\\", - \\"param5\\": \\"a\\", - \\"param6\\": \\"1\\" - }" - `); - }); }); diff --git a/packages/graphql/tests/tck/experimental/interface-pagination.test.ts b/packages/graphql/tests/tck/experimental/interface-pagination.test.ts index 3a442e4b0fe..f1aac4dbe06 100644 --- a/packages/graphql/tests/tck/experimental/interface-pagination.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-pagination.test.ts @@ -19,7 +19,7 @@ import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../../src"; -import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; describe("Top-level Interface query pagination (sort and limit)", () => { let typeDefs: string; @@ -164,112 +164,6 @@ describe("Top-level Interface query pagination (sort and limit)", () => { `); }); - test("Sort with filter on Interface top-level", async () => { - const query = gql` - query { - myInterfaces( - where: { _on: { SomeNodeType: { somethingElse_NOT: "test" }, MyOtherImplementationType: {} } } - options: { sort: [{ id: ASC }], limit: 10 } - ) { - id - ... on MyOtherImplementationType { - someField - } - ... on MyOtherInterface { - something - ... on SomeNodeType { - somethingElse - other { - id - } - } - } - } - } - `; - - const result = await translateQuery(neoSchema, query); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - WHERE NOT (this0.somethingElse = $param0) - CALL { - WITH this0 - MATCH (this0)-[this1:HAS_OTHER_NODES]->(this2:OtherNodeType) - WITH this2 { .id } AS this2 - RETURN collect(this2) AS var3 - } - WITH this0 { .id, .something, .somethingElse, other: var3, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - UNION - MATCH (this4:MyOtherImplementationType) - WITH this4 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this4) } AS this4 - RETURN this4 AS this - } - RETURN this - ORDER BY this.id ASC - LIMIT $param1" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"test\\", - \\"param1\\": { - \\"low\\": 10, - \\"high\\": 0 - } - }" - `); - }); - - test("Sort on Interfaces filtered by _on type", async () => { - const query = gql` - query { - myInterfaces( - where: { _on: { MyOtherImplementationType: {} } } - options: { sort: [{ id: ASC }], limit: 10 } - ) { - id - ... on MyOtherImplementationType { - someField - } - ... on MyOtherInterface { - something - ... on SomeNodeType { - somethingElse - other { - id - } - } - } - } - } - `; - - const result = await translateQuery(neoSchema, query); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:MyOtherImplementationType) - WITH this0 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - } - RETURN this - ORDER BY this.id ASC - LIMIT $param0" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": { - \\"low\\": 10, - \\"high\\": 0 - } - }" - `); - }); - test("Sort on Interfaces top-level + nested", async () => { const query = gql` query { diff --git a/packages/graphql/tests/tck/experimental/interface-top-level.test.ts b/packages/graphql/tests/tck/experimental/interface-top-level.test.ts index d40f2e68337..cea86f3f483 100644 --- a/packages/graphql/tests/tck/experimental/interface-top-level.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-top-level.test.ts @@ -17,11 +17,11 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../../src"; -import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; import { createBearerToken } from "../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; describe("Interface top level operations", () => { const secret = "secret"; @@ -305,172 +305,4 @@ describe("Interface top level operations", () => { }" `); }); - - test("Read interface with filters", async () => { - const query = gql` - { - myOtherInterfaces(where: { _on: { SomeNodeType: { other: { id: "2" } } } }) { - id - ... on SomeNodeType { - id - other { - id - } - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - OPTIONAL MATCH (this0)-[:HAS_OTHER_NODES]->(this1:OtherNodeType) - WITH *, count(this1) AS otherCount - WITH * - WHERE (otherCount <> 0 AND this1.id = $param0) - CALL { - WITH this0 - MATCH (this0)-[this2:HAS_OTHER_NODES]->(this3:OtherNodeType) - WITH this3 { .id } AS this3 - RETURN head(collect(this3)) AS var4 - } - WITH this0 { .id, other: var4, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"2\\" - }" - `); - }); - - test("Read interface with filters (interface target of a relationship)", async () => { - const query = gql` - { - myInterfaces( - where: { - _on: { - SomeNodeType: { somethingElse_NOT: "test" } - MyOtherImplementationType: { someField: "bla" } - } - } - ) { - id - ... on MyOtherImplementationType { - someField - } - ... on MyOtherInterface { - something - ... on SomeNodeType { - somethingElse - } - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - WHERE NOT (this0.somethingElse = $param0) - WITH this0 { .id, .something, .somethingElse, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - UNION - MATCH (this1:MyOtherImplementationType) - WHERE this1.someField = $param1 - WITH this1 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this1) } AS this1 - RETURN this1 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"test\\", - \\"param1\\": \\"bla\\" - }" - `); - }); - - test("Type filtering using onType", async () => { - const query = gql` - { - myInterfaces(where: { _on: { MyOtherImplementationType: {} } }) { - id - ... on MyOtherImplementationType { - someField - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:MyOtherImplementationType) - WITH this0 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); - }); - - test("Filter overriding using onType", async () => { - const query = gql` - { - myInterfaces( - where: { id_STARTS_WITH: "4", _on: { MyOtherImplementationType: { id_STARTS_WITH: "1" } } } - ) { - id - ... on MyOtherImplementationType { - someField - } - } - } - `; - - const token = createBearerToken("secret", { jwtAllowedNamesExample: "Horror" }); - const result = await translateQuery(neoSchema, query, { token }); - - expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:SomeNodeType) - WHERE this0.id STARTS WITH $param0 - WITH this0 { .id, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 - RETURN this0 AS this - UNION - MATCH (this1:MyImplementationType) - WHERE this1.id STARTS WITH $param1 - WITH this1 { .id, __resolveType: \\"MyImplementationType\\", __id: id(this1) } AS this1 - RETURN this1 AS this - UNION - MATCH (this2:MyOtherImplementationType) - WHERE this2.id STARTS WITH $param2 - WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 - RETURN this2 AS this - } - RETURN this" - `); - - expect(formatParams(result.params)).toMatchInlineSnapshot(` - "{ - \\"param0\\": \\"4\\", - \\"param1\\": \\"4\\", - \\"param2\\": \\"1\\" - }" - `); - }); }); From 5c42f8d5226dcc87c804bc752d676fdc9f623d30 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 30 Nov 2023 15:20:04 +0000 Subject: [PATCH 003/136] Add changeset --- .changeset/khaki-spiders-heal.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/khaki-spiders-heal.md diff --git a/.changeset/khaki-spiders-heal.md b/.changeset/khaki-spiders-heal.md new file mode 100644 index 00000000000..3d50ba825ed --- /dev/null +++ b/.changeset/khaki-spiders-heal.md @@ -0,0 +1,5 @@ +--- +"@neo4j/graphql": patch +--- + +Remove \_on filter for interfaces From 742c2937a28ea96aa693d23aa1b67b24708e49f1 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Dec 2023 09:44:16 +0000 Subject: [PATCH 004/136] Move plural test to experimental --- .../tests/schema/directives/plural.test.ts | 307 +--------------- .../schema/experimental-schema/plural.test.ts | 330 ++++++++++++++++++ 2 files changed, 331 insertions(+), 306 deletions(-) create mode 100644 packages/graphql/tests/schema/experimental-schema/plural.test.ts diff --git a/packages/graphql/tests/schema/directives/plural.test.ts b/packages/graphql/tests/schema/directives/plural.test.ts index 646d7b95da0..4880f400d87 100644 --- a/packages/graphql/tests/schema/directives/plural.test.ts +++ b/packages/graphql/tests/schema/directives/plural.test.ts @@ -18,8 +18,8 @@ */ import { printSchemaWithDirectives } from "@graphql-tools/utils"; -import { lexicographicSortSchema } from "graphql/utilities"; import { gql } from "graphql-tag"; +import { lexicographicSortSchema } from "graphql/utilities"; import { Neo4jGraphQL } from "../../../src"; describe("Plural option", () => { @@ -1138,309 +1138,4 @@ describe("Plural option", () => { }" `); }); - - test("Plural on interface and union", async () => { - const typeDefs = gql` - interface Animal @plural(value: "animales") { - name: String - } - - type Dog implements Animal { - name: String - breed: String - } - - type Cat { - queenOf: String - } - - union Pet @plural(value: "petties") = Dog | Cat - `; - const neoSchema = new Neo4jGraphQL({ typeDefs, experimental: true }); - const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); - - expect(printedSchema).toMatchInlineSnapshot(` - "schema { - query: Query - mutation: Mutation - } - - interface Animal { - name: String - } - - type AnimalAggregateSelection { - count: Int! - name: StringAggregateSelectionNullable! - } - - input AnimalOptions { - limit: Int - offset: Int - \\"\\"\\" - Specify one or more AnimalSort objects to sort Animales by. The sorts will be applied in the order in which they are arranged in the array. - \\"\\"\\" - sort: [AnimalSort] - } - - \\"\\"\\" - Fields to sort Animales by. The order in which sorts are applied is not guaranteed when specifying many fields in one AnimalSort object. - \\"\\"\\" - input AnimalSort { - name: SortDirection - } - - input AnimalWhere { - name: String - name_CONTAINS: String - name_ENDS_WITH: String - name_IN: [String] - name_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_STARTS_WITH: String - } - - type Cat { - queenOf: String - } - - type CatAggregateSelection { - count: Int! - queenOf: StringAggregateSelectionNullable! - } - - input CatCreateInput { - queenOf: String - } - - type CatEdge { - cursor: String! - node: Cat! - } - - input CatOptions { - limit: Int - offset: Int - \\"\\"\\" - Specify one or more CatSort objects to sort Cats by. The sorts will be applied in the order in which they are arranged in the array. - \\"\\"\\" - sort: [CatSort!] - } - - \\"\\"\\" - Fields to sort Cats by. The order in which sorts are applied is not guaranteed when specifying many fields in one CatSort object. - \\"\\"\\" - input CatSort { - queenOf: SortDirection - } - - input CatUpdateInput { - queenOf: String - } - - input CatWhere { - AND: [CatWhere!] - NOT: CatWhere - OR: [CatWhere!] - queenOf: String - queenOf_CONTAINS: String - queenOf_ENDS_WITH: String - queenOf_IN: [String] - queenOf_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - queenOf_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - queenOf_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - queenOf_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - queenOf_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - queenOf_STARTS_WITH: String - } - - type CatsConnection { - edges: [CatEdge!]! - pageInfo: PageInfo! - totalCount: Int! - } - - type CreateCatsMutationResponse { - cats: [Cat!]! - info: CreateInfo! - } - - type CreateDogsMutationResponse { - dogs: [Dog!]! - info: CreateInfo! - } - - \\"\\"\\" - Information about the number of nodes and relationships created during a create mutation - \\"\\"\\" - type CreateInfo { - bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") - nodesCreated: Int! - relationshipsCreated: Int! - } - - \\"\\"\\" - Information about the number of nodes and relationships deleted during a delete mutation - \\"\\"\\" - type DeleteInfo { - bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") - nodesDeleted: Int! - relationshipsDeleted: Int! - } - - type Dog implements Animal { - breed: String - name: String - } - - type DogAggregateSelection { - breed: StringAggregateSelectionNullable! - count: Int! - name: StringAggregateSelectionNullable! - } - - input DogCreateInput { - breed: String - name: String - } - - type DogEdge { - cursor: String! - node: Dog! - } - - input DogOptions { - limit: Int - offset: Int - \\"\\"\\" - Specify one or more DogSort objects to sort Dogs by. The sorts will be applied in the order in which they are arranged in the array. - \\"\\"\\" - sort: [DogSort!] - } - - \\"\\"\\" - Fields to sort Dogs by. The order in which sorts are applied is not guaranteed when specifying many fields in one DogSort object. - \\"\\"\\" - input DogSort { - breed: SortDirection - name: SortDirection - } - - input DogUpdateInput { - breed: String - name: String - } - - input DogWhere { - AND: [DogWhere!] - NOT: DogWhere - OR: [DogWhere!] - breed: String - breed_CONTAINS: String - breed_ENDS_WITH: String - breed_IN: [String] - breed_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - breed_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - breed_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - breed_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - breed_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - breed_STARTS_WITH: String - name: String - name_CONTAINS: String - name_ENDS_WITH: String - name_IN: [String] - name_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - name_STARTS_WITH: String - } - - type DogsConnection { - edges: [DogEdge!]! - pageInfo: PageInfo! - totalCount: Int! - } - - type Mutation { - createCats(input: [CatCreateInput!]!): CreateCatsMutationResponse! - createDogs(input: [DogCreateInput!]!): CreateDogsMutationResponse! - deleteCats(where: CatWhere): DeleteInfo! - deleteDogs(where: DogWhere): DeleteInfo! - updateCats(update: CatUpdateInput, where: CatWhere): UpdateCatsMutationResponse! - updateDogs(update: DogUpdateInput, where: DogWhere): UpdateDogsMutationResponse! - } - - \\"\\"\\"Pagination information (Relay)\\"\\"\\" - type PageInfo { - endCursor: String - hasNextPage: Boolean! - hasPreviousPage: Boolean! - startCursor: String - } - - union Pet = Cat | Dog - - input PetWhere { - Cat: CatWhere - Dog: DogWhere - } - - type Query { - animales(options: AnimalOptions, where: AnimalWhere): [Animal!]! - animalesAggregate(where: AnimalWhere): AnimalAggregateSelection! - cats(options: CatOptions, where: CatWhere): [Cat!]! - catsAggregate(where: CatWhere): CatAggregateSelection! - catsConnection(after: String, first: Int, sort: [CatSort], where: CatWhere): CatsConnection! - dogs(options: DogOptions, where: DogWhere): [Dog!]! - dogsAggregate(where: DogWhere): DogAggregateSelection! - dogsConnection(after: String, first: Int, sort: [DogSort], where: DogWhere): DogsConnection! - petties(options: QueryOptions, where: PetWhere): [Pet!]! - } - - \\"\\"\\"Input type for options that can be specified on a query operation.\\"\\"\\" - input QueryOptions { - limit: Int - offset: Int - } - - \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" - enum SortDirection { - \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" - ASC - \\"\\"\\"Sort by field values in descending order.\\"\\"\\" - DESC - } - - type StringAggregateSelectionNullable { - longest: String - shortest: String - } - - type UpdateCatsMutationResponse { - cats: [Cat!]! - info: UpdateInfo! - } - - type UpdateDogsMutationResponse { - dogs: [Dog!]! - info: UpdateInfo! - } - - \\"\\"\\" - Information about the number of nodes and relationships created and deleted during an update mutation - \\"\\"\\" - type UpdateInfo { - bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") - nodesCreated: Int! - nodesDeleted: Int! - relationshipsCreated: Int! - relationshipsDeleted: Int! - }" - `); - }); }); diff --git a/packages/graphql/tests/schema/experimental-schema/plural.test.ts b/packages/graphql/tests/schema/experimental-schema/plural.test.ts new file mode 100644 index 00000000000..f7050f6b43b --- /dev/null +++ b/packages/graphql/tests/schema/experimental-schema/plural.test.ts @@ -0,0 +1,330 @@ +/* + * 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 { printSchemaWithDirectives } from "@graphql-tools/utils"; +import { gql } from "graphql-tag"; +import { lexicographicSortSchema } from "graphql/utilities"; +import { Neo4jGraphQL } from "../../../src"; + +describe("Experimental Plural option", () => { + test("Plural on interface and union", async () => { + const typeDefs = gql` + interface Animal @plural(value: "animales") { + name: String + } + + type Dog implements Animal { + name: String + breed: String + } + + type Cat { + queenOf: String + } + + union Pet @plural(value: "petties") = Dog | Cat + `; + const neoSchema = new Neo4jGraphQL({ typeDefs, experimental: true }); + const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); + + expect(printedSchema).toMatchInlineSnapshot(` + "schema { + query: Query + mutation: Mutation + } + + interface Animal { + name: String + } + + type AnimalAggregateSelection { + count: Int! + name: StringAggregateSelectionNullable! + } + + input AnimalOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more AnimalSort objects to sort Animales by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [AnimalSort] + } + + \\"\\"\\" + Fields to sort Animales by. The order in which sorts are applied is not guaranteed when specifying many fields in one AnimalSort object. + \\"\\"\\" + input AnimalSort { + name: SortDirection + } + + input AnimalWhere { + name: String + name_CONTAINS: String + name_ENDS_WITH: String + name_IN: [String] + name_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_STARTS_WITH: String + } + + type Cat { + queenOf: String + } + + type CatAggregateSelection { + count: Int! + queenOf: StringAggregateSelectionNullable! + } + + input CatCreateInput { + queenOf: String + } + + type CatEdge { + cursor: String! + node: Cat! + } + + input CatOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more CatSort objects to sort Cats by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [CatSort!] + } + + \\"\\"\\" + Fields to sort Cats by. The order in which sorts are applied is not guaranteed when specifying many fields in one CatSort object. + \\"\\"\\" + input CatSort { + queenOf: SortDirection + } + + input CatUpdateInput { + queenOf: String + } + + input CatWhere { + AND: [CatWhere!] + NOT: CatWhere + OR: [CatWhere!] + queenOf: String + queenOf_CONTAINS: String + queenOf_ENDS_WITH: String + queenOf_IN: [String] + queenOf_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + queenOf_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + queenOf_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + queenOf_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + queenOf_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + queenOf_STARTS_WITH: String + } + + type CatsConnection { + edges: [CatEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + type CreateCatsMutationResponse { + cats: [Cat!]! + info: CreateInfo! + } + + type CreateDogsMutationResponse { + dogs: [Dog!]! + info: CreateInfo! + } + + \\"\\"\\" + Information about the number of nodes and relationships created during a create mutation + \\"\\"\\" + type CreateInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesCreated: Int! + relationshipsCreated: Int! + } + + \\"\\"\\" + Information about the number of nodes and relationships deleted during a delete mutation + \\"\\"\\" + type DeleteInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesDeleted: Int! + relationshipsDeleted: Int! + } + + type Dog implements Animal { + breed: String + name: String + } + + type DogAggregateSelection { + breed: StringAggregateSelectionNullable! + count: Int! + name: StringAggregateSelectionNullable! + } + + input DogCreateInput { + breed: String + name: String + } + + type DogEdge { + cursor: String! + node: Dog! + } + + input DogOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more DogSort objects to sort Dogs by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [DogSort!] + } + + \\"\\"\\" + Fields to sort Dogs by. The order in which sorts are applied is not guaranteed when specifying many fields in one DogSort object. + \\"\\"\\" + input DogSort { + breed: SortDirection + name: SortDirection + } + + input DogUpdateInput { + breed: String + name: String + } + + input DogWhere { + AND: [DogWhere!] + NOT: DogWhere + OR: [DogWhere!] + breed: String + breed_CONTAINS: String + breed_ENDS_WITH: String + breed_IN: [String] + breed_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + breed_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + breed_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + breed_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + breed_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + breed_STARTS_WITH: String + name: String + name_CONTAINS: String + name_ENDS_WITH: String + name_IN: [String] + name_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_STARTS_WITH: String + } + + type DogsConnection { + edges: [DogEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + type Mutation { + createCats(input: [CatCreateInput!]!): CreateCatsMutationResponse! + createDogs(input: [DogCreateInput!]!): CreateDogsMutationResponse! + deleteCats(where: CatWhere): DeleteInfo! + deleteDogs(where: DogWhere): DeleteInfo! + updateCats(update: CatUpdateInput, where: CatWhere): UpdateCatsMutationResponse! + updateDogs(update: DogUpdateInput, where: DogWhere): UpdateDogsMutationResponse! + } + + \\"\\"\\"Pagination information (Relay)\\"\\"\\" + type PageInfo { + endCursor: String + hasNextPage: Boolean! + hasPreviousPage: Boolean! + startCursor: String + } + + union Pet = Cat | Dog + + input PetWhere { + Cat: CatWhere + Dog: DogWhere + } + + type Query { + animales(options: AnimalOptions, where: AnimalWhere): [Animal!]! + animalesAggregate(where: AnimalWhere): AnimalAggregateSelection! + cats(options: CatOptions, where: CatWhere): [Cat!]! + catsAggregate(where: CatWhere): CatAggregateSelection! + catsConnection(after: String, first: Int, sort: [CatSort], where: CatWhere): CatsConnection! + dogs(options: DogOptions, where: DogWhere): [Dog!]! + dogsAggregate(where: DogWhere): DogAggregateSelection! + dogsConnection(after: String, first: Int, sort: [DogSort], where: DogWhere): DogsConnection! + petties(options: QueryOptions, where: PetWhere): [Pet!]! + } + + \\"\\"\\"Input type for options that can be specified on a query operation.\\"\\"\\" + input QueryOptions { + limit: Int + offset: Int + } + + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" + enum SortDirection { + \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" + ASC + \\"\\"\\"Sort by field values in descending order.\\"\\"\\" + DESC + } + + type StringAggregateSelectionNullable { + longest: String + shortest: String + } + + type UpdateCatsMutationResponse { + cats: [Cat!]! + info: UpdateInfo! + } + + type UpdateDogsMutationResponse { + dogs: [Dog!]! + info: UpdateInfo! + } + + \\"\\"\\" + Information about the number of nodes and relationships created and deleted during an update mutation + \\"\\"\\" + type UpdateInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesCreated: Int! + nodesDeleted: Int! + relationshipsCreated: Int! + relationshipsDeleted: Int! + }" + `); + }); +}); From 3c5927f26f21528b1e48b039debf60c3090fc697 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Dec 2023 10:44:48 +0000 Subject: [PATCH 005/136] Update experimental test 3439 --- .../experimental-schema/issues/3439.test.ts | 69 ++++++++++++++++--- 1 file changed, 61 insertions(+), 8 deletions(-) diff --git a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts index fc90226a296..edb1bf9de51 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts @@ -18,11 +18,11 @@ */ import { printSchemaWithDirectives } from "@graphql-tools/utils"; +import { validateSchema } from "graphql"; import { gql } from "graphql-tag"; import { lexicographicSortSchema } from "graphql/utilities"; import { Neo4jGraphQL } from "../../../../src"; import { TestSubscriptionsEngine } from "../../../utils/TestSubscriptionsEngine"; -import { validateSchema } from "graphql"; describe("https://github.com/neo4j/graphql/issues/3439", () => { test("Type definitions implementing multiple interfaces", async () => { @@ -59,7 +59,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { `; const subscriptionsEngine = new TestSubscriptionsEngine(); - const neoSchema = new Neo4jGraphQL({ typeDefs, features: { subscriptions: subscriptionsEngine } }); + const neoSchema = new Neo4jGraphQL({ + typeDefs, + features: { subscriptions: subscriptionsEngine }, + experimental: true, + }); const schema = await neoSchema.getSchema(); const errors = validateSchema(schema); @@ -118,6 +122,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { type Genre { name: String! product(directed: Boolean = true, options: IProductOptions, where: IProductWhere): [IProduct!]! + productAggregate(directed: Boolean = true, where: IProductWhere): GenreIProductProductAggregationSelection productConnection(after: String, directed: Boolean = true, first: Int, sort: [GenreProductConnectionSort!], where: GenreProductConnectionWhere): GenreProductConnection! } @@ -176,6 +181,16 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + type GenreIProductProductAggregationSelection { + count: Int! + node: GenreIProductProductNodeAggregateSelection + } + + type GenreIProductProductNodeAggregateSelection { + id: StringAggregateSelectionNonNullable! + name: StringAggregateSelectionNonNullable! + } + input GenreOnCreateInput { name: String! } @@ -380,12 +395,52 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { id: String! } + type INodeAggregateSelection { + count: Int! + id: StringAggregateSelectionNonNullable! + } + + input INodeOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more INodeSort objects to sort INodes by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [INodeSort] + } + + \\"\\"\\" + Fields to sort INodes by. The order in which sorts are applied is not guaranteed when specifying many fields in one INodeSort object. + \\"\\"\\" + input INodeSort { + id: SortDirection + } + + input INodeWhere { + id: String + id_CONTAINS: String + id_ENDS_WITH: String + id_IN: [String!] + id_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + id_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + id_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + id_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + id_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + id_STARTS_WITH: String + } + interface IProduct { genre: Genre! id: String! name: String! } + type IProductAggregateSelection { + count: Int! + id: StringAggregateSelectionNonNullable! + name: StringAggregateSelectionNonNullable! + } + input IProductConnectInput { _on: IProductImplementationsConnectInput } @@ -437,11 +492,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { Series: SeriesUpdateInput } - input IProductImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input IProductOptions { limit: Int offset: Int @@ -493,7 +543,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { - _on: IProductImplementationsWhere id: String id_CONTAINS: String id_ENDS_WITH: String @@ -880,6 +929,10 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genres(options: GenreOptions, where: GenreWhere): [Genre!]! genresAggregate(where: GenreWhere): GenreAggregateSelection! genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! + iNodes(options: INodeOptions, where: INodeWhere): [INode!]! + iNodesAggregate(where: INodeWhere): INodeAggregateSelection! + iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! + iProductsAggregate(where: IProductWhere): IProductAggregateSelection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! From 680ec6d6d7a78ed9fd51c3e98be647f51c3bf417 Mon Sep 17 00:00:00 2001 From: MacondoExpress Date: Mon, 4 Dec 2023 11:37:21 +0000 Subject: [PATCH 006/136] Minor improvements (#4361) * improve typings on unwind-create implementation * boy scouting around create * clean up unwind create implementation, remove uuid dependency * Cypher.RawCypher to Cypher.Raw * change error message in unwind-create * add access modifier --- packages/graphql/package.json | 3 +- .../compatibility/compile-predicate-return.ts | 2 +- .../batch-create/GraphQLInputAST/CreateAST.ts | 14 +- .../GraphQLInputAST/GraphQLInputAST.ts | 6 +- .../GraphQLInputAST/NestedCreateAST.ts | 16 +-- .../{AST.ts => UnwindASTNode.ts} | 16 ++- .../batch-create/GraphQLInputAST/types.ts | 51 +------ .../src/translate/batch-create/parser.ts | 112 ++++++++-------- .../src/translate/batch-create/types.ts | 2 +- .../UnwindCreateVisitor.ts | 125 ++++++++++-------- .../translate/create-connect-and-params.ts | 2 +- .../create-connect-or-create-and-params.ts | 12 +- .../src/translate/create-delete-and-params.ts | 2 +- .../translate/create-disconnect-and-params.ts | 2 +- .../create-projection-and-params.test.ts | 4 +- .../translate/create-projection-and-params.ts | 28 ++-- .../src/translate/create-update-and-params.ts | 2 +- .../aggregation-sub-queries.ts | 18 +-- .../create-field-aggregation.ts | 4 +- .../elements/create-datetime-element.test.ts | 4 +- .../elements/create-datetime-element.ts | 2 +- .../elements/create-point-element.test.ts | 4 +- .../elements/create-point-element.ts | 4 +- ...create-relationship-property-value.test.ts | 6 +- .../subquery/create-projection-subquery.ts | 2 +- .../translate-cypher-directive-projection.ts | 14 +- .../CypherUnionAttributePartial.ts | 2 +- .../CypherAnnotationSubqueryGenerator.ts | 2 +- .../queryAST/factory/OperationFactory.ts | 1 - .../graphql/src/translate/translate-create.ts | 2 +- .../graphql/src/translate/translate-delete.ts | 2 +- .../translate/translate-resolve-reference.ts | 2 +- .../translate/translate-top-level-cypher.ts | 8 +- .../graphql/src/translate/translate-update.ts | 12 +- .../src/translate/utils/callback-utils.ts | 4 +- .../src/translate/utils/stringify-object.ts | 8 +- .../create-connection-where-and-params.ts | 2 +- .../where/create-where-and-params.ts | 2 +- yarn.lock | 1 - 39 files changed, 234 insertions(+), 271 deletions(-) rename packages/graphql/src/translate/batch-create/GraphQLInputAST/{AST.ts => UnwindASTNode.ts} (70%) diff --git a/packages/graphql/package.json b/packages/graphql/package.json index dbdbd406a64..3a88661cf34 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -102,8 +102,7 @@ "jose": "^5.0.0", "pluralize": "^8.0.0", "semver": "^7.5.4", - "typescript-memoize": "^1.1.1", - "uuid": "^9.0.0" + "typescript-memoize": "^1.1.1" }, "peerDependencies": { "graphql": "^16.0.0", diff --git a/packages/graphql/src/translate/authorization/compatibility/compile-predicate-return.ts b/packages/graphql/src/translate/authorization/compatibility/compile-predicate-return.ts index dfac8b304fa..14f67bae1e5 100644 --- a/packages/graphql/src/translate/authorization/compatibility/compile-predicate-return.ts +++ b/packages/graphql/src/translate/authorization/compatibility/compile-predicate-return.ts @@ -44,7 +44,7 @@ export function compilePredicateReturn( let subqueries: string | undefined; if (predicate) { - const predicateCypher = new Cypher.RawCypher((env) => { + const predicateCypher = new Cypher.Raw((env) => { const predicateStr = compileCypher(predicate, env); if (preComputedSubqueries && !preComputedSubqueries.empty) { // Assign the Cypher string to a variable outside of the scope of the compilation diff --git a/packages/graphql/src/translate/batch-create/GraphQLInputAST/CreateAST.ts b/packages/graphql/src/translate/batch-create/GraphQLInputAST/CreateAST.ts index fd1829f564e..672fb01a4a5 100644 --- a/packages/graphql/src/translate/batch-create/GraphQLInputAST/CreateAST.ts +++ b/packages/graphql/src/translate/batch-create/GraphQLInputAST/CreateAST.ts @@ -17,21 +17,21 @@ * limitations under the License. */ -import type { Visitor, ICreateAST } from "./types"; +import type { Visitor } from "./types"; import type { Node } from "../../../classes"; -import { AST } from "./AST"; +import { UnwindASTNode } from "./UnwindASTNode"; -export class CreateAST extends AST implements ICreateAST { +export class CreateAST extends UnwindASTNode { nodeProperties: string[]; node: Node; - constructor(nodeProperties: string[], node: Node) { - super(); + constructor(id: number, nodeProperties: string[], node: Node) { + super(id); this.nodeProperties = nodeProperties; this.node = node; } - accept(visitor: Visitor): void { - visitor.visitCreate(this); + accept(visitor: Visitor): T { + return visitor.visitCreate(this); } } diff --git a/packages/graphql/src/translate/batch-create/GraphQLInputAST/GraphQLInputAST.ts b/packages/graphql/src/translate/batch-create/GraphQLInputAST/GraphQLInputAST.ts index b697050283c..38cc847d7a3 100644 --- a/packages/graphql/src/translate/batch-create/GraphQLInputAST/GraphQLInputAST.ts +++ b/packages/graphql/src/translate/batch-create/GraphQLInputAST/GraphQLInputAST.ts @@ -17,9 +17,9 @@ * limitations under the License. */ -import { AST } from "./AST"; +import { UnwindASTNode } from "./UnwindASTNode"; import { CreateAST } from "./CreateAST"; import { NestedCreateAST } from "./NestedCreateAST"; -export { AST, CreateAST, NestedCreateAST }; -export type { IAST, IConnectAST, IConnectOrCreateAST, ICreateAST, INestedCreateAST, Visitor } from "./types"; +export { UnwindASTNode, CreateAST, NestedCreateAST }; +export type { Visitor } from "./types"; diff --git a/packages/graphql/src/translate/batch-create/GraphQLInputAST/NestedCreateAST.ts b/packages/graphql/src/translate/batch-create/GraphQLInputAST/NestedCreateAST.ts index f4a2c6bf0fb..a664b0334b8 100644 --- a/packages/graphql/src/translate/batch-create/GraphQLInputAST/NestedCreateAST.ts +++ b/packages/graphql/src/translate/batch-create/GraphQLInputAST/NestedCreateAST.ts @@ -17,12 +17,11 @@ * limitations under the License. */ -import type { RelationField } from "../../../types"; -import type { Visitor, INestedCreateAST } from "./types"; +import type { Visitor } from "./types"; +import { UnwindASTNode } from "./UnwindASTNode"; import type { Node, Relationship } from "../../../classes"; -import { AST } from "./AST"; - -export class NestedCreateAST extends AST implements INestedCreateAST { +import type { RelationField } from "../../../types"; +export class NestedCreateAST extends UnwindASTNode { node: Node; parent: Node; nodeProperties: string[]; @@ -32,6 +31,7 @@ export class NestedCreateAST extends AST implements INestedCreateAST { edge: Relationship | undefined; constructor( + id: number, node: Node, parent: Node, nodeProperties: string[], @@ -40,7 +40,7 @@ export class NestedCreateAST extends AST implements INestedCreateAST { relationship: [RelationField | undefined, Node[]], edge?: Relationship ) { - super(); + super(id); this.node = node; this.parent = parent; this.nodeProperties = nodeProperties; @@ -50,7 +50,7 @@ export class NestedCreateAST extends AST implements INestedCreateAST { this.edge = edge; } - accept(visitor: Visitor): void { - visitor.visitNestedCreate(this); + accept(visitor: Visitor): T { + return visitor.visitNestedCreate(this); } } diff --git a/packages/graphql/src/translate/batch-create/GraphQLInputAST/AST.ts b/packages/graphql/src/translate/batch-create/GraphQLInputAST/UnwindASTNode.ts similarity index 70% rename from packages/graphql/src/translate/batch-create/GraphQLInputAST/AST.ts rename to packages/graphql/src/translate/batch-create/GraphQLInputAST/UnwindASTNode.ts index a40b3786360..2011428398c 100644 --- a/packages/graphql/src/translate/batch-create/GraphQLInputAST/AST.ts +++ b/packages/graphql/src/translate/batch-create/GraphQLInputAST/UnwindASTNode.ts @@ -17,16 +17,18 @@ * limitations under the License. */ -import type { IAST, Visitor } from "./types"; -import { v4 as uuidv4 } from "uuid"; +import type { Visitor } from "./types"; -export abstract class AST implements IAST { - id = uuidv4(); - children: IAST[] = []; +export abstract class UnwindASTNode { + public id: number; + public children: UnwindASTNode[] = []; - addChildren(node: IAST): void { + constructor(id: number) { + this.id = id; + } + addChildren(node: UnwindASTNode): void { this.children.push(node); } - abstract accept(visitor: Visitor): void; + abstract accept(visitor: Visitor): T; } diff --git a/packages/graphql/src/translate/batch-create/GraphQLInputAST/types.ts b/packages/graphql/src/translate/batch-create/GraphQLInputAST/types.ts index bcae7a6525d..cf2f2619bbc 100644 --- a/packages/graphql/src/translate/batch-create/GraphQLInputAST/types.ts +++ b/packages/graphql/src/translate/batch-create/GraphQLInputAST/types.ts @@ -17,51 +17,10 @@ * limitations under the License. */ -import type { TreeDescriptor } from "../types"; -import type { RelationField } from "../../../types"; -import type { Node, Relationship } from "../../../classes"; +import type { CreateAST } from "./CreateAST"; +import type { NestedCreateAST } from "./NestedCreateAST"; -export interface IAST { - id: string; - children: IAST[]; - addChildren: (children: IAST) => void; - accept: (visitor: Visitor) => void; -} - -export interface IConnectAST extends IAST { - node: Node; - parent: Node; - edgeProperties: string[]; - where: TreeDescriptor; - connect: TreeDescriptor; - relationshipPropertyPath: string; - relationship: [RelationField | undefined, Node[]]; -} - -export interface IConnectOrCreateAST extends IAST { - parent: Node; - where: TreeDescriptor; - onCreate: TreeDescriptor; -} - -export interface ICreateAST extends IAST { - nodeProperties: string[]; - node: Node; -} - -export interface INestedCreateAST extends IAST { - node: Node; - parent: Node; - nodeProperties: string[]; - edgeProperties: string[]; - relationshipPropertyPath: string; - relationship: [RelationField | undefined, Node[]]; - edge: Relationship | undefined; -} - -export interface Visitor { - visitCreate: (create: ICreateAST) => void; - visitNestedCreate: (nestedCreate: INestedCreateAST) => void; - // visitConnect: (connect: IConnectAST) => void; - // visitConnectOrCreate: (connectOrCreate: IConnectOrCreateAST) => void; +export interface Visitor { + visitCreate: (create: CreateAST) => T; + visitNestedCreate: (nestedCreate: NestedCreateAST) => T; } diff --git a/packages/graphql/src/translate/batch-create/parser.ts b/packages/graphql/src/translate/batch-create/parser.ts index 5042a5f12ea..011170870ca 100644 --- a/packages/graphql/src/translate/batch-create/parser.ts +++ b/packages/graphql/src/translate/batch-create/parser.ts @@ -23,7 +23,7 @@ import { UnsupportedUnwindOptimization } from "./types"; import type { GraphElement, Node, Relationship } from "../../classes"; import { Neo4jGraphQLError } from "../../classes"; import Cypher from "@neo4j/cypher-builder"; -import type { AST } from "./GraphQLInputAST/GraphQLInputAST"; +import type { UnwindASTNode } from "./GraphQLInputAST/GraphQLInputAST"; import { CreateAST, NestedCreateAST } from "./GraphQLInputAST/GraphQLInputAST"; import mapToDbProperty from "../../utils/map-to-db-property"; import type { Neo4jGraphQLTranslationContext } from "../../types/neo4j-graphql-translation-context"; @@ -40,7 +40,10 @@ function getRelationshipFields( if (relationField.interface || relationField.union) { throw new UnsupportedUnwindOptimization(`Not supported operation: Interface or Union`); } else { - refNodes.push(context.nodes.find((x) => x.name === relationField.typeMeta.name) as Node); + const node = context.nodes.find((x) => x.name === relationField.typeMeta.name); + if (node) { + refNodes.push(node); + } } } return [relationField, refNodes]; @@ -60,51 +63,41 @@ export function inputTreeToCypherMap( ) ); } - const properties = (Object.entries(input) as GraphQLCreateInput).reduce( + const properties = Object.entries(input).reduce( (obj: Record, [key, value]: [string, Record]) => { const [relationField, relatedNodes] = getRelationshipFields(node, key, context); if (relationField && relationField.properties) { - relationship = context.relationships.find( - (x) => x.properties === relationField.properties - ) as unknown as Relationship; + relationship = context.relationships.find((x) => x.properties === relationField.properties); } let scalarOrEnum = false; if (parentKey === "edge") { - scalarOrEnum = isScalarOrEnum(key, relationship as Relationship); + if (!relationship) { + throw new Error("Transpile error: relationship expected to be defined"); + } + scalarOrEnum = isScalarOrEnum(key, relationship); } // it assume that if parentKey is not defined then it means that the key belong to a Node else if (parentKey === "node" || parentKey === undefined) { scalarOrEnum = isScalarOrEnum(key, node); } if (typeof value === "object" && value !== null && (relationField || !scalarOrEnum)) { + const nodeInput = relationField ? (relatedNodes[0] as Node) : node; if (Array.isArray(value)) { obj[key] = new Cypher.List( value.map((GraphQLCreateInput: GraphQLCreateInput) => - inputTreeToCypherMap( - GraphQLCreateInput, - relationField ? (relatedNodes[0] as Node) : node, - context, - key, - relationship - ) + inputTreeToCypherMap(GraphQLCreateInput, nodeInput, context, key, relationship) ) ); return obj; } - obj[key] = inputTreeToCypherMap( - value as GraphQLCreateInput[] | GraphQLCreateInput, - relationField ? (relatedNodes[0] as Node) : node, - context, - key, - relationship - ) as Cypher.Map; + obj[key] = inputTreeToCypherMap(value, nodeInput, context, key, relationship); return obj; } obj[key] = new Cypher.Param(value); return obj; }, - {} as Record - ) as Record; + {} + ); return new Cypher.Map(properties); } @@ -127,18 +120,19 @@ export function getTreeDescriptor( parentKey?: string, relationship?: Relationship ): TreeDescriptor { - return Object.entries(input).reduce( + return Object.entries(input).reduce( (previous, [key, value]) => { const [relationField, relatedNodes] = getRelationshipFields(node, key, context); if (relationField && relationField.properties) { - relationship = context.relationships.find( - (x) => x.properties === relationField.properties - ) as unknown as Relationship; + relationship = context.relationships.find((x) => x.properties === relationField.properties); } let scalarOrEnum = false; if (parentKey === "edge") { - scalarOrEnum = isScalarOrEnum(key, relationship as Relationship); + if (!relationship) { + throw new Error("Transpile error: relationship expected to be defined"); + } + scalarOrEnum = isScalarOrEnum(key, relationship); } // it assume that if parentKey is not defined then it means that the key belong to a Node else if (parentKey === "node" || parentKey === undefined) { @@ -150,25 +144,17 @@ export function getTreeDescriptor( if (Array.isArray(value)) { previous.children[key] = mergeTreeDescriptors( - value.map((el) => - getTreeDescriptor(el as GraphQLCreateInput, innerNode, context, key, relationship) - ) + value.map((el) => getTreeDescriptor(el, innerNode, context, key, relationship)) ); return previous; } - previous.children[key] = getTreeDescriptor( - value as GraphQLCreateInput, - innerNode, - context, - key, - relationship - ); + previous.children[key] = getTreeDescriptor(value, innerNode, context, key, relationship); return previous; } previous.properties.add(key); return previous; }, - { properties: new Set(), children: {} } as TreeDescriptor + { properties: new Set(), children: {} } ); } @@ -178,30 +164,41 @@ export function mergeTreeDescriptors(input: TreeDescriptor[]): TreeDescriptor { previous.properties = new Set([...previous.properties, ...node.properties]); const entries = [...new Set([...Object.keys(previous.children), ...Object.keys(node.children)])].map( (childrenKey) => { - const previousChildren: TreeDescriptor = - previous.children[childrenKey] ?? ({ properties: new Set(), children: {} } as TreeDescriptor); - const nodeChildren: TreeDescriptor = - node.children[childrenKey] ?? ({ properties: new Set(), children: {} } as TreeDescriptor); + const previousChildren: TreeDescriptor = previous.children[childrenKey] ?? { + properties: new Set(), + children: {}, + }; + const nodeChildren: TreeDescriptor = node.children[childrenKey] ?? { + properties: new Set(), + children: {}, + }; return [childrenKey, mergeTreeDescriptors([previousChildren, nodeChildren])]; } ); previous.children = Object.fromEntries(entries); return previous; }, - { properties: new Set(), children: {} } as TreeDescriptor + { properties: new Set(), children: {} } ); } -function parser(input: TreeDescriptor, node: Node, context: Neo4jGraphQLTranslationContext, parentASTNode: AST): AST { +function parser( + input: TreeDescriptor, + node: Node, + context: Neo4jGraphQLTranslationContext, + parentASTNode: UnwindASTNode, + counter: number +): UnwindASTNode { Object.entries(input.children).forEach(([key, value]) => { const [relationField, relatedNodes] = getRelationshipFields(node, key, context); if (relationField) { let edge; if (relationField.properties) { - edge = context.relationships.find( - (x) => x.properties === relationField.properties - ) as unknown as Relationship; + edge = context.relationships.find((x) => x.properties === relationField.properties); + if (!edge) { + throw new Error("Transpile error: relationship expected to be defined"); + } } if (relationField.interface || relationField.union) { throw new UnsupportedUnwindOptimization(`Not supported operation: Interface or Union`); @@ -217,6 +214,7 @@ function parser(input: TreeDescriptor, node: Node, context: Neo4jGraphQLTranslat node, key, [relationField, relatedNodes], + counter++, edge ) ); @@ -266,12 +264,12 @@ function raiseOnNotSupportedProperty(graphElement: GraphElement) { }); } -export function parseCreate(input: TreeDescriptor, node: Node, context: Neo4jGraphQLTranslationContext) { +export function parseCreate(input: TreeDescriptor, node: Node, context: Neo4jGraphQLTranslationContext, counter = 0) { const nodeProperties = input.properties; raiseOnNotSupportedProperty(node); raiseAttributeAmbiguity(input.properties, node); - const createAST = new CreateAST([...nodeProperties], node); - parser(input, node, context, createAST); + const createAST = new CreateAST(counter++, [...nodeProperties], node); + parser(input, node, context, createAST, counter); return createAST; } @@ -282,9 +280,16 @@ function parseNestedCreate( parentNode: Node, relationshipPropertyPath: string, relationship: [RelationField | undefined, Node[]], + counter: number, edge?: Relationship ) { - const nodeProperties = (input.children.node as TreeDescriptor).properties; + if (!relationship[0]) { + throw new Error("what?"); + } + if (!input.children.node) { + throw new Error("Transpile error: node expected to be defined"); + } + const nodeProperties = input.children.node.properties; const edgeProperties = input.children.edge ? input.children.edge.properties : []; raiseOnNotSupportedProperty(node); raiseAttributeAmbiguity(nodeProperties, node); @@ -294,6 +299,7 @@ function parseNestedCreate( } const nestedCreateAST = new NestedCreateAST( + counter++, node, parentNode, [...nodeProperties], @@ -303,7 +309,7 @@ function parseNestedCreate( edge ); if (input.children.node) { - parser(input.children.node, node, context, nestedCreateAST); + parser(input.children.node, node, context, nestedCreateAST, counter); } return nestedCreateAST; } diff --git a/packages/graphql/src/translate/batch-create/types.ts b/packages/graphql/src/translate/batch-create/types.ts index 669f727c2aa..014a0782582 100644 --- a/packages/graphql/src/translate/batch-create/types.ts +++ b/packages/graphql/src/translate/batch-create/types.ts @@ -22,7 +22,7 @@ export type GraphQLCreateInput = Record; export interface TreeDescriptor { properties: Set; children: Record; - path: string; + path?: string; } export class UnsupportedUnwindOptimization extends Error { diff --git a/packages/graphql/src/translate/batch-create/unwind-create-visitors/UnwindCreateVisitor.ts b/packages/graphql/src/translate/batch-create/unwind-create-visitors/UnwindCreateVisitor.ts index 4e59ae6177f..04f095d691e 100644 --- a/packages/graphql/src/translate/batch-create/unwind-create-visitors/UnwindCreateVisitor.ts +++ b/packages/graphql/src/translate/batch-create/unwind-create-visitors/UnwindCreateVisitor.ts @@ -17,16 +17,9 @@ * limitations under the License. */ -import type { PredicateReturn, RelationField } from "../../../types"; +import type { PredicateReturn } from "../../../types"; import type { CallbackBucket } from "../../../classes/CallbackBucket"; -import type { - Visitor, - ICreateAST, - INestedCreateAST, - CreateAST, - NestedCreateAST, - IAST, -} from "../GraphQLInputAST/GraphQLInputAST"; +import type { Visitor, CreateAST, NestedCreateAST, UnwindASTNode } from "../GraphQLInputAST/GraphQLInputAST"; import type { Node, Relationship } from "../../../classes"; import createRelationshipValidationString from "../../create-relationship-validation-string"; import { filterTruthy } from "../../../utils/utils"; @@ -44,12 +37,11 @@ import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphq type UnwindCreateScopeDefinition = { unwindVar: Cypher.Variable; parentVar: Cypher.Variable; - clause?: Cypher.Clause; }; type GraphQLInputASTNodeRef = string; type UnwindCreateEnvironment = Record; -export class UnwindCreateVisitor implements Visitor { +export class UnwindCreateVisitor implements Visitor { unwindVar: Cypher.Variable; callbackBucket: CallbackBucket; context: Neo4jGraphQLTranslationContext; @@ -64,25 +56,23 @@ export class UnwindCreateVisitor implements Visitor { this.environment = {}; } - visitChildren( - currentASTNode: IAST, + public visitChildren( + currentASTNode: UnwindASTNode, unwindVar: Cypher.Variable, parentVar: Cypher.Variable - ): (Cypher.Clause | undefined)[] { + ): Cypher.Clause[] { if (currentASTNode.children) { + const scope = { unwindVar, parentVar }; const childrenRefs = currentASTNode.children.map((children) => { - this.environment[children.id] = { unwindVar, parentVar }; - children.accept(this); - return children.id; + this.environment[children.id] = scope; + return children.accept(this); }); - return childrenRefs.map( - (childrenRef) => (this.environment[childrenRef] as UnwindCreateScopeDefinition).clause - ); + return childrenRefs; } return []; } - visitCreate(create: ICreateAST): void { + public visitCreate(create: CreateAST): Cypher.Clause { const labels = create.node.getLabels(this.context); const currentNode = new Cypher.Node({ labels, @@ -97,13 +87,13 @@ export class UnwindCreateVisitor implements Visitor { const createClause = new Cypher.Create(currentNode).set(...setProperties, ...autogeneratedProperties); - const relationshipValidationClause = new Cypher.RawCypher((env: Cypher.Environment) => { + const relationshipValidationClause = new Cypher.Raw((env: Cypher.Environment) => { const validationStr = createRelationshipValidationString({ node: create.node, context: this.context, varName: env.getReferenceId(currentNode), }); - const cypher = [] as string[]; + const cypher: string[] = []; if (validationStr) { cypher.push(`WITH ${env.getReferenceId(currentNode)}`); @@ -150,11 +140,14 @@ export class UnwindCreateVisitor implements Visitor { ); this.rootNode = currentNode; this.clause = new Cypher.Call(clause).innerWith(this.unwindVar); + return this.clause; } - visitNestedCreate(nestedCreate: INestedCreateAST): void { - const parentVar = (this.environment[nestedCreate.id] as UnwindCreateScopeDefinition).parentVar; - const unwindVar = (this.environment[nestedCreate.id] as UnwindCreateScopeDefinition).unwindVar; + public visitNestedCreate(nestedCreate: NestedCreateAST): Cypher.Clause { + const scope = this.getScope(nestedCreate.id); + + const parentVar = scope.parentVar; + const unwindVar = scope.unwindVar; const { node, relationship, relationshipPropertyPath } = nestedCreate; const blockWith = new Cypher.With(parentVar, unwindVar); const createUnwindVar = new Cypher.Variable(); @@ -178,7 +171,8 @@ export class UnwindCreateVisitor implements Visitor { const nestedClauses = this.visitChildren(nestedCreate, nodeVar, currentNode); const createClause = new Cypher.Create(currentNode); - const relationField = relationship[0] as RelationField; + const relationField = relationship[0]; + if (!relationField) throw new Error("Transpile error: No relationship found"); const relationshipVar = new Cypher.Relationship({ type: relationField.type }); @@ -200,29 +194,36 @@ export class UnwindCreateVisitor implements Visitor { createClause.set(...setPropertiesNode, ...autogeneratedProperties); if (nestedCreate.edgeProperties && nestedCreate.edgeProperties.length && nestedCreate.edge) { - const setPropertiesEdge = nestedCreate.edgeProperties.map((property) => { - return fieldToSetParam( - nestedCreate.edge as Relationship, - relationshipVar, - property, - edgeVar.property(property) - ); - }); + const setPropertiesEdge = nestedCreate.edgeProperties + .map((property) => { + if (nestedCreate.edge) { + return fieldToSetParam( + nestedCreate.edge, + relationshipVar, + property, + edgeVar.property(property) + ); + } + }) + .filter((v): v is Cypher.SetParam => !!v); const autogeneratedEdgeProperties = getAutoGeneratedFields(nestedCreate.edge, relationshipVar); mergeClause.set(...setPropertiesEdge, ...autogeneratedEdgeProperties); } - const subQueryStatements = [blockWith, createUnwindClause, withCreate, createClause, mergeClause] as ( - | undefined - | Cypher.Clause - )[]; - const relationshipValidationClause = new Cypher.RawCypher((env: Cypher.Environment) => { + const subQueryStatements: Cypher.Clause[] = [ + blockWith, + createUnwindClause, + withCreate, + createClause, + mergeClause, + ]; + const relationshipValidationClause = new Cypher.Raw((env: Cypher.Environment) => { const validationStr = createRelationshipValidationString({ node, context: this.context, varName: env.getReferenceId(currentNode), }); - const cypher = [] as string[]; + const cypher: string[] = []; if (validationStr) { cypher.push(`WITH ${env.getReferenceId(currentNode)}`); cypher.push(validationStr); @@ -257,18 +258,20 @@ export class UnwindCreateVisitor implements Visitor { } subQueryStatements.push(...nestedClauses); - subQueryStatements.push(authNodeClause); - subQueryStatements.push(authorizationFieldsClause); + if (authNodeClause) { + subQueryStatements.push(authNodeClause); + } + if (authorizationFieldsClause) { + subQueryStatements.push(authorizationFieldsClause); + } + subQueryStatements.push(relationshipValidationClause); - subQueryStatements.push(new Cypher.Return([Cypher.collect(new Cypher.Literal(null)), new Cypher.Variable()])); + subQueryStatements.push(new Cypher.Return([Cypher.collect(Cypher.Null), new Cypher.Variable()])); const subQuery = Cypher.concat(...subQueryStatements); const callClause = new Cypher.Call(subQuery); const outsideWith = new Cypher.With(parentVar, unwindVar); - (this.environment[nestedCreate.id] as UnwindCreateScopeDefinition).clause = Cypher.concat( - outsideWith, - callClause - ); + return Cypher.concat(outsideWith, callClause); } private getAuthNodeClause( @@ -358,10 +361,18 @@ export class UnwindCreateVisitor implements Visitor { }; } + public getScope(identifier: number): UnwindCreateScopeDefinition { + const scope = this.environment[identifier]; + if (!scope) { + throw new Error("Transpile error: No scope found"); + } + return scope; + } + /* * Returns the Cypher Reference of the root Nodes and the Cypher Clause generated */ - build(): [Cypher.Node?, Cypher.Clause?] { + public build(): [Cypher.Node?, Cypher.Clause?] { return [this.rootNode, this.clause]; } } @@ -376,19 +387,17 @@ function getAutoGeneratedFields( ); timestampedFields.forEach((field) => { // DateTime -> datetime(); Time -> time() - const relatedCypherExpression = Cypher[field.typeMeta.name.toLowerCase()]() as Cypher.Expr; - setParams.push([ - cypherNodeRef.property(field.dbPropertyName as string), - relatedCypherExpression, - ] as Cypher.SetParam); + const relatedCypherExpression = Cypher[field.typeMeta.name.toLowerCase()](); + if (field.dbPropertyName) { + setParams.push([cypherNodeRef.property(field.dbPropertyName), relatedCypherExpression]); + } }); const autogeneratedIdFields = graphQLElement.primitiveFields.filter((x) => x.autogenerate); autogeneratedIdFields.forEach((field) => { - setParams.push([ - cypherNodeRef.property(field.dbPropertyName as string), - Cypher.randomUUID(), - ] as Cypher.SetParam); + if (field.dbPropertyName) { + setParams.push([cypherNodeRef.property(field.dbPropertyName), Cypher.randomUUID()]); + } }); return setParams; } diff --git a/packages/graphql/src/translate/create-connect-and-params.ts b/packages/graphql/src/translate/create-connect-and-params.ts index 822e3c71824..a7f8ef9b390 100644 --- a/packages/graphql/src/translate/create-connect-and-params.ts +++ b/packages/graphql/src/translate/create-connect-and-params.ts @@ -205,7 +205,7 @@ function createConnectAndParams({ const predicate = `${whereStrs.join(" AND ")}`; if (aggregationWhere) { const columns = [new Cypher.NamedVariable(nodeName)]; - const caseWhereClause = caseWhere(new Cypher.RawCypher(predicate), columns); + const caseWhereClause = caseWhere(new Cypher.Raw(predicate), columns); const { cypher } = caseWhereClause.build("aggregateWhereFilter"); subquery.push(cypher); } else { diff --git a/packages/graphql/src/translate/create-connect-or-create-and-params.ts b/packages/graphql/src/translate/create-connect-or-create-and-params.ts index 4f73106d286..e1496af49cb 100644 --- a/packages/graphql/src/translate/create-connect-or-create-and-params.ts +++ b/packages/graphql/src/translate/create-connect-or-create-and-params.ts @@ -104,7 +104,7 @@ export function createConnectOrCreateAndParams({ const wrappedQueries = statements.map((statement) => { const returnStatement = context.subscriptionsEnabled ? new Cypher.Return([new Cypher.NamedVariable("meta"), "update_meta"]) - : new Cypher.Return([Cypher.count(new Cypher.RawCypher("*")), "_"]); + : new Cypher.Return([Cypher.count(new Cypher.Raw("*")), "_"]); const withStatement = new Cypher.With(...withVarsVariables); @@ -250,7 +250,7 @@ function mergeStatement({ const callbackFields = getCallbackFields(refNode); const callbackParams = callbackFields - .map((callbackField): [Cypher.Property, Cypher.RawCypher] | [] => { + .map((callbackField): [Cypher.Property, Cypher.Raw] | [] => { const varNameVariable = new Cypher.NamedVariable(varName); return addCallbackAndSetParamCypher( callbackField, @@ -261,7 +261,7 @@ function mergeStatement({ node ); }) - .filter((tuple) => tuple.length !== 0) as [Cypher.Property, Cypher.RawCypher][]; + .filter((tuple) => tuple.length !== 0) as [Cypher.Property, Cypher.Raw][]; const rawNodeParams = { ...unsetAutogeneratedParams, @@ -304,7 +304,7 @@ function mergeStatement({ relationField.direction === "IN" ? [refNode.name, parentRefNode.name] : [parentRefNode.name, refNode.name]; const [fromNode, toNode] = relationField.direction === "IN" ? [node, parentNode] : [parentNode, node]; - withClause = new Cypher.RawCypher((env: Cypher.Environment) => { + withClause = new Cypher.Raw((env: Cypher.Environment) => { const eventWithMetaStr = createConnectionEventMeta({ event: "create_relationship", relVariable: compileCypher(relationship, env), @@ -443,7 +443,7 @@ function getAutogeneratedParams(node: Node | Relationship): Record f.autogenerate) .reduce((acc, field) => { if (field.dbPropertyName) { - acc[field.dbPropertyName] = new Cypher.RawCypher("randomUUID()"); + acc[field.dbPropertyName] = new Cypher.Raw("randomUUID()"); } return acc; }, {}); @@ -452,7 +452,7 @@ function getAutogeneratedParams(node: Node | Relationship): Record ["DateTime", "Time"].includes(field.typeMeta.name) && field.timestamps?.includes("CREATE")) .reduce((acc, field) => { if (field.dbPropertyName) { - acc[field.dbPropertyName] = new Cypher.RawCypher(`${field.typeMeta.name.toLowerCase()}()`); + acc[field.dbPropertyName] = new Cypher.Raw(`${field.typeMeta.name.toLowerCase()}()`); } return acc; }, {}); diff --git a/packages/graphql/src/translate/create-delete-and-params.ts b/packages/graphql/src/translate/create-delete-and-params.ts index 3374dab1b26..0103ed0d05c 100644 --- a/packages/graphql/src/translate/create-delete-and-params.ts +++ b/packages/graphql/src/translate/create-delete-and-params.ts @@ -180,7 +180,7 @@ function createDeleteAndParams({ new Cypher.NamedVariable(relationshipVariable), new Cypher.NamedVariable(variableName), ]; - const caseWhereClause = caseWhere(new Cypher.RawCypher(predicate), columns); + const caseWhereClause = caseWhere(new Cypher.Raw(predicate), columns); const { cypher } = caseWhereClause.build("aggregateWhereFilter"); innerStrs.push(cypher); } else { diff --git a/packages/graphql/src/translate/create-disconnect-and-params.ts b/packages/graphql/src/translate/create-disconnect-and-params.ts index f147b7dc70f..5d2032bacf2 100644 --- a/packages/graphql/src/translate/create-disconnect-and-params.ts +++ b/packages/graphql/src/translate/create-disconnect-and-params.ts @@ -140,7 +140,7 @@ function createDisconnectAndParams({ const predicate = `${whereStrs.join(" AND ")}`; if (aggregationWhere) { const columns = [new Cypher.NamedVariable(relVarName), new Cypher.NamedVariable(variableName)]; - const caseWhereClause = caseWhere(new Cypher.RawCypher(predicate), columns); + const caseWhereClause = caseWhere(new Cypher.Raw(predicate), columns); const { cypher } = caseWhereClause.build("aggregateWhereFilter"); subquery.push(cypher); } else { diff --git a/packages/graphql/src/translate/create-projection-and-params.test.ts b/packages/graphql/src/translate/create-projection-and-params.test.ts index df0e46db925..f114d3ce6cc 100644 --- a/packages/graphql/src/translate/create-projection-and-params.test.ts +++ b/packages/graphql/src/translate/create-projection-and-params.test.ts @@ -118,7 +118,7 @@ describe("createProjectionAndParams", () => { varName: new Cypher.NamedNode("this"), cypherFieldAliasMap: {}, }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(result.projection, env)).toBe(`{ .title }`); return ""; }).build(); @@ -213,7 +213,7 @@ describe("createProjectionAndParams", () => { varName: new Cypher.NamedNode("this"), cypherFieldAliasMap: {}, }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(result.projection, env)).toBe(`{ .title }`); return ""; }).build(); diff --git a/packages/graphql/src/translate/create-projection-and-params.ts b/packages/graphql/src/translate/create-projection-and-params.ts index f643c87562f..45f037bd591 100644 --- a/packages/graphql/src/translate/create-projection-and-params.ts +++ b/packages/graphql/src/translate/create-projection-and-params.ts @@ -196,7 +196,7 @@ export default function createProjectionAndParams({ const direction = getCypherRelationshipDirection(relationField, field.args); - const nestedProjection = new Cypher.RawCypher((env) => { + const nestedProjection = new Cypher.Raw((env) => { // The nested projection will be surrounded by brackets, so we want to remove // any linebreaks, and then the first opening and the last closing bracket of the line, // as well as any surrounding whitespace. @@ -241,9 +241,7 @@ export default function createProjectionAndParams({ const unionAndSort = Cypher.concat(new Cypher.Call(unionClause), collectAndLimitStatements); res.subqueries.push(new Cypher.Call(unionAndSort).innerWith(parentNode)); - res.projection.push( - new Cypher.RawCypher((env) => `${alias}: ${compileCypher(subqueryReturnAlias, env)}`) - ); + res.projection.push(new Cypher.Raw((env) => `${alias}: ${compileCypher(subqueryReturnAlias, env)}`)); return res; } @@ -280,7 +278,7 @@ export default function createProjectionAndParams({ nestedPredicates: recurse.predicates, }); res.subqueries.push(new Cypher.Call(subquery).innerWith(varName)); - res.projection.push(new Cypher.RawCypher((env) => `${alias}: ${compileCypher(subqueryReturnAlias, env)}`)); + res.projection.push(new Cypher.Raw((env) => `${alias}: ${compileCypher(subqueryReturnAlias, env)}`)); return res; } @@ -296,9 +294,7 @@ export default function createProjectionAndParams({ res.subqueries.push(aggregationFieldProjection.projectionSubqueryCypher); } res.projection.push( - new Cypher.RawCypher( - (env) => `${alias}: ${compileCypher(aggregationFieldProjection.projectionCypher, env)}` - ) + new Cypher.Raw((env) => `${alias}: ${compileCypher(aggregationFieldProjection.projectionCypher, env)}`) ); return res; } @@ -317,21 +313,21 @@ export default function createProjectionAndParams({ ).innerWith(varName); res.subqueries.push(connectionClause); - res.projection.push(new Cypher.RawCypher((env) => `${field.alias}: ${compileCypher(returnVariable, env)}`)); + res.projection.push(new Cypher.Raw((env) => `${field.alias}: ${compileCypher(returnVariable, env)}`)); return res; } if (pointField) { const pointExpr = createPointExpression({ resolveTree: field, field: pointField, variable: varName }); - res.projection.push(new Cypher.RawCypher((env) => `${field.alias}: ${compileCypher(pointExpr, env)}`)); + res.projection.push(new Cypher.Raw((env) => `${field.alias}: ${compileCypher(pointExpr, env)}`)); } else if (temporalField?.typeMeta.name === "DateTime") { const datetimeExpr = createDatetimeExpression({ resolveTree: field, field: temporalField, variable: varName, }); - res.projection.push(new Cypher.RawCypher((env) => `${field.alias}: ${compileCypher(datetimeExpr, env)}`)); + res.projection.push(new Cypher.Raw((env) => `${field.alias}: ${compileCypher(datetimeExpr, env)}`)); } else { // In the case of using the @alias directive (map a GraphQL field to a db prop) // the output will be RETURN varName {GraphQLfield: varName.dbAlias} @@ -342,10 +338,10 @@ export default function createProjectionAndParams({ if (alias !== field.name || dbFieldName !== field.name || literalElements) { res.projection.push( - new Cypher.RawCypher((env) => `${alias}: ${compileCypher(varName.property(dbFieldName), env)}`) + new Cypher.Raw((env) => `${alias}: ${compileCypher(varName.property(dbFieldName), env)}`) ); } else { - res.projection.push(new Cypher.RawCypher(`.${dbFieldName}`)); + res.projection.push(new Cypher.Raw(`.${dbFieldName}`)); } } @@ -411,8 +407,8 @@ export default function createProjectionAndParams({ { projection: resolveType ? [ - new Cypher.RawCypher(`__resolveType: "${node.name}"`), - new Cypher.RawCypher((env) => `__id: id(${compileCypher(varName, env)})`), + new Cypher.Raw(`__resolveType: "${node.name}"`), + new Cypher.Raw((env) => `__id: id(${compileCypher(varName, env)})`), ] : [], params: {}, @@ -421,7 +417,7 @@ export default function createProjectionAndParams({ predicates: [], } ); - const projectionCypher = new Cypher.RawCypher((env) => { + const projectionCypher = new Cypher.Raw((env) => { return `{ ${projection.map((proj) => compileCypher(proj, env)).join(", ")} }`; }); return { diff --git a/packages/graphql/src/translate/create-update-and-params.ts b/packages/graphql/src/translate/create-update-and-params.ts index 0f136428d65..72eb9b1b215 100644 --- a/packages/graphql/src/translate/create-update-and-params.ts +++ b/packages/graphql/src/translate/create-update-and-params.ts @@ -263,7 +263,7 @@ export default function createUpdateAndParams({ new Cypher.NamedVariable(relationshipVariable), new Cypher.NamedVariable(variableName), ]; - const caseWhereClause = caseWhere(new Cypher.RawCypher(predicate), columns); + const caseWhereClause = caseWhere(new Cypher.Raw(predicate), columns); const { cypher } = caseWhereClause.build("aggregateWhereFilter"); innerUpdate.push(cypher); } else { diff --git a/packages/graphql/src/translate/field-aggregations/aggregation-sub-queries.ts b/packages/graphql/src/translate/field-aggregations/aggregation-sub-queries.ts index 35ebd487005..1c7d6965096 100644 --- a/packages/graphql/src/translate/field-aggregations/aggregation-sub-queries.ts +++ b/packages/graphql/src/translate/field-aggregations/aggregation-sub-queries.ts @@ -44,7 +44,7 @@ export function stringAggregationQuery( ): Cypher.Clause { const fieldPath = targetAlias.property(fieldName); - return new Cypher.RawCypher((env) => { + return new Cypher.Raw((env) => { const targetAliasCypher = compileCypher(targetAlias, env); const fieldPathCypher = compileCypher(fieldPath, env); @@ -61,9 +61,9 @@ export function numberAggregationQuery( fieldName: string, fieldRef: Cypher.Variable, targetAlias: Cypher.Node | Cypher.Relationship -): Cypher.RawCypher { +): Cypher.Raw { const fieldPath = targetAlias.property(fieldName); - return new Cypher.RawCypher((env) => { + return new Cypher.Raw((env) => { const fieldPathCypher = compileCypher(fieldPath, env); return dedent`${compileCypher(matchWherePattern, env)} @@ -79,9 +79,9 @@ export function defaultAggregationQuery( fieldName: string, fieldRef: Cypher.Variable, targetAlias: Cypher.Node | Cypher.Relationship -): Cypher.RawCypher { +): Cypher.Raw { const fieldPath = targetAlias.property(fieldName); - return new Cypher.RawCypher((env) => { + return new Cypher.Raw((env) => { const fieldPathCypher = compileCypher(fieldPath, env); return dedent`${compileCypher(matchWherePattern, env)} @@ -94,14 +94,14 @@ export function dateTimeAggregationQuery( fieldName: string, fieldRef: Cypher.Variable, targetAlias: Cypher.Node | Cypher.Relationship -): Cypher.RawCypher { +): Cypher.Raw { const fieldPath = targetAlias.property(fieldName); - return new Cypher.RawCypher((env) => { + return new Cypher.Raw((env) => { const fieldPathCypher = compileCypher(fieldPath, env); return dedent`${compileCypher(matchWherePattern, env)} RETURN ${stringifyObject({ - min: new Cypher.RawCypher(wrapApocConvertDate(`min(${fieldPathCypher})`)), - max: new Cypher.RawCypher(wrapApocConvertDate(`max(${fieldPathCypher})`)), + min: new Cypher.Raw(wrapApocConvertDate(`min(${fieldPathCypher})`)), + max: new Cypher.Raw(wrapApocConvertDate(`max(${fieldPathCypher})`)), }).getCypher(env)} AS ${compileCypher(fieldRef, env)}`; }); } diff --git a/packages/graphql/src/translate/field-aggregations/create-field-aggregation.ts b/packages/graphql/src/translate/field-aggregations/create-field-aggregation.ts index 87add712aeb..392f3a52167 100644 --- a/packages/graphql/src/translate/field-aggregations/create-field-aggregation.ts +++ b/packages/graphql/src/translate/field-aggregations/create-field-aggregation.ts @@ -165,7 +165,7 @@ export function createFieldAggregation({ return { projectionCypher: projectionMap, - projectionSubqueryCypher: projectionSubqueries || new Cypher.RawCypher(""), + projectionSubqueryCypher: projectionSubqueries || new Cypher.Raw(""), }; } @@ -204,7 +204,7 @@ function getAggregationProjectionAndSubqueries({ ); }); if (!innerProjectionSubqueries) { - innerProjectionSubqueries = new Cypher.RawCypher(""); + innerProjectionSubqueries = new Cypher.Raw(""); } return { innerProjectionMap, innerProjectionSubqueries }; } diff --git a/packages/graphql/src/translate/projection/elements/create-datetime-element.test.ts b/packages/graphql/src/translate/projection/elements/create-datetime-element.test.ts index 580d7d07ac8..6f38ab83306 100644 --- a/packages/graphql/src/translate/projection/elements/create-datetime-element.test.ts +++ b/packages/graphql/src/translate/projection/elements/create-datetime-element.test.ts @@ -44,7 +44,7 @@ describe("createDatetimeElement", () => { field, variable: new Cypher.NamedVariable("this"), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toBe( 'datetime: apoc.date.convertFormat(toString(this.datetime), "iso_zoned_date_time", "iso_offset_date_time")' ); @@ -73,7 +73,7 @@ describe("createDatetimeElement", () => { field, variable: new Cypher.NamedVariable("this"), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toBe( 'datetimes: [ dt in this.datetimes | apoc.date.convertFormat(toString(dt), "iso_zoned_date_time", "iso_offset_date_time") ]' ); diff --git a/packages/graphql/src/translate/projection/elements/create-datetime-element.ts b/packages/graphql/src/translate/projection/elements/create-datetime-element.ts index e157d8a9fa1..2e98435d2c7 100644 --- a/packages/graphql/src/translate/projection/elements/create-datetime-element.ts +++ b/packages/graphql/src/translate/projection/elements/create-datetime-element.ts @@ -35,7 +35,7 @@ export function createDatetimeElement({ valueOverride?: string; }): Cypher.Expr { const dbFieldName = field.dbPropertyName || resolveTree.name; - return new Cypher.RawCypher((env) => + return new Cypher.Raw((env) => field.typeMeta.array ? `${resolveTree.alias}: [ dt in ${compileCypher(variable, env)}.${dbFieldName} | ${wrapApocConvertDate( "dt" diff --git a/packages/graphql/src/translate/projection/elements/create-point-element.test.ts b/packages/graphql/src/translate/projection/elements/create-point-element.test.ts index 4f10db72bb2..6650bde1e62 100644 --- a/packages/graphql/src/translate/projection/elements/create-point-element.test.ts +++ b/packages/graphql/src/translate/projection/elements/create-point-element.test.ts @@ -60,7 +60,7 @@ describe("createPointElement", () => { variable: new Cypher.NamedVariable("this"), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toMatchInlineSnapshot(` "point: (CASE WHEN this.point IS NOT NULL THEN { point: this.point, crs: this.point.crs } @@ -107,7 +107,7 @@ describe("createPointElement", () => { field, variable: new Cypher.NamedVariable("this"), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toMatchInlineSnapshot(` "points: (CASE WHEN this.points IS NOT NULL THEN [p_var0 IN this.points | { point: p_var0, crs: p_var0.crs }] diff --git a/packages/graphql/src/translate/projection/elements/create-point-element.ts b/packages/graphql/src/translate/projection/elements/create-point-element.ts index a01f56c2748..9f6b82fa485 100644 --- a/packages/graphql/src/translate/projection/elements/create-point-element.ts +++ b/packages/graphql/src/translate/projection/elements/create-point-element.ts @@ -34,11 +34,11 @@ export default function createPointElement({ }): Cypher.Expr { const expression = createPointExpression({ resolveTree, field, variable }); - const cypherClause = new Cypher.RawCypher((env) => { + const cypherClause = new Cypher.Raw((env) => { return compileCypher(expression, env); }); const { cypher } = cypherClause.build("p_"); - return new Cypher.RawCypher(`${resolveTree.alias}: (${cypher})`); + return new Cypher.Raw(`${resolveTree.alias}: (${cypher})`); } export function createPointExpression({ diff --git a/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts b/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts index ccef42e7d37..2f8cbb36f9f 100644 --- a/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts +++ b/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts @@ -178,7 +178,7 @@ describe("createRelationshipPropertyElement", () => { relationship, relationshipVariable: new Cypher.Relationship(), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toMatchInlineSnapshot(`"this0.int"`); return ""; }).build(); @@ -197,7 +197,7 @@ describe("createRelationshipPropertyElement", () => { relationship, relationshipVariable: new Cypher.Relationship(), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toMatchInlineSnapshot( `"apoc.date.convertFormat(toString(this0.datetime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\")"` ); @@ -233,7 +233,7 @@ describe("createRelationshipPropertyElement", () => { relationship, relationshipVariable: new Cypher.Relationship(), }); - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { expect(compileCypher(element, env)).toMatchInlineSnapshot(` "CASE WHEN this0.point IS NOT NULL THEN { point: this0.point, crs: this0.point.crs } diff --git a/packages/graphql/src/translate/projection/subquery/create-projection-subquery.ts b/packages/graphql/src/translate/projection/subquery/create-projection-subquery.ts index 74e60538bd3..484d97b81db 100644 --- a/packages/graphql/src/translate/projection/subquery/create-projection-subquery.ts +++ b/packages/graphql/src/translate/projection/subquery/create-projection-subquery.ts @@ -73,7 +73,7 @@ export function createProjectionSubquery({ const subqueryMatch = new Cypher.Match(pattern); const predicates = nestedPredicates; - const projection = new Cypher.RawCypher((env) => { + const projection = new Cypher.Raw((env) => { // TODO: use MapProjection return `${compileCypher(targetNode, env)} ${compileCypher(nestedProjection, env)}`; }); diff --git a/packages/graphql/src/translate/projection/subquery/translate-cypher-directive-projection.ts b/packages/graphql/src/translate/projection/subquery/translate-cypher-directive-projection.ts index 4023a9efbf2..21d042eb0f7 100644 --- a/packages/graphql/src/translate/projection/subquery/translate-cypher-directive-projection.ts +++ b/packages/graphql/src/translate/projection/subquery/translate-cypher-directive-projection.ts @@ -86,7 +86,7 @@ export function translateCypherDirectiveProjection({ cypherFieldAliasMap, }); - projectionExpr = new Cypher.RawCypher((env) => { + projectionExpr = new Cypher.Raw((env) => { return `${compileCypher(resultVariable, env)} ${compileCypher(str, env)}`; }); res.params = { ...res.params, ...p }; @@ -137,7 +137,7 @@ export function translateCypherDirectiveProjection({ const withAndSubqueries = Cypher.concat(beforeCallWith, ...nestedSubqueries); subqueries.push(withAndSubqueries); } - const projection = new Cypher.RawCypher( + const projection = new Cypher.Raw( (env) => `{ __resolveType: "${refNode.name}", ${compileCypher(str, env).replace("{", "")}` ); unionProjections.push({ @@ -149,7 +149,7 @@ export function translateCypherDirectiveProjection({ res.params = { ...res.params, ...p }; } else { - const projection = new Cypher.RawCypher(() => `{ __resolveType: "${refNode.name}" }`); + const projection = new Cypher.Raw(() => `{ __resolveType: "${refNode.name}" }`); unionProjections.push({ projection, predicate: labelsSubPredicate, @@ -164,9 +164,7 @@ export function translateCypherDirectiveProjection({ projectionExpr .when(predicate) .then( - new Cypher.RawCypher( - (env) => `${compileCypher(resultVariable, env)} ${compileCypher(projection, env)}` - ) + new Cypher.Raw((env) => `${compileCypher(resultVariable, env)} ${compileCypher(projection, env)}`) ); } } @@ -212,7 +210,7 @@ export function translateCypherDirectiveProjection({ } const aliasVar = new Cypher.NamedVariable(alias); res.projection.push( - new Cypher.RawCypher((env) => `${compileCypher(aliasVar, env)}: ${compileCypher(resultVariable, env)}`) + new Cypher.Raw((env) => `${compileCypher(aliasVar, env)}: ${compileCypher(resultVariable, env)}`) ); return res; } @@ -229,7 +227,7 @@ function createCypherDirectiveSubquery({ extraArgs: Record; }): Cypher.Clause { const innerWithAlias = new Cypher.With([nodeRef, new Cypher.NamedNode("this")]); - const rawCypher = new Cypher.RawCypher((env) => { + const rawCypher = new Cypher.Raw((env) => { let statement = cypherField.statement; for (const [key, value] of Object.entries(extraArgs)) { const param = new Cypher.Param(value); diff --git a/packages/graphql/src/translate/queryAST/ast/fields/attribute-fields/CypherUnionAttributePartial.ts b/packages/graphql/src/translate/queryAST/ast/fields/attribute-fields/CypherUnionAttributePartial.ts index 87a94949303..07b22075074 100644 --- a/packages/graphql/src/translate/queryAST/ast/fields/attribute-fields/CypherUnionAttributePartial.ts +++ b/packages/graphql/src/translate/queryAST/ast/fields/attribute-fields/CypherUnionAttributePartial.ts @@ -55,7 +55,7 @@ export class CypherUnionAttributePartial extends QueryASTNode { // TODO: Refactor when `.hasLabel` on variables is supported in CypherBuilder const predicates = labels.map((label) => { - return new Cypher.RawCypher((env) => { + return new Cypher.Raw((env) => { const varName = env.compile(variable); const labelStr = Cypher.utils.escapeLabel(label); return `${varName}:${labelStr}`; diff --git a/packages/graphql/src/translate/queryAST/cypher-generators/CypherAnnotationSubqueryGenerator.ts b/packages/graphql/src/translate/queryAST/cypher-generators/CypherAnnotationSubqueryGenerator.ts index dfce0fc18a1..540bd268dac 100644 --- a/packages/graphql/src/translate/queryAST/cypher-generators/CypherAnnotationSubqueryGenerator.ts +++ b/packages/graphql/src/translate/queryAST/cypher-generators/CypherAnnotationSubqueryGenerator.ts @@ -123,7 +123,7 @@ export class CypherAnnotationSubqueryGenerator { const target = this.context.target; const aliasTargetToPublicTarget = new Cypher.With([target, CYPHER_TARGET_VARIABLE]); - const statementCypherQuery = new Cypher.RawCypher((env) => { + const statementCypherQuery = new Cypher.Raw((env) => { const statement = this.replaceArgumentsInStatement({ env, rawArguments, diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index 9e6a5abb308..d6d036f6c73 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -332,7 +332,6 @@ export class OperationsFactory { resolveTree: ResolveTree, context: Neo4jGraphQLTranslationContext ): AggregationOperation | CompositeAggregationOperation { - console.log("createAggregationOperation"); let entity: ConcreteEntityAdapter | InterfaceEntityAdapter; if (entityOrRel instanceof RelationshipAdapter) { entity = entityOrRel.target as ConcreteEntityAdapter; diff --git a/packages/graphql/src/translate/translate-create.ts b/packages/graphql/src/translate/translate-create.ts index 51ec0d2b5e3..402e59e5b3d 100644 --- a/packages/graphql/src/translate/translate-create.ts +++ b/packages/graphql/src/translate/translate-create.ts @@ -150,7 +150,7 @@ export default async function translateCreate({ ); const returnStatement = getReturnStatement(projectedVariables, context); - const createQuery = new Cypher.RawCypher((env) => { + const createQuery = new Cypher.Raw((env) => { const cypher = filterTruthy([ `${createStrs.join("\n")}`, context.subscriptionsEnabled ? `WITH ${projectionWith.join(", ")}` : "", diff --git a/packages/graphql/src/translate/translate-delete.ts b/packages/graphql/src/translate/translate-delete.ts index 198cfb766f4..7e91e278942 100644 --- a/packages/graphql/src/translate/translate-delete.ts +++ b/packages/graphql/src/translate/translate-delete.ts @@ -81,7 +81,7 @@ export function translateDelete({ deleteStr = findConnectedNodesCypherQuery(varName); } - const deleteQuery = new Cypher.RawCypher(() => { + const deleteQuery = new Cypher.Raw(() => { const eventMeta = createEventMeta({ event: "delete", nodeVariable: varName, typename: node.name }); const cypher = [ ...(context.subscriptionsEnabled ? [`WITH [] AS ${META_CYPHER_VARIABLE}`] : []), diff --git a/packages/graphql/src/translate/translate-resolve-reference.ts b/packages/graphql/src/translate/translate-resolve-reference.ts index e9815579075..a0d3fd7e716 100644 --- a/packages/graphql/src/translate/translate-resolve-reference.ts +++ b/packages/graphql/src/translate/translate-resolve-reference.ts @@ -72,7 +72,7 @@ export function translateResolveReference({ const projectionSubqueries = Cypher.concat(...projection.subqueries, ...projection.subqueriesBeforeSort); - const projectionExpression = new Cypher.RawCypher((env) => { + const projectionExpression = new Cypher.Raw((env) => { return [`${varName} ${compileCypher(projection.projection, env)}`, projection.params]; }); diff --git a/packages/graphql/src/translate/translate-top-level-cypher.ts b/packages/graphql/src/translate/translate-top-level-cypher.ts index ade8b908dd2..55169a64c8d 100644 --- a/packages/graphql/src/translate/translate-top-level-cypher.ts +++ b/packages/graphql/src/translate/translate-top-level-cypher.ts @@ -114,7 +114,7 @@ export function translateTopLevelCypher({ const innerNodePartialProjection = `[ this IN [this] WHERE (${labelsStatements.join(" AND ")})`; if (!resolveTree.fieldsByTypeName[node.name]) { headStrs.push( - new Cypher.RawCypher(`${innerNodePartialProjection}| this { __resolveType: "${node.name}" }]`) + new Cypher.Raw(`${innerNodePartialProjection}| this { __resolveType: "${node.name}" }]`) ); } else { const { @@ -135,7 +135,7 @@ export function translateTopLevelCypher({ projectionValidatePredicates.push(...predicates); } headStrs.push( - new Cypher.RawCypher((env) => { + new Cypher.Raw((env) => { return innerNodePartialProjection .concat(`| this { __resolveType: "${node.name}", `) .concat(compileCypher(str, env).replace("{", "")) @@ -146,7 +146,7 @@ export function translateTopLevelCypher({ } }); - projectionStr = new Cypher.RawCypher( + projectionStr = new Cypher.Raw( (env) => `${headStrs.map((headStr) => compileCypher(headStr, env)).join(" + ")}` ); } @@ -192,7 +192,7 @@ export function translateTopLevelCypher({ const projectionSubquery = Cypher.concat(...projectionSubqueries); - return new Cypher.RawCypher((env) => { + return new Cypher.Raw((env) => { const authPredicates: Cypher.Predicate[] = []; if (projectionValidatePredicates.length) { diff --git a/packages/graphql/src/translate/translate-update.ts b/packages/graphql/src/translate/translate-update.ts index c580cc68990..53a490736d2 100644 --- a/packages/graphql/src/translate/translate-update.ts +++ b/packages/graphql/src/translate/translate-update.ts @@ -464,7 +464,7 @@ export default async function translateUpdate({ const relationshipValidationStr = createRelationshipValidationStr({ node, context, varName }); - const updateQuery = new Cypher.RawCypher((env: Cypher.Environment) => { + const updateQuery = new Cypher.Raw((env: Cypher.Environment) => { const projectionSubqueryStr = projectionSubquery ? compileCypher(projectionSubquery, env) : ""; const cypher = [ @@ -524,21 +524,19 @@ function generateUpdateReturnStatement( ): Cypher.Clause { let statements; if (varName && projStr) { - statements = new Cypher.RawCypher( - (env) => `collect(DISTINCT ${varName} ${compileCypher(projStr, env)}) AS data` - ); + statements = new Cypher.Raw((env) => `collect(DISTINCT ${varName} ${compileCypher(projStr, env)}) AS data`); } if (subscriptionsEnabled) { statements = Cypher.concat( statements, - new Cypher.RawCypher(statements ? ", " : ""), - new Cypher.RawCypher(`collect(DISTINCT m) as ${META_CYPHER_VARIABLE}`) + new Cypher.Raw(statements ? ", " : ""), + new Cypher.Raw(`collect(DISTINCT m) as ${META_CYPHER_VARIABLE}`) ); } if (!statements) { - statements = new Cypher.RawCypher("'Query cannot conclude with CALL'"); + statements = new Cypher.Raw("'Query cannot conclude with CALL'"); } return new Cypher.Return(statements); diff --git a/packages/graphql/src/translate/utils/callback-utils.ts b/packages/graphql/src/translate/utils/callback-utils.ts index 7ff885976ed..60d5a5d7f85 100644 --- a/packages/graphql/src/translate/utils/callback-utils.ts +++ b/packages/graphql/src/translate/utils/callback-utils.ts @@ -52,13 +52,13 @@ export const addCallbackAndSetParamCypher = ( callbackBucket: CallbackBucket, operation: "CREATE" | "UPDATE", node: Cypher.Node -): [Cypher.Property, Cypher.RawCypher] | [] => { +): [Cypher.Property, Cypher.Raw] | [] => { if (!field.callback || !field.callback.operations.includes(operation)) { return []; } const propRef = node.property(field.dbPropertyName as string); - const rawCypherStatement = new Cypher.RawCypher((env: Cypher.Environment) => { + const rawCypherStatement = new Cypher.Raw((env: Cypher.Environment) => { const variableCypher = compileCypher(variable, env); const paramName = `${variableCypher}_${field.fieldName}_${field.callback?.callbackName}`; diff --git a/packages/graphql/src/translate/utils/stringify-object.ts b/packages/graphql/src/translate/utils/stringify-object.ts index 771f2db5047..925ce8f0415 100644 --- a/packages/graphql/src/translate/utils/stringify-object.ts +++ b/packages/graphql/src/translate/utils/stringify-object.ts @@ -20,15 +20,13 @@ import Cypher from "@neo4j/cypher-builder"; /** Serializes object into a string for Cypher objects */ -export function stringifyObject( - fields: Record -): Cypher.RawCypher { - return new Cypher.RawCypher( +export function stringifyObject(fields: Record): Cypher.Raw { + return new Cypher.Raw( (env) => `{ ${Object.entries(fields) .filter(([, value]) => Boolean(value)) .map(([key, value]): string | undefined => { - if (value instanceof Cypher.RawCypher) { + if (value instanceof Cypher.Raw) { return `${key}: ${value?.getCypher(env)}`; } else { return `${key}: ${value}`; diff --git a/packages/graphql/src/translate/where/create-connection-where-and-params.ts b/packages/graphql/src/translate/where/create-connection-where-and-params.ts index 23fca8ba264..20cde103bf2 100644 --- a/packages/graphql/src/translate/where/create-connection-where-and-params.ts +++ b/packages/graphql/src/translate/where/create-connection-where-and-params.ts @@ -54,7 +54,7 @@ export default function createConnectionWhereAndParams({ }); let subquery = ""; - const whereCypher = new Cypher.RawCypher((env: Cypher.Environment) => { + const whereCypher = new Cypher.Raw((env: Cypher.Environment) => { const cypher = (andOp as any)?.getCypher(env) || ""; if (preComputedSubqueries) { subquery = compileCypher(preComputedSubqueries, env); diff --git a/packages/graphql/src/translate/where/create-where-and-params.ts b/packages/graphql/src/translate/where/create-where-and-params.ts index 3a559c46fb2..10438d8b5c5 100644 --- a/packages/graphql/src/translate/where/create-where-and-params.ts +++ b/packages/graphql/src/translate/where/create-where-and-params.ts @@ -53,7 +53,7 @@ export default function createWhereAndParams({ let preComputedWhereFieldsResult = ""; - const whereCypher = new Cypher.RawCypher((env: Cypher.Environment) => { + const whereCypher = new Cypher.Raw((env: Cypher.Environment) => { preComputedWhereFieldsResult = compileCypherIfExists(preComputedSubqueries, env); const cypher = (wherePredicate as any)?.getCypher(env) || ""; return [cypher, {}]; diff --git a/yarn.lock b/yarn.lock index 535c5aeec04..b48d86cefa2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3748,7 +3748,6 @@ __metadata: ts-node: 10.9.1 typescript: 5.1.6 typescript-memoize: ^1.1.1 - uuid: ^9.0.0 ws: 8.14.2 peerDependencies: graphql: ^16.0.0 From 0ecd4662185278dbdf5bf75f6734b19d769acb29 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Dec 2023 12:02:14 +0000 Subject: [PATCH 007/136] Remove _on on subscriptions filters --- .../src/schema/make-augmented-schema.ts | 1 + .../generate-subscription-types.ts | 3 + .../generate-subscription-where-type.ts | 13 ++- .../directives/filterable.test.ts | 28 +++--- .../experimental-schema/issues/3439.test.ts | 80 ++++++++++------- .../experimental-schema/subscriptions.test.ts | 88 +++++++++---------- 6 files changed, 126 insertions(+), 87 deletions(-) diff --git a/packages/graphql/src/schema/make-augmented-schema.ts b/packages/graphql/src/schema/make-augmented-schema.ts index b93bac37acb..96e7fbaebc7 100644 --- a/packages/graphql/src/schema/make-augmented-schema.ts +++ b/packages/graphql/src/schema/make-augmented-schema.ts @@ -498,6 +498,7 @@ function makeAugmentedSchema({ schemaModel, userDefinedFieldDirectivesForNode, generateRelationshipTypes: !isCDCEngine, + experimental, }); } diff --git a/packages/graphql/src/schema/subscriptions/generate-subscription-types.ts b/packages/graphql/src/schema/subscriptions/generate-subscription-types.ts index 777248f8f75..6ad495618f4 100644 --- a/packages/graphql/src/schema/subscriptions/generate-subscription-types.ts +++ b/packages/graphql/src/schema/subscriptions/generate-subscription-types.ts @@ -38,11 +38,13 @@ export function generateSubscriptionTypes({ schemaModel, userDefinedFieldDirectivesForNode, generateRelationshipTypes, + experimental, }: { schemaComposer: SchemaComposer; schemaModel: Neo4jGraphQLSchemaModel; userDefinedFieldDirectivesForNode: Map>; generateRelationshipTypes: boolean; + experimental: boolean; }): void { const subscriptionComposer = schemaComposer.Subscription; @@ -301,6 +303,7 @@ export function generateSubscriptionTypes({ const connectionWhere = generateSubscriptionConnectionWhereType({ entityAdapter, schemaComposer, + experimental, }); if (entityAdapter.relationships.size > 0) { if (entityAdapter.isSubscribableOnRelationshipCreate) { diff --git a/packages/graphql/src/schema/subscriptions/generate-subscription-where-type.ts b/packages/graphql/src/schema/subscriptions/generate-subscription-where-type.ts index 39beb6d886a..524adec0d6c 100644 --- a/packages/graphql/src/schema/subscriptions/generate-subscription-where-type.ts +++ b/packages/graphql/src/schema/subscriptions/generate-subscription-where-type.ts @@ -46,13 +46,16 @@ export function generateSubscriptionWhereType( export function generateSubscriptionConnectionWhereType({ entityAdapter, schemaComposer, + experimental, }: { entityAdapter: ConcreteEntityAdapter; schemaComposer: SchemaComposer; + experimental: boolean; }): { created: InputTypeComposer; deleted: InputTypeComposer } | undefined { const connectedRelationship = getRelationshipConnectionWhereTypes({ entityAdapter, schemaComposer, + experimental, }); const isConnectedNodeTypeNotExcluded = schemaComposer.has(entityAdapter.operations.subscriptionWhereInputTypeName); if (!isConnectedNodeTypeNotExcluded && !connectedRelationship) { @@ -91,15 +94,18 @@ export function generateSubscriptionConnectionWhereType({ function getRelationshipConnectionWhereTypes({ entityAdapter, schemaComposer, + experimental, }: { entityAdapter: ConcreteEntityAdapter; schemaComposer: SchemaComposer; + experimental: boolean; }): InputTypeComposer | undefined { const relationsFieldInputWhereTypeFields = Array.from(entityAdapter.relationships.values()).reduce( (acc, relationshipAdapter) => { const fields = makeNodeRelationFields({ relationshipAdapter, schemaComposer, + experimental, }); if (!fields) { return acc; @@ -127,9 +133,11 @@ function getRelationshipConnectionWhereTypes({ function makeNodeRelationFields({ relationshipAdapter, schemaComposer, + experimental, }: { relationshipAdapter: RelationshipAdapter; schemaComposer: SchemaComposer; + experimental: boolean; }) { const edgeType = makeRelationshipWhereType({ schemaComposer, @@ -148,6 +156,7 @@ function makeNodeRelationFields({ schemaComposer, interfaceEntity, edgeType, + experimental, }); } return makeRelationshipToConcreteTypeWhereType({ relationshipAdapter, edgeType, schemaComposer }); @@ -229,10 +238,12 @@ function makeRelationshipToInterfaceTypeWhereType({ schemaComposer, interfaceEntity, edgeType, + experimental, }: { schemaComposer: SchemaComposer; interfaceEntity: InterfaceEntityAdapter; edgeType: InputTypeComposer | undefined; + experimental: boolean; }): { node?: InputTypeComposer; edge?: InputTypeComposer } | undefined { let interfaceImplementationsType: InputTypeComposer | undefined = undefined; let interfaceNodeType: InputTypeComposer | undefined = undefined; @@ -251,7 +262,7 @@ function makeRelationshipToInterfaceTypeWhereType({ } const interfaceFields: InputTypeComposerFieldConfigMapDefinition = attributesToSubscriptionsWhereInputFields(interfaceEntity); - if (interfaceImplementationsType) { + if (interfaceImplementationsType && !experimental) { interfaceFields["_on"] = interfaceImplementationsType; } if (!isEmptyObject(interfaceFields)) { 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 f922295804f..9f78579e621 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts @@ -6656,6 +6656,7 @@ describe("@filterable directive", () => { features: { subscriptions: plugin, }, + experimental: true, }); const schema = await neoSchema.getSchema(); @@ -7054,6 +7055,7 @@ describe("@filterable directive", () => { type Movie { actors(directed: Boolean = true, options: PersonOptions, where: PersonWhere): [Person!]! + actorsAggregate(directed: Boolean = true, where: PersonWhere): MoviePersonActorsAggregationSelection actorsConnection(after: String, directed: Boolean = true, first: Int, sort: [MovieActorsConnectionSort!], where: MovieActorsConnectionWhere): MovieActorsConnection! title: String } @@ -7186,6 +7188,15 @@ describe("@filterable directive", () => { sort: [MovieSort!] } + type MoviePersonActorsAggregationSelection { + count: Int! + node: MoviePersonActorsNodeAggregateSelection + } + + type MoviePersonActorsNodeAggregateSelection { + username: StringAggregateSelectionNonNullable! + } + input MovieRelationInput { actors: [MovieActorsCreateFieldInput!] } @@ -7322,6 +7333,11 @@ describe("@filterable directive", () => { username: String! } + type PersonAggregateSelection { + count: Int! + username: StringAggregateSelectionNonNullable! + } + input PersonConnectInput { _on: PersonImplementationsConnectInput } @@ -7358,18 +7374,10 @@ describe("@filterable directive", () => { Actor: [ActorDisconnectInput!] } - input PersonImplementationsSubscriptionWhere { - Actor: ActorSubscriptionWhere - } - input PersonImplementationsUpdateInput { Actor: ActorUpdateInput } - input PersonImplementationsWhere { - Actor: ActorWhere - } - input PersonOptions { limit: Int offset: Int @@ -7390,7 +7398,6 @@ describe("@filterable directive", () => { AND: [PersonSubscriptionWhere!] NOT: PersonSubscriptionWhere OR: [PersonSubscriptionWhere!] - _on: PersonImplementationsSubscriptionWhere username: String username_CONTAINS: String username_ENDS_WITH: String @@ -7409,7 +7416,6 @@ describe("@filterable directive", () => { } input PersonWhere { - _on: PersonImplementationsWhere username: String username_CONTAINS: String username_ENDS_WITH: String @@ -7429,6 +7435,8 @@ describe("@filterable directive", () => { movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! + people(options: PersonOptions, where: PersonWhere): [Person!]! + peopleAggregate(where: PersonWhere): PersonAggregateSelection! } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts index edb1bf9de51..20addafd757 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts @@ -482,11 +482,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { Series: [SeriesDisconnectInput!] } - input IProductImplementationsSubscriptionWhere { - Movie: MovieSubscriptionWhere - Series: SeriesSubscriptionWhere - } - input IProductImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -513,7 +508,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { AND: [IProductSubscriptionWhere!] NOT: IProductSubscriptionWhere OR: [IProductSubscriptionWhere!] - _on: IProductImplementationsSubscriptionWhere id: String id_CONTAINS: String id_ENDS_WITH: String @@ -1370,7 +1364,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { `; const subscriptionsEngine = new TestSubscriptionsEngine(); - const neoSchema = new Neo4jGraphQL({ typeDefs, features: { subscriptions: subscriptionsEngine } }); + const neoSchema = new Neo4jGraphQL({ + typeDefs, + features: { subscriptions: subscriptionsEngine }, + experimental: true, + }); const schema = await neoSchema.getSchema(); const errors = validateSchema(schema); @@ -1429,6 +1427,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { type Genre { name: String! product(directed: Boolean = true, options: IProductOptions, where: IProductWhere): [IProduct!]! + productAggregate(directed: Boolean = true, where: IProductWhere): GenreIProductProductAggregationSelection productConnection(after: String, directed: Boolean = true, first: Int, sort: [GenreProductConnectionSort!], where: GenreProductConnectionWhere): GenreProductConnection! } @@ -1487,6 +1486,16 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + type GenreIProductProductAggregationSelection { + count: Int! + node: GenreIProductProductNodeAggregateSelection + } + + type GenreIProductProductNodeAggregateSelection { + id: StringAggregateSelectionNonNullable! + name: StringAggregateSelectionNonNullable! + } + input GenreOnCreateInput { name: String! } @@ -1693,6 +1702,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + type IProductAggregateSelection { + count: Int! + id: StringAggregateSelectionNonNullable! + name: StringAggregateSelectionNonNullable! + } + input IProductConnectInput { _on: IProductImplementationsConnectInput } @@ -1809,21 +1824,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { Series: [SeriesDisconnectInput!] } - input IProductImplementationsSubscriptionWhere { - Movie: MovieSubscriptionWhere - Series: SeriesSubscriptionWhere - } - input IProductImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput } - input IProductImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input IProductOptions { limit: Int offset: Int @@ -1845,7 +1850,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { AND: [IProductSubscriptionWhere!] NOT: IProductSubscriptionWhere OR: [IProductSubscriptionWhere!] - _on: IProductImplementationsSubscriptionWhere id: String id_CONTAINS: String id_ENDS_WITH: String @@ -1875,7 +1879,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { - _on: IProductImplementationsWhere id: String id_CONTAINS: String id_ENDS_WITH: String @@ -2187,6 +2190,8 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genres(options: GenreOptions, where: GenreWhere): [Genre!]! genresAggregate(where: GenreWhere): GenreAggregateSelection! genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! + iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! + iProductsAggregate(where: IProductWhere): IProductAggregateSelection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -2549,7 +2554,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { `; const subscriptionsEngine = new TestSubscriptionsEngine(); - const neoSchema = new Neo4jGraphQL({ typeDefs, features: { subscriptions: subscriptionsEngine } }); + const neoSchema = new Neo4jGraphQL({ + typeDefs, + features: { subscriptions: subscriptionsEngine }, + experimental: true, + }); const schema = await neoSchema.getSchema(); const errors = validateSchema(schema); @@ -2608,6 +2617,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { type Genre { name: String! product(directed: Boolean = true, options: IProductOptions, where: IProductWhere): [IProduct!]! + productAggregate(directed: Boolean = true, where: IProductWhere): GenreIProductProductAggregationSelection productConnection(after: String, directed: Boolean = true, first: Int, sort: [GenreProductConnectionSort!], where: GenreProductConnectionWhere): GenreProductConnection! } @@ -2658,6 +2668,16 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + type GenreIProductProductAggregationSelection { + count: Int! + node: GenreIProductProductNodeAggregateSelection + } + + type GenreIProductProductNodeAggregateSelection { + id: StringAggregateSelectionNonNullable! + name: StringAggregateSelectionNonNullable! + } + input GenreOptions { limit: Int offset: Int @@ -2853,6 +2873,12 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + type IProductAggregateSelection { + count: Int! + id: StringAggregateSelectionNonNullable! + name: StringAggregateSelectionNonNullable! + } + input IProductConnectWhere { node: IProductWhere! } @@ -2867,21 +2893,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } - input IProductImplementationsSubscriptionWhere { - Movie: MovieSubscriptionWhere - Series: SeriesSubscriptionWhere - } - input IProductImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput } - input IProductImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input IProductOptions { limit: Int offset: Int @@ -2903,7 +2919,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { AND: [IProductSubscriptionWhere!] NOT: IProductSubscriptionWhere OR: [IProductSubscriptionWhere!] - _on: IProductImplementationsSubscriptionWhere id: String id_CONTAINS: String id_ENDS_WITH: String @@ -2933,7 +2948,6 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { - _on: IProductImplementationsWhere id: String id_CONTAINS: String id_ENDS_WITH: String @@ -3106,6 +3120,8 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { genres(options: GenreOptions, where: GenreWhere): [Genre!]! genresAggregate(where: GenreWhere): GenreAggregateSelection! genresConnection(after: String, first: Int, sort: [GenreSort], where: GenreWhere): GenresConnection! + iProducts(options: IProductOptions, where: IProductWhere): [IProduct!]! + iProductsAggregate(where: IProductWhere): IProductAggregateSelection! 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/subscriptions.test.ts b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts index 5c17f1630d5..2e89b01382f 100644 --- a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts @@ -18,8 +18,8 @@ */ import { printSchemaWithDirectives } from "@graphql-tools/utils"; -import { lexicographicSortSchema } from "graphql/utilities"; import { gql } from "graphql-tag"; +import { lexicographicSortSchema } from "graphql/utilities"; import { Neo4jGraphQL } from "../../../src"; import { TestSubscriptionsEngine } from "../../utils/TestSubscriptionsEngine"; @@ -49,6 +49,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -689,6 +690,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -1455,6 +1457,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -2208,6 +2211,7 @@ describe("Subscriptions", () => { } type Query { + actors(options: QueryOptions, where: ActorWhere): [Actor!]! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -2593,6 +2597,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -3473,6 +3478,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -3997,6 +4003,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -4603,6 +4610,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -5356,6 +5364,7 @@ describe("Subscriptions", () => { } type Query { + actors(options: QueryOptions, where: ActorWhere): [Actor!]! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! @@ -5689,6 +5698,7 @@ describe("Subscriptions", () => { features: { subscriptions: plugin, }, + experimental: true, }); const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); @@ -5729,6 +5739,10 @@ describe("Subscriptions", () => { moviesConnection(after: String, directed: Boolean = true, first: Int, sort: [CreatureMoviesConnectionSort!], where: CreatureMoviesConnectionWhere): CreatureMoviesConnection! } + type CreatureAggregateSelection { + count: Int! + } + input CreatureConnectInput { _on: CreatureImplementationsConnectInput movies: CreatureMoviesConnectFieldInput @@ -5768,10 +5782,6 @@ describe("Subscriptions", () => { Person: PersonUpdateInput } - input CreatureImplementationsWhere { - Person: PersonWhere - } - input CreatureMoviesConnectFieldInput { connect: ProductionConnectInput where: ProductionConnectWhere @@ -5843,7 +5853,6 @@ describe("Subscriptions", () => { } input CreatureWhere { - _on: CreatureImplementationsWhere moviesConnection: CreatureMoviesConnectionWhere moviesConnection_NOT: CreatureMoviesConnectionWhere } @@ -5879,6 +5888,7 @@ describe("Subscriptions", () => { type Movie implements Production { director(directed: Boolean = true, options: CreatureOptions, where: CreatureWhere): Creature! + directorAggregate(directed: Boolean = true, where: CreatureWhere): MovieCreatureDirectorAggregationSelection directorConnection(after: String, directed: Boolean = true, first: Int, where: ProductionDirectorConnectionWhere): ProductionDirectorConnection! id: ID title: String! @@ -5900,6 +5910,10 @@ describe("Subscriptions", () => { title: String! } + type MovieCreatureDirectorAggregationSelection { + count: Int! + } + input MovieDeleteInput { director: MovieDirectorDeleteFieldInput } @@ -5966,32 +5980,6 @@ describe("Subscriptions", () => { title: SortDirection } - input MovieSubscriptionWhere { - AND: [MovieSubscriptionWhere!] - NOT: MovieSubscriptionWhere - OR: [MovieSubscriptionWhere!] - id: ID - id_CONTAINS: ID - id_ENDS_WITH: ID - id_IN: [ID] - id_NOT: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - id_NOT_CONTAINS: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - id_NOT_ENDS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - id_STARTS_WITH: ID - title: String - title_CONTAINS: String - title_ENDS_WITH: String - title_IN: [String] - title_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - title_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - title_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - title_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") - title_STARTS_WITH: String - } - input MovieUpdateInput { director: MovieDirectorUpdateFieldInput id: ID @@ -6060,6 +6048,7 @@ describe("Subscriptions", () => { type Person implements Creature { movies(directed: Boolean = true, options: ProductionOptions, where: ProductionWhere): Production! + moviesAggregate(directed: Boolean = true, where: ProductionWhere): PersonProductionMoviesAggregationSelection moviesConnection(after: String, directed: Boolean = true, first: Int, sort: [CreatureMoviesConnectionSort!], where: CreatureMoviesConnectionWhere): CreatureMoviesConnection! } @@ -6147,6 +6136,15 @@ describe("Subscriptions", () => { offset: Int } + type PersonProductionMoviesAggregationSelection { + count: Int! + node: PersonProductionMoviesNodeAggregateSelection + } + + type PersonProductionMoviesNodeAggregateSelection { + id: IDAggregateSelectionNullable! + } + input PersonRelationInput { movies: PersonMoviesCreateFieldInput } @@ -6204,6 +6202,11 @@ describe("Subscriptions", () => { id: ID } + type ProductionAggregateSelection { + count: Int! + id: IDAggregateSelectionNullable! + } + input ProductionConnectInput { _on: ProductionImplementationsConnectInput director: ProductionDirectorConnectFieldInput @@ -6303,21 +6306,11 @@ describe("Subscriptions", () => { Series: [SeriesDisconnectInput!] } - input ProductionImplementationsSubscriptionWhere { - Movie: MovieSubscriptionWhere - Series: SeriesSubscriptionWhere - } - input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput } - input ProductionImplementationsWhere { - Movie: MovieWhere - Series: SeriesWhere - } - input ProductionOptions { limit: Int offset: Int @@ -6338,7 +6331,6 @@ describe("Subscriptions", () => { AND: [ProductionSubscriptionWhere!] NOT: ProductionSubscriptionWhere OR: [ProductionSubscriptionWhere!] - _on: ProductionImplementationsSubscriptionWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -6358,7 +6350,6 @@ describe("Subscriptions", () => { } input ProductionWhere { - _on: ProductionImplementationsWhere directorConnection: ProductionDirectorConnectionWhere directorConnection_NOT: ProductionDirectorConnectionWhere id: ID @@ -6374,12 +6365,16 @@ describe("Subscriptions", () => { } type Query { + creatures(options: CreatureOptions, where: CreatureWhere): [Creature!]! + creaturesAggregate(where: CreatureWhere): CreatureAggregateSelection! movies(options: MovieOptions, where: MovieWhere): [Movie!]! moviesAggregate(where: MovieWhere): MovieAggregateSelection! 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, where: PersonWhere): PeopleConnection! + productions(options: ProductionOptions, where: ProductionWhere): [Production!]! + productionsAggregate(where: ProductionWhere): ProductionAggregateSelection! series(options: SeriesOptions, where: SeriesWhere): [Series!]! seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! @@ -6387,6 +6382,7 @@ describe("Subscriptions", () => { type Series implements Production { director(directed: Boolean = true, options: CreatureOptions, where: CreatureWhere): Creature! + directorAggregate(directed: Boolean = true, where: CreatureWhere): SeriesCreatureDirectorAggregationSelection directorConnection(after: String, directed: Boolean = true, first: Int, where: ProductionDirectorConnectionWhere): ProductionDirectorConnection! episode: Int! id: ID @@ -6423,6 +6419,10 @@ describe("Subscriptions", () => { timestamp: Float! } + type SeriesCreatureDirectorAggregationSelection { + count: Int! + } + input SeriesDeleteInput { director: SeriesDirectorDeleteFieldInput } From 62c2516d5a8cf90725d7e29d879b823751c22a06 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Dec 2023 12:51:00 +0000 Subject: [PATCH 008/136] Update .changeset/khaki-spiders-heal.md --- .changeset/khaki-spiders-heal.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/khaki-spiders-heal.md b/.changeset/khaki-spiders-heal.md index 3d50ba825ed..96a48d9e168 100644 --- a/.changeset/khaki-spiders-heal.md +++ b/.changeset/khaki-spiders-heal.md @@ -2,4 +2,4 @@ "@neo4j/graphql": patch --- -Remove \_on filter for interfaces +Remove \_on filter for interfaces under experimental flag From 7c0519adc0015bc0cef0e0c46f86bc678838259a Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Dec 2023 13:33:52 +0000 Subject: [PATCH 009/136] Update schema to allow logical operators on interfaces when experimental flag is set --- .../src/schema/generation/where-input.ts | 8 +- .../queryAST/ast/selection/EntitySelection.ts | 3 +- .../interface-filtering.int.test.ts | 182 ++++++++++++++++++ .../experimental-schema/comments.test.ts | 3 + .../directive-preserve.test.ts | 6 + .../directives/default.test.ts | 3 + .../directives/filterable.test.ts | 3 + .../directives/private.test.ts | 3 + .../directives/relationship-aggregate.test.ts | 6 + .../relationship-nested-operations.test.ts | 24 +++ .../directives/selectable.test.ts | 6 + .../directives/settable.test.ts | 12 ++ .../experimental-schema/inheritance.test.ts | 3 + .../interface-relationships.test.ts | 15 ++ .../experimental-schema/interfaces.test.ts | 6 + .../interfaces/aggregations.test.ts | 6 + .../experimental-schema/issues/2377.test.ts | 3 + .../experimental-schema/issues/2993.test.ts | 6 + .../experimental-schema/issues/3439.test.ts | 12 ++ .../schema/experimental-schema/math.test.ts | 3 + .../nested-aggregation-on-interface.test.ts | 6 + .../schema/experimental-schema/plural.test.ts | 3 + .../experimental-schema/subscriptions.test.ts | 6 + .../union-interface-relationship.test.ts | 3 + .../experimental/interface-filtering.test.ts | 151 +++++++++++++++ 25 files changed, 480 insertions(+), 2 deletions(-) create mode 100644 packages/graphql/tests/integration/experimental/interface-filtering.int.test.ts create mode 100644 packages/graphql/tests/tck/experimental/interface-filtering.test.ts diff --git a/packages/graphql/src/schema/generation/where-input.ts b/packages/graphql/src/schema/generation/where-input.ts index bb37611b947..79215f9212e 100644 --- a/packages/graphql/src/schema/generation/where-input.ts +++ b/packages/graphql/src/schema/generation/where-input.ts @@ -93,7 +93,13 @@ export function withWhereInputType({ NOT: whereInputType, }); } else if (entityAdapter instanceof InterfaceEntityAdapter) { - if (!experimental) { + if (experimental) { + whereInputType.addFields({ + OR: whereInputType.NonNull.List, + AND: whereInputType.NonNull.List, + NOT: whereInputType, + }); + } else { const implementationsWhereInputType = makeImplementationsWhereInput({ interfaceEntityAdapter: entityAdapter, composer, diff --git a/packages/graphql/src/translate/queryAST/ast/selection/EntitySelection.ts b/packages/graphql/src/translate/queryAST/ast/selection/EntitySelection.ts index df06591b7ec..7afbf0f8a92 100644 --- a/packages/graphql/src/translate/queryAST/ast/selection/EntitySelection.ts +++ b/packages/graphql/src/translate/queryAST/ast/selection/EntitySelection.ts @@ -28,7 +28,8 @@ export abstract class EntitySelection extends QueryASTNode { return []; } - /** Apply selection over the given context, returns the updated context and the selection clause */ + /** Apply selection over the given context, returns the updated context and the selection clause + * TODO: Improve naming */ public abstract apply(context: QueryASTContext): { nestedContext: QueryASTContext; selection: SelectionClause; diff --git a/packages/graphql/tests/integration/experimental/interface-filtering.int.test.ts b/packages/graphql/tests/integration/experimental/interface-filtering.int.test.ts new file mode 100644 index 00000000000..7f61a5b6771 --- /dev/null +++ b/packages/graphql/tests/integration/experimental/interface-filtering.int.test.ts @@ -0,0 +1,182 @@ +/* + * 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 { createBearerToken } from "../../utils/create-bearer-token"; +import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; + +describe("Interface filtering", () => { + const secret = "the-secret"; + + let schema: GraphQLSchema; + let neo4j: Neo4j; + let driver: Driver; + let typeDefs: string; + + const Movie = new UniqueType("Movie"); + const Series = new UniqueType("Series"); + const Actor = new UniqueType("Actor"); + + async function graphqlQuery(query: string, token: string) { + return graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ token }), + }); + } + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + + typeDefs = ` + interface Show { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type ${Movie} implements Show @limit(default: 3, max: 10) { + 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") + } + + interface ActedIn @relationshipProperties { + screenTime: Int + } + `; + + const session = await neo4j.getSession(); + + try { + await session.run(` + CREATE(m:${Movie} { title: "The Office" }) + CREATE(m2:${Movie}{ title: "The Office 2" }) + CREATE(m3:${Movie}{ title: "NOT The Office 2" }) + CREATE(s1:${Series}{ title: "The Office 2" }) + CREATE(s2:${Series}{ title: "NOT The Office" }) + CREATE(a:${Actor} {name: "Keanu"}) + MERGE(a)-[:ACTED_IN]->(m) + MERGE(a)-[:ACTED_IN]->(m2) + MERGE(a)-[:ACTED_IN]->(m3) + MERGE(a)-[:ACTED_IN]->(s1) + MERGE(a)-[:ACTED_IN]->(s2) + + `); + } finally { + await session.close(); + } + + const neoGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + features: { + authorization: { + key: secret, + }, + }, + experimental: true, + }); + schema = await neoGraphql.getSchema(); + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + await cleanNodes(session, [Movie, Series, Actor]); + await session.close(); + await driver.close(); + }); + + test("allow for logical filters on top-level interfaces", async () => { + const query = ` + query actedInWhere { + shows(where: { OR: [{ title: "The Office" }, { title: "The Office 2" }] }) { + title + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + shows: expect.toIncludeSameMembers([ + { + title: "The Office", + }, + { + title: "The Office 2", + }, + { + title: "The Office 2", + }, + ]), + }); + }); + + test("allow for logical filters on nested-level interfaces", async () => { + const query = ` + query actedInWhere { + ${Actor.plural} { + actedIn(where: { OR: [{ title: "The Office" }, { title: "The Office 2" }] }) { + title + } + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: [ + { + actedIn: expect.toIncludeSameMembers([ + { + title: "The Office", + }, + { + title: "The Office 2", + }, + { + title: "The Office 2", + }, + ]), + }, + ], + }); + }); +}); diff --git a/packages/graphql/tests/schema/experimental-schema/comments.test.ts b/packages/graphql/tests/schema/experimental-schema/comments.test.ts index 714da69c3ab..c0fed31a04a 100644 --- a/packages/graphql/tests/schema/experimental-schema/comments.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/comments.test.ts @@ -1125,6 +1125,9 @@ describe("Comments", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String 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 653ffe1732c..28dc4af3189 100644 --- a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts @@ -1563,6 +1563,9 @@ describe("Directive-preserve", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String @@ -2555,6 +2558,9 @@ describe("Directive-preserve", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String 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 73d777631a5..0534c6bae67 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts @@ -233,6 +233,9 @@ describe("@default directive", () => { } input UserInterfaceWhere { + AND: [UserInterfaceWhere!] + NOT: UserInterfaceWhere + OR: [UserInterfaceWhere!] fromInterface: String fromInterface_CONTAINS: String fromInterface_ENDS_WITH: String 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 9f78579e621..e8f336072c9 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts @@ -7416,6 +7416,9 @@ describe("@filterable directive", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] username: String username_CONTAINS: String username_ENDS_WITH: String 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 b9844283400..4e70a7f29df 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts @@ -163,6 +163,9 @@ describe("@private directive", () => { } input UserInterfaceWhere { + AND: [UserInterfaceWhere!] + NOT: UserInterfaceWhere + OR: [UserInterfaceWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 ba6c3fe3e5f..9899f0dc978 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 @@ -1474,6 +1474,9 @@ describe("@relationship directive, aggregate argument", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] password: String password_CONTAINS: String password_ENDS_WITH: String @@ -1907,6 +1910,9 @@ describe("@relationship directive, aggregate argument", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] password: String password_CONTAINS: String password_ENDS_WITH: String 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 a527d4d6021..7213b559ad9 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 @@ -8880,6 +8880,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -9326,6 +9329,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -9771,6 +9777,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10213,6 +10222,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10649,6 +10661,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -11085,6 +11100,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -11643,6 +11661,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -12167,6 +12188,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String 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 9e5a63e774f..bfb7ad8a19a 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts @@ -3096,6 +3096,9 @@ describe("@selectable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String @@ -3627,6 +3630,9 @@ describe("@selectable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String 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 6e7e02fdf8f..0b9b2d27f59 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts @@ -5583,6 +5583,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String @@ -6090,6 +6093,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String @@ -6866,6 +6872,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") @@ -7803,6 +7812,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") diff --git a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts index 637fc28520a..cad158581c0 100644 --- a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts @@ -424,6 +424,9 @@ describe("inheritance", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] friendsConnection: PersonFriendsConnectionWhere @deprecated(reason: \\"Use \`friendsConnection_SOME\` instead.\\") \\"\\"\\" Return People where all of the related PersonFriendsConnections match this filter 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 7b1d5160125..0ba86e54146 100644 --- a/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts @@ -446,6 +446,9 @@ describe("Interface Relationships", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String @@ -1615,6 +1618,9 @@ describe("Interface Relationships", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") @@ -2323,6 +2329,9 @@ describe("Interface Relationships", () => { } input Interface1Where { + AND: [Interface1Where!] + NOT: Interface1Where + OR: [Interface1Where!] field1: String field1_CONTAINS: String field1_ENDS_WITH: String @@ -2398,6 +2407,9 @@ describe("Interface Relationships", () => { } input Interface2Where { + AND: [Interface2Where!] + NOT: Interface2Where + OR: [Interface2Where!] field2: String field2_CONTAINS: String field2_ENDS_WITH: String @@ -3630,6 +3642,9 @@ describe("Interface Relationships", () => { } input ContentWhere { + AND: [ContentWhere!] + NOT: ContentWhere + OR: [ContentWhere!] content: String content_CONTAINS: String content_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts index f2fd4435278..bd927609f56 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts @@ -243,6 +243,9 @@ describe("Interfaces", () => { } input MovieNodeWhere { + AND: [MovieNodeWhere!] + NOT: MovieNodeWhere + OR: [MovieNodeWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -602,6 +605,9 @@ describe("Interfaces", () => { } input MovieNodeWhere { + AND: [MovieNodeWhere!] + NOT: MovieNodeWhere + OR: [MovieNodeWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 caaa12d7833..a6dc7efeeb7 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts @@ -217,6 +217,9 @@ describe("Interface Top Level Aggregations", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float @@ -735,6 +738,9 @@ describe("Interface Top Level Aggregations", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float 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 d3159548206..d86a42d7874 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts @@ -407,6 +407,9 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { } input ResourceEntityWhere { + AND: [ResourceEntityWhere!] + NOT: ResourceEntityWhere + OR: [ResourceEntityWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 1566b4557d1..9a28707a9e0 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts @@ -193,6 +193,9 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input ProfileWhere { + AND: [ProfileWhere!] + NOT: ProfileWhere + OR: [ProfileWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -613,6 +616,9 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input ProfileWhere { + AND: [ProfileWhere!] + NOT: ProfileWhere + OR: [ProfileWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID diff --git a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts index 20addafd757..174cf3a4afb 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts @@ -417,6 +417,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input INodeWhere { + AND: [INodeWhere!] + NOT: INodeWhere + OR: [INodeWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String @@ -537,6 +540,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { + AND: [IProductWhere!] + NOT: IProductWhere + OR: [IProductWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String @@ -1879,6 +1885,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { + AND: [IProductWhere!] + NOT: IProductWhere + OR: [IProductWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String @@ -2948,6 +2957,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { + AND: [IProductWhere!] + NOT: IProductWhere + OR: [IProductWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/math.test.ts b/packages/graphql/tests/schema/experimental-schema/math.test.ts index a24e91ac530..95be8ee3b73 100644 --- a/packages/graphql/tests/schema/experimental-schema/math.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/math.test.ts @@ -1704,6 +1704,9 @@ describe("Algebraic", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] viewers: Int viewers_GT: Int viewers_GTE: Int 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 6127c3054bd..0731ebf8663 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 @@ -463,6 +463,9 @@ describe("nested aggregation on interface", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float @@ -1074,6 +1077,9 @@ describe("nested aggregation on interface", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float diff --git a/packages/graphql/tests/schema/experimental-schema/plural.test.ts b/packages/graphql/tests/schema/experimental-schema/plural.test.ts index f7050f6b43b..2297b2b1a61 100644 --- a/packages/graphql/tests/schema/experimental-schema/plural.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/plural.test.ts @@ -75,6 +75,9 @@ describe("Experimental Plural option", () => { } input AnimalWhere { + AND: [AnimalWhere!] + NOT: AnimalWhere + OR: [AnimalWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts index 2e89b01382f..5e30f9f616d 100644 --- a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts @@ -5853,6 +5853,9 @@ describe("Subscriptions", () => { } input CreatureWhere { + AND: [CreatureWhere!] + NOT: CreatureWhere + OR: [CreatureWhere!] moviesConnection: CreatureMoviesConnectionWhere moviesConnection_NOT: CreatureMoviesConnectionWhere } @@ -6350,6 +6353,9 @@ describe("Subscriptions", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] directorConnection: ProductionDirectorConnectionWhere directorConnection_NOT: ProductionDirectorConnectionWhere id: ID 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 259a1b2b309..56744f2f329 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 @@ -1860,6 +1860,9 @@ describe("Union Interface Relationships", () => { } input ReviewerWhere { + AND: [ReviewerWhere!] + NOT: ReviewerWhere + OR: [ReviewerWhere!] reputation: Int reputation_GT: Int reputation_GTE: Int diff --git a/packages/graphql/tests/tck/experimental/interface-filtering.test.ts b/packages/graphql/tests/tck/experimental/interface-filtering.test.ts new file mode 100644 index 00000000000..ab5c812d0fb --- /dev/null +++ b/packages/graphql/tests/tck/experimental/interface-filtering.test.ts @@ -0,0 +1,151 @@ +/* + * 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 { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { createBearerToken } from "../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; + +describe("Interface top level operations", () => { + const secret = "secret"; + let typeDefs: DocumentNode; + let neoSchema: Neo4jGraphQL; + + beforeEach(() => { + typeDefs = gql` + interface Show { + title: String! + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Movie implements Show @limit(default: 3, max: 10) { + 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") + } + + interface ActedIn @relationshipProperties { + screenTime: Int + } + `; + + neoSchema = new Neo4jGraphQL({ + typeDefs, + features: { authorization: { key: secret } }, + experimental: true, + }); + }); + + test("Logical operator filter (top level)", async () => { + const query = gql` + query actedInWhere { + shows(where: { OR: [{ title: "The Office" }, { title: "The Office 2" }] }) { + title + } + } + `; + + const token = createBearerToken(secret); + const result = await translateQuery(neoSchema, query, { token }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + MATCH (this0:Movie) + WHERE (this0.title = $param0 OR this0.title = $param1) + WITH this0 { .title, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 + RETURN this0 AS this + UNION + MATCH (this1:Series) + WHERE (this1.title = $param2 OR this1.title = $param3) + WITH this1 { .title, __resolveType: \\"Series\\", __id: id(this1) } AS this1 + RETURN this1 AS this + } + RETURN this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Office\\", + \\"param1\\": \\"The Office 2\\", + \\"param2\\": \\"The Office\\", + \\"param3\\": \\"The Office 2\\" + }" + `); + }); + + test("Logical operator filter on relationship", async () => { + const query = gql` + query actedInWhere { + actors { + actedIn(where: { OR: [{ title: "The Office" }, { title: "The Office 2" }] }) { + title + } + } + } + `; + + const token = createBearerToken(secret); + const result = await translateQuery(neoSchema, query, { token }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + CALL { + WITH this + CALL { + WITH * + MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + WHERE (this1.title = $param0 OR this1.title = $param1) + WITH this1 { .title, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 + RETURN this1 AS var2 + UNION + WITH * + MATCH (this)-[this3:ACTED_IN]->(this4:Series) + WHERE (this4.title = $param2 OR this4.title = $param3) + WITH this4 { .title, __resolveType: \\"Series\\", __id: id(this4) } AS this4 + RETURN this4 AS var2 + } + WITH var2 + RETURN collect(var2) AS var2 + } + RETURN this { actedIn: var2 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Office\\", + \\"param1\\": \\"The Office 2\\", + \\"param2\\": \\"The Office\\", + \\"param3\\": \\"The Office 2\\" + }" + `); + }); +}); From d3c6d0e8897dfc7ca168f1c387c6c33b92f8cb56 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 4 Dec 2023 13:36:26 +0000 Subject: [PATCH 010/136] Add changeset --- .changeset/friendly-rockets-drive.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .changeset/friendly-rockets-drive.md diff --git a/.changeset/friendly-rockets-drive.md b/.changeset/friendly-rockets-drive.md new file mode 100644 index 00000000000..130aff57d85 --- /dev/null +++ b/.changeset/friendly-rockets-drive.md @@ -0,0 +1,28 @@ +--- +"@neo4j/graphql": patch +--- + +Add support for logical operators on filters for interfaces under the experimental flag: + +``` +interface Show { + title: String! +} + +type Movie implements Show { + title: String! +} + +type Series implements Show { + title: String! +} + +``` + +``` +query actedInWhere { + shows(where: { OR: [{ title: "Show 1" }, { title: "Show 2" }] }) { + title + } +} +``` From 3fceadfe42969e04a58bd08a93d44a972661be0a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 00:32:47 +0000 Subject: [PATCH 011/136] chore(deps): update dependency tailwindcss to v3.3.6 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 19cfd018540..84ebe6a0080 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -97,7 +97,7 @@ "postcss-loader": "7.3.3", "randomstring": "1.3.0", "style-loader": "3.3.3", - "tailwindcss": "3.3.5", + "tailwindcss": "3.3.6", "terser-webpack-plugin": "5.3.9", "ts-jest": "29.1.1", "ts-loader": "9.5.1", diff --git a/yarn.lock b/yarn.lock index b48d86cefa2..3e201a6bbf2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3677,7 +3677,7 @@ __metadata: react: 18.2.0 react-dom: 18.2.0 style-loader: 3.3.3 - tailwindcss: 3.3.5 + tailwindcss: 3.3.6 terser-webpack-plugin: 5.3.9 thememirror: 2.0.1 ts-jest: 29.1.1 @@ -24833,9 +24833,9 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:3.3.5": - version: 3.3.5 - resolution: "tailwindcss@npm:3.3.5" +"tailwindcss@npm:3.3.6": + version: 3.3.6 + resolution: "tailwindcss@npm:3.3.6" dependencies: "@alloc/quick-lru": ^5.2.0 arg: ^5.0.2 @@ -24862,7 +24862,7 @@ __metadata: bin: tailwind: lib/cli.js tailwindcss: lib/cli.js - checksum: e04bb3bb7f9f17e9b6db0c7ace755ef0d6d05bff36ebeb9e5006e13c018ed5566f09db30a1a34380e38fa93ebbb4ae0e28fe726879d5e9ddd8c5b52bffd26f14 + checksum: 44632ac471248ecebcee1a2f15a0c3e9b8383513e71692b586aa2fe56dca12828ff70de3d340c898f27b27480e8475e5eb345fb2ebb813028bb2393578a34337 languageName: node linkType: hard From 3a497c338cf211e66c0ccaf5eb0e3b514db1d280 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 00:41:57 +0000 Subject: [PATCH 012/136] chore(deps): update srvaroa/labeler action to v1.8.1 --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 80d205f614b..87c2d624773 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -13,6 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: srvaroa/labeler@74404350883f8b689b026d8747622bd12d3f070a # v1.8.0 + - uses: srvaroa/labeler@50320c5cb41e9208947c68a1a05a85261155958e # v1.8.1 env: GITHUB_TOKEN: ${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }} From 7d18f4ff2d4ccdce28ca14d137034f4aaa6d0402 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 04:47:27 +0000 Subject: [PATCH 013/136] chore(deps): update typescript-eslint monorepo to v6.13.2 --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index d3e3c8f3a74..0a676bcc799 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.13.1", - "@typescript-eslint/parser": "6.13.1", + "@typescript-eslint/eslint-plugin": "6.13.2", + "@typescript-eslint/parser": "6.13.2", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.55.0", diff --git a/yarn.lock b/yarn.lock index 3e201a6bbf2..0d201d1e89b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7964,15 +7964,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/eslint-plugin@npm:6.13.1" +"@typescript-eslint/eslint-plugin@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/eslint-plugin@npm:6.13.2" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.13.1 - "@typescript-eslint/type-utils": 6.13.1 - "@typescript-eslint/utils": 6.13.1 - "@typescript-eslint/visitor-keys": 6.13.1 + "@typescript-eslint/scope-manager": 6.13.2 + "@typescript-eslint/type-utils": 6.13.2 + "@typescript-eslint/utils": 6.13.2 + "@typescript-eslint/visitor-keys": 6.13.2 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7985,25 +7985,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 568093d76c200a8502047d74f29300110a59b9f2a5cbf995a6cbe419c803a7ec22220e9592a884401d2dde72c79346b4cc0ee393e7b422924ad4a8a2040af3b0 + checksum: e50cbbe7104eecef59faf3355ab981d9f353b19327f0b4607dfd829b4726f9e694b536fe43ab55f50bb00fbfdd2e4268a7e2a568b28d5fcd0d2a32a8d2466218 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/parser@npm:6.13.1" +"@typescript-eslint/parser@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/parser@npm:6.13.2" dependencies: - "@typescript-eslint/scope-manager": 6.13.1 - "@typescript-eslint/types": 6.13.1 - "@typescript-eslint/typescript-estree": 6.13.1 - "@typescript-eslint/visitor-keys": 6.13.1 + "@typescript-eslint/scope-manager": 6.13.2 + "@typescript-eslint/types": 6.13.2 + "@typescript-eslint/typescript-estree": 6.13.2 + "@typescript-eslint/visitor-keys": 6.13.2 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 58b7fef6f2d02c8f4737f9908a8d335a20bee20dba648233a69f28e7b39237791d2b9fbb818e628dcc053ddf16507b161ace7f1139e093d72365f1270c426de3 + checksum: aeafc414d295d7855384f10d57abb4f5f2ff35b57991b5c8854f43268761b3cc995e62af585dea1dc48295d762f466b565b5ae5699bfe642585d3f83ba8e1515 languageName: node linkType: hard @@ -8017,22 +8017,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/scope-manager@npm:6.13.1" +"@typescript-eslint/scope-manager@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/scope-manager@npm:6.13.2" dependencies: - "@typescript-eslint/types": 6.13.1 - "@typescript-eslint/visitor-keys": 6.13.1 - checksum: 109a213f82719e10f8c6a0168f2e105dc1369c7e0c075c1f30af137030fc866a3a585a77ff78a9a3538afc213061c8aedbb4462a91f26cbd90eefbab8b89ea10 + "@typescript-eslint/types": 6.13.2 + "@typescript-eslint/visitor-keys": 6.13.2 + checksum: ff8fd64ddf324e296e2e0e34a8f73149c9a5f14d1761ea8e8665fc5998faa2b0bbbd1a5d416aa10d725f13c804032d532f68e39a0ca6cc36d1c9b9c0aea94311 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/type-utils@npm:6.13.1" +"@typescript-eslint/type-utils@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/type-utils@npm:6.13.2" dependencies: - "@typescript-eslint/typescript-estree": 6.13.1 - "@typescript-eslint/utils": 6.13.1 + "@typescript-eslint/typescript-estree": 6.13.2 + "@typescript-eslint/utils": 6.13.2 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8040,7 +8040,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: e39d28dd2f3b47a26b4f6aa2c7a301bdd769ce9148d734be93441a813c3d1111eba1d655677355bba5519f3d4dbe93e4ff4e46830216b0302df0070bf7a80057 + checksum: ba54e5746139f778c35e4058e523ec8c20b68cf6472b3a7784170328e48c228f0761d2fc7e43dab053ca7d85ac4378b6965567774e6afedf551e600638404215 languageName: node linkType: hard @@ -8051,10 +8051,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/types@npm:6.13.1" - checksum: bb1d52f1646bab9acd3ec874567ffbaaaf7fe4a5f79845bdacbfea46d15698e58d45797da05b08c23f9496a17229b7f2c1363d000fd89ce4e79874fd57ba1d4a +"@typescript-eslint/types@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/types@npm:6.13.2" + checksum: 4493ff06fa07c68c5adbcbd842f6dd6f5c88f14d160b53c3379b6b703e6f62808fab7fdebcc06ff06a56f20ab432b6ceeb0afb8931dc97d4061cb417e787f2c1 languageName: node linkType: hard @@ -8076,12 +8076,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/typescript-estree@npm:6.13.1" +"@typescript-eslint/typescript-estree@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/typescript-estree@npm:6.13.2" dependencies: - "@typescript-eslint/types": 6.13.1 - "@typescript-eslint/visitor-keys": 6.13.1 + "@typescript-eslint/types": 6.13.2 + "@typescript-eslint/visitor-keys": 6.13.2 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8090,24 +8090,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 09aa0f5cbd60e84df4f58f3d479be352549600b24dbefe75c686ea89252526c52c1c06ce1ae56c0405dd7337002e741c2ba02b71fb1caa3b94a740a70fcc8699 + checksum: 0c18ee5ef594a2411a788fe9d7bc6d51a03bce38d9d764bcb24ab557e5bc1942c2ddf9bd6fb4877eb102b0ae488974fb7b7fe72daa70a2054bf04d3cc6803546 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/utils@npm:6.13.1" +"@typescript-eslint/utils@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/utils@npm:6.13.2" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.13.1 - "@typescript-eslint/types": 6.13.1 - "@typescript-eslint/typescript-estree": 6.13.1 + "@typescript-eslint/scope-manager": 6.13.2 + "@typescript-eslint/types": 6.13.2 + "@typescript-eslint/typescript-estree": 6.13.2 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 14f64840869c8755af4d287cfc74abc424dc139559e87ca1a8b0e850f4fa56311d99dfb61a43dd4433eae5914be12b4b3390e55de1f236dce6701830d17e31c9 + checksum: b66bcf2a945e9c55f3dccb48af49565863d974837ee23b2f01ce7f3fb2462eb8a5871784d4a2fcc80dac7d5cd4ed90c8d01431cd177c0249de89a448f6663fc8 languageName: node linkType: hard @@ -8139,13 +8139,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.13.1": - version: 6.13.1 - resolution: "@typescript-eslint/visitor-keys@npm:6.13.1" +"@typescript-eslint/visitor-keys@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/visitor-keys@npm:6.13.2" dependencies: - "@typescript-eslint/types": 6.13.1 + "@typescript-eslint/types": 6.13.2 eslint-visitor-keys: ^3.4.1 - checksum: d15d362203a2fe995ea62a59d5b44c15c8fb1fb30ff59dd1542a980f75b3b62035303dfb781d83709921613f6ac8cc5bf57b70f6e20d820aec8b7911f07152e9 + checksum: 4b4def7acd7451e6a18dab3ee13f06504b3d23e51f195fced7c544f2203ee8a83426c82fa57ab6b58725c70fdedaf7a3eccb69793180be35756eed0f2c69fe04 languageName: node linkType: hard @@ -19878,8 +19878,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.13.1 - "@typescript-eslint/parser": 6.13.1 + "@typescript-eslint/eslint-plugin": 6.13.2 + "@typescript-eslint/parser": 6.13.2 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.55.0 From 6c014d490a5188b2b638a7bd53d54b9d4e119002 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 5 Dec 2023 04:56:24 +0000 Subject: [PATCH 014/136] fix(deps): update dependency @neo4j-ndl/react to v2.0.16 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 84ebe6a0080..ab567454767 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -51,7 +51,7 @@ "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", "@neo4j-ndl/base": "2.0.7", - "@neo4j-ndl/react": "2.0.14", + "@neo4j-ndl/react": "2.0.16", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.3.2", diff --git a/yarn.lock b/yarn.lock index 0d201d1e89b..50634f32252 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3525,9 +3525,9 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.0.14": - version: 2.0.14 - resolution: "@neo4j-ndl/react@npm:2.0.14" +"@neo4j-ndl/react@npm:2.0.16": + version: 2.0.16 + resolution: "@neo4j-ndl/react@npm:2.0.16" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 @@ -3552,7 +3552,7 @@ __metadata: peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: be5ab15da9f8fe4b57310caf01972e15de83dc42f60abb9f731410385429db116cd388d1bb934cd6bac64995c168a0f12251ca81f38b080f34e34e18c80fea63 + checksum: 448698c2c8c69eaae8932e4f64147c7048b6809f36126fb6ce051b2dd058b81a1b2b030da8791ce45821de726a25e85eb88ed8395b2f4238879ee88e44f72d9f languageName: node linkType: hard @@ -3635,7 +3635,7 @@ __metadata: "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 "@neo4j-ndl/base": 2.0.7 - "@neo4j-ndl/react": 2.0.14 + "@neo4j-ndl/react": 2.0.16 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 From ed9df971ea09bfe01404ab716ed07fd1ef1e3480 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 5 Dec 2023 11:33:44 +0000 Subject: [PATCH 015/136] Follow up support for logical filtering on interface aggregations --- .../src/schema/generation/where-input.ts | 8 +- ...egation-interfaces-field-level.int.test.ts | 64 +++++++++++++ ...gregation-interfaces-top-level.int.test.ts | 19 ++++ .../experimental-schema/comments.test.ts | 3 + .../directive-preserve.test.ts | 6 ++ .../directives/default.test.ts | 3 + .../directives/filterable.test.ts | 3 + .../directives/private.test.ts | 3 + .../directives/relationship-aggregate.test.ts | 6 ++ .../relationship-nested-operations.test.ts | 24 +++++ .../directives/selectable.test.ts | 6 ++ .../directives/settable.test.ts | 12 +++ .../experimental-schema/inheritance.test.ts | 3 + .../interface-relationships.test.ts | 15 +++ .../experimental-schema/interfaces.test.ts | 6 ++ .../interfaces/aggregations.test.ts | 6 ++ .../experimental-schema/issues/2377.test.ts | 3 + .../experimental-schema/issues/2993.test.ts | 6 ++ .../experimental-schema/issues/3439.test.ts | 12 +++ .../schema/experimental-schema/math.test.ts | 3 + .../nested-aggregation-on-interface.test.ts | 6 ++ .../schema/experimental-schema/plural.test.ts | 3 + .../experimental-schema/subscriptions.test.ts | 6 ++ .../union-interface-relationship.test.ts | 3 + ...aggregation-interfaces-field-level.test.ts | 91 +++++++++++++++++++ ...r-aggregation-interfaces-top-level.test.ts | 70 ++++++++++++++ 26 files changed, 389 insertions(+), 1 deletion(-) diff --git a/packages/graphql/src/schema/generation/where-input.ts b/packages/graphql/src/schema/generation/where-input.ts index bb37611b947..79215f9212e 100644 --- a/packages/graphql/src/schema/generation/where-input.ts +++ b/packages/graphql/src/schema/generation/where-input.ts @@ -93,7 +93,13 @@ export function withWhereInputType({ NOT: whereInputType, }); } else if (entityAdapter instanceof InterfaceEntityAdapter) { - if (!experimental) { + if (experimental) { + whereInputType.addFields({ + OR: whereInputType.NonNull.List, + AND: whereInputType.NonNull.List, + NOT: whereInputType, + }); + } else { const implementationsWhereInputType = makeImplementationsWhereInput({ interfaceEntityAdapter: entityAdapter, composer, diff --git a/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-field-level.int.test.ts b/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-field-level.int.test.ts index 9fd2176c30c..75b1620b232 100644 --- a/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-field-level.int.test.ts +++ b/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-field-level.int.test.ts @@ -192,4 +192,68 @@ describe("Field-level filter interface query fields", () => { }, ]); }); + + test("complex query on nested aggregation with logical operator", async () => { + const query = /* GraphQL */ ` + query { + ${Actor.plural} { + actedInAggregate(where: { AND: [{title_STARTS_WITH: "The"}, {NOT: {title_CONTAINS: "Series"}}] }) { + edge { + screenTime { + min + max + } + } + node { + title { + longest + shortest + } + } + } + name, + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect((queryResult as any).data[Actor.plural]).toIncludeSameMembers([ + { + actedInAggregate: { + edge: { + screenTime: { + max: 100, + min: 20, + }, + }, + node: { + title: { + longest: "The Movie Three", + shortest: "The Movie One", + }, + }, + }, + name: "Actor One", + }, + { + actedInAggregate: { + edge: { + screenTime: { + max: 728, + min: 240, + }, + }, + node: { + title: { + longest: "The Movie Three", + shortest: "The Movie Two", + }, + }, + }, + name: "Actor Two", + }, + ]); + }); }); diff --git a/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-top-level.int.test.ts b/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-top-level.int.test.ts index f284917224b..d6753071db4 100644 --- a/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-top-level.int.test.ts +++ b/packages/graphql/tests/integration/experimental/aggegations/filter-aggregation-interfaces-top-level.int.test.ts @@ -116,6 +116,25 @@ describe("Top-level filter interface query fields", () => { }); }); + test("top level count with logical operator", async () => { + const query = ` + query { + productionsAggregate(where: { OR: [{title: "The Show"}, {title: "A Movie"}] }) { + count + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + productionsAggregate: { + count: 2, + }, + }); + }); + test("top level count and string fields", async () => { const query = ` query { diff --git a/packages/graphql/tests/schema/experimental-schema/comments.test.ts b/packages/graphql/tests/schema/experimental-schema/comments.test.ts index 714da69c3ab..c0fed31a04a 100644 --- a/packages/graphql/tests/schema/experimental-schema/comments.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/comments.test.ts @@ -1125,6 +1125,9 @@ describe("Comments", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String 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 653ffe1732c..28dc4af3189 100644 --- a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts @@ -1563,6 +1563,9 @@ describe("Directive-preserve", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String @@ -2555,6 +2558,9 @@ describe("Directive-preserve", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String 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 73d777631a5..0534c6bae67 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts @@ -233,6 +233,9 @@ describe("@default directive", () => { } input UserInterfaceWhere { + AND: [UserInterfaceWhere!] + NOT: UserInterfaceWhere + OR: [UserInterfaceWhere!] fromInterface: String fromInterface_CONTAINS: String fromInterface_ENDS_WITH: String 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 9f78579e621..e8f336072c9 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts @@ -7416,6 +7416,9 @@ describe("@filterable directive", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] username: String username_CONTAINS: String username_ENDS_WITH: String 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 b9844283400..4e70a7f29df 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts @@ -163,6 +163,9 @@ describe("@private directive", () => { } input UserInterfaceWhere { + AND: [UserInterfaceWhere!] + NOT: UserInterfaceWhere + OR: [UserInterfaceWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 ba6c3fe3e5f..9899f0dc978 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 @@ -1474,6 +1474,9 @@ describe("@relationship directive, aggregate argument", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] password: String password_CONTAINS: String password_ENDS_WITH: String @@ -1907,6 +1910,9 @@ describe("@relationship directive, aggregate argument", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] password: String password_CONTAINS: String password_ENDS_WITH: String 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 a527d4d6021..7213b559ad9 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 @@ -8880,6 +8880,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -9326,6 +9329,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -9771,6 +9777,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10213,6 +10222,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -10649,6 +10661,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -11085,6 +11100,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -11643,6 +11661,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String @@ -12167,6 +12188,9 @@ describe("Relationship nested operations", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String 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 9e5a63e774f..bfb7ad8a19a 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts @@ -3096,6 +3096,9 @@ describe("@selectable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String @@ -3627,6 +3630,9 @@ describe("@selectable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String 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 6e7e02fdf8f..0b9b2d27f59 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts @@ -5583,6 +5583,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String @@ -6090,6 +6093,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] description: String description_CONTAINS: String description_ENDS_WITH: String @@ -6866,6 +6872,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") @@ -7803,6 +7812,9 @@ describe("@settable", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") diff --git a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts index 637fc28520a..cad158581c0 100644 --- a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts @@ -424,6 +424,9 @@ describe("inheritance", () => { } input PersonWhere { + AND: [PersonWhere!] + NOT: PersonWhere + OR: [PersonWhere!] friendsConnection: PersonFriendsConnectionWhere @deprecated(reason: \\"Use \`friendsConnection_SOME\` instead.\\") \\"\\"\\" Return People where all of the related PersonFriendsConnections match this filter 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 7b1d5160125..0ba86e54146 100644 --- a/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts @@ -446,6 +446,9 @@ describe("Interface Relationships", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] title: String title_CONTAINS: String title_ENDS_WITH: String @@ -1615,6 +1618,9 @@ describe("Interface Relationships", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsAggregate: ProductionActorsAggregateInput actorsConnection: ProductionActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") @@ -2323,6 +2329,9 @@ describe("Interface Relationships", () => { } input Interface1Where { + AND: [Interface1Where!] + NOT: Interface1Where + OR: [Interface1Where!] field1: String field1_CONTAINS: String field1_ENDS_WITH: String @@ -2398,6 +2407,9 @@ describe("Interface Relationships", () => { } input Interface2Where { + AND: [Interface2Where!] + NOT: Interface2Where + OR: [Interface2Where!] field2: String field2_CONTAINS: String field2_ENDS_WITH: String @@ -3630,6 +3642,9 @@ describe("Interface Relationships", () => { } input ContentWhere { + AND: [ContentWhere!] + NOT: ContentWhere + OR: [ContentWhere!] content: String content_CONTAINS: String content_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts index f2fd4435278..bd927609f56 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts @@ -243,6 +243,9 @@ describe("Interfaces", () => { } input MovieNodeWhere { + AND: [MovieNodeWhere!] + NOT: MovieNodeWhere + OR: [MovieNodeWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -602,6 +605,9 @@ describe("Interfaces", () => { } input MovieNodeWhere { + AND: [MovieNodeWhere!] + NOT: MovieNodeWhere + OR: [MovieNodeWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 caaa12d7833..a6dc7efeeb7 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces/aggregations.test.ts @@ -217,6 +217,9 @@ describe("Interface Top Level Aggregations", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float @@ -735,6 +738,9 @@ describe("Interface Top Level Aggregations", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float 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 d3159548206..d86a42d7874 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts @@ -407,6 +407,9 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { } input ResourceEntityWhere { + AND: [ResourceEntityWhere!] + NOT: ResourceEntityWhere + OR: [ResourceEntityWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID 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 1566b4557d1..9a28707a9e0 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts @@ -193,6 +193,9 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input ProfileWhere { + AND: [ProfileWhere!] + NOT: ProfileWhere + OR: [ProfileWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -613,6 +616,9 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input ProfileWhere { + AND: [ProfileWhere!] + NOT: ProfileWhere + OR: [ProfileWhere!] id: ID id_CONTAINS: ID id_ENDS_WITH: ID diff --git a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts index 20addafd757..174cf3a4afb 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts @@ -417,6 +417,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input INodeWhere { + AND: [INodeWhere!] + NOT: INodeWhere + OR: [INodeWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String @@ -537,6 +540,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { + AND: [IProductWhere!] + NOT: IProductWhere + OR: [IProductWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String @@ -1879,6 +1885,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { + AND: [IProductWhere!] + NOT: IProductWhere + OR: [IProductWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String @@ -2948,6 +2957,9 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { } input IProductWhere { + AND: [IProductWhere!] + NOT: IProductWhere + OR: [IProductWhere!] id: String id_CONTAINS: String id_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/math.test.ts b/packages/graphql/tests/schema/experimental-schema/math.test.ts index a24e91ac530..95be8ee3b73 100644 --- a/packages/graphql/tests/schema/experimental-schema/math.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/math.test.ts @@ -1704,6 +1704,9 @@ describe("Algebraic", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] viewers: Int viewers_GT: Int viewers_GTE: Int 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 6127c3054bd..0731ebf8663 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 @@ -463,6 +463,9 @@ describe("nested aggregation on interface", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float @@ -1074,6 +1077,9 @@ describe("nested aggregation on interface", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] cost: Float cost_GT: Float cost_GTE: Float diff --git a/packages/graphql/tests/schema/experimental-schema/plural.test.ts b/packages/graphql/tests/schema/experimental-schema/plural.test.ts index f7050f6b43b..2297b2b1a61 100644 --- a/packages/graphql/tests/schema/experimental-schema/plural.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/plural.test.ts @@ -75,6 +75,9 @@ describe("Experimental Plural option", () => { } input AnimalWhere { + AND: [AnimalWhere!] + NOT: AnimalWhere + OR: [AnimalWhere!] name: String name_CONTAINS: String name_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts index 2e89b01382f..5e30f9f616d 100644 --- a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts @@ -5853,6 +5853,9 @@ describe("Subscriptions", () => { } input CreatureWhere { + AND: [CreatureWhere!] + NOT: CreatureWhere + OR: [CreatureWhere!] moviesConnection: CreatureMoviesConnectionWhere moviesConnection_NOT: CreatureMoviesConnectionWhere } @@ -6350,6 +6353,9 @@ describe("Subscriptions", () => { } input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] directorConnection: ProductionDirectorConnectionWhere directorConnection_NOT: ProductionDirectorConnectionWhere id: ID 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 259a1b2b309..56744f2f329 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 @@ -1860,6 +1860,9 @@ describe("Union Interface Relationships", () => { } input ReviewerWhere { + AND: [ReviewerWhere!] + NOT: ReviewerWhere + OR: [ReviewerWhere!] reputation: Int reputation_GT: Int reputation_GTE: Int diff --git a/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-field-level.test.ts b/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-field-level.test.ts index a541177ae35..08788c3ba1d 100644 --- a/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-field-level.test.ts +++ b/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-field-level.test.ts @@ -189,4 +189,95 @@ describe("Interface Field Level Aggregations", () => { }" `); }); + + test("Count with OR operator and string aggregation", async () => { + const query = gql` + { + actors { + actedInAggregate(where: { OR: [{ title_STARTS_WITH: "The" }, { title_STARTS_WITH: "A" }] }) { + count + edge { + screenTime { + min + max + } + } + node { + title { + longest + shortest + } + } + } + name + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + CALL { + WITH this + CALL { + WITH this + MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + RETURN this1 AS node, this0 AS edge + UNION + WITH this + MATCH (this)-[this2:ACTED_IN]->(this3:Series) + RETURN this3 AS node, this2 AS edge + } + WITH * + WHERE (node.title STARTS WITH $param0 OR node.title STARTS WITH $param1) + RETURN count(node) AS this4 + } + CALL { + WITH this + CALL { + WITH this + MATCH (this)-[this5:ACTED_IN]->(this6:Movie) + RETURN this6 AS node, this5 AS edge + UNION + WITH this + MATCH (this)-[this7:ACTED_IN]->(this8:Series) + RETURN this8 AS node, this7 AS edge + } + WITH * + WHERE (node.title STARTS WITH $param2 OR node.title STARTS WITH $param3) + WITH node + ORDER BY size(node.title) DESC + WITH collect(node.title) AS list + RETURN { longest: head(list), shortest: last(list) } AS this9 + } + CALL { + WITH this + CALL { + WITH this + MATCH (this)-[this10:ACTED_IN]->(this11:Movie) + RETURN this11 AS node, this10 AS edge + UNION + WITH this + MATCH (this)-[this12:ACTED_IN]->(this13:Series) + RETURN this13 AS node, this12 AS edge + } + WITH * + WHERE (node.title STARTS WITH $param4 OR node.title STARTS WITH $param5) + RETURN { min: min(edge.screenTime), max: max(edge.screenTime) } AS this14 + } + RETURN this { .name, actedInAggregate: { count: this4, node: { title: this9 }, edge: { screenTime: this14 } } } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The\\", + \\"param1\\": \\"A\\", + \\"param2\\": \\"The\\", + \\"param3\\": \\"A\\", + \\"param4\\": \\"The\\", + \\"param5\\": \\"A\\" + }" + `); + }); }); diff --git a/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-top-level.test.ts b/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-top-level.test.ts index 94f7b43f175..e2c0a6dd81e 100644 --- a/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-top-level.test.ts +++ b/packages/graphql/tests/tck/experimental/aggregations/filter-aggregation-interfaces-top-level.test.ts @@ -128,4 +128,74 @@ describe("Top level filter on aggregation interfaces", () => { }" `); }); + + test("top level count and string fields with AND operation", async () => { + const query = gql` + { + productionsAggregate(where: { AND: [{ cost_GTE: 10 }, { title: "The Matrix" }] }) { + count + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + CALL { + MATCH (this0:Movie) + RETURN this0 AS node + UNION + MATCH (this1:Series) + RETURN this1 AS node + } + WITH * + WHERE (node.cost >= $param0 AND node.title = $param1) + RETURN count(node) AS this2 + } + RETURN { count: this2 }" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": 10, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + + test("top level count and string fields with OR operation", async () => { + const query = gql` + { + productionsAggregate(where: { OR: [{ cost_GTE: 10 }, { title: "The Matrix" }] }) { + count + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + CALL { + MATCH (this0:Movie) + RETURN this0 AS node + UNION + MATCH (this1:Series) + RETURN this1 AS node + } + WITH * + WHERE (node.cost >= $param0 OR node.title = $param1) + RETURN count(node) AS this2 + } + RETURN { count: this2 }" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": 10, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); }); From abf7431c0df4e843d158f66c187e209ea177f868 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 01:26:37 +0000 Subject: [PATCH 016/136] chore(deps): update dependency @types/jest to v29.5.11 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- packages/introspector/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index aa890ab7886..2cafe532996 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -39,7 +39,7 @@ "@types/body-parser": "1.19.5", "@types/cors": "2.8.17", "@types/debug": "4.1.12", - "@types/jest": "29.5.10", + "@types/jest": "29.5.11", "@types/node": "20.10.3", "camelcase": "6.3.0", "graphql-ws": "5.14.2", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 3a88661cf34..372495a66d3 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -54,7 +54,7 @@ "@faker-js/faker": "8.3.1", "@types/deep-equal": "1.0.4", "@types/is-uuid": "1.0.2", - "@types/jest": "29.5.10", + "@types/jest": "29.5.11", "@types/jsonwebtoken": "9.0.5", "@types/node": "20.10.3", "@types/pluralize": "0.0.33", diff --git a/packages/introspector/package.json b/packages/introspector/package.json index 947b2c6f40a..f369600e63a 100644 --- a/packages/introspector/package.json +++ b/packages/introspector/package.json @@ -37,7 +37,7 @@ "author": "Neo4j Inc.", "devDependencies": { "@neo4j/graphql": "^4.0.0", - "@types/jest": "29.5.10", + "@types/jest": "29.5.11", "@types/node": "20.10.3", "@types/pluralize": "0.0.33", "jest": "29.7.0", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index 58603cd0a82..68b4a60d8cb 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -46,7 +46,7 @@ "neo4j-driver": "^5.8.0" }, "devDependencies": { - "@types/jest": "29.5.10", + "@types/jest": "29.5.11", "@types/node": "20.10.3", "camelcase": "6.3.0", "graphql-tag": "2.12.6", diff --git a/yarn.lock b/yarn.lock index 50634f32252..689ed921473 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3573,7 +3573,7 @@ __metadata: "@types/body-parser": 1.19.5 "@types/cors": 2.8.17 "@types/debug": 4.1.12 - "@types/jest": 29.5.10 + "@types/jest": 29.5.11 "@types/node": 20.10.3 amqplib: 0.10.3 body-parser: ^1.20.2 @@ -3602,7 +3602,7 @@ __metadata: "@graphql-codegen/typescript": ^4.0.0 "@graphql-tools/merge": ^9.0.0 "@neo4j/graphql": ^4.4.4 - "@types/jest": 29.5.10 + "@types/jest": 29.5.11 "@types/node": 20.10.3 camelcase: 6.3.0 graphql-tag: 2.12.6 @@ -3708,7 +3708,7 @@ __metadata: "@neo4j/cypher-builder": ^1.7.1 "@types/deep-equal": 1.0.4 "@types/is-uuid": 1.0.2 - "@types/jest": 29.5.10 + "@types/jest": 29.5.11 "@types/jsonwebtoken": 9.0.5 "@types/node": 20.10.3 "@types/pluralize": 0.0.33 @@ -3766,7 +3766,7 @@ __metadata: resolution: "@neo4j/introspector@workspace:packages/introspector" dependencies: "@neo4j/graphql": ^4.0.0 - "@types/jest": 29.5.10 + "@types/jest": 29.5.11 "@types/node": 20.10.3 "@types/pluralize": 0.0.33 camelcase: ^6.3.0 @@ -7504,13 +7504,13 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:29.5.10": - version: 29.5.10 - resolution: "@types/jest@npm:29.5.10" +"@types/jest@npm:29.5.11": + version: 29.5.11 + resolution: "@types/jest@npm:29.5.11" dependencies: expect: ^29.0.0 pretty-format: ^29.0.0 - checksum: ef385905787db528de9b6beb2688865c0bb276e64256ed60b9a1a6ffc0b75737456cb5e27e952a3241c5845b6a1da487470010dd30f3ca59c8581624c564a823 + checksum: f892a06ec9f0afa9a61cd7fa316ec614e21d4df1ad301b5a837787e046fcb40dfdf7f264a55e813ac6b9b633cb9d366bd5b8d1cea725e84102477b366df23fdd languageName: node linkType: hard From f651d2f065be8b1ae36328726c166a3eac791689 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 6 Dec 2023 13:26:40 +0000 Subject: [PATCH 017/136] Remove unused node variable --- .../src/schema/make-augmented-schema.ts | 3 --- .../src/schema/resolvers/query/aggregate.ts | 4 ---- .../src/schema/resolvers/query/fulltext.ts | 2 +- .../src/schema/resolvers/query/global-node.ts | 11 +++++------ .../graphql/src/schema/resolvers/query/read.ts | 4 +--- .../schema/resolvers/query/root-connection.ts | 5 ----- packages/graphql/src/translate/index.ts | 6 +++--- .../src/translate/translate-aggregate.ts | 18 +----------------- .../graphql/src/translate/translate-read.ts | 5 ----- 9 files changed, 11 insertions(+), 47 deletions(-) diff --git a/packages/graphql/src/schema/make-augmented-schema.ts b/packages/graphql/src/schema/make-augmented-schema.ts index 96e7fbaebc7..734d101ddd1 100644 --- a/packages/graphql/src/schema/make-augmented-schema.ts +++ b/packages/graphql/src/schema/make-augmented-schema.ts @@ -335,7 +335,6 @@ function makeAugmentedSchema({ if (concreteEntityAdapter.isReadable) { composer.Query.addFields({ [concreteEntityAdapter.operations.rootTypeFieldNames.read]: findResolver({ - node, entityAdapter: concreteEntityAdapter, }), }); @@ -345,7 +344,6 @@ function makeAugmentedSchema({ ); composer.Query.addFields({ [concreteEntityAdapter.operations.rootTypeFieldNames.connection]: rootConnectionResolver({ - node, composer, concreteEntityAdapter, propagatedDirectives, @@ -359,7 +357,6 @@ function makeAugmentedSchema({ if (concreteEntityAdapter.isAggregable) { composer.Query.addFields({ [concreteEntityAdapter.operations.rootTypeFieldNames.aggregate]: aggregateResolver({ - node, concreteEntityAdapter, }), }); diff --git a/packages/graphql/src/schema/resolvers/query/aggregate.ts b/packages/graphql/src/schema/resolvers/query/aggregate.ts index 1fde1c410b9..9fa70d0462d 100644 --- a/packages/graphql/src/schema/resolvers/query/aggregate.ts +++ b/packages/graphql/src/schema/resolvers/query/aggregate.ts @@ -18,7 +18,6 @@ */ import type { GraphQLResolveInfo } from "graphql"; -import type { Node } from "../../../classes"; import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; import type { InterfaceEntityAdapter } from "../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; import { translateAggregate } from "../../../translate"; @@ -28,10 +27,8 @@ import getNeo4jResolveTree from "../../../utils/get-neo4j-resolve-tree"; import type { Neo4jGraphQLComposedContext } from "../composition/wrap-query-and-mutation"; export function aggregateResolver({ - node, concreteEntityAdapter, }: { - node?: Node; concreteEntityAdapter: ConcreteEntityAdapter | InterfaceEntityAdapter; }) { async function resolve(_root: any, _args: any, context: Neo4jGraphQLComposedContext, info: GraphQLResolveInfo) { @@ -41,7 +38,6 @@ export function aggregateResolver({ const { cypher, params } = translateAggregate({ context: context as Neo4jGraphQLTranslationContext, - node, entityAdapter: concreteEntityAdapter, }); diff --git a/packages/graphql/src/schema/resolvers/query/fulltext.ts b/packages/graphql/src/schema/resolvers/query/fulltext.ts index 8eeecedff32..e432e6e5440 100644 --- a/packages/graphql/src/schema/resolvers/query/fulltext.ts +++ b/packages/graphql/src/schema/resolvers/query/fulltext.ts @@ -57,7 +57,7 @@ export function fulltextResolver({ (context as Neo4jGraphQLTranslationContext).resolveTree = resolveTree; const { cypher, params } = translateRead( - { context: context as Neo4jGraphQLTranslationContext, node, entityAdapter }, + { context: context as Neo4jGraphQLTranslationContext, entityAdapter }, node.singular ); const executeResult = await execute({ diff --git a/packages/graphql/src/schema/resolvers/query/global-node.ts b/packages/graphql/src/schema/resolvers/query/global-node.ts index 520eb3d454a..fa7f161301b 100644 --- a/packages/graphql/src/schema/resolvers/query/global-node.ts +++ b/packages/graphql/src/schema/resolvers/query/global-node.ts @@ -20,14 +20,14 @@ import type { GraphQLResolveInfo } from "graphql"; import type { FieldsByTypeName } from "graphql-parse-resolve-info"; import { parseResolveInfo } from "graphql-parse-resolve-info"; -import { execute } from "../../../utils"; -import { translateRead } from "../../../translate"; import type { Node } from "../../../classes"; +import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +import { translateRead } from "../../../translate"; +import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context"; +import { execute } from "../../../utils"; +import getNeo4jResolveTree from "../../../utils/get-neo4j-resolve-tree"; import { fromGlobalId } from "../../../utils/global-ids"; import type { Neo4jGraphQLComposedContext } from "../composition/wrap-query-and-mutation"; -import getNeo4jResolveTree from "../../../utils/get-neo4j-resolve-tree"; -import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context"; -import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; export function globalNodeResolver({ nodes, entities }: { nodes: Node[]; entities: ConcreteEntityAdapter[] }) { async function resolve( @@ -70,7 +70,6 @@ export function globalNodeResolver({ nodes, entities }: { nodes: Node[]; entitie const { cypher, params } = translateRead({ context: context as Neo4jGraphQLTranslationContext, - node, entityAdapter, }); const executeResult = await execute({ diff --git a/packages/graphql/src/schema/resolvers/query/read.ts b/packages/graphql/src/schema/resolvers/query/read.ts index f4a9c8df0c9..75bbb13e0a2 100644 --- a/packages/graphql/src/schema/resolvers/query/read.ts +++ b/packages/graphql/src/schema/resolvers/query/read.ts @@ -18,7 +18,6 @@ */ import type { GraphQLResolveInfo } from "graphql"; -import type { Node } from "../../../classes"; import { QueryOptions } from "../../../graphql/input-objects/QueryOptions"; import type { EntityAdapter } from "../../../schema-model/entity/EntityAdapter"; import { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; @@ -29,7 +28,7 @@ import { execute } from "../../../utils"; import getNeo4jResolveTree from "../../../utils/get-neo4j-resolve-tree"; import type { Neo4jGraphQLComposedContext } from "../composition/wrap-query-and-mutation"; -export function findResolver({ node, entityAdapter }: { node?: Node; entityAdapter: EntityAdapter }) { +export function findResolver({ entityAdapter }: { entityAdapter: EntityAdapter }) { async function resolve(_root: any, args: any, context: Neo4jGraphQLComposedContext, info: GraphQLResolveInfo) { const resolveTree = getNeo4jResolveTree(info, { args }); @@ -37,7 +36,6 @@ export function findResolver({ node, entityAdapter }: { node?: Node; entityAdapt const { cypher, params } = translateRead({ context: context as Neo4jGraphQLTranslationContext, - node, entityAdapter, }); const executeResult = await execute({ diff --git a/packages/graphql/src/schema/resolvers/query/root-connection.ts b/packages/graphql/src/schema/resolvers/query/root-connection.ts index 46f46d4ca55..83cccd9206b 100644 --- a/packages/graphql/src/schema/resolvers/query/root-connection.ts +++ b/packages/graphql/src/schema/resolvers/query/root-connection.ts @@ -27,7 +27,6 @@ import { } from "graphql"; import type { InputTypeComposer, SchemaComposer } from "graphql-compose"; import type { PageInfo as PageInfoRelay } from "graphql-relay"; -import type { Node } from "../../../classes"; import { PageInfo } from "../../../graphql/objects/PageInfo"; import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; import { translateRead } from "../../../translate"; @@ -40,12 +39,10 @@ import { graphqlDirectivesToCompose } from "../../to-compose"; import type { Neo4jGraphQLComposedContext } from "../composition/wrap-query-and-mutation"; export function rootConnectionResolver({ - node, composer, concreteEntityAdapter, propagatedDirectives, }: { - node: Node; composer: SchemaComposer; concreteEntityAdapter: ConcreteEntityAdapter; propagatedDirectives: DirectiveNode[]; @@ -56,9 +53,7 @@ export function rootConnectionResolver({ const { cypher, params } = translateRead({ context: context as Neo4jGraphQLTranslationContext, - node, entityAdapter: concreteEntityAdapter, - isRootConnectionField: true, }); const executeResult = await execute({ diff --git a/packages/graphql/src/translate/index.ts b/packages/graphql/src/translate/index.ts index f225a95db1b..299bbb81edd 100644 --- a/packages/graphql/src/translate/index.ts +++ b/packages/graphql/src/translate/index.ts @@ -17,9 +17,9 @@ * limitations under the License. */ +export { translateAggregate } from "./translate-aggregate"; export { default as translateCreate } from "./translate-create"; -export { translateRead } from "./translate-read"; -export { default as translateUpdate } from "./translate-update"; export { translateDelete } from "./translate-delete"; -export { default as translateAggregate } from "./translate-aggregate"; +export { translateRead } from "./translate-read"; export { translateTopLevelCypher } from "./translate-top-level-cypher"; +export { default as translateUpdate } from "./translate-update"; diff --git a/packages/graphql/src/translate/translate-aggregate.ts b/packages/graphql/src/translate/translate-aggregate.ts index de879f03377..c7b09afce77 100644 --- a/packages/graphql/src/translate/translate-aggregate.ts +++ b/packages/graphql/src/translate/translate-aggregate.ts @@ -19,7 +19,6 @@ import type Cypher from "@neo4j/cypher-builder"; import Debug from "debug"; -import type { Node } from "../classes"; import { DEBUG_TRANSLATE } from "../constants"; import type { EntityAdapter } from "../schema-model/entity/EntityAdapter"; import type { Neo4jGraphQLTranslationContext } from "../types/neo4j-graphql-translation-context"; @@ -27,7 +26,7 @@ import { QueryASTFactory } from "./queryAST/factory/QueryASTFactory"; const debug = Debug(DEBUG_TRANSLATE); -function translateQuery({ +export function translateAggregate({ context, entityAdapter, }: { @@ -44,18 +43,3 @@ function translateQuery({ const clause = queryAST.buildNew(context); return clause.build(); } - -function translateAggregate({ - node, - context, - entityAdapter, -}: { - node: Node | undefined; - context: Neo4jGraphQLTranslationContext; - entityAdapter: EntityAdapter; -}): Cypher.CypherResult { - // TODO: Move fulltext to new translation layer to remove the deprecated translation - return translateQuery({ context, entityAdapter }); -} - -export default translateAggregate; diff --git a/packages/graphql/src/translate/translate-read.ts b/packages/graphql/src/translate/translate-read.ts index f7bd764372b..1fb8202650f 100644 --- a/packages/graphql/src/translate/translate-read.ts +++ b/packages/graphql/src/translate/translate-read.ts @@ -19,7 +19,6 @@ import type Cypher from "@neo4j/cypher-builder"; import Debug from "debug"; -import type { Node } from "../classes"; import { DEBUG_TRANSLATE } from "../constants"; import type { EntityAdapter } from "../schema-model/entity/EntityAdapter"; import type { Neo4jGraphQLTranslationContext } from "../types/neo4j-graphql-translation-context"; @@ -29,14 +28,10 @@ const debug = Debug(DEBUG_TRANSLATE); export function translateRead( { - node, context, - isRootConnectionField, entityAdapter, }: { context: Neo4jGraphQLTranslationContext; - node?: Node; - isRootConnectionField?: boolean; entityAdapter: EntityAdapter; }, varName = "this" From 6e4d227a0a06061875d2b7da1b9afe144e6a14c5 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 6 Dec 2023 13:53:28 +0000 Subject: [PATCH 018/136] Update read operations to use projectionExpr for top level build --- .../src/translate/queryAST/ast/QueryAST.ts | 10 ++++- .../ast/operations/ConnectionReadOperation.ts | 21 +++++----- .../ast/operations/FulltextOperation.ts | 21 +++++++++- .../queryAST/ast/operations/ReadOperation.ts | 14 +++++-- .../composite/CompositeReadOperation.ts | 14 +++---- .../queryAST/ast/operations/operations.ts | 3 +- .../graphql/src/translate/translate-read.ts | 2 +- .../interface-authorization.test.ts | 21 ++++++---- .../experimental/interface-filtering.test.ts | 3 +- .../experimental/interface-pagination.test.ts | 35 +++++++++------- .../experimental/interface-top-level.test.ts | 21 ++++++---- .../experimental/union-authorization.test.ts | 19 +++++---- .../tck/experimental/union-top-level.test.ts | 40 +++++++++++-------- .../graphql/tests/tck/root-connection.test.ts | 4 +- 14 files changed, 149 insertions(+), 79 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/QueryAST.ts b/packages/graphql/src/translate/queryAST/ast/QueryAST.ts index 24fd7d6a6cb..85f79cc3745 100644 --- a/packages/graphql/src/translate/queryAST/ast/QueryAST.ts +++ b/packages/graphql/src/translate/queryAST/ast/QueryAST.ts @@ -43,8 +43,14 @@ export class QueryAST { public buildNew(neo4jGraphQLContext: Neo4jGraphQLTranslationContext, varName?: string): Cypher.Clause { const context = this.buildQueryASTContext(neo4jGraphQLContext, varName); - const { clauses, projectionExpr } = this.transpile(context); - const returnClause = new Cypher.Return(projectionExpr); + const { clauses, projectionExpr, extraProjectionColumns } = this.transpile(context); + const returnClause = varName ? new Cypher.Return([projectionExpr, varName]) : new Cypher.Return(projectionExpr); + + if (extraProjectionColumns) { + for (const projectionColumn of extraProjectionColumns) { + returnClause.addColumns(projectionColumn); + } + } return Cypher.concat(...clauses, returnClause); } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index f4808d8ef00..f32cffcfacd 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -327,13 +327,13 @@ export class ConnectionReadOperation extends Operation { let extraWithOrder: Cypher.Clause | undefined; - const returnClause = new Cypher.Return([ - new Cypher.Map({ - edges: edgesVar, - totalCount: totalCount, - }), - context.returnVariable, - ]); + // const returnClause = new Cypher.Return([ + // new Cypher.Map({ + // edges: edgesVar, + // totalCount: totalCount, + // }), + // context.returnVariable, + // ]); const connectionMatchAndAuthClause = Cypher.concat( ...preSelection, @@ -352,13 +352,16 @@ export class ConnectionReadOperation extends Operation { paginationWith, ...postPaginationSubqueries, withProjection, - returnClause, + // returnClause, ] ); return { clauses: [clause], - projectionExpr: context.returnVariable, + projectionExpr: new Cypher.Map({ + edges: edgesVar, + totalCount: totalCount, + }), }; } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/FulltextOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/FulltextOperation.ts index 681edb2fce8..ed63e1a147c 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/FulltextOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/FulltextOperation.ts @@ -17,7 +17,7 @@ * limitations under the License. */ -import type Cypher from "@neo4j/cypher-builder"; +import Cypher from "@neo4j/cypher-builder"; import type { ConcreteEntityAdapter } from "../../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; import type { RelationshipAdapter } from "../../../../schema-model/relationship/model-adapters/RelationshipAdapter"; import { filterTruthy } from "../../../../utils/utils"; @@ -26,6 +26,7 @@ import type { QueryASTNode } from "../QueryASTNode"; import type { FulltextScoreField } from "../fields/FulltextScoreField"; import type { EntitySelection } from "../selection/EntitySelection"; import { ReadOperation } from "./ReadOperation"; +import type { OperationTranspileResult } from "./operations"; export type FulltextOptions = { index: string; @@ -59,6 +60,24 @@ export class FulltextOperation extends ReadOperation { this.scoreField = scoreField; } + public transpile(context: QueryASTContext): OperationTranspileResult { + const { clauses, projectionExpr } = super.transpile(context); + + const extraProjectionColumns: Array<[Cypher.Expr, Cypher.Variable]> = []; + + if (this.scoreField) { + const scoreProjection = this.scoreField.getProjectionField(context.returnVariable); + + extraProjectionColumns.push([scoreProjection.score, new Cypher.NamedVariable("score")]); + } + + return { + clauses, + projectionExpr, + extraProjectionColumns, + }; + } + public getChildren(): QueryASTNode[] { return filterTruthy([...super.getChildren(), this.scoreField]); } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts index e862c760dd3..7c8b88ff5d7 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts @@ -311,14 +311,14 @@ export class ReadOperation extends Operation { filterSubqueriesClause, filterSubqueryWith, sortAndLimitBlock, - subqueries, - ret + subqueries + // ret ); } return { clauses: [clause], - projectionExpr: context.returnVariable, + projectionExpr: this.getReturnExpression(nestedContext), }; } @@ -330,6 +330,14 @@ export class ReadOperation extends Operation { return new Cypher.Return([projection, returnVariable]); } + protected getReturnExpression(context: QueryASTContext): Cypher.Expr { + const projection = this.getProjectionMap(context); + if (context.shouldCollect) { + return Cypher.collect(projection); + } + return projection; + } + private hasCypherSort(): boolean { return this.sortFields.some((s) => s instanceof CypherPropertySort); } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts index ca9656ef2a4..6f484ad1798 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts @@ -18,16 +18,16 @@ */ import Cypher from "@neo4j/cypher-builder"; -import type { QueryASTNode } from "../../QueryASTNode"; -import type { OperationTranspileResult } from "../operations"; -import { Operation } from "../operations"; -import type { CompositeReadPartial } from "./CompositeReadPartial"; -import type { UnionEntityAdapter } from "../../../../../schema-model/entity/model-adapters/UnionEntityAdapter"; 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 { QueryASTContext } from "../../QueryASTContext"; +import type { QueryASTNode } from "../../QueryASTNode"; import type { Pagination } from "../../pagination/Pagination"; import type { Sort, SortField } from "../../sort/Sort"; -import type { QueryASTContext } from "../../QueryASTContext"; +import type { OperationTranspileResult } from "../operations"; +import { Operation } from "../operations"; +import type { CompositeReadPartial } from "./CompositeReadPartial"; export class CompositeReadOperation extends Operation { private children: CompositeReadPartial[]; @@ -60,7 +60,7 @@ export class CompositeReadOperation extends Operation { const result = c.transpile(context); return result.clauses; }); - const nestedSubquery = new Cypher.Call(new Cypher.Union(...nestedSubqueries)).return(context.returnVariable); + const nestedSubquery = new Cypher.Call(new Cypher.Union(...nestedSubqueries)).with(context.returnVariable); if (this.sortFields.length > 0) { nestedSubquery.orderBy(...this.getSortFields(context, context.returnVariable)); } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/operations.ts b/packages/graphql/src/translate/queryAST/ast/operations/operations.ts index 2350634eb94..616f0f2e0e3 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/operations.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/operations.ts @@ -18,12 +18,13 @@ */ import type Cypher from "@neo4j/cypher-builder"; -import { QueryASTNode } from "../QueryASTNode"; import type { QueryASTContext } from "../QueryASTContext"; +import { QueryASTNode } from "../QueryASTNode"; export type OperationTranspileResult = { projectionExpr: Cypher.Expr; clauses: Cypher.Clause[]; + extraProjectionColumns?: Array<[Cypher.Expr, Cypher.Variable]>; // This embeds extra columns in the last return, used as a hack for fulltext score }; export abstract class Operation extends QueryASTNode { diff --git a/packages/graphql/src/translate/translate-read.ts b/packages/graphql/src/translate/translate-read.ts index 1fb8202650f..5fef0020ae9 100644 --- a/packages/graphql/src/translate/translate-read.ts +++ b/packages/graphql/src/translate/translate-read.ts @@ -42,6 +42,6 @@ export function translateRead( if (!entityAdapter) throw new Error("Entity not found"); const operationsTree = operationsTreeFactory.createQueryAST(resolveTree, entityAdapter, context); debug(operationsTree.print()); - const clause = operationsTree.build(context, varName); + const clause = operationsTree.buildNew(context, varName); return clause.build(); } diff --git a/packages/graphql/tests/tck/experimental/interface-authorization.test.ts b/packages/graphql/tests/tck/experimental/interface-authorization.test.ts index 7d7b60845b6..e439d80308f 100644 --- a/packages/graphql/tests/tck/experimental/interface-authorization.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-authorization.test.ts @@ -106,7 +106,8 @@ describe("Interface top level operations with authorization", () => { WITH this2 { .id, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -153,7 +154,8 @@ describe("Interface top level operations with authorization", () => { WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -203,7 +205,8 @@ describe("Interface top level operations with authorization", () => { WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -255,7 +258,8 @@ describe("Interface top level operations with authorization", () => { WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -302,7 +306,8 @@ describe("Interface top level operations with authorization", () => { WITH this0 { .id, other: var3, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -336,7 +341,8 @@ describe("Interface top level operations with authorization", () => { WITH this0 { .id, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -374,7 +380,8 @@ describe("Interface top level operations with authorization", () => { WITH this0 { .id, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/experimental/interface-filtering.test.ts b/packages/graphql/tests/tck/experimental/interface-filtering.test.ts index ab5c812d0fb..75a09cbcbb8 100644 --- a/packages/graphql/tests/tck/experimental/interface-filtering.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-filtering.test.ts @@ -89,7 +89,8 @@ describe("Interface top level operations", () => { WITH this1 { .title, __resolveType: \\"Series\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/experimental/interface-pagination.test.ts b/packages/graphql/tests/tck/experimental/interface-pagination.test.ts index f1aac4dbe06..ebd06368076 100644 --- a/packages/graphql/tests/tck/experimental/interface-pagination.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-pagination.test.ts @@ -104,9 +104,10 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this5 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this5) } AS this5 RETURN this5 AS this } - RETURN this + WITH this ORDER BY this.id ASC - LIMIT $param0" + LIMIT $param0 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -149,9 +150,10 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this2 { .someField, .id, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this + WITH this ORDER BY this.id ASC - LIMIT $param0" + LIMIT $param0 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -209,9 +211,10 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this5 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this5) } AS this5 RETURN this5 AS this } - RETURN this + WITH this ORDER BY this.id ASC - LIMIT $param1" + LIMIT $param1 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -340,8 +343,9 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this5 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this5) } AS this5 RETURN this5 AS this } - RETURN this - LIMIT $param0" + WITH this + LIMIT $param0 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -396,8 +400,9 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this5 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this5) } AS this5 RETURN this5 AS this } - RETURN this - LIMIT $param0" + WITH this + LIMIT $param0 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -452,8 +457,9 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this5 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this5) } AS this5 RETURN this5 AS this } - RETURN this - LIMIT $param0" + WITH this + LIMIT $param0 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -508,9 +514,10 @@ describe("Top-level Interface query pagination (sort and limit)", () => { WITH this5 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this5) } AS this5 RETURN this5 AS this } - RETURN this + WITH this ORDER BY this.id ASC - LIMIT $param0" + LIMIT $param0 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/experimental/interface-top-level.test.ts b/packages/graphql/tests/tck/experimental/interface-top-level.test.ts index cea86f3f483..62f9120a011 100644 --- a/packages/graphql/tests/tck/experimental/interface-top-level.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-top-level.test.ts @@ -90,7 +90,8 @@ describe("Interface top level operations", () => { WITH this2 { .id, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -125,7 +126,8 @@ describe("Interface top level operations", () => { WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -163,7 +165,8 @@ describe("Interface top level operations", () => { WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -203,7 +206,8 @@ describe("Interface top level operations", () => { WITH this2 { .id, .someField, __resolveType: \\"MyOtherImplementationType\\", __id: id(this2) } AS this2 RETURN this2 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -239,7 +243,8 @@ describe("Interface top level operations", () => { WITH this0 { .id, other: var3, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -264,7 +269,8 @@ describe("Interface top level operations", () => { WITH this0 { .id, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -296,7 +302,8 @@ describe("Interface top level operations", () => { WITH this0 { .id, __resolveType: \\"SomeNodeType\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/experimental/union-authorization.test.ts b/packages/graphql/tests/tck/experimental/union-authorization.test.ts index f5d5f5afdec..85c104ab6ba 100644 --- a/packages/graphql/tests/tck/experimental/union-authorization.test.ts +++ b/packages/graphql/tests/tck/experimental/union-authorization.test.ts @@ -17,11 +17,11 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../../src"; -import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; import { createBearerToken } from "../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; describe("Union top level operations with authorization", () => { const secret = "secret"; @@ -81,7 +81,8 @@ describe("Union top level operations with authorization", () => { WITH this1 { .title, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -145,7 +146,8 @@ describe("Union top level operations with authorization", () => { WITH this1 { .title, search: var4, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -210,7 +212,8 @@ describe("Union top level operations with authorization", () => { WITH this1 { .title, search: var4, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -271,7 +274,8 @@ describe("Union top level operations with authorization", () => { WITH this0 { .title, search: var3, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -335,7 +339,8 @@ describe("Union top level operations with authorization", () => { WITH this0 { .title, search: var5, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/experimental/union-top-level.test.ts b/packages/graphql/tests/tck/experimental/union-top-level.test.ts index 2bd74aa1393..0caaf32aff5 100644 --- a/packages/graphql/tests/tck/experimental/union-top-level.test.ts +++ b/packages/graphql/tests/tck/experimental/union-top-level.test.ts @@ -66,17 +66,18 @@ describe("Union top level operations", () => { const result = await translateQuery(neoSchema, query, { token }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "CALL { - MATCH (this0:Genre) - WITH this0 { .name, __resolveType: \\"Genre\\", __id: id(this0) } AS this0 - RETURN this0 AS this - UNION - MATCH (this1:Movie) - WITH this1 { .title, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 - RETURN this1 AS this - } - RETURN this" - `); + "CALL { + MATCH (this0:Genre) + WITH this0 { .name, __resolveType: \\"Genre\\", __id: id(this0) } AS this0 + RETURN this0 AS this + UNION + MATCH (this1:Movie) + WITH this1 { .title, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 + RETURN this1 AS this + } + WITH this + RETURN this AS this" + `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); }); @@ -129,7 +130,8 @@ describe("Union top level operations", () => { WITH this1 { .title, search: var4, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -184,7 +186,8 @@ describe("Union top level operations", () => { WITH this1 { .title, search: var4, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -239,7 +242,8 @@ describe("Union top level operations", () => { WITH this0 { .title, search: var3, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -297,7 +301,8 @@ describe("Union top level operations", () => { WITH this0 { .title, search: var5, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 RETURN this0 AS this } - RETURN this" + WITH this + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -363,9 +368,10 @@ describe("Union top level operations", () => { WITH this1 { .title, search: var4, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 RETURN this1 AS this } - RETURN this + WITH this SKIP $param3 - LIMIT $param4" + LIMIT $param4 + RETURN this AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index d81511b9352..f39afa5d914 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -17,10 +17,10 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../src"; -import { formatCypher, translateQuery, formatParams } from "./utils/tck-test-utils"; +import { formatCypher, formatParams, translateQuery } from "./utils/tck-test-utils"; describe("Root Connection Query tests", () => { let typeDefs: DocumentNode; From ab79b81d64d31e9d5ef07c520ae01a33d8a199e5 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 6 Dec 2023 15:07:39 +0000 Subject: [PATCH 019/136] Use Selection tree node in connections --- .../ast/operations/ConnectionReadOperation.ts | 103 +++++---- .../queryAST/factory/OperationFactory.ts | 22 +- .../integration/connections/sort.int.test.ts | 6 +- .../tests/tck/connections/sort.test.ts | 50 ++-- .../where/connection-auth-filter.test.ts | 214 +++++++++--------- .../projection-connection.test.ts | 62 ++--- .../graphql/tests/tck/issues/1364.test.ts | 76 +++---- .../graphql/tests/tck/issues/2022.test.ts | 35 ++- .../graphql/tests/tck/issues/3394.test.ts | 12 +- .../graphql/tests/tck/root-connection.test.ts | 58 ++--- 10 files changed, 339 insertions(+), 299 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index f32cffcfacd..eb1fea7345f 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -22,7 +22,6 @@ import type { ConcreteEntityAdapter } from "../../../../schema-model/entity/mode import type { RelationshipAdapter } from "../../../../schema-model/relationship/model-adapters/RelationshipAdapter"; import { filterTruthy } from "../../../../utils/utils"; import { hasTarget } from "../../utils/context-has-target"; -import { createNodeFromEntity } from "../../utils/create-node-from-entity"; import { wrapSubqueriesInCypherCalls } from "../../utils/wrap-subquery-in-calls"; import type { QueryASTContext } from "../QueryASTContext"; import type { QueryASTNode } from "../QueryASTNode"; @@ -31,6 +30,7 @@ import { CypherAttributeField } from "../fields/attribute-fields/CypherAttribute import type { Filter } from "../filters/Filter"; import type { AuthorizationFilters } from "../filters/authorization-filters/AuthorizationFilters"; import type { Pagination, PaginationField } from "../pagination/Pagination"; +import type { EntitySelection } from "../selection/EntitySelection"; import { CypherPropertySort } from "../sort/CypherPropertySort"; import type { Sort, SortField } from "../sort/Sort"; import type { OperationTranspileResult } from "./operations"; @@ -49,19 +49,24 @@ export class ConnectionReadOperation extends Operation { protected authFilters: AuthorizationFilters[] = []; public nodeAlias: string | undefined; // This is just to maintain naming with the old way (this), remove after refactor + protected selection: EntitySelection; + constructor({ relationship, directed, target, + selection, }: { relationship: RelationshipAdapter | undefined; target: ConcreteEntityAdapter; directed: boolean; + selection: EntitySelection; }) { super(); this.relationship = relationship; this.directed = directed; this.target = target; + this.selection = selection; } public setNodeFields(fields: Field[]) { @@ -137,25 +142,30 @@ export class ConnectionReadOperation extends Operation { private transpileNested(context: QueryASTContext): OperationTranspileResult { if (!context.target || !this.relationship) throw new Error(); - const targetNode = createNodeFromEntity(this.target, context.neo4jGraphQLContext); - const relationship = new Cypher.Relationship({ type: this.relationship.type }); - const relDirection = this.relationship.getCypherDirection(this.directed); - const pattern = new Cypher.Pattern(context.target) - .withoutLabels() - .related(relationship) - .withDirection(relDirection) - .to(targetNode); + // eslint-disable-next-line prefer-const + let { selection: clause, nestedContext } = this.selection.apply(context); + const relationship = nestedContext.relationship; + if (!relationship) { + throw new Error("Relationship not available"); + } - const nestedContext = context.push({ target: targetNode, relationship }); + let extraMatches: Array = this.getChildren().flatMap((f) => { + return f.getSelection(nestedContext); + }); - const { preSelection, selectionClause: clause } = this.getSelectionClauses(nestedContext, pattern); + if (extraMatches.length > 0) { + extraMatches = [clause, ...extraMatches]; + clause = new Cypher.With("*"); + } const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => - new Cypher.Call(sq).innerWith(targetNode) + new Cypher.Call(sq).innerWith(nestedContext.target) ); - const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [targetNode]); + const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ + nestedContext.target, + ]); const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); const authPredicate = this.getAuthFilterPredicate(nestedContext); @@ -163,10 +173,10 @@ export class ConnectionReadOperation extends Operation { const nodeProjectionMap = new Cypher.Map(); this.nodeFields - .map((f) => f.getProjectionField(targetNode)) + .map((f) => f.getProjectionField(nestedContext.target)) .forEach((p) => { if (typeof p === "string") { - nodeProjectionMap.set(p, targetNode.property(p)); + nodeProjectionMap.set(p, nestedContext.target.property(p)); } else { nodeProjectionMap.set(p); } @@ -176,7 +186,7 @@ export class ConnectionReadOperation extends Operation { const targetNodeName = this.target.name; nodeProjectionMap.set({ __resolveType: new Cypher.Literal(targetNodeName), - __id: Cypher.id(targetNode), + __id: Cypher.id(nestedContext.target), }); } @@ -220,11 +230,11 @@ export class ConnectionReadOperation extends Operation { if (this.sortFields.length > 0) { const sortFields = this.getSortFields({ context: nestedContext, - nodeVar: targetNode, + nodeVar: nestedContext.target, edgeVar: relationship, }); - extraWithOrder = new Cypher.With(relationship, targetNode).orderBy(...sortFields); + extraWithOrder = new Cypher.With(relationship, nestedContext.target).orderBy(...sortFields); } const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) @@ -239,7 +249,7 @@ export class ConnectionReadOperation extends Operation { context.returnVariable, ]); const subClause = Cypher.concat( - ...preSelection, + ...extraMatches, clause, ...authFilterSubqueries, withWhere, @@ -264,22 +274,38 @@ export class ConnectionReadOperation extends Operation { throw new Error("No parent node found!"); } - const targetNode = createNodeFromEntity(this.target, context.neo4jGraphQLContext, this.nodeAlias); + // eslint-disable-next-line prefer-const + let { selection: selectionClause, nestedContext } = this.selection.apply(context); + // const relationship = nestedContext.relationship; + // if (!relationship) { + // throw new Error("Relationship not available"); + // } + + let extraMatches: Array = this.getChildren().flatMap((f) => { + return f.getSelection(nestedContext); + }); + + if (extraMatches.length > 0) { + extraMatches = [selectionClause, ...extraMatches]; + selectionClause = new Cypher.With("*"); + } + + // const targetNode = createNodeFromEntity(this.target, context.neo4jGraphQLContext, this.nodeAlias); - const { preSelection, selectionClause } = this.getSelectionClauses(context, targetNode); + // const { preSelection, selectionClause } = this.getSelectionClauses(context, targetNode); - const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(context); + const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); - const authFilterSubqueries = this.getAuthFilterSubqueries(context).map((sq) => - new Cypher.Call(sq).innerWith(targetNode) + const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => + new Cypher.Call(sq).innerWith(nestedContext.target) ); - const authPredicate = this.getAuthFilterPredicate(context); + const authPredicate = this.getAuthFilterPredicate(nestedContext); - const predicates = this.filters.map((f) => f.getPredicate(context)); + const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); const filters = Cypher.and(...predicates, ...authPredicate); - const nodeProjectionMap = this.getProjectionMap(context); + const nodeProjectionMap = this.getProjectionMap(nestedContext); const edgeVar = new Cypher.NamedVariable("edge"); const edgesVar = new Cypher.NamedVariable("edges"); @@ -298,12 +324,12 @@ export class ConnectionReadOperation extends Operation { selectionClause.where(filters); } } - const withNodeAndTotalCount = new Cypher.With([Cypher.collect(targetNode), edgesVar]).with(edgesVar, [ + const withNodeAndTotalCount = new Cypher.With([Cypher.collect(nestedContext.target), edgesVar]).with(edgesVar, [ Cypher.size(edgesVar), totalCount, ]); - const unwindClause = new Cypher.Unwind([edgesVar, targetNode]).with(targetNode, totalCount); + const unwindClause = new Cypher.Unwind([edgesVar, nestedContext.target]).with(nestedContext.target, totalCount); let paginationWith: Cypher.With | undefined; if (this.pagination || this.sortFields.length > 0) { paginationWith = new Cypher.With("*"); @@ -315,28 +341,24 @@ export class ConnectionReadOperation extends Operation { paginationWith.skip(paginationField.skip); } if (this.sortFields.length > 0) { - const sortFields = this.getSortFields({ context, nodeVar: targetNode, aliased: true }); + const sortFields = this.getSortFields({ + context: nestedContext, + nodeVar: nestedContext.target, + aliased: true, + }); paginationWith.orderBy(...sortFields); } } - const withProjection = new Cypher.With([edgeProjectionMap, edgeVar], totalCount, targetNode).with( + const withProjection = new Cypher.With([edgeProjectionMap, edgeVar], totalCount, nestedContext.target).with( [Cypher.collect(edgeVar), edgesVar], totalCount ); let extraWithOrder: Cypher.Clause | undefined; - // const returnClause = new Cypher.Return([ - // new Cypher.Map({ - // edges: edgesVar, - // totalCount: totalCount, - // }), - // context.returnVariable, - // ]); - const connectionMatchAndAuthClause = Cypher.concat( - ...preSelection, + ...extraMatches, selectionClause, ...authFilterSubqueries, withWhere, @@ -352,7 +374,6 @@ export class ConnectionReadOperation extends Operation { paginationWith, ...postPaginationSubqueries, withProjection, - // returnClause, ] ); diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index d6d036f6c73..c46d7317fef 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -540,10 +540,16 @@ export class OperationsFactory { const concreteEntities = getConcreteEntitiesInOnArgumentOfWhere(target, nodeWhere); const concreteConnectionOperations = concreteEntities.map((concreteEntity: ConcreteEntityAdapter) => { + const selection = new RelationshipSelection({ + relationship, + directed, + }); + const connectionPartial = new CompositeConnectionPartial({ relationship, directed, target: concreteEntity, + selection, }); return this.hydrateConnectionOperationAST({ @@ -585,7 +591,21 @@ export class OperationsFactory { targetOperations: ["READ"], context, }); - const operation = new ConnectionReadOperation({ relationship, directed, target }); + + let selection: EntitySelection; + if (relationship) { + selection = new RelationshipSelection({ + relationship, + directed: Boolean(resolveTree.args?.directed ?? true), + }); + } else { + selection = new NodeSelection({ + target, + // alias: varName, + }); + } + // Add selection here + const operation = new ConnectionReadOperation({ relationship, directed, target, selection }); return this.hydrateConnectionOperationAST({ relationship: relationship, diff --git a/packages/graphql/tests/integration/connections/sort.int.test.ts b/packages/graphql/tests/integration/connections/sort.int.test.ts index 76582e34d5d..a436b82df12 100644 --- a/packages/graphql/tests/integration/connections/sort.int.test.ts +++ b/packages/graphql/tests/integration/connections/sort.int.test.ts @@ -17,14 +17,14 @@ * limitations under the License. */ -import type { Driver, Session } from "neo4j-driver"; import type { GraphQLSchema } from "graphql"; import { graphql } from "graphql"; -import { generate } from "randomstring"; import { gql } from "graphql-tag"; -import Neo4j from "../neo4j"; +import type { Driver, Session } from "neo4j-driver"; +import { generate } from "randomstring"; import { Neo4jGraphQL } from "../../../src/classes"; import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; const testLabel = generate({ charset: "alphabetic" }); diff --git a/packages/graphql/tests/tck/connections/sort.test.ts b/packages/graphql/tests/tck/connections/sort.test.ts index 76a14bb9e7a..cc79e0f9711 100644 --- a/packages/graphql/tests/tck/connections/sort.test.ts +++ b/packages/graphql/tests/tck/connections/sort.test.ts @@ -77,23 +77,23 @@ describe("Relationship Properties Cypher", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount WITH * - ORDER BY this.title ASC + ORDER BY this0.title ASC LIMIT $param0 CALL { - WITH this - MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { name: this1.name } } AS edge + WITH this0 + MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH { node: { name: this2.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + RETURN { edges: edges, totalCount: totalCount } AS var3 } - WITH { node: this { .title, actorsConnection: var2 } } AS edge, totalCount, this + WITH { node: this0 { .title, actorsConnection: var3 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -131,33 +131,33 @@ describe("Relationship Properties Cypher", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this + WITH this0 CALL { - WITH this - WITH this AS this + WITH this0 + WITH this0 AS this MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count } - UNWIND count AS this0 - RETURN head(collect(this0)) AS this0 + UNWIND count AS this1 + RETURN head(collect(this1)) AS this1 } WITH * - ORDER BY this.title DESC, this0 ASC + ORDER BY this0.title DESC, this1 ASC LIMIT $param0 CALL { - WITH this - MATCH (this)<-[this1:ACTED_IN]-(this2:Actor) - WITH { node: { name: this2.name } } AS edge + WITH this0 + MATCH (this0)<-[this2:ACTED_IN]-(this3:Actor) + WITH { node: { name: this3.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this { .title, actorsConnection: var3, numberOfActors: this0 } } AS edge, totalCount, this + WITH { node: this0 { .title, actorsConnection: var4, numberOfActors: this1 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index 0cd74be7fda..41e45771b58 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -91,13 +91,13 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount - WITH { node: this { .id } } AS edge, totalCount, this + UNWIND edges AS this0 + WITH this0, totalCount + WITH { node: this0 { .id } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -134,13 +134,13 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE (this.name = $param0 AND ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub))) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE (this0.name = $param0 AND ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub))) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount - WITH { node: this { .id } } AS edge, totalCount, this + UNWIND edges AS this0 + WITH this0, totalCount + WITH { node: this0 { .id } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -181,24 +181,24 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))) - WITH this1 { .content } AS this1 - RETURN collect(this1) AS var3 + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH this2 { .content } AS this2 + RETURN collect(this2) AS var4 } - WITH { node: this { .id, posts: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, posts: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -242,25 +242,25 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))) - WITH { node: { content: this1.content } } AS edge + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH { node: { content: this2.content } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this { .id, postsConnection: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, postsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -304,25 +304,25 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE (this1.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub)))) - WITH { node: { content: this1.content } } AS edge + WHERE (this2.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) + WITH { node: { content: this2.content } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this { .id, postsConnection: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, postsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -363,24 +363,24 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * WITH * - WHERE (this1.content = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub)))) - WITH this1 { .content } AS this1 - RETURN collect(this1) AS var3 + WHERE (this2.content = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) + WITH this2 { .content } AS this2 + RETURN collect(this2) AS var4 } - WITH { node: this { .id, posts: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, posts: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -423,28 +423,28 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this + WITH this0 CALL { WITH * - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))) - WITH this1 { .id, __resolveType: \\"Post\\", __id: id(this1) } AS this1 - RETURN this1 AS var3 + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH this2 { .id, __resolveType: \\"Post\\", __id: id(this2) } AS this2 + RETURN this2 AS var4 } - WITH var3 - RETURN collect(var3) AS var3 + WITH var4 + RETURN collect(var4) AS var4 } - WITH { node: this { .id, content: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, content: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -490,29 +490,29 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this + WITH this0 CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))) - WITH { node: { __resolveType: \\"Post\\", __id: id(this1), id: this1.id } } AS edge + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH { node: { __resolveType: \\"Post\\", __id: id(this2), id: this2.id } } AS edge RETURN edge } WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this { .id, contentConnection: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, contentConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -558,29 +558,29 @@ describe("Connection auth filter", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this + WITH this0 CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE (this1.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub)))) - WITH { node: { __resolveType: \\"Post\\", __id: id(this1), id: this1.id } } AS edge + WHERE (this2.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) + WITH { node: { __resolveType: \\"Post\\", __id: id(this2), id: this2.id } } AS edge RETURN edge } WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this { .id, contentConnection: var3 } } AS edge, totalCount, this + WITH { node: this0 { .id, contentConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts index d27c70487c5..ca7c308ea2b 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts @@ -234,25 +234,25 @@ describe("Cypher Auth Projection On top-level connections", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { content: this1.content } } AS edge + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH { node: { content: this2.content } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this { .name, postsConnection: var3 } } AS edge, totalCount, this + WITH { node: this0 { .name, postsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -301,34 +301,34 @@ describe("Cypher Auth Projection On top-level connections", () => { }); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:User) - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH collect(this) AS edges + "MATCH (this0:User) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:HAS_POST]->(this1:Post) - OPTIONAL MATCH (this1)<-[:HAS_POST]-(this2:User) - WITH *, count(this2) AS creatorCount + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) CALL { - WITH this1 - MATCH (this1)<-[this3:HAS_POST]-(this4:User) - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this4.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { name: this4.name } } AS edge + WITH this2 + MATCH (this2)<-[this4:HAS_POST]-(this5:User) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this5.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH { node: { name: this5.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: edges, totalCount: totalCount } AS var6 } - WITH { node: { content: this1.content, creatorConnection: var5 } } AS edge + WITH { node: { content: this2.content, creatorConnection: var6 } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN { edges: edges, totalCount: totalCount } AS var7 } - WITH { node: this { .name, postsConnection: var6 } } AS edge, totalCount, this + WITH { node: this0 { .name, postsConnection: var7 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1364.test.ts b/packages/graphql/tests/tck/issues/1364.test.ts index 125a4c5deee..6ada344a7b7 100644 --- a/packages/graphql/tests/tck/issues/1364.test.ts +++ b/packages/graphql/tests/tck/issues/1364.test.ts @@ -93,25 +93,25 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount WITH * - ORDER BY this.title ASC + ORDER BY this0.title ASC CALL { - WITH this + WITH this0 CALL { - WITH this - WITH this AS this + WITH this0 + WITH this0 AS this MATCH (this)-[:HAS_GENRE]->(genre:Genre) RETURN count(DISTINCT genre) as result } - UNWIND result AS this0 - RETURN head(collect(this0)) AS this0 + UNWIND result AS this1 + RETURN head(collect(this1)) AS this1 } - WITH { node: this { .title, totalGenres: this0 } } AS edge, totalCount, this + WITH { node: this0 { .title, totalGenres: this1 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -134,25 +134,25 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this + WITH this0 CALL { - WITH this - WITH this AS this + WITH this0 + WITH this0 AS this MATCH (this)-[:HAS_GENRE]->(genre:Genre) RETURN count(DISTINCT genre) as result } - UNWIND result AS this0 - RETURN head(collect(this0)) AS this0 + UNWIND result AS this1 + RETURN head(collect(this1)) AS this1 } WITH * - ORDER BY this0 ASC - WITH { node: this { .title, totalGenres: this0 } } AS edge, totalCount, this + ORDER BY this1 ASC + WITH { node: this0 { .title, totalGenres: this1 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -176,36 +176,36 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this + WITH this0 CALL { - WITH this - WITH this AS this + WITH this0 + WITH this0 AS this MATCH (this)-[:HAS_GENRE]->(genre:Genre) RETURN count(DISTINCT genre) as result } - UNWIND result AS this0 - RETURN head(collect(this0)) AS this0 + UNWIND result AS this1 + RETURN head(collect(this1)) AS this1 } WITH * - ORDER BY this0 ASC + ORDER BY this1 ASC CALL { - WITH this + WITH this0 CALL { - WITH this - WITH this AS this + WITH this0 + WITH this0 AS this MATCH (this)<-[:ACTED_IN]-(actor:Actor) RETURN count(DISTINCT actor) as result } - UNWIND result AS this1 - RETURN head(collect(this1)) AS this1 + UNWIND result AS this2 + RETURN head(collect(this2)) AS this2 } - WITH { node: this { .title, totalGenres: this0, totalActors: this1 } } AS edge, totalCount, this + WITH { node: this0 { .title, totalGenres: this1, totalActors: this2 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index e31d11339a1..de9b3cc2110 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -90,35 +90,34 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:ArtPiece) - WITH collect(this) AS edges + "MATCH (this0:ArtPiece) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount CALL { - WITH this - MATCH (this)-[this0:SOLD_AT_AUCTION_AS]->(this1:AuctionItem) + WITH this0 + MATCH (this0)-[this1:SOLD_AT_AUCTION_AS]->(this2:AuctionItem) CALL { - WITH this1 - MATCH (this1)<-[this2:BOUGHT_ITEM_AT_AUCTION]-(this3:Organization) - WITH this3 { .name, dbId: this3.id } AS this3 - RETURN head(collect(this3)) AS var4 + WITH this2 + MATCH (this2)<-[this3:BOUGHT_ITEM_AT_AUCTION]-(this4:Organization) + WITH this4 { .name, dbId: this4.id } AS this4 + RETURN head(collect(this4)) AS var5 } - WITH this1 { .auctionName, .lotNumber, dbId: this1.id, buyer: var4 } AS this1 - RETURN head(collect(this1)) AS var5 + WITH this2 { .auctionName, .lotNumber, dbId: this2.id, buyer: var5 } AS this2 + RETURN head(collect(this2)) AS var6 } CALL { - WITH this - MATCH (this)-[this6:OWNED_BY]->(this7:Organization) - WITH this7 { .name, dbId: this7.id } AS this7 - RETURN head(collect(this7)) AS var8 + WITH this0 + MATCH (this0)-[this7:OWNED_BY]->(this8:Organization) + WITH this8 { .name, dbId: this8.id } AS this8 + RETURN head(collect(this8)) AS var9 } - WITH { node: this { .title, dbId: this.id, auction: var5, owner: var8 } } AS edge, totalCount, this + WITH { node: this0 { .title, dbId: this0.id, auction: var6, owner: var9 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); }); - }); diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index af2aecb9733..0b38c17679f 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -113,14 +113,14 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Product) - WITH collect(this) AS edges + "MATCH (this0:Product) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount WITH * - ORDER BY this.fg_item DESC - WITH { node: this { .description, id: this.fg_item_id, partNumber: this.fg_item } } AS edge, totalCount, this + ORDER BY this0.fg_item DESC + WITH { node: this0 { .description, id: this0.fg_item_id, partNumber: this0.fg_item } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index f39afa5d914..8ec159d3cbd 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -62,13 +62,13 @@ describe("Root Connection Query tests", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WHERE this.title = $param0 - WITH collect(this) AS edges + "MATCH (this0:Movie) + WHERE this0.title = $param0 + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount - WITH { node: this { .title } } AS edge, totalCount, this + UNWIND edges AS this0 + WITH this0, totalCount + WITH { node: this0 { .title } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -96,15 +96,15 @@ describe("Root Connection Query tests", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount WITH * - ORDER BY this.title ASC + ORDER BY this0.title ASC LIMIT $param0 - WITH { node: this { .title } } AS edge, totalCount, this + WITH { node: this0 { .title } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -132,16 +132,16 @@ describe("Root Connection Query tests", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WHERE this.title CONTAINS $param0 - WITH collect(this) AS edges + "MATCH (this0:Movie) + WHERE this0.title CONTAINS $param0 + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount WITH * - ORDER BY this.title ASC + ORDER BY this0.title ASC LIMIT $param1 - WITH { node: this { .title } } AS edge, totalCount, this + WITH { node: this0 { .title } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -177,23 +177,23 @@ describe("Root Connection Query tests", () => { `; const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` - "MATCH (this:Movie) - WITH collect(this) AS edges + "MATCH (this0:Movie) + WITH collect(this0) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this - WITH this, totalCount + UNWIND edges AS this0 + WITH this0, totalCount WITH * - ORDER BY this.title ASC + ORDER BY this0.title ASC LIMIT $param0 CALL { - WITH this - MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { name: this1.name } } AS edge + WITH this0 + MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH { node: { name: this2.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + RETURN { edges: edges, totalCount: totalCount } AS var3 } - WITH { node: this { .title, actorsConnection: var2 } } AS edge, totalCount, this + WITH { node: this0 { .title, actorsConnection: var3 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); From 22907089242cbba4eb05cc46a82410b604cc136d Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 6 Dec 2023 16:03:52 +0000 Subject: [PATCH 020/136] Split connection read transpile in 2 methods --- .../ast/operations/ConnectionReadOperation.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index eb1fea7345f..53869163125 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -266,10 +266,7 @@ export class ConnectionReadOperation extends Operation { }; } - public transpile(context: QueryASTContext): OperationTranspileResult { - if (this.relationship) { - return this.transpileNested(context); - } + private transpileTopLevel(context: QueryASTContext): OperationTranspileResult { if (!hasTarget(context)) { throw new Error("No parent node found!"); } @@ -386,6 +383,14 @@ export class ConnectionReadOperation extends Operation { }; } + public transpile(context: QueryASTContext): OperationTranspileResult { + if (this.relationship) { + return this.transpileNested(context); + } else { + return this.transpileTopLevel(context); + } + } + protected getPaginationSubquery( context: QueryASTContext, edgesVar: Cypher.Variable, From e357ec63f631487f404923fb318eeb4ead24f61f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 22:12:42 +0000 Subject: [PATCH 021/136] chore(deps): update dependency html-webpack-plugin to v5.5.4 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index ab567454767..aab5ed286d7 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -88,7 +88,7 @@ "fork-ts-checker-webpack-plugin": "9.0.2", "html-inline-script-webpack-plugin": "3.2.1", "html-webpack-inline-source-plugin": "0.0.10", - "html-webpack-plugin": "5.5.3", + "html-webpack-plugin": "5.5.4", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "node-polyfill-webpack-plugin": "2.0.1", diff --git a/yarn.lock b/yarn.lock index 689ed921473..a0728b55e2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3662,7 +3662,7 @@ __metadata: graphql-query-complexity: 0.12.0 html-inline-script-webpack-plugin: 3.2.1 html-webpack-inline-source-plugin: 0.0.10 - html-webpack-plugin: 5.5.3 + html-webpack-plugin: 5.5.4 jest: 29.7.0 jest-environment-jsdom: 29.7.0 markdown-it: 13.0.2 @@ -15470,9 +15470,9 @@ __metadata: languageName: node linkType: hard -"html-webpack-plugin@npm:5.5.3": - version: 5.5.3 - resolution: "html-webpack-plugin@npm:5.5.3" +"html-webpack-plugin@npm:5.5.4": + version: 5.5.4 + resolution: "html-webpack-plugin@npm:5.5.4" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -15481,7 +15481,7 @@ __metadata: tapable: ^2.0.0 peerDependencies: webpack: ^5.20.0 - checksum: ccf685195739c372ad641bbd0c9100a847904f34eedc7aff3ece7856cd6c78fd3746d2d615af1bb71e5727993fe711b89e9b744f033ed3fde646540bf5d5e954 + checksum: b49befb73d67a3716fd0e6f7776b108d2b0b7050fb8221f05cd114cbae13c03150a13b7cdf5e76170be040ce7936a1cf76f7a4bfd9ebe1552b72d7889a74c374 languageName: node linkType: hard From 338d5a68d6e0ce3302d21d91fe781c80b6ce2fc4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 6 Dec 2023 22:21:53 +0000 Subject: [PATCH 022/136] chore(deps): update dependency libnpmsearch to v7.0.1 --- packages/graphql/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 372495a66d3..5631cc0aa37 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -73,7 +73,7 @@ "koa": "2.14.2", "koa-jwt": "4.0.4", "koa-router": "12.0.1", - "libnpmsearch": "7.0.0", + "libnpmsearch": "7.0.1", "mock-jwks": "1.0.10", "nock": "13.4.0", "npm-run-all": "4.1.5", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index 68b4a60d8cb..cd749113d16 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -52,7 +52,7 @@ "graphql-tag": "2.12.6", "jest": "29.7.0", "jsonwebtoken": "9.0.2", - "libnpmsearch": "7.0.0", + "libnpmsearch": "7.0.1", "npm-run-all": "4.1.5", "pluralize": "8.0.0", "randomstring": "1.3.0", diff --git a/yarn.lock b/yarn.lock index a0728b55e2b..7e88df633eb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3608,7 +3608,7 @@ __metadata: graphql-tag: 2.12.6 jest: 29.7.0 jsonwebtoken: 9.0.2 - libnpmsearch: 7.0.0 + libnpmsearch: 7.0.1 npm-run-all: 4.1.5 pluralize: 8.0.0 prettier: ^2.7.1 @@ -3735,7 +3735,7 @@ __metadata: koa: 2.14.2 koa-jwt: 4.0.4 koa-router: 12.0.1 - libnpmsearch: 7.0.0 + libnpmsearch: 7.0.1 mock-jwks: 1.0.10 nock: 13.4.0 npm-run-all: 4.1.5 @@ -17981,12 +17981,12 @@ __metadata: languageName: node linkType: hard -"libnpmsearch@npm:7.0.0": - version: 7.0.0 - resolution: "libnpmsearch@npm:7.0.0" +"libnpmsearch@npm:7.0.1": + version: 7.0.1 + resolution: "libnpmsearch@npm:7.0.1" dependencies: npm-registry-fetch: ^16.0.0 - checksum: 3b10c35b6feb84622d1ca0009e02ae577b5648f10aa28c7c989a4db64ec3bc4f2f866a1c4c07002ae319ac40bda1608fc87bbcfad248f8104946120d58b45e2b + checksum: 97a12306a4f4c8c15eef574b2cf95f3c556c751a7cdf6f7fb9a62bacd79ff1f70300e5bde0c652b4d5e67ae6516ca41b9c43783cafa2c1c4dad6818463cd58a2 languageName: node linkType: hard From a06a555bb0b2dd5bc76b93a988b0114ab136698b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 7 Dec 2023 00:26:24 +0000 Subject: [PATCH 023/136] fix(deps): update neo4j-ndl --- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index aab5ed286d7..2dfdadc0b67 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -50,8 +50,8 @@ "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", - "@neo4j-ndl/base": "2.0.7", - "@neo4j-ndl/react": "2.0.16", + "@neo4j-ndl/base": "2.0.8", + "@neo4j-ndl/react": "2.0.17", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.3.2", diff --git a/yarn.lock b/yarn.lock index 7e88df633eb..122b85c75a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3518,21 +3518,21 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/base@npm:2.0.7, @neo4j-ndl/base@npm:^2.0.7": - version: 2.0.7 - resolution: "@neo4j-ndl/base@npm:2.0.7" - checksum: 1f5792dc0ded8e4d72bcfdcb7d11a79c7ddf31d48c4ad1ae117ba14976d7b6bf89ccd159183163316919d46f74bc2b56389d326d6af635d4089301f295ef0e03 +"@neo4j-ndl/base@npm:2.0.8, @neo4j-ndl/base@npm:^2.0.8": + version: 2.0.8 + resolution: "@neo4j-ndl/base@npm:2.0.8" + checksum: 817971a4e0c770a40af88733563f403024133a1bcba08eb19095a8dc94f1538ae3effaeaa1e8cac97ca01f50b4a072d47d020cb6ac4790002901b25a12e042e3 languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.0.16": - version: 2.0.16 - resolution: "@neo4j-ndl/react@npm:2.0.16" +"@neo4j-ndl/react@npm:2.0.17": + version: 2.0.17 + resolution: "@neo4j-ndl/react@npm:2.0.17" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 "@neo4j-cypher/react-codemirror": ^1.0.1 - "@neo4j-ndl/base": ^2.0.7 + "@neo4j-ndl/base": ^2.0.8 "@table-nav/core": 0.0.7 "@table-nav/react": 0.0.7 "@tanstack/react-table": ^8.9.3 @@ -3552,7 +3552,7 @@ __metadata: peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: 448698c2c8c69eaae8932e4f64147c7048b6809f36126fb6ce051b2dd058b81a1b2b030da8791ce45821de726a25e85eb88ed8395b2f4238879ee88e44f72d9f + checksum: 4f294107ebe15d8e28e1c426764e7332c1c127f71b6ee0f224e07c53bd7251e7e508f60ddf18311a3996c2879c856b70a8655a97e2354ecaaaf7bf6d03416722 languageName: node linkType: hard @@ -3634,8 +3634,8 @@ __metadata: "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 - "@neo4j-ndl/base": 2.0.7 - "@neo4j-ndl/react": 2.0.16 + "@neo4j-ndl/base": 2.0.8 + "@neo4j-ndl/react": 2.0.17 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 From 09ad9231ef11b7d19ac88eff260a0a90b7f81aa2 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Wed, 6 Dec 2023 17:05:51 +0000 Subject: [PATCH 024/136] WIP unify top and nested connections --- .../ast/operations/ConnectionReadOperation.ts | 169 +++++++++++------- .../queryAST/ast/operations/ReadOperation.ts | 6 +- .../CompositeConnectionReadOperation.ts | 10 +- .../composite/CompositeReadOperation.ts | 3 + .../graphql/src/translate/translate-read.ts | 4 +- .../tests/tck/connections/sort.test.ts | 4 +- .../where/connection-auth-filter.test.ts | 22 +-- .../projection-connection.test.ts | 4 +- .../graphql/tests/tck/issues/1364.test.ts | 6 +- .../graphql/tests/tck/issues/2022.test.ts | 2 +- .../graphql/tests/tck/issues/3394.test.ts | 2 +- .../graphql/tests/tck/root-connection.test.ts | 8 +- 12 files changed, 141 insertions(+), 99 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 53869163125..324447f0cdc 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -144,34 +144,47 @@ export class ConnectionReadOperation extends Operation { if (!context.target || !this.relationship) throw new Error(); // eslint-disable-next-line prefer-const - let { selection: clause, nestedContext } = this.selection.apply(context); - const relationship = nestedContext.relationship; - if (!relationship) { - throw new Error("Relationship not available"); - } + let { selection: selectionClause, nestedContext } = this.selection.apply(context); let extraMatches: Array = this.getChildren().flatMap((f) => { return f.getSelection(nestedContext); }); if (extraMatches.length > 0) { - extraMatches = [clause, ...extraMatches]; - clause = new Cypher.With("*"); + extraMatches = [selectionClause, ...extraMatches]; + selectionClause = new Cypher.With("*"); } - const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => new Cypher.Call(sq).innerWith(nestedContext.target) ); - - const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ - nestedContext.target, - ]); - const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); const authPredicate = this.getAuthFilterPredicate(nestedContext); const filters = Cypher.and(...predicates, ...authPredicate); + // Specific but compatible + const nodeProjectionMap = new Cypher.Map(); + + const edgeProjectionMap = new Cypher.Map(); + const relationship = nestedContext.relationship; + + if (relationship) { + this.edgeFields + .map((f) => f.getProjectionField(relationship)) + .forEach((p) => { + if (typeof p === "string") { + edgeProjectionMap.set(p, relationship.property(p)); + } else { + edgeProjectionMap.set(p); + } + }); + } + + // NOT compatible + const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ + nestedContext.target, + ]); + this.nodeFields .map((f) => f.getProjectionField(nestedContext.target)) .forEach((p) => { @@ -189,35 +202,24 @@ export class ConnectionReadOperation extends Operation { __id: Cypher.id(nestedContext.target), }); } + edgeProjectionMap.set("node", nodeProjectionMap); const edgeVar = new Cypher.NamedVariable("edge"); const edgesVar = new Cypher.NamedVariable("edges"); const totalCount = new Cypher.NamedVariable("totalCount"); - const edgeProjectionMap = new Cypher.Map(); - - this.edgeFields - .map((f) => f.getProjectionField(relationship)) - .forEach((p) => { - if (typeof p === "string") { - edgeProjectionMap.set(p, relationship.property(p)); - } else { - edgeProjectionMap.set(p); - } - }); - - edgeProjectionMap.set("node", nodeProjectionMap); - let withWhere: Cypher.Clause | undefined; if (filters) { if (authFilterSubqueries.length > 0) { // This is to avoid unnecessary With * withWhere = new Cypher.With("*").where(filters); } else { - clause.where(filters); + selectionClause.where(filters); } } + // Common transpile ends + // Pagination is different let sortSubquery: Cypher.With | undefined; if (this.pagination || this.sortFields.length > 0) { const paginationField = this.pagination && this.pagination.getPagination(); @@ -234,13 +236,17 @@ export class ConnectionReadOperation extends Operation { edgeVar: relationship, }); - extraWithOrder = new Cypher.With(relationship, nestedContext.target).orderBy(...sortFields); + const orderWithItems = relationship ? [relationship, nestedContext.target] : [nestedContext.target]; + + extraWithOrder = new Cypher.With(...orderWithItems).orderBy(...sortFields); } + // Projection is different const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) .with([Cypher.collect(edgeVar), edgesVar]) .with(edgesVar, [Cypher.size(edgesVar), totalCount]); + // Common Return const returnClause = new Cypher.Return([ new Cypher.Map({ edges: edgesVar, @@ -250,7 +256,7 @@ export class ConnectionReadOperation extends Operation { ]); const subClause = Cypher.concat( ...extraMatches, - clause, + selectionClause, ...authFilterSubqueries, withWhere, extraWithOrder, @@ -273,10 +279,6 @@ export class ConnectionReadOperation extends Operation { // eslint-disable-next-line prefer-const let { selection: selectionClause, nestedContext } = this.selection.apply(context); - // const relationship = nestedContext.relationship; - // if (!relationship) { - // throw new Error("Relationship not available"); - // } let extraMatches: Array = this.getChildren().flatMap((f) => { return f.getSelection(nestedContext); @@ -286,32 +288,66 @@ export class ConnectionReadOperation extends Operation { extraMatches = [selectionClause, ...extraMatches]; selectionClause = new Cypher.With("*"); } + const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => + new Cypher.Call(sq).innerWith(nestedContext.target) + ); + const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); + const authPredicate = this.getAuthFilterPredicate(nestedContext); + const filters = Cypher.and(...predicates, ...authPredicate); + // Specific but compatible + + const nodeProjectionMap = new Cypher.Map(); - // const targetNode = createNodeFromEntity(this.target, context.neo4jGraphQLContext, this.nodeAlias); + // const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ + // nestedContext.target, + // ]); - // const { preSelection, selectionClause } = this.getSelectionClauses(context, targetNode); + const edgeProjectionMap = new Cypher.Map(); + const relationship = nestedContext.relationship; + if (relationship) { + this.edgeFields + .map((f) => f.getProjectionField(relationship)) + .forEach((p) => { + if (typeof p === "string") { + edgeProjectionMap.set(p, relationship.property(p)); + } else { + edgeProjectionMap.set(p); + } + }); + } + // // NOTE: this is not compatible, but required due to transpile being called before projectionField const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); - const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => - new Cypher.Call(sq).innerWith(nestedContext.target) - ); + //Nested version: + // const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ + // nestedContext.target, + // ]); - const authPredicate = this.getAuthFilterPredicate(nestedContext); + this.nodeFields + .map((f) => f.getProjectionField(nestedContext.target)) + .forEach((p) => { + if (typeof p === "string") { + nodeProjectionMap.set(p, nestedContext.target.property(p)); + } else { + nodeProjectionMap.set(p); + } + }); - const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); - const filters = Cypher.and(...predicates, ...authPredicate); + if (nodeProjectionMap.size === 0) { + const targetNodeName = this.target.name; + nodeProjectionMap.set({ + __resolveType: new Cypher.Literal(targetNodeName), + __id: Cypher.id(nestedContext.target), + }); + } - const nodeProjectionMap = this.getProjectionMap(nestedContext); + edgeProjectionMap.set("node", nodeProjectionMap); const edgeVar = new Cypher.NamedVariable("edge"); const edgesVar = new Cypher.NamedVariable("edges"); const totalCount = new Cypher.NamedVariable("totalCount"); - const edgeProjectionMap = new Cypher.Map(); - - edgeProjectionMap.set("node", nodeProjectionMap); - let withWhere: Cypher.Clause | undefined; if (filters) { if (authFilterSubqueries.length > 0) { @@ -325,8 +361,9 @@ export class ConnectionReadOperation extends Operation { Cypher.size(edgesVar), totalCount, ]); + // Common transpile ends - const unwindClause = new Cypher.Unwind([edgesVar, nestedContext.target]).with(nestedContext.target, totalCount); + // Pagination is different let paginationWith: Cypher.With | undefined; if (this.pagination || this.sortFields.length > 0) { paginationWith = new Cypher.With("*"); @@ -347,39 +384,39 @@ export class ConnectionReadOperation extends Operation { } } + // Projection is different + const unwindClause = new Cypher.Unwind([edgesVar, nestedContext.target]).with(nestedContext.target, totalCount); const withProjection = new Cypher.With([edgeProjectionMap, edgeVar], totalCount, nestedContext.target).with( [Cypher.collect(edgeVar), edgesVar], totalCount ); - let extraWithOrder: Cypher.Clause | undefined; + // Common Return + const returnClause = new Cypher.Return([ + new Cypher.Map({ + edges: edgesVar, + totalCount: totalCount, + }), + context.returnVariable, + ]); - const connectionMatchAndAuthClause = Cypher.concat( + const clause = Cypher.concat( ...extraMatches, selectionClause, ...authFilterSubqueries, withWhere, - extraWithOrder, withNodeAndTotalCount, - unwindClause - ); - - const clause = Cypher.concat( - ...[ - connectionMatchAndAuthClause, - ...prePaginationSubqueries, - paginationWith, - ...postPaginationSubqueries, - withProjection, - ] + unwindClause, + ...prePaginationSubqueries, + paginationWith, + ...postPaginationSubqueries, + withProjection, + returnClause ); return { clauses: [clause], - projectionExpr: new Cypher.Map({ - edges: edgesVar, - totalCount: totalCount, - }), + projectionExpr: context.returnVariable, }; } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts index 7c8b88ff5d7..f8e86eca960 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts @@ -311,14 +311,14 @@ export class ReadOperation extends Operation { filterSubqueriesClause, filterSubqueryWith, sortAndLimitBlock, - subqueries - // ret + subqueries, + ret ); } return { clauses: [clause], - projectionExpr: this.getReturnExpression(nestedContext), + projectionExpr: context.returnVariable, // this.getReturnExpression(nestedContext), }; } 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 8888b8e3e5d..edc11653e6a 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionReadOperation.ts @@ -21,13 +21,13 @@ import Cypher from "@neo4j/cypher-builder"; import type { OperationTranspileResult } from "../operations"; import { Operation } from "../operations"; -import type { QueryASTNode } from "../../QueryASTNode"; -import type { CompositeConnectionPartial } from "./CompositeConnectionPartial"; -import type { Sort, SortField } from "../../sort/Sort"; -import type { Pagination } from "../../pagination/Pagination"; -import { QueryASTContext } from "../../QueryASTContext"; import { filterTruthy } from "../../../../../utils/utils"; import { hasTarget } from "../../../utils/context-has-target"; +import { QueryASTContext } from "../../QueryASTContext"; +import type { QueryASTNode } from "../../QueryASTNode"; +import type { Pagination } from "../../pagination/Pagination"; +import type { Sort, SortField } from "../../sort/Sort"; +import type { CompositeConnectionPartial } from "./CompositeConnectionPartial"; export class CompositeConnectionReadOperation extends Operation { private children: CompositeConnectionPartial[]; diff --git a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts index 6f484ad1798..604f254ab36 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts @@ -75,6 +75,9 @@ export class CompositeReadOperation extends Operation { } } } + + nestedSubquery.return([context.returnVariable, context.returnVariable]); + return { clauses: [nestedSubquery], projectionExpr: context.returnVariable, diff --git a/packages/graphql/src/translate/translate-read.ts b/packages/graphql/src/translate/translate-read.ts index 5fef0020ae9..78d3a69de79 100644 --- a/packages/graphql/src/translate/translate-read.ts +++ b/packages/graphql/src/translate/translate-read.ts @@ -42,6 +42,8 @@ export function translateRead( if (!entityAdapter) throw new Error("Entity not found"); const operationsTree = operationsTreeFactory.createQueryAST(resolveTree, entityAdapter, context); debug(operationsTree.print()); - const clause = operationsTree.buildNew(context, varName); + const clause = operationsTree.build(context, varName); return clause.build(); + // const clause = operationsTree.buildNew(context, varName); + // return clause.build(); } diff --git a/packages/graphql/tests/tck/connections/sort.test.ts b/packages/graphql/tests/tck/connections/sort.test.ts index cc79e0f9711..c852d3c7cd2 100644 --- a/packages/graphql/tests/tck/connections/sort.test.ts +++ b/packages/graphql/tests/tck/connections/sort.test.ts @@ -93,7 +93,7 @@ describe("Relationship Properties Cypher", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 } - WITH { node: this0 { .title, actorsConnection: var3 } } AS edge, totalCount, this0 + WITH { node: { title: this0.title, actorsConnection: var3 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -157,7 +157,7 @@ describe("Relationship Properties Cypher", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this0 { .title, actorsConnection: var4, numberOfActors: this1 } } AS edge, totalCount, this0 + WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index 41e45771b58..ed567bc7296 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -17,11 +17,11 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../../../../../src"; -import { formatCypher, translateQuery, formatParams } from "../../../../utils/tck-test-utils"; import { createBearerToken } from "../../../../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../../../../utils/tck-test-utils"; describe("Connection auth filter", () => { const secret = "secret"; @@ -97,7 +97,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount UNWIND edges AS this0 WITH this0, totalCount - WITH { node: this0 { .id } } AS edge, totalCount, this0 + WITH { node: { id: this0.id } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -140,7 +140,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount UNWIND edges AS this0 WITH this0, totalCount - WITH { node: this0 { .id } } AS edge, totalCount, this0 + WITH { node: { id: this0.id } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -198,7 +198,7 @@ describe("Connection auth filter", () => { WITH this2 { .content } AS this2 RETURN collect(this2) AS var4 } - WITH { node: this0 { .id, posts: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, posts: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -260,7 +260,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this0 { .id, postsConnection: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, postsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -322,7 +322,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this0 { .id, postsConnection: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, postsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -380,7 +380,7 @@ describe("Connection auth filter", () => { WITH this2 { .content } AS this2 RETURN collect(this2) AS var4 } - WITH { node: this0 { .id, posts: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, posts: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -444,7 +444,7 @@ describe("Connection auth filter", () => { WITH var4 RETURN collect(var4) AS var4 } - WITH { node: this0 { .id, content: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, content: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -512,7 +512,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this0 { .id, contentConnection: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, contentConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -580,7 +580,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this0 { .id, contentConnection: var4 } } AS edge, totalCount, this0 + WITH { node: { id: this0.id, contentConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts index ca7c308ea2b..46e2dbad9f6 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts @@ -252,7 +252,7 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: this0 { .name, postsConnection: var4 } } AS edge, totalCount, this0 + WITH { node: { name: this0.name, postsConnection: var4 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -328,7 +328,7 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var7 } - WITH { node: this0 { .name, postsConnection: var7 } } AS edge, totalCount, this0 + WITH { node: { name: this0.name, postsConnection: var7 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1364.test.ts b/packages/graphql/tests/tck/issues/1364.test.ts index 6ada344a7b7..f23ad028ebe 100644 --- a/packages/graphql/tests/tck/issues/1364.test.ts +++ b/packages/graphql/tests/tck/issues/1364.test.ts @@ -111,7 +111,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { UNWIND result AS this1 RETURN head(collect(this1)) AS this1 } - WITH { node: this0 { .title, totalGenres: this1 } } AS edge, totalCount, this0 + WITH { node: { title: this0.title, totalGenres: this1 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -152,7 +152,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { } WITH * ORDER BY this1 ASC - WITH { node: this0 { .title, totalGenres: this1 } } AS edge, totalCount, this0 + WITH { node: { title: this0.title, totalGenres: this1 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -205,7 +205,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { UNWIND result AS this2 RETURN head(collect(this2)) AS this2 } - WITH { node: this0 { .title, totalGenres: this1, totalActors: this2 } } AS edge, totalCount, this0 + WITH { node: { title: this0.title, totalGenres: this1, totalActors: this2 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index de9b3cc2110..89cded2d63e 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -113,7 +113,7 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { WITH this8 { .name, dbId: this8.id } AS this8 RETURN head(collect(this8)) AS var9 } - WITH { node: this0 { .title, dbId: this0.id, auction: var6, owner: var9 } } AS edge, totalCount, this0 + WITH { node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index 0b38c17679f..e0be5486828 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -120,7 +120,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH this0, totalCount WITH * ORDER BY this0.fg_item DESC - WITH { node: this0 { .description, id: this0.fg_item_id, partNumber: this0.fg_item } } AS edge, totalCount, this0 + WITH { node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index 8ec159d3cbd..dba35fa86ef 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -68,7 +68,7 @@ describe("Root Connection Query tests", () => { WITH edges, size(edges) AS totalCount UNWIND edges AS this0 WITH this0, totalCount - WITH { node: this0 { .title } } AS edge, totalCount, this0 + WITH { node: { title: this0.title } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -104,7 +104,7 @@ describe("Root Connection Query tests", () => { WITH * ORDER BY this0.title ASC LIMIT $param0 - WITH { node: this0 { .title } } AS edge, totalCount, this0 + WITH { node: { title: this0.title } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -141,7 +141,7 @@ describe("Root Connection Query tests", () => { WITH * ORDER BY this0.title ASC LIMIT $param1 - WITH { node: this0 { .title } } AS edge, totalCount, this0 + WITH { node: { title: this0.title } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -193,7 +193,7 @@ describe("Root Connection Query tests", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 } - WITH { node: this0 { .title, actorsConnection: var3 } } AS edge, totalCount, this0 + WITH { node: { title: this0.title, actorsConnection: var3 } } AS edge, totalCount, this0 WITH collect(edge) AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); From 3f4779dc11ca6f6e9a43a68c7f6f83f6cdbd6608 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 7 Dec 2023 11:11:38 +0000 Subject: [PATCH 025/136] WIP move common code to common transpile method in connections --- .../ast/operations/ConnectionReadOperation.ts | 189 ++++++++---------- 1 file changed, 81 insertions(+), 108 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 324447f0cdc..445b79fafb4 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -140,83 +140,43 @@ export class ConnectionReadOperation extends Operation { }; } + private transpileReturn({ + context, + edgesVar, + totalCount, + }: { + context: QueryASTContext; + edgesVar: Cypher.Variable; + totalCount: Cypher.Variable; + }): Cypher.Return { + return new Cypher.Return([ + new Cypher.Map({ + edges: edgesVar, + totalCount: totalCount, + }), + context.returnVariable, + ]); + } + private transpileNested(context: QueryASTContext): OperationTranspileResult { if (!context.target || !this.relationship) throw new Error(); - // eslint-disable-next-line prefer-const - let { selection: selectionClause, nestedContext } = this.selection.apply(context); - - let extraMatches: Array = this.getChildren().flatMap((f) => { - return f.getSelection(nestedContext); + const { + prePaginationSubqueries, + postPaginationSubqueries, + withWhere, + edgeProjectionMap, + nestedContext, + extraMatches, + selectionClause, + authFilterSubqueries, + } = this.transpileCommon({ + context, }); - if (extraMatches.length > 0) { - extraMatches = [selectionClause, ...extraMatches]; - selectionClause = new Cypher.With("*"); - } - const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => - new Cypher.Call(sq).innerWith(nestedContext.target) - ); - const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); - const authPredicate = this.getAuthFilterPredicate(nestedContext); - const filters = Cypher.and(...predicates, ...authPredicate); - - // Specific but compatible - - const nodeProjectionMap = new Cypher.Map(); - - const edgeProjectionMap = new Cypher.Map(); - const relationship = nestedContext.relationship; - - if (relationship) { - this.edgeFields - .map((f) => f.getProjectionField(relationship)) - .forEach((p) => { - if (typeof p === "string") { - edgeProjectionMap.set(p, relationship.property(p)); - } else { - edgeProjectionMap.set(p); - } - }); - } - - // NOT compatible - const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ - nestedContext.target, - ]); - - this.nodeFields - .map((f) => f.getProjectionField(nestedContext.target)) - .forEach((p) => { - if (typeof p === "string") { - nodeProjectionMap.set(p, nestedContext.target.property(p)); - } else { - nodeProjectionMap.set(p); - } - }); - - if (nodeProjectionMap.size === 0) { - const targetNodeName = this.target.name; - nodeProjectionMap.set({ - __resolveType: new Cypher.Literal(targetNodeName), - __id: Cypher.id(nestedContext.target), - }); - } - edgeProjectionMap.set("node", nodeProjectionMap); - const edgeVar = new Cypher.NamedVariable("edge"); const edgesVar = new Cypher.NamedVariable("edges"); const totalCount = new Cypher.NamedVariable("totalCount"); - - let withWhere: Cypher.Clause | undefined; - if (filters) { - if (authFilterSubqueries.length > 0) { - // This is to avoid unnecessary With * - withWhere = new Cypher.With("*").where(filters); - } else { - selectionClause.where(filters); - } - } // Common transpile ends // Pagination is different @@ -229,6 +189,8 @@ export class ConnectionReadOperation extends Operation { } let extraWithOrder: Cypher.Clause | undefined; + const relationship = nestedContext.relationship; + if (this.sortFields.length > 0) { const sortFields = this.getSortFields({ context: nestedContext, @@ -247,20 +209,19 @@ export class ConnectionReadOperation extends Operation { .with(edgesVar, [Cypher.size(edgesVar), totalCount]); // Common Return - const returnClause = new Cypher.Return([ - new Cypher.Map({ - edges: edgesVar, - totalCount: totalCount, - }), - context.returnVariable, - ]); + const returnClause = this.transpileReturn({ + context, + edgesVar, + totalCount, + }); const subClause = Cypher.concat( ...extraMatches, selectionClause, ...authFilterSubqueries, withWhere, extraWithOrder, - ...nodeProjectionSubqueries, + ...prePaginationSubqueries, + ...postPaginationSubqueries, projectionClauses, sortSubquery, returnClause @@ -272,11 +233,7 @@ export class ConnectionReadOperation extends Operation { }; } - private transpileTopLevel(context: QueryASTContext): OperationTranspileResult { - if (!hasTarget(context)) { - throw new Error("No parent node found!"); - } - + private transpileCommon({ context }: { context: QueryASTContext }) { // eslint-disable-next-line prefer-const let { selection: selectionClause, nestedContext } = this.selection.apply(context); @@ -294,13 +251,10 @@ export class ConnectionReadOperation extends Operation { const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); const authPredicate = this.getAuthFilterPredicate(nestedContext); const filters = Cypher.and(...predicates, ...authPredicate); - // Specific but compatible - const nodeProjectionMap = new Cypher.Map(); + const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); - // const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ - // nestedContext.target, - // ]); + const nodeProjectionMap = new Cypher.Map(); const edgeProjectionMap = new Cypher.Map(); const relationship = nestedContext.relationship; @@ -316,14 +270,6 @@ export class ConnectionReadOperation extends Operation { }); } - // // NOTE: this is not compatible, but required due to transpile being called before projectionField - const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); - - //Nested version: - // const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ - // nestedContext.target, - // ]); - this.nodeFields .map((f) => f.getProjectionField(nestedContext.target)) .forEach((p) => { @@ -344,10 +290,6 @@ export class ConnectionReadOperation extends Operation { edgeProjectionMap.set("node", nodeProjectionMap); - const edgeVar = new Cypher.NamedVariable("edge"); - const edgesVar = new Cypher.NamedVariable("edges"); - const totalCount = new Cypher.NamedVariable("totalCount"); - let withWhere: Cypher.Clause | undefined; if (filters) { if (authFilterSubqueries.length > 0) { @@ -357,11 +299,45 @@ export class ConnectionReadOperation extends Operation { selectionClause.where(filters); } } + + return { + prePaginationSubqueries, + postPaginationSubqueries, + withWhere, + edgeProjectionMap, + nestedContext, + extraMatches, + selectionClause, + authFilterSubqueries, + }; + } + + private transpileTopLevel(context: QueryASTContext): OperationTranspileResult { + if (!hasTarget(context)) { + throw new Error("No parent node found!"); + } + + const { + prePaginationSubqueries, + postPaginationSubqueries, + withWhere, + edgeProjectionMap, + nestedContext, + extraMatches, + selectionClause, + authFilterSubqueries, + } = this.transpileCommon({ + context, + }); + + const edgeVar = new Cypher.NamedVariable("edge"); + const edgesVar = new Cypher.NamedVariable("edges"); + const totalCount = new Cypher.NamedVariable("totalCount"); + // Common transpile ends const withNodeAndTotalCount = new Cypher.With([Cypher.collect(nestedContext.target), edgesVar]).with(edgesVar, [ Cypher.size(edgesVar), totalCount, ]); - // Common transpile ends // Pagination is different let paginationWith: Cypher.With | undefined; @@ -392,14 +368,11 @@ export class ConnectionReadOperation extends Operation { ); // Common Return - const returnClause = new Cypher.Return([ - new Cypher.Map({ - edges: edgesVar, - totalCount: totalCount, - }), - context.returnVariable, - ]); - + const returnClause = this.transpileReturn({ + context, + edgesVar, + totalCount, + }); const clause = Cypher.concat( ...extraMatches, selectionClause, From 089e16be5e9774169ee39ccb7bcf6b1d14a537a2 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 7 Dec 2023 14:31:12 +0000 Subject: [PATCH 026/136] Remove extra sorting in nested connections --- .../ast/operations/ConnectionReadOperation.ts | 16 ---------------- .../connections/relationship-properties.test.ts | 6 ------ packages/graphql/tests/tck/issues/1528.test.ts | 2 -- packages/graphql/tests/tck/issues/2262.test.ts | 2 -- packages/graphql/tests/tck/issues/3394.test.ts | 2 -- 5 files changed, 28 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 445b79fafb4..6522ae26044 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -188,21 +188,6 @@ export class ConnectionReadOperation extends Operation { sortSubquery.addColumns(totalCount); } - let extraWithOrder: Cypher.Clause | undefined; - const relationship = nestedContext.relationship; - - if (this.sortFields.length > 0) { - const sortFields = this.getSortFields({ - context: nestedContext, - nodeVar: nestedContext.target, - edgeVar: relationship, - }); - - const orderWithItems = relationship ? [relationship, nestedContext.target] : [nestedContext.target]; - - extraWithOrder = new Cypher.With(...orderWithItems).orderBy(...sortFields); - } - // Projection is different const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) .with([Cypher.collect(edgeVar), edgesVar]) @@ -219,7 +204,6 @@ export class ConnectionReadOperation extends Operation { selectionClause, ...authFilterSubqueries, withWhere, - extraWithOrder, ...prePaginationSubqueries, ...postPaginationSubqueries, projectionClauses, diff --git a/packages/graphql/tests/tck/connections/relationship-properties.test.ts b/packages/graphql/tests/tck/connections/relationship-properties.test.ts index 71b8f23b614..62171e89ac1 100644 --- a/packages/graphql/tests/tck/connections/relationship-properties.test.ts +++ b/packages/graphql/tests/tck/connections/relationship-properties.test.ts @@ -156,8 +156,6 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH this0, this1 - ORDER BY this0.screenTime DESC WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount @@ -204,8 +202,6 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH this0, this1 - ORDER BY this0.year DESC, this1.name ASC WITH { year: this0.year, node: { name: this1.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount @@ -247,8 +243,6 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH this0, this1 - ORDER BY this1.name ASC, this0.year DESC WITH { year: this0.year, node: { name: this1.name } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount diff --git a/packages/graphql/tests/tck/issues/1528.test.ts b/packages/graphql/tests/tck/issues/1528.test.ts index 74019eef180..06ca79d5c20 100644 --- a/packages/graphql/tests/tck/issues/1528.test.ts +++ b/packages/graphql/tests/tck/issues/1528.test.ts @@ -74,8 +74,6 @@ describe("https://github.com/neo4j/graphql/issues/1528", () => { CALL { WITH this MATCH (this)<-[this0:IS_GENRE]-(this1:Movie) - WITH this0, this1 - ORDER BY this1.actorsCount DESC CALL { WITH this1 CALL { diff --git a/packages/graphql/tests/tck/issues/2262.test.ts b/packages/graphql/tests/tck/issues/2262.test.ts index 96b972ae9aa..b0485260535 100644 --- a/packages/graphql/tests/tck/issues/2262.test.ts +++ b/packages/graphql/tests/tck/issues/2262.test.ts @@ -79,8 +79,6 @@ describe("https://github.com/neo4j/graphql/issues/2262", () => { CALL { WITH this1 MATCH (this1)<-[this2:INPUT]-(this3:Component) - WITH this2, this3 - ORDER BY this3.uuid DESC WITH { node: { uuid: this3.uuid } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index e0be5486828..57aa708ab24 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -152,8 +152,6 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { CALL { WITH this MATCH (this)-[this0:CAN_ACCESS]->(this1:Product) - WITH this0, this1 - ORDER BY this1.partNumber DESC WITH { node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } } AS edge WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount From 26b2974fe468bc5412873fe1bedf25ab5652814a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:03:20 +0000 Subject: [PATCH 027/136] chore(deps): update github/codeql-action digest to c0d1daa --- .github/workflows/reusable-codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-codeql-analysis.yml b/.github/workflows/reusable-codeql-analysis.yml index 72717506d99..b0dafb9ee0e 100644 --- a/.github/workflows/reusable-codeql-analysis.yml +++ b/.github/workflows/reusable-codeql-analysis.yml @@ -14,9 +14,9 @@ jobs: with: node-version: lts/* - name: Initialize CodeQL - uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2 + uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2 with: config-file: ./.github/codeql/codeql-config.yml languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2 + uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2 From 461180be205d1a956c2d193c1753a234b59f2ea0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:12:59 +0000 Subject: [PATCH 028/136] chore(deps): update dependency @types/node to v20.10.4 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- packages/introspector/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index 2cafe532996..a7e206c0014 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -40,7 +40,7 @@ "@types/cors": "2.8.17", "@types/debug": "4.1.12", "@types/jest": "29.5.11", - "@types/node": "20.10.3", + "@types/node": "20.10.4", "camelcase": "6.3.0", "graphql-ws": "5.14.2", "jest": "29.7.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 5631cc0aa37..8f5454590af 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -56,7 +56,7 @@ "@types/is-uuid": "1.0.2", "@types/jest": "29.5.11", "@types/jsonwebtoken": "9.0.5", - "@types/node": "20.10.3", + "@types/node": "20.10.4", "@types/pluralize": "0.0.33", "@types/randomstring": "1.1.11", "@types/semver": "7.5.6", diff --git a/packages/introspector/package.json b/packages/introspector/package.json index f369600e63a..b14d2e537c8 100644 --- a/packages/introspector/package.json +++ b/packages/introspector/package.json @@ -38,7 +38,7 @@ "devDependencies": { "@neo4j/graphql": "^4.0.0", "@types/jest": "29.5.11", - "@types/node": "20.10.3", + "@types/node": "20.10.4", "@types/pluralize": "0.0.33", "jest": "29.7.0", "ts-jest": "29.1.1", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index cd749113d16..d44649b137c 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@types/jest": "29.5.11", - "@types/node": "20.10.3", + "@types/node": "20.10.4", "camelcase": "6.3.0", "graphql-tag": "2.12.6", "jest": "29.7.0", diff --git a/yarn.lock b/yarn.lock index 122b85c75a3..616be8bf9b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3574,7 +3574,7 @@ __metadata: "@types/cors": 2.8.17 "@types/debug": 4.1.12 "@types/jest": 29.5.11 - "@types/node": 20.10.3 + "@types/node": 20.10.4 amqplib: 0.10.3 body-parser: ^1.20.2 camelcase: 6.3.0 @@ -3603,7 +3603,7 @@ __metadata: "@graphql-tools/merge": ^9.0.0 "@neo4j/graphql": ^4.4.4 "@types/jest": 29.5.11 - "@types/node": 20.10.3 + "@types/node": 20.10.4 camelcase: 6.3.0 graphql-tag: 2.12.6 jest: 29.7.0 @@ -3710,7 +3710,7 @@ __metadata: "@types/is-uuid": 1.0.2 "@types/jest": 29.5.11 "@types/jsonwebtoken": 9.0.5 - "@types/node": 20.10.3 + "@types/node": 20.10.4 "@types/pluralize": 0.0.33 "@types/randomstring": 1.1.11 "@types/semver": 7.5.6 @@ -3767,7 +3767,7 @@ __metadata: dependencies: "@neo4j/graphql": ^4.0.0 "@types/jest": 29.5.11 - "@types/node": 20.10.3 + "@types/node": 20.10.4 "@types/pluralize": 0.0.33 camelcase: ^6.3.0 debug: ^4.3.4 @@ -7665,12 +7665,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.10.3": - version: 20.10.3 - resolution: "@types/node@npm:20.10.3" +"@types/node@npm:20.10.4": + version: 20.10.4 + resolution: "@types/node@npm:20.10.4" dependencies: undici-types: ~5.26.4 - checksum: 34a329494f0ea239af05eeb6f00f396963725b3eb9a2f79c5e6a6d37e823f2ab85e1079c2ee56723a37d8b89e7bbe2bd050c97144e5bb06dab93fd1cace65c97 + checksum: 054b296417e771ab524bea63cf3289559c6bdf290d45428f7cc68e9b00030ff7a0ece47b8c99a26b4f47a443919813bcf42beadff2f0bea7d8125fa541d92eb0 languageName: node linkType: hard From 4707a9fb6282d2132539ccdf125a134217642748 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:23:05 +0000 Subject: [PATCH 029/136] chore(deps): update actions/setup-go action to v5 --- .github/workflows/pull-requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index f896438ec48..b117c83e0a0 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -61,7 +61,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4 + - uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491 # v5 with: go-version: "^1.17.0" - name: Install addlicense From 6131f6f56f3c3d290c5eb9ceba42b82cdc0e2d89 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 00:23:09 +0000 Subject: [PATCH 030/136] chore(deps): update actions/setup-python action to v5 --- .github/workflows/cla-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cla-check.yml b/.github/workflows/cla-check.yml index 254377baf70..afb9e30e58b 100644 --- a/.github/workflows/cla-check.yml +++ b/.github/workflows/cla-check.yml @@ -17,7 +17,7 @@ jobs: with: repository: neo-technology/whitelist-check token: ${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }} - - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4 + - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5 with: python-version: 3 - name: Install dependencies From b323ab34a735c343d96838738d8d8dc71f7d9e55 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Fri, 8 Dec 2023 09:31:34 +0000 Subject: [PATCH 031/136] Remove markdown-it from the list of dependencies --- packages/graphql-toolbox/package.json | 2 -- yarn.lock | 52 +-------------------------- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 2dfdadc0b67..9e52ad97699 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -61,7 +61,6 @@ "graphiql-explorer": "0.9.0", "graphql": "16.8.1", "graphql-query-complexity": "0.12.0", - "markdown-it": "13.0.2", "neo4j-driver": "5.15.0", "prettier": "3.0.0", "process": "0.11.10", @@ -75,7 +74,6 @@ "@tsconfig/create-react-app": "2.0.1", "@types/codemirror": "5.60.15", "@types/lodash.debounce": "4.0.9", - "@types/markdown-it": "13.0.7", "@types/prettier": "2.7.3", "@types/react-dom": "18.2.17", "@types/webpack": "5.28.5", diff --git a/yarn.lock b/yarn.lock index 616be8bf9b9..2a9b251fdde 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3642,7 +3642,6 @@ __metadata: "@tsconfig/create-react-app": 2.0.1 "@types/codemirror": 5.60.15 "@types/lodash.debounce": 4.0.9 - "@types/markdown-it": 13.0.7 "@types/prettier": 2.7.3 "@types/react-dom": 18.2.17 "@types/webpack": 5.28.5 @@ -3665,7 +3664,6 @@ __metadata: html-webpack-plugin: 5.5.4 jest: 29.7.0 jest-environment-jsdom: 29.7.0 - markdown-it: 13.0.2 neo4j-driver: 5.15.0 node-polyfill-webpack-plugin: 2.0.1 parse5: 7.1.2 @@ -7573,13 +7571,6 @@ __metadata: languageName: node linkType: hard -"@types/linkify-it@npm:*": - version: 3.0.3 - resolution: "@types/linkify-it@npm:3.0.3" - checksum: a734becc4e7476833b0e6951ec133c006a34809639c722d3e28b7cf88f5f6ccbb433f195788be5e56209b1e9e6e0778879291dd2db401acee3bb585c44dcc329 - languageName: node - linkType: hard - "@types/lodash.debounce@npm:4.0.9": version: 4.0.9 resolution: "@types/lodash.debounce@npm:4.0.9" @@ -7603,23 +7594,6 @@ __metadata: languageName: node linkType: hard -"@types/markdown-it@npm:13.0.7": - version: 13.0.7 - resolution: "@types/markdown-it@npm:13.0.7" - dependencies: - "@types/linkify-it": "*" - "@types/mdurl": "*" - checksum: c9e9af441340eb870a7b90b298f6197aa80b55bee28f179a4f85052333f0cb3d3f2763981359d58cf09024961f013999c1c743c1e52a185ca36576d4403f7eb9 - languageName: node - linkType: hard - -"@types/mdurl@npm:*": - version: 1.0.3 - resolution: "@types/mdurl@npm:1.0.3" - checksum: 5bbed4f0eb9f60040fa26be77aa2158ca468b6423876cec0d2043e7f8298e83b8e5b95fb66056327b02d747c4d376aed16c11ff3fdc4cb3dca327a6931a71f18 - languageName: node - linkType: hard - "@types/mime@npm:*": version: 3.0.2 resolution: "@types/mime@npm:3.0.2" @@ -12836,7 +12810,7 @@ __metadata: languageName: node linkType: hard -"entities@npm:^3.0.1, entities@npm:~3.0.1": +"entities@npm:^3.0.1": version: 3.0.1 resolution: "entities@npm:3.0.1" checksum: aaf7f12033f0939be91f5161593f853f2da55866db55ccbf72f45430b8977e2b79dbd58c53d0fdd2d00bd7d313b75b0968d09f038df88e308aa97e39f9456572 @@ -18138,15 +18112,6 @@ __metadata: languageName: node linkType: hard -"linkify-it@npm:^4.0.1": - version: 4.0.1 - resolution: "linkify-it@npm:4.0.1" - dependencies: - uc.micro: ^1.0.1 - checksum: 3e0a29921269c14eb7ac6f5db2da68d4854ea9acca6e9014a323f75f2dd39b197ffab57c1fbd6a906ceb021aad3ee6d7ba7d0181236dd9630ffc452b392f7f71 - languageName: node - linkType: hard - "lint-staged@npm:15.2.0": version: 15.2.0 resolution: "lint-staged@npm:15.2.0" @@ -18819,21 +18784,6 @@ __metadata: languageName: node linkType: hard -"markdown-it@npm:13.0.2": - version: 13.0.2 - resolution: "markdown-it@npm:13.0.2" - dependencies: - argparse: ^2.0.1 - entities: ~3.0.1 - linkify-it: ^4.0.1 - mdurl: ^1.0.1 - uc.micro: ^1.0.5 - bin: - markdown-it: bin/markdown-it.js - checksum: bb4bf2cb3e5d77a7f3dc9cf48e17d050fbcd26d37992204eaa5812220752858fe9debe439b2ae1de06e749a3bba537c0baf6ce7510307cf7163a70f04fafe672 - languageName: node - linkType: hard - "markdown-it@npm:^12.2.0": version: 12.3.2 resolution: "markdown-it@npm:12.3.2" From fbdc0e21fb6818611fdbc436d76fb2d9f5dc6ec7 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Fri, 8 Dec 2023 10:29:42 +0000 Subject: [PATCH 032/136] Reorder methods --- .../ast/operations/ConnectionReadOperation.ts | 208 +++++++++--------- 1 file changed, 104 insertions(+), 104 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 6522ae26044..e402cc9c44d 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -140,22 +140,93 @@ export class ConnectionReadOperation extends Operation { }; } - private transpileReturn({ - context, - edgesVar, - totalCount, - }: { - context: QueryASTContext; - edgesVar: Cypher.Variable; - totalCount: Cypher.Variable; - }): Cypher.Return { - return new Cypher.Return([ - new Cypher.Map({ - edges: edgesVar, - totalCount: totalCount, - }), - context.returnVariable, + public transpile(context: QueryASTContext): OperationTranspileResult { + if (this.relationship) { + return this.transpileNested(context); + } else { + return this.transpileTopLevel(context); + } + } + + private transpileTopLevel(context: QueryASTContext): OperationTranspileResult { + if (!hasTarget(context)) { + throw new Error("No parent node found!"); + } + + const { + prePaginationSubqueries, + postPaginationSubqueries, + withWhere, + edgeProjectionMap, + nestedContext, + extraMatches, + selectionClause, + authFilterSubqueries, + } = this.transpileCommon({ + context, + }); + + const edgeVar = new Cypher.NamedVariable("edge"); + const edgesVar = new Cypher.NamedVariable("edges"); + const totalCount = new Cypher.NamedVariable("totalCount"); + // Common transpile ends + const withNodeAndTotalCount = new Cypher.With([Cypher.collect(nestedContext.target), edgesVar]).with(edgesVar, [ + Cypher.size(edgesVar), + totalCount, ]); + + // Pagination is different + let paginationWith: Cypher.With | undefined; + if (this.pagination || this.sortFields.length > 0) { + paginationWith = new Cypher.With("*"); + const paginationField = this.pagination && this.pagination.getPagination(); + if (paginationField?.limit) { + paginationWith.limit(paginationField.limit); + } + if (paginationField?.skip) { + paginationWith.skip(paginationField.skip); + } + if (this.sortFields.length > 0) { + const sortFields = this.getSortFields({ + context: nestedContext, + nodeVar: nestedContext.target, + aliased: true, + }); + paginationWith.orderBy(...sortFields); + } + } + + // Projection is different + const unwindClause = new Cypher.Unwind([edgesVar, nestedContext.target]).with(nestedContext.target, totalCount); + const withProjection = new Cypher.With([edgeProjectionMap, edgeVar], totalCount, nestedContext.target).with( + [Cypher.collect(edgeVar), edgesVar], + totalCount + ); + + // Common Return + const returnClause = this.transpileReturn({ + context, + edgesVar, + totalCount, + }); + const clause = Cypher.concat( + ...extraMatches, + selectionClause, + ...authFilterSubqueries, + withWhere, + withNodeAndTotalCount, + unwindClause, + ...prePaginationSubqueries, + paginationWith, + ...postPaginationSubqueries, + withProjection, + returnClause + ); + + return { + clauses: [clause], + projectionExpr: context.returnVariable, + }; } private transpileNested(context: QueryASTContext): OperationTranspileResult { @@ -217,6 +288,24 @@ export class ConnectionReadOperation extends Operation { }; } + private transpileReturn({ + context, + edgesVar, + totalCount, + }: { + context: QueryASTContext; + edgesVar: Cypher.Variable; + totalCount: Cypher.Variable; + }): Cypher.Return { + return new Cypher.Return([ + new Cypher.Map({ + edges: edgesVar, + totalCount: totalCount, + }), + context.returnVariable, + ]); + } + private transpileCommon({ context }: { context: QueryASTContext }) { // eslint-disable-next-line prefer-const let { selection: selectionClause, nestedContext } = this.selection.apply(context); @@ -296,95 +385,6 @@ export class ConnectionReadOperation extends Operation { }; } - private transpileTopLevel(context: QueryASTContext): OperationTranspileResult { - if (!hasTarget(context)) { - throw new Error("No parent node found!"); - } - - const { - prePaginationSubqueries, - postPaginationSubqueries, - withWhere, - edgeProjectionMap, - nestedContext, - extraMatches, - selectionClause, - authFilterSubqueries, - } = this.transpileCommon({ - context, - }); - - const edgeVar = new Cypher.NamedVariable("edge"); - const edgesVar = new Cypher.NamedVariable("edges"); - const totalCount = new Cypher.NamedVariable("totalCount"); - // Common transpile ends - const withNodeAndTotalCount = new Cypher.With([Cypher.collect(nestedContext.target), edgesVar]).with(edgesVar, [ - Cypher.size(edgesVar), - totalCount, - ]); - - // Pagination is different - let paginationWith: Cypher.With | undefined; - if (this.pagination || this.sortFields.length > 0) { - paginationWith = new Cypher.With("*"); - const paginationField = this.pagination && this.pagination.getPagination(); - if (paginationField?.limit) { - paginationWith.limit(paginationField.limit); - } - if (paginationField?.skip) { - paginationWith.skip(paginationField.skip); - } - if (this.sortFields.length > 0) { - const sortFields = this.getSortFields({ - context: nestedContext, - nodeVar: nestedContext.target, - aliased: true, - }); - paginationWith.orderBy(...sortFields); - } - } - - // Projection is different - const unwindClause = new Cypher.Unwind([edgesVar, nestedContext.target]).with(nestedContext.target, totalCount); - const withProjection = new Cypher.With([edgeProjectionMap, edgeVar], totalCount, nestedContext.target).with( - [Cypher.collect(edgeVar), edgesVar], - totalCount - ); - - // Common Return - const returnClause = this.transpileReturn({ - context, - edgesVar, - totalCount, - }); - const clause = Cypher.concat( - ...extraMatches, - selectionClause, - ...authFilterSubqueries, - withWhere, - withNodeAndTotalCount, - unwindClause, - ...prePaginationSubqueries, - paginationWith, - ...postPaginationSubqueries, - withProjection, - returnClause - ); - - return { - clauses: [clause], - projectionExpr: context.returnVariable, - }; - } - - public transpile(context: QueryASTContext): OperationTranspileResult { - if (this.relationship) { - return this.transpileNested(context); - } else { - return this.transpileTopLevel(context); - } - } - protected getPaginationSubquery( context: QueryASTContext, edgesVar: Cypher.Variable, From 040b8f88fa74a24b81476a9996e4e19a49274367 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Fri, 8 Dec 2023 13:50:30 +0000 Subject: [PATCH 033/136] Unify connection transpilation --- .../ast/operations/ConnectionReadOperation.ts | 122 ++++++++- .../queryAST/ast/sort/CypherPropertySort.ts | 11 +- .../tests/integration/issues/1683.int.test.ts | 27 +- .../tests/integration/issues/1686.int.test.ts | 2 +- .../relationship-properties/read.int.test.ts | 8 +- .../tests/integration/sort.int.test.ts | 6 +- .../where/connection-auth-filter.test.ts | 2 +- packages/graphql/tests/tck/sort.test.ts | 254 +++++++++++++++++- 8 files changed, 394 insertions(+), 38 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index e402cc9c44d..c44d24e63bf 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -144,7 +144,8 @@ export class ConnectionReadOperation extends Operation { if (this.relationship) { return this.transpileNested(context); } else { - return this.transpileTopLevel(context); + // return this.transpileTopLevel(context); + return this.transpileNested(context); } } @@ -203,6 +204,18 @@ export class ConnectionReadOperation extends Operation { totalCount ); + // let sortSubquery: Cypher.With | undefined; + // if (this.pagination || this.sortFields.length > 0) { + // const paginationField = this.pagination && this.pagination.getPagination(); + + // sortSubquery = this.getPaginationSubquery(nestedContext, edgesVar, paginationField); + // sortSubquery.addColumns(totalCount); + // } + // // Projection is different + // const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) + // .with([Cypher.collect(edgeVar), edgesVar]) + // .with(edgesVar, [Cypher.size(edgesVar), totalCount]); + // Common Return const returnClause = this.transpileReturn({ context, @@ -219,6 +232,8 @@ export class ConnectionReadOperation extends Operation { ...prePaginationSubqueries, paginationWith, ...postPaginationSubqueries, + // projectionClauses, + // sortSubquery, withProjection, returnClause ); @@ -230,7 +245,8 @@ export class ConnectionReadOperation extends Operation { } private transpileNested(context: QueryASTContext): OperationTranspileResult { - if (!context.target || !this.relationship) throw new Error(); + // if (!context.target || !this.relationship) throw new Error(); + if (!context.target) throw new Error(); const { prePaginationSubqueries, @@ -251,18 +267,68 @@ export class ConnectionReadOperation extends Operation { // Common transpile ends // Pagination is different - let sortSubquery: Cypher.With | undefined; + // let sortSubquery: Cypher.With | undefined; + // if (this.pagination || this.sortFields.length > 0) { + // const paginationField = this.pagination && this.pagination.getPagination(); + + // sortSubquery = this.getPaginationSubquery(nestedContext, edgesVar, paginationField); + // sortSubquery.addColumns(totalCount); + // } + + // // Projection is different + // const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) + // .with([Cypher.collect(edgeVar), edgesVar]) + // .with(edgesVar, [Cypher.size(edgesVar), totalCount]); + + const edgeMap1 = new Cypher.Map({ + node: nestedContext.target, + }); + + if (nestedContext.relationship) { + edgeMap1.set("relationship", nestedContext.relationship); + } + + const withNodeAndTotalCount = new Cypher.With([Cypher.collect(edgeMap1), edgesVar]).with(edgesVar, [ + Cypher.size(edgesVar), + totalCount, + ]); + + let paginationWith: Cypher.With | undefined; if (this.pagination || this.sortFields.length > 0) { + paginationWith = new Cypher.With("*"); const paginationField = this.pagination && this.pagination.getPagination(); - - sortSubquery = this.getPaginationSubquery(nestedContext, edgesVar, paginationField); - sortSubquery.addColumns(totalCount); + if (paginationField?.limit) { + paginationWith.limit(paginationField.limit); + } + if (paginationField?.skip) { + paginationWith.skip(paginationField.skip); + } + if (this.sortFields.length > 0) { + const sortFields = this.getSortFields({ + context: nestedContext, + nodeVar: nestedContext.target, + edgeVar: nestedContext.relationship, + aliased: true, + }); + paginationWith.orderBy(...sortFields); + } } + const edgesVar2 = new Cypher.Variable(); + let unwindClause: Cypher.With; // Projection is different - const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) - .with([Cypher.collect(edgeVar), edgesVar]) - .with(edgesVar, [Cypher.size(edgesVar), totalCount]); + if (nestedContext.relationship) { + unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with( + [edgeVar.property("node"), nestedContext.target], + [edgeVar.property("relationship"), nestedContext.relationship] + ); + } else { + unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with([ + edgeVar.property("node"), + nestedContext.target, + ]); + } + const withProjection = new Cypher.With([edgeProjectionMap, edgeVar]).with([Cypher.collect(edgeVar), edgesVar]); // Common Return const returnClause = this.transpileReturn({ @@ -270,15 +336,36 @@ export class ConnectionReadOperation extends Operation { edgesVar, totalCount, }); + + const nestedThingy = new Cypher.Call( + Cypher.concat( + unwindClause, + ...prePaginationSubqueries, + paginationWith, + ...postPaginationSubqueries, + withProjection, + new Cypher.Return([edgesVar, edgesVar2]) + ) + ) + .innerWith(edgesVar) + .with([edgesVar2, edgesVar], totalCount); + const subClause = Cypher.concat( ...extraMatches, selectionClause, ...authFilterSubqueries, withWhere, - ...prePaginationSubqueries, - ...postPaginationSubqueries, - projectionClauses, - sortSubquery, + withNodeAndTotalCount, + nestedThingy, + // unwindClause, + // ...prePaginationSubqueries, + // paginationWith, + // ...postPaginationSubqueries, + // withProjection, + + // projectionClauses, + // sortSubquery, + returnClause ); @@ -423,6 +510,15 @@ export class ConnectionReadOperation extends Operation { aliased?: boolean; }): SortField[] { return this.sortFields.flatMap(({ node, edge }) => { + // Small hack to trick nested sortFields that the operation is always a nested operation + // const fakeNestedContext = new QueryASTContext({ + // source: context.source || context.target, + // relationship: context.relationship, + // target: context.target, + // env: context.env, + // neo4jGraphQLContext: context.neo4jGraphQLContext, + // }); + const nodeFields = node.flatMap((s) => s.getSortFields(context, nodeVar, aliased)); if (edgeVar) { const edgeFields = edge.flatMap((s) => s.getSortFields(context, edgeVar, aliased)); diff --git a/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts b/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts index 0d6bbffec72..3a571a5cbbd 100644 --- a/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts +++ b/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts @@ -18,12 +18,12 @@ */ import type Cypher from "@neo4j/cypher-builder"; -import type { SortField } from "./Sort"; -import { Sort } from "./Sort"; import type { AttributeAdapter } from "../../../../schema-model/attribute/model-adapters/AttributeAdapter"; -import type { QueryASTNode } from "../QueryASTNode"; -import type { QueryASTContext } from "../QueryASTContext"; import { CypherAnnotationSubqueryGenerator } from "../../cypher-generators/CypherAnnotationSubqueryGenerator"; +import type { QueryASTContext } from "../QueryASTContext"; +import type { QueryASTNode } from "../QueryASTNode"; +import type { SortField } from "./Sort"; +import { Sort } from "./Sort"; export class CypherPropertySort extends Sort { private attribute: AttributeAdapter; @@ -52,7 +52,8 @@ export class CypherPropertySort extends Sort { variable: Cypher.Variable | Cypher.Property, sortByDatabaseName = true ): SortField[] { - const isNested = context.source; + // const isNested = context.source; // TODO: avoid this, this should know if it is nested or not + const isNested = false; // TODO: avoid this, this should know if it is nested or not if (isNested) { const attributeName = sortByDatabaseName ? this.attribute.databaseName : this.attribute.name; diff --git a/packages/graphql/tests/integration/issues/1683.int.test.ts b/packages/graphql/tests/integration/issues/1683.int.test.ts index 55eb64f0fea..7e190500fe3 100644 --- a/packages/graphql/tests/integration/issues/1683.int.test.ts +++ b/packages/graphql/tests/integration/issues/1683.int.test.ts @@ -20,9 +20,9 @@ import type { GraphQLSchema } from "graphql"; import { graphql } from "graphql"; import type { Driver } from "neo4j-driver"; -import Neo4j from "../neo4j"; import { Neo4jGraphQL } from "../../../src"; import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; describe("https://github.com/neo4j/graphql/issues/1683", () => { const systemType = new UniqueType("System"); @@ -65,6 +65,31 @@ describe("https://github.com/neo4j/graphql/issues/1683", () => { await driver.close(); }); + // MATCH (this:oJzvmvwxSystem) + // CALL { + // WITH this + // MATCH (this)<-[this0:UPDATED_BY]-(this1:GuBXKcPnGovernedData) + // WITH { node: { code: this1.code } } AS edge + // WITH collect(edge) AS edges + // WITH edges, size(edges) AS totalCount + // RETURN { edges: edges, totalCount: totalCount } AS var2 + // } + // RETURN this { .code, updatesDataConnection: var2 } AS this + + // MATCH (this:bsCwrZgmSystem) + // CALL { + // WITH this + // MATCH (this)<-[this0:UPDATED_BY]-(this1:RqkfUGLmGovernedData) + // WITH collect({ relationship: this0, node: this1 }) AS edges + // WITH edges, size(edges) AS totalCount + // UNWIND edges AS edge + // WITH edge.node AS this1, edge.relationship AS this0, totalCount + // WITH { node: { code: this1.code } } AS edge, totalCount + // WITH collect(edge) AS edges, totalCount + // RETURN { edges: edges, totalCount: totalCount } AS var2 + // } + // RETURN this { .code, updatesDataConnection: var2 } AS this + test("should return top level entity, even if no connections exist", async () => { const query = ` { diff --git a/packages/graphql/tests/integration/issues/1686.int.test.ts b/packages/graphql/tests/integration/issues/1686.int.test.ts index 37295185a7d..7da25397708 100644 --- a/packages/graphql/tests/integration/issues/1686.int.test.ts +++ b/packages/graphql/tests/integration/issues/1686.int.test.ts @@ -20,9 +20,9 @@ import type { GraphQLSchema } from "graphql"; import { graphql } from "graphql"; import type { Driver } from "neo4j-driver"; -import Neo4j from "../neo4j"; import { Neo4jGraphQL } from "../../../src"; import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; describe("https://github.com/neo4j/graphql/issues/1686", () => { const productionType = new UniqueType("Production"); diff --git a/packages/graphql/tests/integration/relationship-properties/read.int.test.ts b/packages/graphql/tests/integration/relationship-properties/read.int.test.ts index ccb01adaf1e..c5e72462e1f 100644 --- a/packages/graphql/tests/integration/relationship-properties/read.int.test.ts +++ b/packages/graphql/tests/integration/relationship-properties/read.int.test.ts @@ -17,17 +17,17 @@ * limitations under the License. */ -import { offsetToCursor } from "graphql-relay"; -import type { Driver } from "neo4j-driver"; import type { DocumentNode } from "graphql"; import { graphql } from "graphql"; +import { offsetToCursor } from "graphql-relay"; import { gql } from "graphql-tag"; +import type { Driver } from "neo4j-driver"; import { generate } from "randomstring"; -import Neo4j from "../neo4j"; import { Neo4jGraphQL } from "../../../src/classes"; +import { cleanNodes } from "../../utils/clean-nodes"; import { UniqueType } from "../../utils/graphql-types"; import { runCypher } from "../../utils/run-cypher"; -import { cleanNodes } from "../../utils/clean-nodes"; +import Neo4j from "../neo4j"; describe("Relationship properties - read", () => { let driver: Driver; diff --git a/packages/graphql/tests/integration/sort.int.test.ts b/packages/graphql/tests/integration/sort.int.test.ts index 03bf7aab5c0..c3921552b43 100644 --- a/packages/graphql/tests/integration/sort.int.test.ts +++ b/packages/graphql/tests/integration/sort.int.test.ts @@ -17,14 +17,14 @@ * limitations under the License. */ -import type { Driver, Session } from "neo4j-driver"; import type { GraphQLSchema } from "graphql"; import { graphql } from "graphql"; -import { generate } from "randomstring"; import { gql } from "graphql-tag"; -import Neo4j from "./neo4j"; +import type { Driver, Session } from "neo4j-driver"; +import { generate } from "randomstring"; import { Neo4jGraphQL } from "../../src/classes"; import { UniqueType } from "../utils/graphql-types"; +import Neo4j from "./neo4j"; const testLabel = generate({ charset: "alphabetic" }); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index ed567bc7296..8d1d0c644e0 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -530,7 +530,7 @@ describe("Connection auth filter", () => { `); }); - test("Read Union Using Connection + User Defined Where", async () => { + test.only("Read Union Using Connection + User Defined Where", async () => { const query = gql` { usersConnection { diff --git a/packages/graphql/tests/tck/sort.test.ts b/packages/graphql/tests/tck/sort.test.ts index f3edbc9b4e4..6b14ff17705 100644 --- a/packages/graphql/tests/tck/sort.test.ts +++ b/packages/graphql/tests/tck/sort.test.ts @@ -19,26 +19,65 @@ import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../src"; -import { formatCypher, translateQuery, formatParams } from "./utils/tck-test-utils"; +import { formatCypher, formatParams, translateQuery } from "./utils/tck-test-utils"; describe("Cypher sort tests", () => { let typeDefs: string; let neoSchema: Neo4jGraphQL; beforeAll(() => { + // type Movie { + // id: ID + // title: String + // genres: [Genre!]! @relationship(type: "HAS_GENRE", direction: OUT) + // totalGenres: Int! + // @cypher( + // statement: """ + // MATCH (this)-[:HAS_GENRE]->(genre:Genre) + // RETURN count(DISTINCT genre) as result + // """ + // columnName: "result" + // ) + // } + + // type Genre { + // id: ID + // name: String + // totalMovies: Int! + // @cypher( + // statement: """ + // MATCH (this)<-[:HAS_GENRE]-(movie:Movie) + // RETURN count(DISTINCT movie) as result + // """ + // columnName: "result" + // ) + // } typeDefs = ` - type Movie { - id: ID - title: String + + + interface Production { + id: ID! + title: String! + } + type Movie implements Production { + id: ID! + title: String! + runtime: Int! + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") genres: [Genre!]! @relationship(type: "HAS_GENRE", direction: OUT) - totalGenres: Int! + numberOfActors: Int! @cypher( - statement: """ - MATCH (this)-[:HAS_GENRE]->(genre:Genre) - RETURN count(DISTINCT genre) as result - """ - columnName: "result" + statement: "MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count" + columnName: "count" ) + totalGenres: Int! + @cypher( + statement: """ + MATCH (this)-[:HAS_GENRE]->(genre:Genre) + RETURN count(DISTINCT genre) as result + """ + columnName: "result" + ) } type Genre { @@ -53,6 +92,29 @@ describe("Cypher sort tests", () => { columnName: "result" ) } + + type Series implements Production { + id: ID! + title: String! + episodes: Int! + } + type Actor { + id: ID! + name: String! + movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + totalScreenTime: Int! + @cypher( + statement: """ + MATCH (this)-[r:ACTED_IN]->(:Movie) + RETURN sum(r.screenTime) as sum + """ + columnName: "sum" + ) + } + interface ActedIn @relationshipProperties { + screenTime: Int! + } `; neoSchema = new Neo4jGraphQL({ @@ -350,4 +412,176 @@ describe("Cypher sort tests", () => { expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); }); + + test("Connection top level", async () => { + const query = gql` + query { + moviesConnection(first: 2, sort: { title: DESC, numberOfActors: ASC }) { + totalCount + edges { + node { + title + actorsConnection { + edges { + node { + name + totalScreenTime + } + } + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this0:Movie) + WITH collect(this0) AS edges + WITH edges, size(edges) AS totalCount + UNWIND edges AS this0 + WITH this0, totalCount + CALL { + WITH this0 + CALL { + WITH this0 + WITH this0 AS this + MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + } + UNWIND count AS this1 + RETURN head(collect(this1)) AS this1 + } + WITH * + ORDER BY this0.title DESC, this1 ASC + LIMIT $param0 + CALL { + WITH this0 + MATCH (this0)<-[this2:ACTED_IN]-(this3:Actor) + CALL { + WITH this3 + CALL { + WITH this3 + WITH this3 AS this + MATCH (this)-[r:ACTED_IN]->(:Movie) + RETURN sum(r.screenTime) as sum + } + UNWIND sum AS this4 + RETURN head(collect(this4)) AS this4 + } + WITH { node: { name: this3.name, totalScreenTime: this4 } } AS edge + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 + } + WITH { node: { title: this0.title, actorsConnection: var5 } } AS edge, totalCount, this0 + WITH collect(edge) AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": { + \\"low\\": 2, + \\"high\\": 0 + } + }" + `); + }); + + test("Connection nested", async () => { + const query = gql` + query { + actors { + moviesConnection(first: 2, sort: { node: { title: DESC, numberOfActors: ASC } }) { + totalCount + edges { + node { + title + actorsConnection { + edges { + node { + name + totalScreenTime + } + } + } + } + } + pageInfo { + hasNextPage + endCursor + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + CALL { + WITH this + MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + CALL { + WITH this1 + CALL { + WITH this1 + WITH this1 AS this + MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + } + UNWIND count AS this2 + RETURN head(collect(this2)) AS this2 + } + CALL { + WITH this1 + MATCH (this1)<-[this3:ACTED_IN]-(this4:Actor) + CALL { + WITH this4 + CALL { + WITH this4 + WITH this4 AS this + MATCH (this)-[r:ACTED_IN]->(:Movie) + RETURN sum(r.screenTime) as sum + } + UNWIND sum AS this5 + RETURN head(collect(this5)) AS this5 + } + WITH { node: { name: this4.name, totalScreenTime: this5 } } AS edge + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + RETURN { edges: edges, totalCount: totalCount } AS var6 + } + WITH { node: { title: this1.title, actorsConnection: var6 } } AS edge + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge + ORDER BY edge.node.title DESC, edge.node.numberOfActors ASC + LIMIT $param0 + RETURN collect(edge) AS var7 + } + WITH var7 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var8 + } + RETURN this { moviesConnection: var8 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": { + \\"low\\": 2, + \\"high\\": 0 + } + }" + `); + }); }); From 43e05e9be064e460f3c025b90a691440faed1c94 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Fri, 8 Dec 2023 16:33:02 +0000 Subject: [PATCH 034/136] Update tck tests --- .../ast/operations/ConnectionReadOperation.ts | 129 -------------- .../tests/tck/connections/alias.test.ts | 50 ++++-- .../connections/filtering/composite.test.ts | 80 ++++++--- .../connections/filtering/node/and.test.ts | 32 +++- .../connections/filtering/node/arrays.test.ts | 64 +++++-- .../filtering/node/equality.test.ts | 32 +++- .../filtering/node/numerical.test.ts | 64 +++++-- .../tck/connections/filtering/node/or.test.ts | 16 +- .../connections/filtering/node/points.test.ts | 22 ++- .../filtering/node/relationship.test.ts | 16 +- .../connections/filtering/node/string.test.ts | 112 +++++++++---- .../filtering/relationship/and.test.ts | 32 +++- .../filtering/relationship/arrays.test.ts | 64 +++++-- .../filtering/relationship/equality.test.ts | 32 +++- .../filtering/relationship/numerical.test.ts | 64 +++++-- .../filtering/relationship/or.test.ts | 16 +- .../filtering/relationship/points.test.ts | 22 ++- .../filtering/relationship/string.test.ts | 112 +++++++++---- .../filtering/relationship/temporal.test.ts | 16 +- .../tck/connections/mixed-nesting.test.ts | 96 +++++++---- .../connections/projections/create.test.ts | 48 ++++-- .../projections/projections.test.ts | 68 +++++--- .../relationship-properties.test.ts | 158 ++++++++++++------ .../relationship_properties/connect.test.ts | 36 ++-- .../relationship_properties/create.test.ts | 16 +- .../tests/tck/connections/sort.test.ts | 92 ++++++---- .../tests/tck/directives/alias.test.ts | 32 +++- .../arguments/roles-where.test.ts | 32 +++- .../where/connection-auth-filter.test.ts | 35 ++-- .../arguments/where/where.test.ts | 32 +++- .../projection-connection-union.test.ts | 20 ++- .../projection-connection.test.ts | 156 +++++++++++------ .../tests/tck/directives/coalesce.test.ts | 32 +++- .../tck/directives/node/node-label.test.ts | 16 +- .../node/node-with-auth-projection.test.ts | 16 +- .../graphql/tests/tck/issues/1150.test.ts | 44 +++-- .../graphql/tests/tck/issues/1221.test.ts | 96 +++++++---- .../graphql/tests/tck/issues/1249.test.ts | 20 ++- .../graphql/tests/tck/issues/1364.test.ts | 109 ++++++------ .../graphql/tests/tck/issues/1528.test.ts | 34 ++-- .../graphql/tests/tck/issues/1760.test.ts | 70 +++++--- .../graphql/tests/tck/issues/1783.test.ts | 56 +++++-- .../graphql/tests/tck/issues/2022.test.ts | 43 ++--- .../graphql/tests/tck/issues/2262.test.ts | 44 +++-- .../graphql/tests/tck/issues/2437.test.ts | 10 +- .../graphql/tests/tck/issues/3394.test.ts | 31 ++-- .../graphql/tests/tck/issues/4007.test.ts | 16 +- .../graphql/tests/tck/issues/4015.test.ts | 16 +- .../graphql/tests/tck/issues/4292.test.ts | 20 ++- packages/graphql/tests/tck/issues/433.test.ts | 16 +- packages/graphql/tests/tck/issues/601.test.ts | 20 ++- packages/graphql/tests/tck/issues/630.test.ts | 16 +- packages/graphql/tests/tck/issues/988.test.ts | 32 +++- .../tests/tck/operations/create.test.ts | 22 ++- .../tests/tck/rfcs/query-limits.test.ts | 30 ++-- .../graphql/tests/tck/root-connection.test.ts | 96 +++++++---- packages/graphql/tests/tck/sort.test.ts | 145 +++++++++------- .../tests/tck/subscriptions/create.test.ts | 54 ++++-- .../query-direction-connection.test.ts | 48 ++++-- .../undirected-connection.test.ts | 16 +- 60 files changed, 1968 insertions(+), 996 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index c44d24e63bf..469929a69f8 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -141,111 +141,6 @@ export class ConnectionReadOperation extends Operation { } public transpile(context: QueryASTContext): OperationTranspileResult { - if (this.relationship) { - return this.transpileNested(context); - } else { - // return this.transpileTopLevel(context); - return this.transpileNested(context); - } - } - - private transpileTopLevel(context: QueryASTContext): OperationTranspileResult { - if (!hasTarget(context)) { - throw new Error("No parent node found!"); - } - - const { - prePaginationSubqueries, - postPaginationSubqueries, - withWhere, - edgeProjectionMap, - nestedContext, - extraMatches, - selectionClause, - authFilterSubqueries, - } = this.transpileCommon({ - context, - }); - - const edgeVar = new Cypher.NamedVariable("edge"); - const edgesVar = new Cypher.NamedVariable("edges"); - const totalCount = new Cypher.NamedVariable("totalCount"); - // Common transpile ends - const withNodeAndTotalCount = new Cypher.With([Cypher.collect(nestedContext.target), edgesVar]).with(edgesVar, [ - Cypher.size(edgesVar), - totalCount, - ]); - - // Pagination is different - let paginationWith: Cypher.With | undefined; - if (this.pagination || this.sortFields.length > 0) { - paginationWith = new Cypher.With("*"); - const paginationField = this.pagination && this.pagination.getPagination(); - if (paginationField?.limit) { - paginationWith.limit(paginationField.limit); - } - if (paginationField?.skip) { - paginationWith.skip(paginationField.skip); - } - if (this.sortFields.length > 0) { - const sortFields = this.getSortFields({ - context: nestedContext, - nodeVar: nestedContext.target, - aliased: true, - }); - paginationWith.orderBy(...sortFields); - } - } - - // Projection is different - const unwindClause = new Cypher.Unwind([edgesVar, nestedContext.target]).with(nestedContext.target, totalCount); - const withProjection = new Cypher.With([edgeProjectionMap, edgeVar], totalCount, nestedContext.target).with( - [Cypher.collect(edgeVar), edgesVar], - totalCount - ); - - // let sortSubquery: Cypher.With | undefined; - // if (this.pagination || this.sortFields.length > 0) { - // const paginationField = this.pagination && this.pagination.getPagination(); - - // sortSubquery = this.getPaginationSubquery(nestedContext, edgesVar, paginationField); - // sortSubquery.addColumns(totalCount); - // } - // // Projection is different - // const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) - // .with([Cypher.collect(edgeVar), edgesVar]) - // .with(edgesVar, [Cypher.size(edgesVar), totalCount]); - - // Common Return - const returnClause = this.transpileReturn({ - context, - edgesVar, - totalCount, - }); - const clause = Cypher.concat( - ...extraMatches, - selectionClause, - ...authFilterSubqueries, - withWhere, - withNodeAndTotalCount, - unwindClause, - ...prePaginationSubqueries, - paginationWith, - ...postPaginationSubqueries, - // projectionClauses, - // sortSubquery, - withProjection, - returnClause - ); - - return { - clauses: [clause], - projectionExpr: context.returnVariable, - }; - } - - private transpileNested(context: QueryASTContext): OperationTranspileResult { - // if (!context.target || !this.relationship) throw new Error(); if (!context.target) throw new Error(); const { @@ -264,21 +159,6 @@ export class ConnectionReadOperation extends Operation { const edgeVar = new Cypher.NamedVariable("edge"); const edgesVar = new Cypher.NamedVariable("edges"); const totalCount = new Cypher.NamedVariable("totalCount"); - // Common transpile ends - - // Pagination is different - // let sortSubquery: Cypher.With | undefined; - // if (this.pagination || this.sortFields.length > 0) { - // const paginationField = this.pagination && this.pagination.getPagination(); - - // sortSubquery = this.getPaginationSubquery(nestedContext, edgesVar, paginationField); - // sortSubquery.addColumns(totalCount); - // } - - // // Projection is different - // const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]) - // .with([Cypher.collect(edgeVar), edgesVar]) - // .with(edgesVar, [Cypher.size(edgesVar), totalCount]); const edgeMap1 = new Cypher.Map({ node: nestedContext.target, @@ -357,15 +237,6 @@ export class ConnectionReadOperation extends Operation { withWhere, withNodeAndTotalCount, nestedThingy, - // unwindClause, - // ...prePaginationSubqueries, - // paginationWith, - // ...postPaginationSubqueries, - // withProjection, - - // projectionClauses, - // sortSubquery, - returnClause ); diff --git a/packages/graphql/tests/tck/connections/alias.test.ts b/packages/graphql/tests/tck/connections/alias.test.ts index 156d7f1a41c..596d823d4aa 100644 --- a/packages/graphql/tests/tck/connections/alias.test.ts +++ b/packages/graphql/tests/tck/connections/alias.test.ts @@ -66,12 +66,20 @@ describe("Connections Alias", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { actors: var2 } AS this" + RETURN this { actors: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -111,21 +119,37 @@ describe("Connections Alias", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name = $param1 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } CALL { WITH this - MATCH (this)<-[this3:ACTED_IN]-(this4:Actor) - WHERE this4.name = $param2 - WITH { screenTime: this3.screenTime, node: { name: this4.name } } AS edge - WITH collect(edge) AS edges + MATCH (this)<-[this4:ACTED_IN]-(this5:Actor) + WHERE this5.name = $param2 + WITH collect({ node: this5, relationship: this4 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this5, edge.relationship AS this4 + WITH { screenTime: this4.screenTime, node: { name: this5.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var6 + } + WITH var6 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var7 } - RETURN this { .title, hanks: var2, jenny: var5 } AS this" + RETURN this { .title, hanks: var3, jenny: var7 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/composite.test.ts b/packages/graphql/tests/tck/connections/filtering/composite.test.ts index a265d701540..efddee6a059 100644 --- a/packages/graphql/tests/tck/connections/filtering/composite.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/composite.test.ts @@ -81,12 +81,20 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE ((this1.firstName = $param1 AND this1.lastName = $param2) AND (this0.screenTime > $param3 AND this0.screenTime < $param4)) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -138,12 +146,20 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE (NOT (this1.firstName = $param1 AND this1.lastName = $param2) AND NOT (this0.screenTime < $param3 AND this0.screenTime > $param4)) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -197,12 +213,20 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE ((this1.firstName = $param1 AND this1.lastName = $param2) OR (this0.screenTime > $param3 AND this0.screenTime < $param4)) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -258,12 +282,20 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT ((this1.firstName = $param1 AND this1.lastName = $param2) OR (this0.screenTime > $param3 AND this0.screenTime < $param4)) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -324,12 +356,20 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (((this1.firstName = $param1 AND this1.lastName = $param2) OR (this0.screenTime > $param3 AND this0.screenTime < $param4)) AND (this1.firstName = $param5 AND this1.lastName = $param6)) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts index 1244235a023..252115ba21b 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts @@ -75,12 +75,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE (this1.firstName = $param0 AND this1.lastName = $param1) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -117,12 +125,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this1.firstName = $param0) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts index f259e5afa17..4aaa8b5707c 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts @@ -74,12 +74,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name IN $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -117,12 +125,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this1.name IN $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -161,12 +177,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE $param0 IN this1.favouriteColours - WITH { screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -202,12 +226,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT ($param0 IN this1.favouriteColours) - WITH { screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts index 73631b68e2b..d83227dc9dc 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts @@ -73,12 +73,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name = $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -113,12 +121,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this1.name = $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts index e14253a4234..6d94b41e344 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts @@ -75,12 +75,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.age < $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -119,12 +127,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.age <= $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -163,12 +179,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.age > $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -207,12 +231,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.age >= $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts index 8c2281b5915..9b108eca68e 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts @@ -75,12 +75,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> OR", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE (this1.firstName = $param0 OR this1.lastName = $param1) - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts index 943728053a2..b196e00a6fd 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts @@ -91,15 +91,23 @@ describe("Cypher -> Connections -> Filtering -> Node -> Points", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE point.distance(this1.currentLocation, point($param0.point)) = $param0.distance - WITH { screenTime: this0.screenTime, node: { name: this1.name, currentLocation: CASE - WHEN this1.currentLocation IS NOT NULL THEN { point: this1.currentLocation } - ELSE NULL - END } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name, currentLocation: CASE + WHEN this1.currentLocation IS NOT NULL THEN { point: this1.currentLocation } + ELSE NULL + END } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts index 74240205033..7a9f089dbe8 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts @@ -71,12 +71,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> Relationship", () => { MATCH (this1)-[:ACTED_IN]->(this2:Movie) WHERE this2.title = $param0 } - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .title, actorsConnection: var3 } AS this" + RETURN this { .title, actorsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts index e372199efe4..499aaf4de60 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts @@ -91,12 +91,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name CONTAINS $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -131,12 +139,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this1.name CONTAINS $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -171,12 +187,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name STARTS WITH $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -211,12 +235,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this1.name STARTS WITH $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -251,12 +283,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name ENDS WITH $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -291,12 +331,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this1.name ENDS WITH $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -331,12 +379,20 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name =~ $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts index 2a80be5e1f6..d089f9ce599 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts @@ -75,12 +75,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE (this0.role ENDS WITH $param0 AND this0.screenTime < $param1) - WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -120,12 +128,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this0.role ENDS WITH $param0) - WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts index c8839a08528..14d940d5af6 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts @@ -74,12 +74,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.screenTime IN $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -123,12 +131,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this0.screenTime IN $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -172,12 +188,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE $param0 IN this0.quotes - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -212,12 +236,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT ($param0 IN this0.quotes) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts index 2c6cf8d5e0d..1e13e05ef85 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts @@ -73,12 +73,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.screenTime = $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -116,12 +124,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this0.screenTime = $param0) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts index ef945d40bc3..704fd81318a 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts @@ -73,12 +73,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.screenTime < $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -116,12 +124,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.screenTime <= $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -159,12 +175,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.screenTime > $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -202,12 +226,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.screenTime >= $param0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts index d287005a98a..222ab90c85a 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts @@ -75,12 +75,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> OR", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE (this0.role ENDS WITH $param0 OR this0.screenTime < $param1) - WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts index ef1ba000150..53afb3b3ec7 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts @@ -89,15 +89,23 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Points", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE point.distance(this0.location, point($param0.point)) = $param0.distance - WITH { screenTime: this0.screenTime, location: CASE - WHEN this0.location IS NOT NULL THEN { point: this0.location } - ELSE NULL - END, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, location: CASE + WHEN this0.location IS NOT NULL THEN { point: this0.location } + ELSE NULL + END, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts index 342a33b671d..372f9541c68 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts @@ -91,12 +91,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.role CONTAINS $param0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -131,12 +139,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this0.role CONTAINS $param0) - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -171,12 +187,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.role STARTS WITH $param0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -211,12 +235,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this0.role STARTS WITH $param0) - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -251,12 +283,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.role ENDS WITH $param0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -291,12 +331,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE NOT (this0.role ENDS WITH $param0) - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -331,12 +379,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this0.role =~ $param0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { role: this0.role, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts index 88af9c47f6f..567c9402235 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts @@ -77,12 +77,20 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Temporal", () => WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE (this0.startDate > $param0 AND this0.endDateTime < $param1) - WITH { startDate: this0.startDate, endDateTime: apoc.date.convertFormat(toString(this0.endDateTime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { startDate: this0.startDate, endDateTime: apoc.date.convertFormat(toString(this0.endDateTime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts index 05ed6d7e7ca..7a695d6ca5d 100644 --- a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts +++ b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts @@ -77,19 +77,27 @@ describe("Mixed nesting", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name = $param1 + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 - MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) - WHERE NOT (this3.title = $param2) - WITH this3 { .title } AS this3 - RETURN collect(this3) AS var4 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + CALL { + WITH this1 + MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) + WHERE NOT (this3.title = $param2) + WITH this3 { .title } AS this3 + RETURN collect(this3) AS var4 + } + WITH { screenTime: this0.screenTime, node: { name: this1.name, movies: var4 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var5 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, movies: var4 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + WITH var5 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var6 } - RETURN this { .title, actorsConnection: var5 } AS this" + RETURN this { .title, actorsConnection: var6 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -137,28 +145,44 @@ describe("Mixed nesting", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name = $param1 + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 - MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) - WHERE NOT (this3.title = $param2) + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 CALL { - WITH this3 - MATCH (this3)<-[this4:ACTED_IN]-(this5:Actor) - WHERE NOT (this5.name = $param3) - WITH this5 { .name } AS this5 - RETURN collect(this5) AS var6 + WITH this1 + MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) + WHERE NOT (this3.title = $param2) + WITH collect({ node: this3, relationship: this2 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + CALL { + WITH this3 + MATCH (this3)<-[this4:ACTED_IN]-(this5:Actor) + WHERE NOT (this5.name = $param3) + WITH this5 { .name } AS this5 + RETURN collect(this5) AS var6 + } + WITH { node: { title: this3.title, actors: var6 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var7 + } + WITH var7 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var8 } - WITH { node: { title: this3.title, actors: var6 } } AS edge + WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var8 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN edges AS var9 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var7 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + WITH var9 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var10 } - RETURN this { .title, actorsConnection: var8 } AS this" + RETURN this { .title, actorsConnection: var10 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -204,15 +228,23 @@ describe("Mixed nesting", () => { WITH this1 MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) WHERE NOT (this3.title = $param2) - WITH { screenTime: this2.screenTime, node: { title: this3.title } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this3, relationship: this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + WITH { screenTime: this2.screenTime, node: { title: this3.title } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 } - WITH this1 { .name, moviesConnection: var4 } AS this1 - RETURN collect(this1) AS var5 + WITH this1 { .name, moviesConnection: var5 } AS this1 + RETURN collect(this1) AS var6 } - RETURN this { .title, actors: var5 } AS this" + RETURN this { .title, actors: var6 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/projections/create.test.ts b/packages/graphql/tests/tck/connections/projections/create.test.ts index 5a7e052517b..f1db245ac15 100644 --- a/packages/graphql/tests/tck/connections/projections/create.test.ts +++ b/packages/graphql/tests/tck/connections/projections/create.test.ts @@ -81,12 +81,20 @@ describe("Cypher -> Connections -> Projections -> Create", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this2:ACTED_IN]-(create_this3:Actor) - WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this3, relationship: create_this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this3, edge.relationship AS create_this2 + WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var4 + } + WITH create_var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var5 } - RETURN collect(create_this1 { .title, actorsConnection: create_var4 }) AS data" + RETURN collect(create_this1 { .title, actorsConnection: create_var5 }) AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -134,12 +142,20 @@ describe("Cypher -> Connections -> Projections -> Create", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this2:ACTED_IN]-(create_this3:Actor) - WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this3, relationship: create_this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this3, edge.relationship AS create_this2 + WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var4 + } + WITH create_var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var5 } - RETURN collect(create_this1 { .title, actorsConnection: create_var4 }) AS data" + RETURN collect(create_this1 { .title, actorsConnection: create_var5 }) AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -191,12 +207,20 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH create_this1 MATCH (create_this1)<-[create_this2:ACTED_IN]-(create_this3:Actor) WHERE create_this3.name = $create_param1 - WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this3, relationship: create_this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this3, edge.relationship AS create_this2 + WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var4 + } + WITH create_var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var5 } - RETURN collect(create_this1 { .title, actorsConnection: create_var4 }) AS data" + RETURN collect(create_this1 { .title, actorsConnection: create_var5 }) AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/projections/projections.test.ts b/packages/graphql/tests/tck/connections/projections/projections.test.ts index f1ecf4801af..6202df5c759 100644 --- a/packages/graphql/tests/tck/connections/projections/projections.test.ts +++ b/packages/graphql/tests/tck/connections/projections/projections.test.ts @@ -71,12 +71,20 @@ describe("Relay Cursor Connection projections", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -111,12 +119,20 @@ describe("Relay Cursor Connection projections", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -146,15 +162,17 @@ describe("Relay Cursor Connection projections", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH * LIMIT $param1 - RETURN collect(edge) AS var2 + WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 @@ -291,12 +309,20 @@ describe("Relay Cursor Connection projections", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -331,15 +357,17 @@ describe("Relay Cursor Connection projections", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH * LIMIT $param1 - RETURN collect(edge) AS var2 + WITH { node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/relationship-properties.test.ts b/packages/graphql/tests/tck/connections/relationship-properties.test.ts index 62171e89ac1..b59f50b3a4e 100644 --- a/packages/graphql/tests/tck/connections/relationship-properties.test.ts +++ b/packages/graphql/tests/tck/connections/relationship-properties.test.ts @@ -74,12 +74,20 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -115,12 +123,20 @@ describe("Relationship Properties Cypher", () => { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) WHERE this1.name = $param1 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -156,15 +172,17 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge - ORDER BY edge.screenTime DESC - RETURN collect(edge) AS var2 + WITH edge.node AS this1, edge.relationship AS this0 + WITH * + ORDER BY this0.screenTime DESC + WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 @@ -202,15 +220,17 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { year: this0.year, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge - ORDER BY edge.year DESC, edge.node.name ASC - RETURN collect(edge) AS var2 + WITH edge.node AS this1, edge.relationship AS this0 + WITH * + ORDER BY this0.year DESC, this1.name ASC + WITH { year: this0.year, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 @@ -243,15 +263,17 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { year: this0.year, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge - ORDER BY edge.node.name ASC, edge.year DESC - RETURN collect(edge) AS var2 + WITH edge.node AS this1, edge.relationship AS this0 + WITH * + ORDER BY this1.name ASC, this0.year DESC + WITH { year: this0.year, node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 @@ -295,20 +317,36 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 - MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) - WITH { screenTime: this2.screenTime, node: { title: this3.title } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + CALL { + WITH this1 + MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) + WITH collect({ node: this3, relationship: this2 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + WITH { screenTime: this2.screenTime, node: { title: this3.title } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 + } + WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var5 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN edges AS var6 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var4 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + WITH var6 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var7 } - RETURN this { .title, actorsConnection: var5 } AS this" + RETURN this { .title, actorsConnection: var7 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -359,28 +397,52 @@ describe("Relationship Properties Cypher", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 - MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 CALL { - WITH this3 - MATCH (this3)<-[this4:ACTED_IN]-(this5:Actor) - WITH { screenTime: this4.screenTime, node: { name: this5.name } } AS edge - WITH collect(edge) AS edges + WITH this1 + MATCH (this1)-[this2:ACTED_IN]->(this3:Movie) + WITH collect({ node: this3, relationship: this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + CALL { + WITH this3 + MATCH (this3)<-[this4:ACTED_IN]-(this5:Actor) + WITH collect({ node: this5, relationship: this4 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this5, edge.relationship AS this4 + WITH { screenTime: this4.screenTime, node: { name: this5.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var6 + } + WITH var6 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var7 + } + WITH { screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var7 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var8 + } + WITH var8 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var9 } - WITH { screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var6 } } AS edge + WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var9 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN edges AS var10 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var7 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + WITH var10 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var11 } - RETURN this { .title, actorsConnection: var8 } AS this" + RETURN this { .title, actorsConnection: var11 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts index 7ec6fde941a..7696a72d5f9 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts @@ -98,14 +98,22 @@ describe("Relationship Properties Connect Cypher", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this1, relationship: create_this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this1, edge.relationship AS create_this0 + WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var2 + } + WITH create_var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var3 } - RETURN this0 { .title, actorsConnection: create_var2 } AS create_var3 + RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } - RETURN [create_var3] AS data" + RETURN [create_var4] AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -178,14 +186,22 @@ describe("Relationship Properties Connect Cypher", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this1, relationship: create_this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this1, edge.relationship AS create_this0 + WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var2 + } + WITH create_var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var3 } - RETURN this0 { .title, actorsConnection: create_var2 } AS create_var3 + RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } - RETURN [create_var3] AS data" + RETURN [create_var4] AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts index a7b01afb791..78b063fc355 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts @@ -101,12 +101,20 @@ describe("Relationship Properties Create Cypher", () => { CALL { WITH create_this1 MATCH (create_this1)<-[create_this8:ACTED_IN]-(create_this9:Actor) - WITH { screenTime: create_this8.screenTime, node: { name: create_this9.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this9, relationship: create_this8 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var10 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this9, edge.relationship AS create_this8 + WITH { screenTime: create_this8.screenTime, node: { name: create_this9.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var10 + } + WITH create_var10 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var11 } - RETURN collect(create_this1 { .title, actorsConnection: create_var10 }) AS data" + RETURN collect(create_this1 { .title, actorsConnection: create_var11 }) AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/connections/sort.test.ts b/packages/graphql/tests/tck/connections/sort.test.ts index c852d3c7cd2..4a61d518b48 100644 --- a/packages/graphql/tests/tck/connections/sort.test.ts +++ b/packages/graphql/tests/tck/connections/sort.test.ts @@ -78,23 +78,36 @@ describe("Relationship Properties Cypher", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH * - ORDER BY this0.title ASC - LIMIT $param0 CALL { - WITH this0 - MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) - WITH { node: { name: this2.name } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH * + ORDER BY this0.title ASC + LIMIT $param0 + CALL { + WITH this0 + MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH collect({ node: this2, relationship: this1 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + WITH { node: { name: this2.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 + } + WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN edges AS var5 } - WITH { node: { title: this0.title, actorsConnection: var3 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var5 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -132,33 +145,46 @@ describe("Relationship Properties Cypher", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { WITH this0 - WITH this0 AS this - MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + CALL { + WITH this0 + WITH this0 AS this + MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + } + UNWIND count AS this1 + RETURN head(collect(this1)) AS this1 } - UNWIND count AS this1 - RETURN head(collect(this1)) AS this1 - } - WITH * - ORDER BY this0.title DESC, this1 ASC - LIMIT $param0 - CALL { - WITH this0 - MATCH (this0)<-[this2:ACTED_IN]-(this3:Actor) - WITH { node: { name: this3.name } } AS edge + WITH * + ORDER BY this0.title DESC, this1 ASC + LIMIT $param0 + CALL { + WITH this0 + MATCH (this0)<-[this2:ACTED_IN]-(this3:Actor) + WITH collect({ node: this3, relationship: this2 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + WITH { node: { name: this3.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 + } + WITH { node: { title: this0.title, actorsConnection: var5 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN edges AS var6 } - WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var6 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/alias.test.ts b/packages/graphql/tests/tck/directives/alias.test.ts index c93bcede695..d0deb40321f 100644 --- a/packages/graphql/tests/tck/directives/alias.test.ts +++ b/packages/graphql/tests/tck/directives/alias.test.ts @@ -107,12 +107,20 @@ describe("Cypher alias directive", () => { CALL { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Movie) - WITH { character: this0.characterPropInDb, screenTime: this0.screenTime, node: { title: this1.title, rating: this1.ratingPropInDb } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { character: this0.characterPropInDb, screenTime: this0.screenTime, node: { title: this1.title, rating: this1.ratingPropInDb } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .name, city: this.cityPropInDb, actedInConnection: var2 } AS this" + RETURN this { .name, city: this.cityPropInDb, actedInConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -193,12 +201,20 @@ describe("Cypher alias directive", () => { CALL { WITH create_this1 MATCH (create_this1)-[create_this11:ACTED_IN]->(create_this12:Movie) - WITH { character: create_this11.characterPropInDb, screenTime: create_this11.screenTime, node: { title: create_this12.title, rating: create_this12.ratingPropInDb } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this12, relationship: create_this11 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var13 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this12, edge.relationship AS create_this11 + WITH { character: create_this11.characterPropInDb, screenTime: create_this11.screenTime, node: { title: create_this12.title, rating: create_this12.ratingPropInDb } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var13 + } + WITH create_var13 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var14 } - RETURN collect(create_this1 { .name, city: create_this1.cityPropInDb, actedIn: create_var10, actedInConnection: create_var13 }) AS data" + RETURN collect(create_this1 { .name, city: create_this1.cityPropInDb, actedIn: create_var10, actedInConnection: create_var14 }) AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts index c49b733e228..a19b557c074 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts @@ -232,12 +232,20 @@ describe("Cypher Auth Where with Roles", () => { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(this2 IN [(this1)<-[:HAS_POST]-(this2:User) WHERE ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $param4 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param5 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { content: this1.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .id, postsConnection: var3 } AS this" + RETURN this { .id, postsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -286,12 +294,20 @@ describe("Cypher Auth Where with Roles", () => { WITH this MATCH (this)-[this0:HAS_POST]->(this1:Post) WHERE (this1.id = $param4 AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(this2 IN [(this1)<-[:HAS_POST]-(this2:User) WHERE ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $param5 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param6 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { content: this1.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .id, postsConnection: var3 } AS this" + RETURN this { .id, postsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index 8d1d0c644e0..ec7bccff18c 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -560,28 +560,33 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE (this2.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) - WITH { node: { __resolveType: \\"Post\\", __id: id(this2), id: this2.id } } AS edge - RETURN edge + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE (this2.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) + WITH { node: { __resolveType: \\"Post\\", __id: id(this2), id: this2.id } } AS edge + RETURN edge + } + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } + WITH { node: { id: this0.id, contentConnection: var4 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN edges AS var5 } - WITH { node: { id: this0.id, contentConnection: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var5 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index 55f41370f5a..0942413ffa8 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -221,12 +221,20 @@ describe("Cypher Auth Where", () => { WITH *, count(this2) AS creatorCount WITH * WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))) - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { content: this1.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .id, postsConnection: var3 } AS this" + RETURN this { .id, postsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -274,12 +282,20 @@ describe("Cypher Auth Where", () => { WITH *, count(this2) AS creatorCount WITH * WHERE (this1.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub)))) - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { content: this1.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .id, postsConnection: var3 } AS this" + RETURN this { .id, postsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts index 872011ef23e..6d898071797 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts @@ -104,19 +104,27 @@ describe("Cypher Auth Projection On Connections On Unions", () => { WITH this1 MATCH (this1)<-[this3:HAS_POST]-(this4:User) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this4.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { name: this4.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this4, relationship: this3 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this4, edge.relationship AS this3 + WITH { node: { name: this4.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var5 + } + WITH var5 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var6 } - WITH { node: { __resolveType: \\"Post\\", __id: id(this1), content: this1.content, creatorConnection: var5 } } AS edge + WITH { node: { __resolveType: \\"Post\\", __id: id(this1), content: this1.content, creatorConnection: var6 } } AS edge RETURN edge } WITH collect(edge) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN { edges: edges, totalCount: totalCount } AS var7 } - RETURN this { contentConnection: var6 } AS this" + RETURN this { contentConnection: var7 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts index 46e2dbad9f6..836d1ed5277 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts @@ -88,12 +88,20 @@ describe("Cypher Auth Projection On Connections", () => { WITH *, count(this2) AS creatorCount WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { content: this1.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .name, postsConnection: var3 } AS this" + RETURN this { .name, postsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -146,21 +154,37 @@ describe("Cypher Auth Projection On Connections", () => { WITH *, count(this2) AS creatorCount WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 - MATCH (this1)<-[this3:HAS_POST]-(this4:User) - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this4.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { name: this4.name } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + CALL { + WITH this1 + MATCH (this1)<-[this3:HAS_POST]-(this4:User) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this4.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this4, relationship: this3 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this4, edge.relationship AS this3 + WITH { node: { name: this4.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var5 + } + WITH var5 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var6 + } + WITH { node: { content: this1.content, creatorConnection: var6 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN edges AS var7 } - WITH { node: { content: this1.content, creatorConnection: var5 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + WITH var7 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var8 } - RETURN this { .name, postsConnection: var6 } AS this" + RETURN this { .name, postsConnection: var8 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -236,24 +260,37 @@ describe("Cypher Auth Projection On top-level connections", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { content: this2.content } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this2, relationship: this1 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + WITH { node: { content: this2.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 + } + WITH { node: { name: this0.name, postsConnection: var5 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN edges AS var6 } - WITH { node: { name: this0.name, postsConnection: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var6 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -303,33 +340,54 @@ describe("Cypher Auth Projection On top-level connections", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { - WITH this2 - MATCH (this2)<-[this4:HAS_POST]-(this5:User) - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this5.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { name: this5.name } } AS edge - WITH collect(edge) AS edges + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this2, relationship: this1 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + CALL { + WITH this2 + MATCH (this2)<-[this4:HAS_POST]-(this5:User) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this5.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this5, relationship: this4 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this5, edge.relationship AS this4 + WITH { node: { name: this5.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var6 + } + WITH var6 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var7 + } + WITH { node: { content: this2.content, creatorConnection: var7 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var8 + } + WITH var8 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var9 } - WITH { node: { content: this2.content, creatorConnection: var6 } } AS edge + WITH { node: { name: this0.name, postsConnection: var9 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN edges AS var10 } - WITH { node: { name: this0.name, postsConnection: var7 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var10 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/coalesce.test.ts b/packages/graphql/tests/tck/directives/coalesce.test.ts index ae9cb545605..b20500a507c 100644 --- a/packages/graphql/tests/tck/directives/coalesce.test.ts +++ b/packages/graphql/tests/tck/directives/coalesce.test.ts @@ -215,12 +215,20 @@ describe("Cypher coalesce()", () => { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Movie) WHERE coalesce(this1.status, \\"ACTIVE\\") = $param0 - WITH { node: { id: this1.id, status: this1.status } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { id: this1.id, status: this1.status } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { moviesConnection: var2 } AS this" + RETURN this { moviesConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -273,12 +281,20 @@ describe("Cypher coalesce()", () => { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Movie) WHERE coalesce(this1.statuses, [\\"ACTIVE\\", \\"INACTIVE\\"]) = $param0 - WITH { node: { id: this1.id, statuses: this1.statuses } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { id: this1.id, statuses: this1.statuses } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { moviesConnection: var2 } AS this" + RETURN this { moviesConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/node/node-label.test.ts b/packages/graphql/tests/tck/directives/node/node-label.test.ts index 2170d099177..f504beb3e88 100644 --- a/packages/graphql/tests/tck/directives/node/node-label.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-label.test.ts @@ -115,12 +115,20 @@ describe("Label in Node directive", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); diff --git a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts index 2785c72b60d..7da5c3164a7 100644 --- a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts @@ -84,12 +84,20 @@ describe("Cypher Auth Projection On Connections", () => { WITH *, count(this2) AS creatorCount WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this2.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { content: this1.content } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN this { .name, postsConnection: var3 } AS this" + RETURN this { .name, postsConnection: var4 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/1150.test.ts b/packages/graphql/tests/tck/issues/1150.test.ts index eb9091a449d..18cea43e517 100644 --- a/packages/graphql/tests/tck/issues/1150.test.ts +++ b/packages/graphql/tests/tck/issues/1150.test.ts @@ -113,31 +113,39 @@ describe("https://github.com/neo4j/graphql/issues/1150", () => { WITH this MATCH (this)-[this0:CONSISTS_OF]->(this1:DriveComposition) WHERE this0.current = $param1 + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 CALL { WITH this1 - MATCH (this1)-[this2:HAS]->(this3:Battery) - WHERE (this2.current = $param2 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param5 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) - WITH { current: this2.current, node: { __resolveType: \\"Battery\\", __id: id(this3), id: this3.id } } AS edge - RETURN edge - UNION - WITH this1 - MATCH (this1)-[this4:HAS]->(this5:CombustionEngine) - WHERE this4.current = $param6 - WITH { current: this4.current, node: { __resolveType: \\"CombustionEngine\\", __id: id(this5), id: this5.id } } AS edge - RETURN edge + CALL { + WITH this1 + MATCH (this1)-[this2:HAS]->(this3:Battery) + WHERE (this2.current = $param2 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param5 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WITH { current: this2.current, node: { __resolveType: \\"Battery\\", __id: id(this3), id: this3.id } } AS edge + RETURN edge + UNION + WITH this1 + MATCH (this1)-[this4:HAS]->(this5:CombustionEngine) + WHERE this4.current = $param6 + WITH { current: this4.current, node: { __resolveType: \\"CombustionEngine\\", __id: id(this5), id: this5.id } } AS edge + RETURN edge + } + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + RETURN { edges: edges, totalCount: totalCount } AS var6 } + WITH { node: { driveComponentConnection: var6 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN edges AS var7 } - WITH { node: { driveComponentConnection: var6 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + WITH var7 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var8 } - RETURN this { .current, driveCompositionsConnection: var7 } AS this" + RETURN this { .current, driveCompositionsConnection: var8 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/1221.test.ts b/packages/graphql/tests/tck/issues/1221.test.ts index e628d6d2ea9..0a3dea1bd23 100644 --- a/packages/graphql/tests/tck/issues/1221.test.ts +++ b/packages/graphql/tests/tck/issues/1221.test.ts @@ -91,21 +91,37 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH this MATCH (this)-[this4:ARCHITECTURE]->(this5:MasterData) WHERE this4.current = $param2 + WITH collect({ node: this5, relationship: this4 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this5 - MATCH (this5)-[this6:HAS_NAME]->(this7:NameDetails) - WHERE this6.current = $param3 - WITH { node: { fullName: this7.fullName } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this5, edge.relationship AS this4 + CALL { + WITH this5 + MATCH (this5)-[this6:HAS_NAME]->(this7:NameDetails) + WHERE this6.current = $param3 + WITH collect({ node: this7, relationship: this6 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this7, edge.relationship AS this6 + WITH { node: { fullName: this7.fullName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var8 + } + WITH var8 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var9 + } + WITH { node: { nameDetailsConnection: var9 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + RETURN edges AS var10 } - WITH { node: { nameDetailsConnection: var8 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + WITH var10 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var11 } - RETURN this { .id, architectureConnection: var9 } AS this" + RETURN this { .id, architectureConnection: var11 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -202,30 +218,54 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH this MATCH (this)-[this6:MAIN]->(this7:Series) WHERE this6.current = $param2 + WITH collect({ node: this7, relationship: this6 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this7 - MATCH (this7)-[this8:ARCHITECTURE]->(this9:MasterData) - WHERE this8.current = $param3 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this7, edge.relationship AS this6 CALL { - WITH this9 - MATCH (this9)-[this10:HAS_NAME]->(this11:NameDetails) - WHERE this10.current = $param4 - WITH { node: { fullName: this11.fullName } } AS edge - WITH collect(edge) AS edges + WITH this7 + MATCH (this7)-[this8:ARCHITECTURE]->(this9:MasterData) + WHERE this8.current = $param3 + WITH collect({ node: this9, relationship: this8 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var12 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this9, edge.relationship AS this8 + CALL { + WITH this9 + MATCH (this9)-[this10:HAS_NAME]->(this11:NameDetails) + WHERE this10.current = $param4 + WITH collect({ node: this11, relationship: this10 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this11, edge.relationship AS this10 + WITH { node: { fullName: this11.fullName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var12 + } + WITH var12 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var13 + } + WITH { node: { nameDetailsConnection: var13 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var14 + } + WITH var14 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var15 } - WITH { node: { nameDetailsConnection: var12 } } AS edge + WITH { node: { architectureConnection: var15 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var13 + RETURN edges AS var16 } - WITH { node: { architectureConnection: var13 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var14 + WITH var16 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var17 } - RETURN this { .id, mainConnection: var14 } AS this" + RETURN this { .id, mainConnection: var17 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/1249.test.ts b/packages/graphql/tests/tck/issues/1249.test.ts index 56301a4bece..07fa9379a49 100644 --- a/packages/graphql/tests/tck/issues/1249.test.ts +++ b/packages/graphql/tests/tck/issues/1249.test.ts @@ -88,15 +88,23 @@ describe("https://github.com/neo4j/graphql/issues/1249", () => { CALL { WITH this1 MATCH (this1)-[this2:MATERIAL_SUPPLIER]->(this3:Supplier) - WITH { supplierMaterialNumber: this2.supplierMaterialNumber, node: { supplierId: this3.supplierId } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this3, relationship: this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + WITH { supplierMaterialNumber: this2.supplierMaterialNumber, node: { supplierId: this3.supplierId } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 } - WITH this1 { .id, suppliersConnection: var4 } AS this1 - RETURN head(collect(this1)) AS var5 + WITH this1 { .id, suppliersConnection: var5 } AS this1 + RETURN head(collect(this1)) AS var6 } - RETURN this { .supplierMaterialNumber, material: var5 } AS this" + RETURN this { .supplierMaterialNumber, material: var6 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/1364.test.ts b/packages/graphql/tests/tck/issues/1364.test.ts index f23ad028ebe..1de6c96260c 100644 --- a/packages/graphql/tests/tck/issues/1364.test.ts +++ b/packages/graphql/tests/tck/issues/1364.test.ts @@ -94,25 +94,30 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH * - ORDER BY this0.title ASC CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH * + ORDER BY this0.title ASC CALL { WITH this0 - WITH this0 AS this - MATCH (this)-[:HAS_GENRE]->(genre:Genre) - RETURN count(DISTINCT genre) as result + CALL { + WITH this0 + WITH this0 AS this + MATCH (this)-[:HAS_GENRE]->(genre:Genre) + RETURN count(DISTINCT genre) as result + } + UNWIND result AS this1 + RETURN head(collect(this1)) AS this1 } - UNWIND result AS this1 - RETURN head(collect(this1)) AS this1 + WITH { node: { title: this0.title, totalGenres: this1 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } - WITH { node: { title: this0.title, totalGenres: this1 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); }); @@ -135,25 +140,30 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { WITH this0 - WITH this0 AS this - MATCH (this)-[:HAS_GENRE]->(genre:Genre) - RETURN count(DISTINCT genre) as result + CALL { + WITH this0 + WITH this0 AS this + MATCH (this)-[:HAS_GENRE]->(genre:Genre) + RETURN count(DISTINCT genre) as result + } + UNWIND result AS this1 + RETURN head(collect(this1)) AS this1 } - UNWIND result AS this1 - RETURN head(collect(this1)) AS this1 + WITH * + ORDER BY this1 ASC + WITH { node: { title: this0.title, totalGenres: this1 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } - WITH * - ORDER BY this1 ASC - WITH { node: { title: this0.title, totalGenres: this1 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); }); @@ -177,36 +187,41 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { WITH this0 - WITH this0 AS this - MATCH (this)-[:HAS_GENRE]->(genre:Genre) - RETURN count(DISTINCT genre) as result + CALL { + WITH this0 + WITH this0 AS this + MATCH (this)-[:HAS_GENRE]->(genre:Genre) + RETURN count(DISTINCT genre) as result + } + UNWIND result AS this1 + RETURN head(collect(this1)) AS this1 } - UNWIND result AS this1 - RETURN head(collect(this1)) AS this1 - } - WITH * - ORDER BY this1 ASC - CALL { - WITH this0 + WITH * + ORDER BY this1 ASC CALL { WITH this0 - WITH this0 AS this - MATCH (this)<-[:ACTED_IN]-(actor:Actor) - RETURN count(DISTINCT actor) as result + CALL { + WITH this0 + WITH this0 AS this + MATCH (this)<-[:ACTED_IN]-(actor:Actor) + RETURN count(DISTINCT actor) as result + } + UNWIND result AS this2 + RETURN head(collect(this2)) AS this2 } - UNWIND result AS this2 - RETURN head(collect(this2)) AS this2 + WITH { node: { title: this0.title, totalGenres: this1, totalActors: this2 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 } - WITH { node: { title: this0.title, totalGenres: this1, totalActors: this2 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var3 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); }); diff --git a/packages/graphql/tests/tck/issues/1528.test.ts b/packages/graphql/tests/tck/issues/1528.test.ts index 06ca79d5c20..10c0fd7c2b7 100644 --- a/packages/graphql/tests/tck/issues/1528.test.ts +++ b/packages/graphql/tests/tck/issues/1528.test.ts @@ -74,26 +74,28 @@ describe("https://github.com/neo4j/graphql/issues/1528", () => { CALL { WITH this MATCH (this)<-[this0:IS_GENRE]-(this1:Movie) - CALL { - WITH this1 - CALL { - WITH this1 - WITH this1 AS this - MATCH (this)<-[:ACTED_IN]-(ac:Person) - RETURN count(ac) as res - } - UNWIND res AS this2 - RETURN head(collect(this2)) AS this2 - } - WITH { node: { title: this1.title, actorsCount: this2 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge - ORDER BY edge.node.actorsCount DESC - RETURN collect(edge) AS var3 + WITH edge.node AS this1, edge.relationship AS this0 + CALL { + WITH this1 + CALL { + WITH this1 + WITH this1 AS this + MATCH (this)<-[:ACTED_IN]-(ac:Person) + RETURN count(ac) as res + } + UNWIND res AS this2 + RETURN head(collect(this2)) AS this2 + } + WITH * + ORDER BY this2 DESC + WITH { node: { title: this1.title, actorsCount: this2 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 } WITH var3 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/issues/1760.test.ts b/packages/graphql/tests/tck/issues/1760.test.ts index 57c9e7db6fd..ecaa1ec5391 100644 --- a/packages/graphql/tests/tck/issues/1760.test.ts +++ b/packages/graphql/tests/tck/issues/1760.test.ts @@ -153,39 +153,71 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH this MATCH (this)-[this1:HAS_NAME]->(this2:NameDetails) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param6 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { fullName: this2.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this2, relationship: this1 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + WITH { node: { fullName: this2.fullName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } CALL { WITH this - MATCH (this)-[this4:HAS_MARKETS]->(this5:Market) + MATCH (this)-[this5:HAS_MARKETS]->(this6:Market) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param7 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this6, relationship: this5 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this5 - MATCH (this5)-[this6:HAS_NAME]->(this7:NameDetails) - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param8 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { fullName: this7.fullName } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this6, edge.relationship AS this5 + CALL { + WITH this6 + MATCH (this6)-[this7:HAS_NAME]->(this8:NameDetails) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param8 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this8, relationship: this7 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this8, edge.relationship AS this7 + WITH { node: { fullName: this8.fullName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var9 + } + WITH var9 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var10 + } + WITH { node: { nameDetailsConnection: var10 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + RETURN edges AS var11 } - WITH { node: { nameDetailsConnection: var8 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + WITH var11 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var12 } CALL { WITH this - MATCH (this)<-[this10:HAS_BASE]-(this11:BaseObject) + MATCH (this)<-[this13:HAS_BASE]-(this14:BaseObject) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param9 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { node: { id: this11.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this14, relationship: this13 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var12 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this14, edge.relationship AS this13 + WITH { node: { id: this14.id } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var15 + } + WITH var15 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var16 } - RETURN this { relatedId: this0, nameDetailsConnection: var3, marketsConnection: var9, baseObjectConnection: var12 } AS this" + RETURN this { relatedId: this0, nameDetailsConnection: var4, marketsConnection: var12, baseObjectConnection: var16 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/1783.test.ts b/packages/graphql/tests/tck/issues/1783.test.ts index 41c1174e599..821910b2a43 100644 --- a/packages/graphql/tests/tck/issues/1783.test.ts +++ b/packages/graphql/tests/tck/issues/1783.test.ts @@ -126,30 +126,54 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH this MATCH (this)-[this6:HAS_NAME]->(this7:NameDetails) WHERE this6.current = $param6 - WITH { node: { fullName: this7.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this7, relationship: this6 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this7, edge.relationship AS this6 + WITH { node: { fullName: this7.fullName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var8 + } + WITH var8 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var9 } CALL { WITH this - MATCH (this)-[this9:ARCHITECTURE]->(this10:MasterData) - WHERE this9.current = $param7 + MATCH (this)-[this10:ARCHITECTURE]->(this11:MasterData) + WHERE this10.current = $param7 + WITH collect({ node: this11, relationship: this10 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this10 - MATCH (this10)-[this11:HAS_NAME]->(this12:NameDetails) - WHERE this11.current = $param8 - WITH { node: { fullName: this12.fullName } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this11, edge.relationship AS this10 + CALL { + WITH this11 + MATCH (this11)-[this12:HAS_NAME]->(this13:NameDetails) + WHERE this12.current = $param8 + WITH collect({ node: this13, relationship: this12 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this13, edge.relationship AS this12 + WITH { node: { fullName: this13.fullName } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var14 + } + WITH var14 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var15 + } + WITH { node: { nameDetailsConnection: var15 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var13 + RETURN edges AS var16 } - WITH { node: { nameDetailsConnection: var13 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var14 + WITH var16 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var17 } - RETURN this { .id, nameDetailsConnection: var8, architectureConnection: var14 } AS this" + RETURN this { .id, nameDetailsConnection: var9, architectureConnection: var17 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index 89cded2d63e..1bb0b3da454 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -91,30 +91,35 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:ArtPiece) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:SOLD_AT_AUCTION_AS]->(this2:AuctionItem) + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { - WITH this2 - MATCH (this2)<-[this3:BOUGHT_ITEM_AT_AUCTION]-(this4:Organization) - WITH this4 { .name, dbId: this4.id } AS this4 - RETURN head(collect(this4)) AS var5 + WITH this0 + MATCH (this0)-[this1:SOLD_AT_AUCTION_AS]->(this2:AuctionItem) + CALL { + WITH this2 + MATCH (this2)<-[this3:BOUGHT_ITEM_AT_AUCTION]-(this4:Organization) + WITH this4 { .name, dbId: this4.id } AS this4 + RETURN head(collect(this4)) AS var5 + } + WITH this2 { .auctionName, .lotNumber, dbId: this2.id, buyer: var5 } AS this2 + RETURN head(collect(this2)) AS var6 } - WITH this2 { .auctionName, .lotNumber, dbId: this2.id, buyer: var5 } AS this2 - RETURN head(collect(this2)) AS var6 - } - CALL { - WITH this0 - MATCH (this0)-[this7:OWNED_BY]->(this8:Organization) - WITH this8 { .name, dbId: this8.id } AS this8 - RETURN head(collect(this8)) AS var9 + CALL { + WITH this0 + MATCH (this0)-[this7:OWNED_BY]->(this8:Organization) + WITH this8 { .name, dbId: this8.id } AS this8 + RETURN head(collect(this8)) AS var9 + } + WITH { node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var10 } - WITH { node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var10 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/2262.test.ts b/packages/graphql/tests/tck/issues/2262.test.ts index b0485260535..03b943620ca 100644 --- a/packages/graphql/tests/tck/issues/2262.test.ts +++ b/packages/graphql/tests/tck/issues/2262.test.ts @@ -76,28 +76,38 @@ describe("https://github.com/neo4j/graphql/issues/2262", () => { CALL { WITH this MATCH (this)<-[this0:OUTPUT]-(this1:Process) + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 - MATCH (this1)<-[this2:INPUT]-(this3:Component) - WITH { node: { uuid: this3.uuid } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 CALL { - WITH edges - UNWIND edges AS edge - WITH edge - ORDER BY edge.node.uuid DESC - RETURN collect(edge) AS var4 + WITH this1 + MATCH (this1)<-[this2:INPUT]-(this3:Component) + WITH collect({ node: this3, relationship: this2 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + WITH * + ORDER BY this3.uuid DESC + WITH { node: { uuid: this3.uuid } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + WITH { node: { uuid: this1.uuid, componentInputsConnection: var5 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var6 } - WITH { node: { uuid: this1.uuid, componentInputsConnection: var5 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + WITH var6 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var7 } - RETURN this { .uuid, upstreamProcessConnection: var6 } AS this" + RETURN this { .uuid, upstreamProcessConnection: var7 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/2437.test.ts b/packages/graphql/tests/tck/issues/2437.test.ts index b4537c25fef..c4e07369d8a 100644 --- a/packages/graphql/tests/tck/issues/2437.test.ts +++ b/packages/graphql/tests/tck/issues/2437.test.ts @@ -86,15 +86,17 @@ describe("https://github.com/neo4j/graphql/issues/2437", () => { WITH this MATCH (this)-[this0:IS_VALUATION_AGENT]->(this1:Valuation) WHERE ($isAuthenticated = true AND this1.archivedAt IS NULL) - WITH { node: { uuid: this1.uuid } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH * LIMIT $param2 - RETURN collect(edge) AS var2 + WITH { node: { uuid: this1.uuid } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index 57aa708ab24..50e06b0f048 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -114,14 +114,19 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Product) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH * - ORDER BY this0.fg_item DESC - WITH { node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH * + ORDER BY this0.fg_item DESC + WITH { node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var1 + } + WITH var1 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -152,15 +157,17 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { CALL { WITH this MATCH (this)-[this0:CAN_ACCESS]->(this1:Product) - WITH { node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge - ORDER BY edge.node.partNumber DESC - RETURN collect(edge) AS var2 + WITH edge.node AS this1, edge.relationship AS this0 + WITH * + ORDER BY this1.fg_item DESC + WITH { node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/4007.test.ts b/packages/graphql/tests/tck/issues/4007.test.ts index d4ed15fb218..bf6d13b1444 100644 --- a/packages/graphql/tests/tck/issues/4007.test.ts +++ b/packages/graphql/tests/tck/issues/4007.test.ts @@ -66,12 +66,20 @@ describe("https://github.com/neo4j/graphql/issues/4007", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { na: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { na: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { t: var2 } AS this" + RETURN this { t: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); diff --git a/packages/graphql/tests/tck/issues/4015.test.ts b/packages/graphql/tests/tck/issues/4015.test.ts index ff7dc95721a..76e12b36d3e 100644 --- a/packages/graphql/tests/tck/issues/4015.test.ts +++ b/packages/graphql/tests/tck/issues/4015.test.ts @@ -70,12 +70,20 @@ describe("https://github.com/neo4j/graphql/issues/4015", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Actor) - WITH { node: { surname: this1.surname, name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { surname: this1.surname, name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { actorsConnection: var2 } AS this" + RETURN this { actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); diff --git a/packages/graphql/tests/tck/issues/4292.test.ts b/packages/graphql/tests/tck/issues/4292.test.ts index 451365dc788..d83d6bc1862 100644 --- a/packages/graphql/tests/tck/issues/4292.test.ts +++ b/packages/graphql/tests/tck/issues/4292.test.ts @@ -248,15 +248,23 @@ describe("https://github.com/neo4j/graphql/issues/4292", () => { } WITH * WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ((creatorCount <> 0 AND ($jwt.uid IS NOT NULL AND this14.id = $jwt.uid)) OR (groupCount <> 0 AND size([(this15)<-[:ADMIN_OF]-(this22:Admin) WHERE single(this21 IN [(this22)-[:IS_USER]->(this21:User) WHERE ($jwt.uid IS NOT NULL AND this21.id = $jwt.uid) | 1] WHERE true) | 1]) > 0) OR (groupCount <> 0 AND size([(this16)<-[:CONTRIBUTOR_TO]-(this24:Contributor) WHERE single(this23 IN [(this24)-[:IS_USER]->(this23:User) WHERE ($jwt.uid IS NOT NULL AND this23.id = $jwt.uid) | 1] WHERE true) | 1]) > 0) OR var20 = true)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { active: this12.active, firstDay: this12.firstDay, lastDay: this12.lastDay, node: { __resolveType: \\"Person\\", __id: id(this13) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this13, relationship: this12 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var25 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this13, edge.relationship AS this12 + WITH { active: this12.active, firstDay: this12.firstDay, lastDay: this12.lastDay, node: { __resolveType: \\"Person\\", __id: id(this13) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var25 + } + WITH var25 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var26 } - WITH this1 { .id, .name, partnersConnection: var25 } AS this1 - RETURN collect(this1) AS var26 + WITH this1 { .id, .name, partnersConnection: var26 } AS this1 + RETURN collect(this1) AS var27 } - RETURN this { .id, .name, members: var26 } AS this" + RETURN this { .id, .name, members: var27 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/433.test.ts b/packages/graphql/tests/tck/issues/433.test.ts index 8944a8950d4..c480ef679f7 100644 --- a/packages/graphql/tests/tck/issues/433.test.ts +++ b/packages/graphql/tests/tck/issues/433.test.ts @@ -67,12 +67,20 @@ describe("#413", () => { CALL { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Person) - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { name: this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { .title, actorsConnection: var2 } AS this" + RETURN this { .title, actorsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); diff --git a/packages/graphql/tests/tck/issues/601.test.ts b/packages/graphql/tests/tck/issues/601.test.ts index 00bdfefa4f1..08f3eba88ad 100644 --- a/packages/graphql/tests/tck/issues/601.test.ts +++ b/packages/graphql/tests/tck/issues/601.test.ts @@ -105,15 +105,23 @@ describe("#601", () => { WITH this1 MATCH (this1)<-[this2:UPLOADED]-(this3:CustomerContact) WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $param4 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) - WITH { fileId: this2.fileId, uploadedAt: apoc.date.convertFormat(toString(this2.uploadedAt), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { __resolveType: \\"CustomerContact\\", __id: id(this3) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this3, relationship: this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + WITH { fileId: this2.fileId, uploadedAt: apoc.date.convertFormat(toString(this2.uploadedAt), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { __resolveType: \\"CustomerContact\\", __id: id(this3) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var4 + } + WITH var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var5 } - WITH this1 { customerContactConnection: var4 } AS this1 - RETURN collect(this1) AS var5 + WITH this1 { customerContactConnection: var5 } AS this1 + RETURN collect(this1) AS var6 } - RETURN this { documents: var5 } AS this" + RETURN this { documents: var6 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/issues/630.test.ts b/packages/graphql/tests/tck/issues/630.test.ts index c1e9224624c..bd508c32373 100644 --- a/packages/graphql/tests/tck/issues/630.test.ts +++ b/packages/graphql/tests/tck/issues/630.test.ts @@ -81,12 +81,20 @@ describe("Cypher directive", () => { CALL { WITH this0 MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) - WITH { node: { __resolveType: \\"Actor\\", __id: id(this2) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this2, relationship: this1 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + WITH { node: { __resolveType: \\"Actor\\", __id: id(this2) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - RETURN collect(this0 { actorsConnection: var3 }) AS this0 + RETURN collect(this0 { actorsConnection: var4 }) AS this0 } RETURN this { movies: this0 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/988.test.ts b/packages/graphql/tests/tck/issues/988.test.ts index 60547daece1..c560b260888 100644 --- a/packages/graphql/tests/tck/issues/988.test.ts +++ b/packages/graphql/tests/tck/issues/988.test.ts @@ -145,20 +145,36 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { CALL { WITH this MATCH (this)-[this6:MANUFACTURER]->(this7:Manufacturer) - WITH { current: this6.current, node: { name: this7.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this7, relationship: this6 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this7, edge.relationship AS this6 + WITH { current: this6.current, node: { name: this7.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var8 + } + WITH var8 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var9 } CALL { WITH this - MATCH (this)-[this9:BRAND]->(this10:Brand) - WITH { current: this9.current, node: { name: this10.name } } AS edge - WITH collect(edge) AS edges + MATCH (this)-[this10:BRAND]->(this11:Brand) + WITH collect({ node: this11, relationship: this10 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var11 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this11, edge.relationship AS this10 + WITH { current: this10.current, node: { name: this11.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var12 + } + WITH var12 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var13 } - RETURN this { .name, .current, manufacturerConnection: var8, brandConnection: var11 } AS this" + RETURN this { .name, .current, manufacturerConnection: var9, brandConnection: var13 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` "{ diff --git a/packages/graphql/tests/tck/operations/create.test.ts b/packages/graphql/tests/tck/operations/create.test.ts index bfdd0dcc001..4d778583c07 100644 --- a/packages/graphql/tests/tck/operations/create.test.ts +++ b/packages/graphql/tests/tck/operations/create.test.ts @@ -417,17 +417,25 @@ describe("Cypher Create", () => { WITH create_this1 MATCH (create_this1)<-[create_this2:ACTED_IN]-(create_this3:Actor) WHERE create_this3.name = $create_param0 - WITH { node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this3, relationship: create_this2 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var4 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this3, edge.relationship AS create_this2 + WITH { node: { name: create_this3.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var4 + } + WITH create_var4 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var5 } - WITH create_this1 { actorsConnection: create_var4 } AS create_this1 - RETURN collect(create_this1) AS create_var5 + WITH create_this1 { actorsConnection: create_var5 } AS create_this1 + RETURN collect(create_this1) AS create_var6 } - RETURN this0 { .name, movies: create_var5 } AS create_var6 + RETURN this0 { .name, movies: create_var6 } AS create_var7 } - RETURN [create_var6] AS data" + RETURN [create_var7] AS data" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/rfcs/query-limits.test.ts b/packages/graphql/tests/tck/rfcs/query-limits.test.ts index fafad4198ca..74f17cbd49e 100644 --- a/packages/graphql/tests/tck/rfcs/query-limits.test.ts +++ b/packages/graphql/tests/tck/rfcs/query-limits.test.ts @@ -206,15 +206,17 @@ describe("tck/rfcs/query-limits", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) - WITH { node: { id: this1.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH * LIMIT $param1 - RETURN collect(edge) AS var2 + WITH { node: { id: this1.id } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 @@ -261,15 +263,17 @@ describe("tck/rfcs/query-limits", () => { CALL { WITH this MATCH (this)<-[this0:ACTED_IN]-(this1:Person) - WITH { node: { id: this1.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH * LIMIT $param1 - RETURN collect(edge) AS var2 + WITH { node: { id: this1.id } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 @@ -314,15 +318,17 @@ describe("tck/rfcs/query-limits", () => { CALL { WITH this MATCH (this)<-[this0:PART_OF]-(this1:Show) - WITH { node: { id: this1.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount CALL { WITH edges UNWIND edges AS edge - WITH edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH * LIMIT $param0 - RETURN collect(edge) AS var2 + WITH { node: { id: this1.id } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 } WITH var2 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index dba35fa86ef..910afebc206 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -64,12 +64,17 @@ describe("Root Connection Query tests", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) WHERE this0.title = $param0 - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH { node: { title: this0.title } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH { node: { title: this0.title } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var1 + } + WITH var1 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -97,15 +102,20 @@ describe("Root Connection Query tests", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH * - ORDER BY this0.title ASC - LIMIT $param0 - WITH { node: { title: this0.title } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH * + ORDER BY this0.title ASC + LIMIT $param0 + WITH { node: { title: this0.title } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var1 + } + WITH var1 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -134,15 +144,20 @@ describe("Root Connection Query tests", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) WHERE this0.title CONTAINS $param0 - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH * - ORDER BY this0.title ASC - LIMIT $param1 - WITH { node: { title: this0.title } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH * + ORDER BY this0.title ASC + LIMIT $param1 + WITH { node: { title: this0.title } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var1 + } + WITH var1 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -178,23 +193,36 @@ describe("Root Connection Query tests", () => { const result = await translateQuery(neoSchema, query); expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH * - ORDER BY this0.title ASC - LIMIT $param0 CALL { - WITH this0 - MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) - WITH { node: { name: this2.name } } AS edge + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + WITH * + ORDER BY this0.title ASC + LIMIT $param0 + CALL { + WITH this0 + MATCH (this0)<-[this1:ACTED_IN]-(this2:Actor) + WITH collect({ node: this2, relationship: this1 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + WITH { node: { name: this2.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var3 + } + WITH var3 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 + } + WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN edges AS var5 } - WITH { node: { title: this0.title, actorsConnection: var3 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var5 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/sort.test.ts b/packages/graphql/tests/tck/sort.test.ts index 6b14ff17705..22d2629ac3a 100644 --- a/packages/graphql/tests/tck/sort.test.ts +++ b/packages/graphql/tests/tck/sort.test.ts @@ -404,7 +404,7 @@ describe("Cypher sort tests", () => { RETURN head(collect(this2)) AS this2 } WITH this1 { .name, totalMovies: this2 } AS this1 - ORDER BY this1.totalMovies ASC + ORDER BY this2 ASC RETURN collect(this1) AS var3 } RETURN this { genres: var3 } AS this" @@ -443,44 +443,57 @@ describe("Cypher sort tests", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:Movie) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { WITH this0 - WITH this0 AS this - MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + CALL { + WITH this0 + WITH this0 AS this + MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + } + UNWIND count AS this1 + RETURN head(collect(this1)) AS this1 } - UNWIND count AS this1 - RETURN head(collect(this1)) AS this1 - } - WITH * - ORDER BY this0.title DESC, this1 ASC - LIMIT $param0 - CALL { - WITH this0 - MATCH (this0)<-[this2:ACTED_IN]-(this3:Actor) + WITH * + ORDER BY this0.title DESC, this1 ASC + LIMIT $param0 CALL { - WITH this3 + WITH this0 + MATCH (this0)<-[this2:ACTED_IN]-(this3:Actor) + WITH collect({ node: this3, relationship: this2 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this3 - WITH this3 AS this - MATCH (this)-[r:ACTED_IN]->(:Movie) - RETURN sum(r.screenTime) as sum + WITH edges + UNWIND edges AS edge + WITH edge.node AS this3, edge.relationship AS this2 + CALL { + WITH this3 + CALL { + WITH this3 + WITH this3 AS this + MATCH (this)-[r:ACTED_IN]->(:Movie) + RETURN sum(r.screenTime) as sum + } + UNWIND sum AS this4 + RETURN head(collect(this4)) AS this4 + } + WITH { node: { name: this3.name, totalScreenTime: this4 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var5 } - UNWIND sum AS this4 - RETURN head(collect(this4)) AS this4 + WITH var5 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var6 } - WITH { node: { name: this3.name, totalScreenTime: this4 } } AS edge + WITH { node: { title: this0.title, actorsConnection: var6 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN edges AS var7 } - WITH { node: { title: this0.title, actorsConnection: var5 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount + WITH var7 AS edges, totalCount RETURN { edges: edges, totalCount: totalCount } AS this" `); @@ -529,50 +542,60 @@ describe("Cypher sort tests", () => { CALL { WITH this MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + WITH collect({ node: this1, relationship: this0 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this1 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 CALL { WITH this1 - WITH this1 AS this - MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + CALL { + WITH this1 + WITH this1 AS this + MATCH (actor:Actor)-[:ACTED_IN]->(this) RETURN count(actor) as count + } + UNWIND count AS this2 + RETURN head(collect(this2)) AS this2 } - UNWIND count AS this2 - RETURN head(collect(this2)) AS this2 - } - CALL { - WITH this1 - MATCH (this1)<-[this3:ACTED_IN]-(this4:Actor) + WITH * + ORDER BY this1.title DESC, this2 ASC + LIMIT $param0 CALL { - WITH this4 + WITH this1 + MATCH (this1)<-[this3:ACTED_IN]-(this4:Actor) + WITH collect({ node: this4, relationship: this3 }) AS edges + WITH edges, size(edges) AS totalCount CALL { - WITH this4 - WITH this4 AS this - MATCH (this)-[r:ACTED_IN]->(:Movie) - RETURN sum(r.screenTime) as sum + WITH edges + UNWIND edges AS edge + WITH edge.node AS this4, edge.relationship AS this3 + CALL { + WITH this4 + CALL { + WITH this4 + WITH this4 AS this + MATCH (this)-[r:ACTED_IN]->(:Movie) + RETURN sum(r.screenTime) as sum + } + UNWIND sum AS this5 + RETURN head(collect(this5)) AS this5 + } + WITH { node: { name: this4.name, totalScreenTime: this5 } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var6 } - UNWIND sum AS this5 - RETURN head(collect(this5)) AS this5 + WITH var6 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var7 } - WITH { node: { name: this4.name, totalScreenTime: this5 } } AS edge + WITH { node: { title: this1.title, actorsConnection: var7 } } AS edge WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 - } - WITH { node: { title: this1.title, actorsConnection: var6 } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - CALL { - WITH edges - UNWIND edges AS edge - WITH edge - ORDER BY edge.node.title DESC, edge.node.numberOfActors ASC - LIMIT $param0 - RETURN collect(edge) AS var7 + RETURN edges AS var8 } - WITH var7 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + WITH var8 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var9 } - RETURN this { moviesConnection: var8 } AS this" + RETURN this { moviesConnection: var9 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/subscriptions/create.test.ts b/packages/graphql/tests/tck/subscriptions/create.test.ts index 482f9f7bd24..aadb6605178 100644 --- a/packages/graphql/tests/tck/subscriptions/create.test.ts +++ b/packages/graphql/tests/tck/subscriptions/create.test.ts @@ -122,14 +122,22 @@ describe("Subscriptions metadata on create", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this1, relationship: create_this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this1, edge.relationship AS create_this0 + WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var2 + } + WITH create_var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var3 } - RETURN this0 { .title, actorsConnection: create_var2 } AS create_var3 + RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } - RETURN [create_var3] AS data, meta" + RETURN [create_var4] AS data, meta" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` "{ @@ -205,14 +213,22 @@ describe("Subscriptions metadata on create", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) - WITH { node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this1, relationship: create_this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this1, edge.relationship AS create_this0 + WITH { node: { name: create_this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var2 + } + WITH create_var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var3 } - RETURN this0 { .title, actorsConnection: create_var2 } AS create_var3 + RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } - RETURN [create_var3] AS data, meta" + RETURN [create_var4] AS data, meta" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` "{ @@ -313,14 +329,22 @@ describe("Subscriptions metadata on create", () => { CALL { WITH this0 MATCH (this0)<-[create_this0:ACTED_IN]-(create_this1:Actor) - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: create_this1, relationship: create_this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS create_this1, edge.relationship AS create_this0 + WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge + WITH collect(edge) AS edges + RETURN edges AS create_var2 + } + WITH create_var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS create_var3 } - RETURN this0 { .title, actorsConnection: create_var2 } AS create_var3 + RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } - RETURN [create_var3] AS data, meta" + RETURN [create_var4] AS data, meta" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` "{ diff --git a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts index f2053dab07f..01a018a56d1 100644 --- a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts @@ -55,12 +55,20 @@ describe("QueryDirection in relationships connection", () => { CALL { WITH this MATCH (this)-[this0:FRIENDS_WITH]-(this1:User) - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { friendsConnection: var2 } AS this" + RETURN this { friendsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -94,12 +102,20 @@ describe("QueryDirection in relationships connection", () => { CALL { WITH this MATCH (this)-[this0:FRIENDS_WITH]->(this1:User) - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { friendsConnection: var2 } AS this" + RETURN this { friendsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -132,12 +148,20 @@ describe("QueryDirection in relationships connection", () => { CALL { WITH this MATCH (this)-[this0:FRIENDS_WITH]-(this1:User) - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { friendsConnection: var2 } AS this" + RETURN this { friendsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); diff --git a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts index 91c85469165..8245ea30a7c 100644 --- a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts @@ -54,12 +54,20 @@ describe("Undirected connections", () => { CALL { WITH this MATCH (this)-[this0:FRIENDS_WITH]-(this1:User) - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: this1, relationship: this0 }) AS edges WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var2 + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this1, edge.relationship AS this0 + WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge + WITH collect(edge) AS edges + RETURN edges AS var2 + } + WITH var2 AS edges, totalCount + RETURN { edges: edges, totalCount: totalCount } AS var3 } - RETURN this { friendsConnection: var2 } AS this" + RETURN this { friendsConnection: var3 } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); From 178c2321771b3755ad57b0899179e8e87cae1d01 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 8 Dec 2023 22:47:55 +0000 Subject: [PATCH 035/136] chore(deps): update dependency ts-node to v10.9.2 --- packages/graphql-toolbox/package.json | 2 +- packages/graphql/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 9e52ad97699..7a296d61938 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -99,7 +99,7 @@ "terser-webpack-plugin": "5.3.9", "ts-jest": "29.1.1", "ts-loader": "9.5.1", - "ts-node": "10.9.1", + "ts-node": "10.9.2", "tsconfig-paths-webpack-plugin": "4.1.0", "typescript": "5.1.6", "webpack": "5.89.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 8f5454590af..5f50fda81b4 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -81,7 +81,7 @@ "rimraf": "5.0.5", "supertest": "6.3.3", "ts-jest": "29.1.1", - "ts-node": "10.9.1", + "ts-node": "10.9.2", "typescript": "5.1.6", "ws": "8.14.2" }, diff --git a/yarn.lock b/yarn.lock index 2a9b251fdde..850b308a754 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3680,7 +3680,7 @@ __metadata: thememirror: 2.0.1 ts-jest: 29.1.1 ts-loader: 9.5.1 - ts-node: 10.9.1 + ts-node: 10.9.2 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.1.6 webpack: 5.89.0 @@ -3743,7 +3743,7 @@ __metadata: semver: ^7.5.4 supertest: 6.3.3 ts-jest: 29.1.1 - ts-node: 10.9.1 + ts-node: 10.9.2 typescript: 5.1.6 typescript-memoize: ^1.1.1 ws: 8.14.2 @@ -25286,9 +25286,9 @@ __metadata: languageName: node linkType: hard -"ts-node@npm:10.9.1": - version: 10.9.1 - resolution: "ts-node@npm:10.9.1" +"ts-node@npm:10.9.2": + version: 10.9.2 + resolution: "ts-node@npm:10.9.2" dependencies: "@cspotcode/source-map-support": ^0.8.0 "@tsconfig/node10": ^1.0.7 @@ -25320,7 +25320,7 @@ __metadata: ts-node-script: dist/bin-script.js ts-node-transpile-only: dist/bin-transpile.js ts-script: dist/bin-script-deprecated.js - checksum: 090adff1302ab20bd3486e6b4799e90f97726ed39e02b39e566f8ab674fd5bd5f727f43615debbfc580d33c6d9d1c6b1b3ce7d8e3cca3e20530a145ffa232c35 + checksum: fde256c9073969e234526e2cfead42591b9a2aec5222bac154b0de2fa9e4ceb30efcd717ee8bc785a56f3a119bdd5aa27b333d9dbec94ed254bd26f8944c67ac languageName: node linkType: hard From 1ca2ac5f116118cea95b7e39e41ec8315c0ffd54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 9 Dec 2023 18:47:37 +0000 Subject: [PATCH 036/136] chore(deps): update dependency ws to v8.15.0 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- yarn.lock | 27 ++++++++++++++----- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index a7e206c0014..6b8a8a24db1 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -50,7 +50,7 @@ "supertest": "6.3.3", "ts-jest": "29.1.1", "typescript": "5.1.6", - "ws": "8.14.2" + "ws": "8.15.0" }, "dependencies": { "amqplib": "0.10.3", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 5f50fda81b4..d26f9d459bb 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -83,7 +83,7 @@ "ts-jest": "29.1.1", "ts-node": "10.9.2", "typescript": "5.1.6", - "ws": "8.14.2" + "ws": "8.15.0" }, "dependencies": { "@apollo/subgraph": "^2.2.3", diff --git a/yarn.lock b/yarn.lock index 850b308a754..b39b9d088b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3587,7 +3587,7 @@ __metadata: supertest: 6.3.3 ts-jest: 29.1.1 typescript: 5.1.6 - ws: 8.14.2 + ws: 8.15.0 peerDependencies: "@neo4j/graphql": ^4.0.0-beta.0 languageName: unknown @@ -3746,7 +3746,7 @@ __metadata: ts-node: 10.9.2 typescript: 5.1.6 typescript-memoize: ^1.1.1 - ws: 8.14.2 + ws: 8.15.0 peerDependencies: graphql: ^16.0.0 neo4j-driver: ^5.8.0 @@ -26857,9 +26857,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.14.2, ws@npm:^8.0.0, ws@npm:^8.11.0, ws@npm:^8.13.0, ws@npm:^8.2.2, ws@npm:^8.5.0": - version: 8.14.2 - resolution: "ws@npm:8.14.2" +"ws@npm:8.15.0": + version: 8.15.0 + resolution: "ws@npm:8.15.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -26868,7 +26868,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 3ca0dad26e8cc6515ff392b622a1467430814c463b3368b0258e33696b1d4bed7510bc7030f7b72838b9fdeb8dbd8839cbf808367d6aae2e1d668ce741d4308b + checksum: ca15c590aa49bc0197223b8ab7d15e7362ae6c4011d91ed0e5cd5867cdd5497fd71470ea36314833b4b078929fe64dc4ba7748b1e58e50a0f8e41f147db2b464 languageName: node linkType: hard @@ -26887,6 +26887,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.0.0, ws@npm:^8.11.0, ws@npm:^8.13.0, ws@npm:^8.2.2, ws@npm:^8.5.0": + version: 8.14.2 + resolution: "ws@npm:8.14.2" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 3ca0dad26e8cc6515ff392b622a1467430814c463b3368b0258e33696b1d4bed7510bc7030f7b72838b9fdeb8dbd8839cbf808367d6aae2e1d668ce741d4308b + languageName: node + linkType: hard + "ws@npm:~7.4.0": version: 7.4.6 resolution: "ws@npm:7.4.6" From fbfe826b14dedd796ebf79a958cb599f96a6745c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 10 Dec 2023 19:36:51 +0000 Subject: [PATCH 037/136] chore(deps): update srvaroa/labeler action to v1.8.2 --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 87c2d624773..14d966b0591 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -13,6 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: srvaroa/labeler@50320c5cb41e9208947c68a1a05a85261155958e # v1.8.1 + - uses: srvaroa/labeler@7d6ef903be9638aad7ada1206470d932dc4bfc50 # v1.8.2 env: GITHUB_TOKEN: ${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }} From cac6e4993731a44d86bef75ac0c3b07c8323b7bd Mon Sep 17 00:00:00 2001 From: angrykoala Date: Fri, 8 Dec 2023 17:03:41 +0000 Subject: [PATCH 038/136] WIP clean connection read operation and updates tck --- .../ast/operations/ConnectionReadOperation.ts | 264 +++++------------- .../composite/CompositeConnectionPartial.ts | 32 ++- .../queryAST/ast/sort/CypherPropertySort.ts | 13 +- .../tests/tck/connections/alias.test.ts | 9 +- .../connections/filtering/composite.test.ts | 15 +- .../connections/filtering/node/and.test.ts | 6 +- .../connections/filtering/node/arrays.test.ts | 12 +- .../filtering/node/equality.test.ts | 6 +- .../filtering/node/numerical.test.ts | 12 +- .../tck/connections/filtering/node/or.test.ts | 3 +- .../connections/filtering/node/points.test.ts | 3 +- .../filtering/node/relationship.test.ts | 3 +- .../connections/filtering/node/string.test.ts | 21 +- .../filtering/relationship/and.test.ts | 6 +- .../filtering/relationship/arrays.test.ts | 12 +- .../filtering/relationship/equality.test.ts | 6 +- .../filtering/relationship/numerical.test.ts | 12 +- .../filtering/relationship/or.test.ts | 3 +- .../filtering/relationship/points.test.ts | 3 +- .../filtering/relationship/string.test.ts | 21 +- .../filtering/relationship/temporal.test.ts | 3 +- .../tck/connections/mixed-nesting.test.ts | 12 +- .../connections/projections/create.test.ts | 9 +- .../projections/projections.test.ts | 15 +- .../relationship-properties.test.ts | 30 +- .../relationship_properties/connect.test.ts | 6 +- .../relationship_properties/create.test.ts | 3 +- .../tests/tck/connections/sort.test.ts | 12 +- .../tests/tck/directives/alias.test.ts | 6 +- .../arguments/roles-where.test.ts | 6 +- .../where/connection-auth-filter.test.ts | 3 +- .../arguments/where/where.test.ts | 6 +- .../projection-connection-union.test.ts | 3 +- .../projection-connection.test.ts | 24 +- .../tests/tck/directives/coalesce.test.ts | 6 +- .../tck/directives/node/node-label.test.ts | 3 +- .../node/node-with-auth-projection.test.ts | 3 +- .../graphql/tests/tck/issues/1150.test.ts | 3 +- .../graphql/tests/tck/issues/1221.test.ts | 15 +- .../graphql/tests/tck/issues/1249.test.ts | 3 +- .../graphql/tests/tck/issues/1364.test.ts | 9 +- .../graphql/tests/tck/issues/1528.test.ts | 3 +- .../graphql/tests/tck/issues/1760.test.ts | 12 +- .../graphql/tests/tck/issues/1783.test.ts | 9 +- .../graphql/tests/tck/issues/2022.test.ts | 3 +- .../graphql/tests/tck/issues/2262.test.ts | 6 +- .../graphql/tests/tck/issues/2437.test.ts | 3 +- .../graphql/tests/tck/issues/3394.test.ts | 6 +- .../graphql/tests/tck/issues/4007.test.ts | 3 +- .../graphql/tests/tck/issues/4015.test.ts | 3 +- .../graphql/tests/tck/issues/4292.test.ts | 3 +- packages/graphql/tests/tck/issues/433.test.ts | 3 +- packages/graphql/tests/tck/issues/601.test.ts | 3 +- packages/graphql/tests/tck/issues/630.test.ts | 3 +- packages/graphql/tests/tck/issues/988.test.ts | 6 +- .../tests/tck/operations/create.test.ts | 3 +- .../tests/tck/rfcs/query-limits.test.ts | 9 +- .../graphql/tests/tck/root-connection.test.ts | 15 +- packages/graphql/tests/tck/sort.test.ts | 12 +- .../tests/tck/subscriptions/create.test.ts | 9 +- .../query-direction-connection.test.ts | 9 +- .../undirected-connection.test.ts | 3 +- 62 files changed, 252 insertions(+), 516 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 469929a69f8..2d42d60477f 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -29,7 +29,7 @@ import type { Field } from "../fields/Field"; import { CypherAttributeField } from "../fields/attribute-fields/CypherAttributeField"; import type { Filter } from "../filters/Filter"; import type { AuthorizationFilters } from "../filters/authorization-filters/AuthorizationFilters"; -import type { Pagination, PaginationField } from "../pagination/Pagination"; +import type { Pagination } from "../pagination/Pagination"; import type { EntitySelection } from "../selection/EntitySelection"; import { CypherPropertySort } from "../sort/CypherPropertySort"; import type { Sort, SortField } from "../sort/Sort"; @@ -85,14 +85,6 @@ export class ConnectionReadOperation extends Operation { this.authFilters.push(...filter); } - protected getAuthFilterSubqueries(context: QueryASTContext): Cypher.Clause[] { - return this.authFilters.flatMap((f) => f.getSubqueries(context)); - } - - protected getAuthFilterPredicate(context: QueryASTContext): Cypher.Predicate[] { - return filterTruthy(this.authFilters.map((f) => f.getPredicate(context))); - } - public addSort(sortElement: { node: Sort[]; edge: Sort[] }): void { this.sortFields.push(sortElement); } @@ -116,45 +108,40 @@ export class ConnectionReadOperation extends Operation { ]); } - protected getSelectionClauses( - context: QueryASTContext, - node: Cypher.Node | Cypher.Pattern - ): { - preSelection: Array; - selectionClause: Cypher.Match | Cypher.With; - } { - let matchClause: Cypher.Match | Cypher.With = new Cypher.Match(node); + public transpile(context: QueryASTContext): OperationTranspileResult { + if (!context.target) throw new Error(); - let extraMatches = this.getChildren().flatMap((f) => { - return f.getSelection(context); + // eslint-disable-next-line prefer-const + let { selection: selectionClause, nestedContext } = this.selection.apply(context); + + let extraMatches: Array = this.getChildren().flatMap((f) => { + return f.getSelection(nestedContext); }); if (extraMatches.length > 0) { - extraMatches = [matchClause, ...extraMatches]; - matchClause = new Cypher.With("*"); + extraMatches = [selectionClause, ...extraMatches]; + selectionClause = new Cypher.With("*"); } - return { - preSelection: extraMatches, - selectionClause: matchClause, - }; - } + const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => + new Cypher.Call(sq).innerWith(nestedContext.target) + ); - public transpile(context: QueryASTContext): OperationTranspileResult { - if (!context.target) throw new Error(); + const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); - const { - prePaginationSubqueries, - postPaginationSubqueries, - withWhere, - edgeProjectionMap, - nestedContext, - extraMatches, - selectionClause, - authFilterSubqueries, - } = this.transpileCommon({ - context, - }); + let withWhere: Cypher.Clause | undefined; + + const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); + const authPredicate = this.getAuthFilterPredicate(nestedContext); + const filters = Cypher.and(...predicates, ...authPredicate); + if (filters) { + if (authFilterSubqueries.length > 0) { + // This is to avoid unnecessary With * + withWhere = new Cypher.With("*").where(filters); + } else { + selectionClause.where(filters); + } + } const edgeVar = new Cypher.NamedVariable("edge"); const edgesVar = new Cypher.NamedVariable("edges"); @@ -188,7 +175,6 @@ export class ConnectionReadOperation extends Operation { context: nestedContext, nodeVar: nestedContext.target, edgeVar: nestedContext.relationship, - aliased: true, }); paginationWith.orderBy(...sortFields); } @@ -196,7 +182,6 @@ export class ConnectionReadOperation extends Operation { const edgesVar2 = new Cypher.Variable(); let unwindClause: Cypher.With; - // Projection is different if (nestedContext.relationship) { unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with( [edgeVar.property("node"), nestedContext.target], @@ -208,82 +193,6 @@ export class ConnectionReadOperation extends Operation { nestedContext.target, ]); } - const withProjection = new Cypher.With([edgeProjectionMap, edgeVar]).with([Cypher.collect(edgeVar), edgesVar]); - - // Common Return - const returnClause = this.transpileReturn({ - context, - edgesVar, - totalCount, - }); - - const nestedThingy = new Cypher.Call( - Cypher.concat( - unwindClause, - ...prePaginationSubqueries, - paginationWith, - ...postPaginationSubqueries, - withProjection, - new Cypher.Return([edgesVar, edgesVar2]) - ) - ) - .innerWith(edgesVar) - .with([edgesVar2, edgesVar], totalCount); - - const subClause = Cypher.concat( - ...extraMatches, - selectionClause, - ...authFilterSubqueries, - withWhere, - withNodeAndTotalCount, - nestedThingy, - returnClause - ); - - return { - clauses: [subClause], - projectionExpr: context.returnVariable, - }; - } - - private transpileReturn({ - context, - edgesVar, - totalCount, - }: { - context: QueryASTContext; - edgesVar: Cypher.Variable; - totalCount: Cypher.Variable; - }): Cypher.Return { - return new Cypher.Return([ - new Cypher.Map({ - edges: edgesVar, - totalCount: totalCount, - }), - context.returnVariable, - ]); - } - - private transpileCommon({ context }: { context: QueryASTContext }) { - // eslint-disable-next-line prefer-const - let { selection: selectionClause, nestedContext } = this.selection.apply(context); - - let extraMatches: Array = this.getChildren().flatMap((f) => { - return f.getSelection(nestedContext); - }); - - if (extraMatches.length > 0) { - extraMatches = [selectionClause, ...extraMatches]; - selectionClause = new Cypher.With("*"); - } - const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => - new Cypher.Call(sq).innerWith(nestedContext.target) - ); - const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); - const authPredicate = this.getAuthFilterPredicate(nestedContext); - const filters = Cypher.and(...predicates, ...authPredicate); - - const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); const nodeProjectionMap = new Cypher.Map(); @@ -321,85 +230,72 @@ export class ConnectionReadOperation extends Operation { edgeProjectionMap.set("node", nodeProjectionMap); - let withWhere: Cypher.Clause | undefined; - if (filters) { - if (authFilterSubqueries.length > 0) { - // This is to avoid unnecessary With * - withWhere = new Cypher.With("*").where(filters); - } else { - selectionClause.where(filters); - } - } + const withProjection = new Cypher.With([edgeProjectionMap, edgeVar]).with([Cypher.collect(edgeVar), edgesVar]); - return { - prePaginationSubqueries, - postPaginationSubqueries, - withWhere, - edgeProjectionMap, - nestedContext, - extraMatches, - selectionClause, - authFilterSubqueries, - }; - } + const unwindAndProjectionSubquery = new Cypher.Call( + Cypher.concat( + unwindClause, + ...prePaginationSubqueries, + paginationWith, + ...postPaginationSubqueries, + withProjection, + new Cypher.Return([edgesVar, edgesVar2]) + ) + ).innerWith(edgesVar); - protected getPaginationSubquery( - context: QueryASTContext, - edgesVar: Cypher.Variable, - paginationField: PaginationField | undefined - ): Cypher.With { - const edgeVar = new Cypher.NamedVariable("edge"); - const subquery = new Cypher.Unwind([edgesVar, edgeVar]).with(edgeVar); - if (this.sortFields.length > 0) { - const sortFields = this.getSortFields({ context, nodeVar: edgeVar.property("node"), edgeVar }); - subquery.orderBy(...sortFields); - } + const returnClause = new Cypher.Return([ + new Cypher.Map({ + edges: edgesVar2, + totalCount: totalCount, + }), + context.returnVariable, + ]); - if (paginationField && paginationField.skip) { - subquery.skip(paginationField.skip); - } + const subClause = Cypher.concat( + ...extraMatches, + selectionClause, + ...authFilterSubqueries, + withWhere, + withNodeAndTotalCount, + unwindAndProjectionSubquery, + returnClause + ); - if (paginationField && paginationField.limit) { - subquery.limit(paginationField.limit); - } + return { + clauses: [subClause], + projectionExpr: context.returnVariable, + }; + } - const returnVar = new Cypher.Variable(); - subquery.return([Cypher.collect(edgeVar), returnVar]); + protected getAuthFilterSubqueries(context: QueryASTContext): Cypher.Clause[] { + return this.authFilters.flatMap((f) => f.getSubqueries(context)); + } - return new Cypher.Call(subquery).innerWith(edgesVar).with([returnVar, edgesVar]); + protected getAuthFilterPredicate(context: QueryASTContext): Cypher.Predicate[] { + return filterTruthy(this.authFilters.map((f) => f.getPredicate(context))); } - protected getSortFields({ + private getSortFields({ context, nodeVar, edgeVar, - aliased = false, }: { context: QueryASTContext; nodeVar: Cypher.Variable | Cypher.Property; edgeVar?: Cypher.Variable | Cypher.Property; - aliased?: boolean; }): SortField[] { + const aliasSort = true; return this.sortFields.flatMap(({ node, edge }) => { - // Small hack to trick nested sortFields that the operation is always a nested operation - // const fakeNestedContext = new QueryASTContext({ - // source: context.source || context.target, - // relationship: context.relationship, - // target: context.target, - // env: context.env, - // neo4jGraphQLContext: context.neo4jGraphQLContext, - // }); - - const nodeFields = node.flatMap((s) => s.getSortFields(context, nodeVar, aliased)); + const nodeFields = node.flatMap((s) => s.getSortFields(context, nodeVar, aliasSort)); if (edgeVar) { - const edgeFields = edge.flatMap((s) => s.getSortFields(context, edgeVar, aliased)); + const edgeFields = edge.flatMap((s) => s.getSortFields(context, edgeVar, aliasSort)); return [...nodeFields, ...edgeFields]; } return nodeFields; }); } - protected getPreAndPostSubqueries(context: QueryASTContext): { + private getPreAndPostSubqueries(context: QueryASTContext): { prePaginationSubqueries: Cypher.Clause[]; postPaginationSubqueries: Cypher.Clause[]; } { @@ -435,26 +331,4 @@ export class ConnectionReadOperation extends Operation { postPaginationSubqueries: postNodeSubqueries, }; } - - protected getProjectionMap(context: QueryASTContext): Cypher.MapProjection { - if (!hasTarget(context)) throw new Error("No parent node found!"); - const projectionFields = this.nodeFields.map((f) => f.getProjectionField(context.target)); - const sortProjectionFields = this.sortFields.flatMap((f) => - f.node.map((sortNode) => sortNode.getProjectionField(context)) - ); - - const uniqueProjectionFields = Array.from(new Set([...projectionFields, ...sortProjectionFields])); // TODO remove duplicates with alias - - const stringFields: string[] = []; - let otherFields: Record = {}; - - for (const field of uniqueProjectionFields) { - if (typeof field === "string") stringFields.push(field); - else { - otherFields = { ...otherFields, ...field }; - } - } - - return new Cypher.MapProjection(context.target, stringFields, otherFields); - } } 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 57466a68683..151a251232a 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts @@ -19,12 +19,12 @@ import Cypher from "@neo4j/cypher-builder"; import { createNodeFromEntity } from "../../../utils/create-node-from-entity"; -import { ConnectionReadOperation } from "../ConnectionReadOperation"; -import type { OperationTranspileResult } from "../operations"; -import type { Sort } from "../../sort/Sort"; -import type { Pagination } from "../../pagination/Pagination"; import { wrapSubqueriesInCypherCalls } from "../../../utils/wrap-subquery-in-calls"; import type { QueryASTContext } from "../../QueryASTContext"; +import type { Pagination } from "../../pagination/Pagination"; +import type { Sort } from "../../sort/Sort"; +import { ConnectionReadOperation } from "../ConnectionReadOperation"; +import type { OperationTranspileResult } from "../operations"; export class CompositeConnectionPartial extends ConnectionReadOperation { public transpile(context: QueryASTContext): OperationTranspileResult { @@ -133,4 +133,28 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { public addPagination(_pagination: Pagination): void { return undefined; } + + private getSelectionClauses( + context: QueryASTContext, + node: Cypher.Node | Cypher.Pattern + ): { + preSelection: Array; + selectionClause: Cypher.Match | Cypher.With; + } { + let matchClause: Cypher.Match | Cypher.With = new Cypher.Match(node); + + let extraMatches = this.getChildren().flatMap((f) => { + return f.getSelection(context); + }); + + if (extraMatches.length > 0) { + extraMatches = [matchClause, ...extraMatches]; + matchClause = new Cypher.With("*"); + } + + return { + preSelection: extraMatches, + selectionClause: matchClause, + }; + } } diff --git a/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts b/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts index 3a571a5cbbd..62bbce8303d 100644 --- a/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts +++ b/packages/graphql/src/translate/queryAST/ast/sort/CypherPropertySort.ts @@ -49,18 +49,9 @@ export class CypherPropertySort extends Sort { public getSortFields( context: QueryASTContext, - variable: Cypher.Variable | Cypher.Property, - sortByDatabaseName = true + _variable: Cypher.Variable | Cypher.Property, + _sortByDatabaseName = true ): SortField[] { - // const isNested = context.source; // TODO: avoid this, this should know if it is nested or not - const isNested = false; // TODO: avoid this, this should know if it is nested or not - if (isNested) { - const attributeName = sortByDatabaseName ? this.attribute.databaseName : this.attribute.name; - - const nodeProperty = variable.property(attributeName); - return [[nodeProperty, this.direction]]; - } - const projectionVar = context.getScopeVariable(this.attribute.name); return [[projectionVar, this.direction]]; } diff --git a/packages/graphql/tests/tck/connections/alias.test.ts b/packages/graphql/tests/tck/connections/alias.test.ts index 596d823d4aa..64de5c003b1 100644 --- a/packages/graphql/tests/tck/connections/alias.test.ts +++ b/packages/graphql/tests/tck/connections/alias.test.ts @@ -76,8 +76,7 @@ describe("Connections Alias", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { actors: var3 } AS this" `); @@ -129,8 +128,7 @@ describe("Connections Alias", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } CALL { WITH this @@ -146,8 +144,7 @@ describe("Connections Alias", () => { WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN { edges: var6, totalCount: totalCount } AS var7 } RETURN this { .title, hanks: var3, jenny: var7 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/composite.test.ts b/packages/graphql/tests/tck/connections/filtering/composite.test.ts index efddee6a059..37ff337784e 100644 --- a/packages/graphql/tests/tck/connections/filtering/composite.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/composite.test.ts @@ -91,8 +91,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -156,8 +155,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -223,8 +221,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -292,8 +289,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -366,8 +362,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts index 252115ba21b..c12c11d3702 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts @@ -85,8 +85,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -135,8 +134,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts index 4aaa8b5707c..31858d3962b 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts @@ -84,8 +84,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -135,8 +134,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -187,8 +185,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -236,8 +233,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts index d83227dc9dc..f15585849ee 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts @@ -83,8 +83,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -131,8 +130,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts index 6d94b41e344..93fa9e2b29e 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts @@ -85,8 +85,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -137,8 +136,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -189,8 +187,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -241,8 +238,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts index 9b108eca68e..c7eca8f9df6 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts @@ -85,8 +85,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> OR", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts index b196e00a6fd..340f6c0893a 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts @@ -104,8 +104,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Points", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts index 7a9f089dbe8..b7706b83e95 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Relationship", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .title, actorsConnection: var4 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts index 499aaf4de60..1c8fda81316 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts @@ -101,8 +101,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -149,8 +148,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -197,8 +195,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -245,8 +242,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -293,8 +289,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -341,8 +336,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -389,8 +383,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts index d089f9ce599..8d4fd2d96c1 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts @@ -85,8 +85,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -138,8 +137,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts index 14d940d5af6..8d08c2985ce 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts @@ -84,8 +84,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -141,8 +140,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -198,8 +196,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -246,8 +243,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts index 1e13e05ef85..94672d532f7 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts @@ -83,8 +83,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -134,8 +133,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts index 704fd81318a..cb6e1d9c12e 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts @@ -83,8 +83,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -134,8 +133,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -185,8 +183,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -236,8 +233,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts index 222ab90c85a..38574b66dae 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts @@ -85,8 +85,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> OR", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts index 53afb3b3ec7..4c10212bf27 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts @@ -102,8 +102,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Points", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts index 372f9541c68..952d4426206 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts @@ -101,8 +101,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -149,8 +148,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -197,8 +195,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -245,8 +242,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -293,8 +289,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -341,8 +336,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -389,8 +383,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts index 567c9402235..12187b152d1 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts @@ -87,8 +87,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Temporal", () => WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts index 7a695d6ca5d..23a370a3cc3 100644 --- a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts +++ b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts @@ -94,8 +94,7 @@ describe("Mixed nesting", () => { WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN { edges: var5, totalCount: totalCount } AS var6 } RETURN this { .title, actorsConnection: var6 } AS this" `); @@ -172,15 +171,13 @@ describe("Mixed nesting", () => { WITH collect(edge) AS edges RETURN edges AS var7 } - WITH var7 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + RETURN { edges: var7, totalCount: totalCount } AS var8 } WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var8 } } AS edge WITH collect(edge) AS edges RETURN edges AS var9 } - WITH var9 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var10 + RETURN { edges: var9, totalCount: totalCount } AS var10 } RETURN this { .title, actorsConnection: var10 } AS this" `); @@ -238,8 +235,7 @@ describe("Mixed nesting", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH this1 { .name, moviesConnection: var5 } AS this1 RETURN collect(this1) AS var6 diff --git a/packages/graphql/tests/tck/connections/projections/create.test.ts b/packages/graphql/tests/tck/connections/projections/create.test.ts index f1db245ac15..6513be3aaac 100644 --- a/packages/graphql/tests/tck/connections/projections/create.test.ts +++ b/packages/graphql/tests/tck/connections/projections/create.test.ts @@ -91,8 +91,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH collect(edge) AS edges RETURN edges AS create_var4 } - WITH create_var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var5 + RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } RETURN collect(create_this1 { .title, actorsConnection: create_var5 }) AS data" `); @@ -152,8 +151,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH collect(edge) AS edges RETURN edges AS create_var4 } - WITH create_var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var5 + RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } RETURN collect(create_this1 { .title, actorsConnection: create_var5 }) AS data" `); @@ -217,8 +215,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH collect(edge) AS edges RETURN edges AS create_var4 } - WITH create_var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var5 + RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } RETURN collect(create_this1 { .title, actorsConnection: create_var5 }) AS data" `); diff --git a/packages/graphql/tests/tck/connections/projections/projections.test.ts b/packages/graphql/tests/tck/connections/projections/projections.test.ts index 6202df5c759..8132cf979a0 100644 --- a/packages/graphql/tests/tck/connections/projections/projections.test.ts +++ b/packages/graphql/tests/tck/connections/projections/projections.test.ts @@ -81,8 +81,7 @@ describe("Relay Cursor Connection projections", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -129,8 +128,7 @@ describe("Relay Cursor Connection projections", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -174,8 +172,7 @@ describe("Relay Cursor Connection projections", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -319,8 +316,7 @@ describe("Relay Cursor Connection projections", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -369,8 +365,7 @@ describe("Relay Cursor Connection projections", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/relationship-properties.test.ts b/packages/graphql/tests/tck/connections/relationship-properties.test.ts index b59f50b3a4e..76d06820a59 100644 --- a/packages/graphql/tests/tck/connections/relationship-properties.test.ts +++ b/packages/graphql/tests/tck/connections/relationship-properties.test.ts @@ -84,8 +84,7 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -133,8 +132,7 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -184,8 +182,7 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); @@ -232,8 +229,7 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { actorsConnection: var3 } AS this" `); @@ -275,8 +271,7 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { actorsConnection: var3 } AS this" `); @@ -336,15 +331,13 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var5 } } AS edge WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN { edges: var6, totalCount: totalCount } AS var7 } RETURN this { .title, actorsConnection: var7 } AS this" `); @@ -425,22 +418,19 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN { edges: var6, totalCount: totalCount } AS var7 } WITH { screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var7 } } AS edge WITH collect(edge) AS edges RETURN edges AS var8 } - WITH var8 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + RETURN { edges: var8, totalCount: totalCount } AS var9 } WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var9 } } AS edge WITH collect(edge) AS edges RETURN edges AS var10 } - WITH var10 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var11 + RETURN { edges: var10, totalCount: totalCount } AS var11 } RETURN this { .title, actorsConnection: var11 } AS this" `); diff --git a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts index 7696a72d5f9..6ea6263b8f8 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts @@ -108,8 +108,7 @@ describe("Relationship Properties Connect Cypher", () => { WITH collect(edge) AS edges RETURN edges AS create_var2 } - WITH create_var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var3 + RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } @@ -196,8 +195,7 @@ describe("Relationship Properties Connect Cypher", () => { WITH collect(edge) AS edges RETURN edges AS create_var2 } - WITH create_var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var3 + RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } diff --git a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts index 78b063fc355..74ce285b45b 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts @@ -111,8 +111,7 @@ describe("Relationship Properties Create Cypher", () => { WITH collect(edge) AS edges RETURN edges AS create_var10 } - WITH create_var10 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var11 + RETURN { edges: create_var10, totalCount: totalCount } AS create_var11 } RETURN collect(create_this1 { .title, actorsConnection: create_var11 }) AS data" `); diff --git a/packages/graphql/tests/tck/connections/sort.test.ts b/packages/graphql/tests/tck/connections/sort.test.ts index 4a61d518b48..7f06e5e73ff 100644 --- a/packages/graphql/tests/tck/connections/sort.test.ts +++ b/packages/graphql/tests/tck/connections/sort.test.ts @@ -100,15 +100,13 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -177,15 +175,13 @@ describe("Relationship Properties Cypher", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH { node: { title: this0.title, actorsConnection: var5 } } AS edge WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var6, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/alias.test.ts b/packages/graphql/tests/tck/directives/alias.test.ts index d0deb40321f..08ccf3bb628 100644 --- a/packages/graphql/tests/tck/directives/alias.test.ts +++ b/packages/graphql/tests/tck/directives/alias.test.ts @@ -117,8 +117,7 @@ describe("Cypher alias directive", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .name, city: this.cityPropInDb, actedInConnection: var3 } AS this" `); @@ -211,8 +210,7 @@ describe("Cypher alias directive", () => { WITH collect(edge) AS edges RETURN edges AS create_var13 } - WITH create_var13 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var14 + RETURN { edges: create_var13, totalCount: totalCount } AS create_var14 } RETURN collect(create_this1 { .name, city: create_this1.cityPropInDb, actedIn: create_var10, actedInConnection: create_var14 }) AS data" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts index a19b557c074..045969a7409 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts @@ -242,8 +242,7 @@ describe("Cypher Auth Where with Roles", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .id, postsConnection: var4 } AS this" `); @@ -304,8 +303,7 @@ describe("Cypher Auth Where with Roles", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .id, postsConnection: var4 } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index ec7bccff18c..8395458106c 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -586,8 +586,7 @@ describe("Connection auth filter", () => { WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index 0942413ffa8..96bdb01d811 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -231,8 +231,7 @@ describe("Cypher Auth Where", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .id, postsConnection: var4 } AS this" `); @@ -292,8 +291,7 @@ describe("Cypher Auth Where", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .id, postsConnection: var4 } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts index 6d898071797..b9caee0dc74 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts @@ -114,8 +114,7 @@ describe("Cypher Auth Projection On Connections On Unions", () => { WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN { edges: var5, totalCount: totalCount } AS var6 } WITH { node: { __resolveType: \\"Post\\", __id: id(this1), content: this1.content, creatorConnection: var6 } } AS edge RETURN edge diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts index 836d1ed5277..6f1c0e17c14 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts @@ -98,8 +98,7 @@ describe("Cypher Auth Projection On Connections", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .name, postsConnection: var4 } AS this" `); @@ -174,15 +173,13 @@ describe("Cypher Auth Projection On Connections", () => { WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN { edges: var5, totalCount: totalCount } AS var6 } WITH { node: { content: this1.content, creatorConnection: var6 } } AS edge WITH collect(edge) AS edges RETURN edges AS var7 } - WITH var7 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + RETURN { edges: var7, totalCount: totalCount } AS var8 } RETURN this { .name, postsConnection: var8 } AS this" `); @@ -283,15 +280,13 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH { node: { name: this0.name, postsConnection: var5 } } AS edge WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var6, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -373,22 +368,19 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN { edges: var6, totalCount: totalCount } AS var7 } WITH { node: { content: this2.content, creatorConnection: var7 } } AS edge WITH collect(edge) AS edges RETURN edges AS var8 } - WITH var8 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + RETURN { edges: var8, totalCount: totalCount } AS var9 } WITH { node: { name: this0.name, postsConnection: var9 } } AS edge WITH collect(edge) AS edges RETURN edges AS var10 } - WITH var10 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var10, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/directives/coalesce.test.ts b/packages/graphql/tests/tck/directives/coalesce.test.ts index b20500a507c..a97dabf7b6c 100644 --- a/packages/graphql/tests/tck/directives/coalesce.test.ts +++ b/packages/graphql/tests/tck/directives/coalesce.test.ts @@ -225,8 +225,7 @@ describe("Cypher coalesce()", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { moviesConnection: var3 } AS this" `); @@ -291,8 +290,7 @@ describe("Cypher coalesce()", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { moviesConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/directives/node/node-label.test.ts b/packages/graphql/tests/tck/directives/node/node-label.test.ts index f504beb3e88..aa0ef5bc416 100644 --- a/packages/graphql/tests/tck/directives/node/node-label.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-label.test.ts @@ -125,8 +125,7 @@ describe("Label in Node directive", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts index 7da5c3164a7..66bac44f10d 100644 --- a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts @@ -94,8 +94,7 @@ describe("Cypher Auth Projection On Connections", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { .name, postsConnection: var4 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1150.test.ts b/packages/graphql/tests/tck/issues/1150.test.ts index 18cea43e517..fc6427040f4 100644 --- a/packages/graphql/tests/tck/issues/1150.test.ts +++ b/packages/graphql/tests/tck/issues/1150.test.ts @@ -142,8 +142,7 @@ describe("https://github.com/neo4j/graphql/issues/1150", () => { WITH collect(edge) AS edges RETURN edges AS var7 } - WITH var7 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var8 + RETURN { edges: var7, totalCount: totalCount } AS var8 } RETURN this { .current, driveCompositionsConnection: var8 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1221.test.ts b/packages/graphql/tests/tck/issues/1221.test.ts index 0a3dea1bd23..c047539b7a6 100644 --- a/packages/graphql/tests/tck/issues/1221.test.ts +++ b/packages/graphql/tests/tck/issues/1221.test.ts @@ -111,15 +111,13 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH collect(edge) AS edges RETURN edges AS var8 } - WITH var8 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + RETURN { edges: var8, totalCount: totalCount } AS var9 } WITH { node: { nameDetailsConnection: var9 } } AS edge WITH collect(edge) AS edges RETURN edges AS var10 } - WITH var10 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var11 + RETURN { edges: var10, totalCount: totalCount } AS var11 } RETURN this { .id, architectureConnection: var11 } AS this" `); @@ -248,22 +246,19 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH collect(edge) AS edges RETURN edges AS var12 } - WITH var12 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var13 + RETURN { edges: var12, totalCount: totalCount } AS var13 } WITH { node: { nameDetailsConnection: var13 } } AS edge WITH collect(edge) AS edges RETURN edges AS var14 } - WITH var14 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var15 + RETURN { edges: var14, totalCount: totalCount } AS var15 } WITH { node: { architectureConnection: var15 } } AS edge WITH collect(edge) AS edges RETURN edges AS var16 } - WITH var16 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var17 + RETURN { edges: var16, totalCount: totalCount } AS var17 } RETURN this { .id, mainConnection: var17 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1249.test.ts b/packages/graphql/tests/tck/issues/1249.test.ts index 07fa9379a49..cd0a0826acf 100644 --- a/packages/graphql/tests/tck/issues/1249.test.ts +++ b/packages/graphql/tests/tck/issues/1249.test.ts @@ -98,8 +98,7 @@ describe("https://github.com/neo4j/graphql/issues/1249", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH this1 { .id, suppliersConnection: var5 } AS this1 RETURN head(collect(this1)) AS var6 diff --git a/packages/graphql/tests/tck/issues/1364.test.ts b/packages/graphql/tests/tck/issues/1364.test.ts index 1de6c96260c..8cfd0150363 100644 --- a/packages/graphql/tests/tck/issues/1364.test.ts +++ b/packages/graphql/tests/tck/issues/1364.test.ts @@ -117,8 +117,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var2, totalCount: totalCount } AS this" `); }); @@ -163,8 +162,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var2, totalCount: totalCount } AS this" `); }); @@ -221,8 +219,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var3, totalCount: totalCount } AS this" `); }); }); diff --git a/packages/graphql/tests/tck/issues/1528.test.ts b/packages/graphql/tests/tck/issues/1528.test.ts index 10c0fd7c2b7..00cb5c142a5 100644 --- a/packages/graphql/tests/tck/issues/1528.test.ts +++ b/packages/graphql/tests/tck/issues/1528.test.ts @@ -97,8 +97,7 @@ describe("https://github.com/neo4j/graphql/issues/1528", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN this { moviesConnection: var4 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1760.test.ts b/packages/graphql/tests/tck/issues/1760.test.ts index ecaa1ec5391..db5abca3e1c 100644 --- a/packages/graphql/tests/tck/issues/1760.test.ts +++ b/packages/graphql/tests/tck/issues/1760.test.ts @@ -163,8 +163,7 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } CALL { WITH this @@ -190,15 +189,13 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH collect(edge) AS edges RETURN edges AS var9 } - WITH var9 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var10 + RETURN { edges: var9, totalCount: totalCount } AS var10 } WITH { node: { nameDetailsConnection: var10 } } AS edge WITH collect(edge) AS edges RETURN edges AS var11 } - WITH var11 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var12 + RETURN { edges: var11, totalCount: totalCount } AS var12 } CALL { WITH this @@ -214,8 +211,7 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH collect(edge) AS edges RETURN edges AS var15 } - WITH var15 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var16 + RETURN { edges: var15, totalCount: totalCount } AS var16 } RETURN this { relatedId: this0, nameDetailsConnection: var4, marketsConnection: var12, baseObjectConnection: var16 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1783.test.ts b/packages/graphql/tests/tck/issues/1783.test.ts index 821910b2a43..2bbdad2b7f6 100644 --- a/packages/graphql/tests/tck/issues/1783.test.ts +++ b/packages/graphql/tests/tck/issues/1783.test.ts @@ -136,8 +136,7 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH collect(edge) AS edges RETURN edges AS var8 } - WITH var8 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + RETURN { edges: var8, totalCount: totalCount } AS var9 } CALL { WITH this @@ -163,15 +162,13 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH collect(edge) AS edges RETURN edges AS var14 } - WITH var14 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var15 + RETURN { edges: var14, totalCount: totalCount } AS var15 } WITH { node: { nameDetailsConnection: var15 } } AS edge WITH collect(edge) AS edges RETURN edges AS var16 } - WITH var16 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var17 + RETURN { edges: var16, totalCount: totalCount } AS var17 } RETURN this { .id, nameDetailsConnection: var9, architectureConnection: var17 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index 1bb0b3da454..db5fd34f29e 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -119,8 +119,7 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { WITH collect(edge) AS edges RETURN edges AS var10 } - WITH var10 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var10, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); diff --git a/packages/graphql/tests/tck/issues/2262.test.ts b/packages/graphql/tests/tck/issues/2262.test.ts index 03b943620ca..abfca0a15fe 100644 --- a/packages/graphql/tests/tck/issues/2262.test.ts +++ b/packages/graphql/tests/tck/issues/2262.test.ts @@ -97,15 +97,13 @@ describe("https://github.com/neo4j/graphql/issues/2262", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH { node: { uuid: this1.uuid, componentInputsConnection: var5 } } AS edge WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN { edges: var6, totalCount: totalCount } AS var7 } RETURN this { .uuid, upstreamProcessConnection: var7 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/2437.test.ts b/packages/graphql/tests/tck/issues/2437.test.ts index c4e07369d8a..fcfcef5c992 100644 --- a/packages/graphql/tests/tck/issues/2437.test.ts +++ b/packages/graphql/tests/tck/issues/2437.test.ts @@ -98,8 +98,7 @@ describe("https://github.com/neo4j/graphql/issues/2437", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .uuid, valuationsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index 50e06b0f048..c55e17e154c 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -126,8 +126,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH collect(edge) AS edges RETURN edges AS var1 } - WITH var1 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var1, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); @@ -169,8 +168,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { productsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/4007.test.ts b/packages/graphql/tests/tck/issues/4007.test.ts index bf6d13b1444..996e09ac54c 100644 --- a/packages/graphql/tests/tck/issues/4007.test.ts +++ b/packages/graphql/tests/tck/issues/4007.test.ts @@ -76,8 +76,7 @@ describe("https://github.com/neo4j/graphql/issues/4007", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { t: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/4015.test.ts b/packages/graphql/tests/tck/issues/4015.test.ts index 76e12b36d3e..42a9be22d2d 100644 --- a/packages/graphql/tests/tck/issues/4015.test.ts +++ b/packages/graphql/tests/tck/issues/4015.test.ts @@ -80,8 +80,7 @@ describe("https://github.com/neo4j/graphql/issues/4015", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/4292.test.ts b/packages/graphql/tests/tck/issues/4292.test.ts index d83d6bc1862..499c240fc8f 100644 --- a/packages/graphql/tests/tck/issues/4292.test.ts +++ b/packages/graphql/tests/tck/issues/4292.test.ts @@ -258,8 +258,7 @@ describe("https://github.com/neo4j/graphql/issues/4292", () => { WITH collect(edge) AS edges RETURN edges AS var25 } - WITH var25 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var26 + RETURN { edges: var25, totalCount: totalCount } AS var26 } WITH this1 { .id, .name, partnersConnection: var26 } AS this1 RETURN collect(this1) AS var27 diff --git a/packages/graphql/tests/tck/issues/433.test.ts b/packages/graphql/tests/tck/issues/433.test.ts index c480ef679f7..7f495e27b69 100644 --- a/packages/graphql/tests/tck/issues/433.test.ts +++ b/packages/graphql/tests/tck/issues/433.test.ts @@ -77,8 +77,7 @@ describe("#413", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .title, actorsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/issues/601.test.ts b/packages/graphql/tests/tck/issues/601.test.ts index 08f3eba88ad..8dbcdea1758 100644 --- a/packages/graphql/tests/tck/issues/601.test.ts +++ b/packages/graphql/tests/tck/issues/601.test.ts @@ -115,8 +115,7 @@ describe("#601", () => { WITH collect(edge) AS edges RETURN edges AS var4 } - WITH var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var5 + RETURN { edges: var4, totalCount: totalCount } AS var5 } WITH this1 { customerContactConnection: var5 } AS this1 RETURN collect(this1) AS var6 diff --git a/packages/graphql/tests/tck/issues/630.test.ts b/packages/graphql/tests/tck/issues/630.test.ts index bd508c32373..a2229f5685b 100644 --- a/packages/graphql/tests/tck/issues/630.test.ts +++ b/packages/graphql/tests/tck/issues/630.test.ts @@ -91,8 +91,7 @@ describe("Cypher directive", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } RETURN collect(this0 { actorsConnection: var4 }) AS this0 } diff --git a/packages/graphql/tests/tck/issues/988.test.ts b/packages/graphql/tests/tck/issues/988.test.ts index c560b260888..4de6a1467e5 100644 --- a/packages/graphql/tests/tck/issues/988.test.ts +++ b/packages/graphql/tests/tck/issues/988.test.ts @@ -155,8 +155,7 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { WITH collect(edge) AS edges RETURN edges AS var8 } - WITH var8 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + RETURN { edges: var8, totalCount: totalCount } AS var9 } CALL { WITH this @@ -171,8 +170,7 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { WITH collect(edge) AS edges RETURN edges AS var12 } - WITH var12 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var13 + RETURN { edges: var12, totalCount: totalCount } AS var13 } RETURN this { .name, .current, manufacturerConnection: var9, brandConnection: var13 } AS this" `); diff --git a/packages/graphql/tests/tck/operations/create.test.ts b/packages/graphql/tests/tck/operations/create.test.ts index 4d778583c07..dd15e1bb30f 100644 --- a/packages/graphql/tests/tck/operations/create.test.ts +++ b/packages/graphql/tests/tck/operations/create.test.ts @@ -427,8 +427,7 @@ describe("Cypher Create", () => { WITH collect(edge) AS edges RETURN edges AS create_var4 } - WITH create_var4 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var5 + RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } WITH create_this1 { actorsConnection: create_var5 } AS create_this1 RETURN collect(create_this1) AS create_var6 diff --git a/packages/graphql/tests/tck/rfcs/query-limits.test.ts b/packages/graphql/tests/tck/rfcs/query-limits.test.ts index 74f17cbd49e..fa881c8359e 100644 --- a/packages/graphql/tests/tck/rfcs/query-limits.test.ts +++ b/packages/graphql/tests/tck/rfcs/query-limits.test.ts @@ -218,8 +218,7 @@ describe("tck/rfcs/query-limits", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .id, actorsConnection: var3 } AS this" `); @@ -275,8 +274,7 @@ describe("tck/rfcs/query-limits", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .id, actorsConnection: var3 } AS this" `); @@ -330,8 +328,7 @@ describe("tck/rfcs/query-limits", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { .name, showsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index 910afebc206..6eb0564d307 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -74,8 +74,7 @@ describe("Root Connection Query tests", () => { WITH collect(edge) AS edges RETURN edges AS var1 } - WITH var1 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var1, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -115,8 +114,7 @@ describe("Root Connection Query tests", () => { WITH collect(edge) AS edges RETURN edges AS var1 } - WITH var1 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var1, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` "{ @@ -157,8 +155,7 @@ describe("Root Connection Query tests", () => { WITH collect(edge) AS edges RETURN edges AS var1 } - WITH var1 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var1, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` "{ @@ -215,15 +212,13 @@ describe("Root Connection Query tests", () => { WITH collect(edge) AS edges RETURN edges AS var3 } - WITH var3 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN { edges: var3, totalCount: totalCount } AS var4 } WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` diff --git a/packages/graphql/tests/tck/sort.test.ts b/packages/graphql/tests/tck/sort.test.ts index 22d2629ac3a..71aaeb2d737 100644 --- a/packages/graphql/tests/tck/sort.test.ts +++ b/packages/graphql/tests/tck/sort.test.ts @@ -486,15 +486,13 @@ describe("Cypher sort tests", () => { WITH collect(edge) AS edges RETURN edges AS var5 } - WITH var5 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var6 + RETURN { edges: var5, totalCount: totalCount } AS var6 } WITH { node: { title: this0.title, actorsConnection: var6 } } AS edge WITH collect(edge) AS edges RETURN edges AS var7 } - WITH var7 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var7, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -585,15 +583,13 @@ describe("Cypher sort tests", () => { WITH collect(edge) AS edges RETURN edges AS var6 } - WITH var6 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var7 + RETURN { edges: var6, totalCount: totalCount } AS var7 } WITH { node: { title: this1.title, actorsConnection: var7 } } AS edge WITH collect(edge) AS edges RETURN edges AS var8 } - WITH var8 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var9 + RETURN { edges: var8, totalCount: totalCount } AS var9 } RETURN this { moviesConnection: var9 } AS this" `); diff --git a/packages/graphql/tests/tck/subscriptions/create.test.ts b/packages/graphql/tests/tck/subscriptions/create.test.ts index aadb6605178..0350384130f 100644 --- a/packages/graphql/tests/tck/subscriptions/create.test.ts +++ b/packages/graphql/tests/tck/subscriptions/create.test.ts @@ -132,8 +132,7 @@ describe("Subscriptions metadata on create", () => { WITH collect(edge) AS edges RETURN edges AS create_var2 } - WITH create_var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var3 + RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } @@ -223,8 +222,7 @@ describe("Subscriptions metadata on create", () => { WITH collect(edge) AS edges RETURN edges AS create_var2 } - WITH create_var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var3 + RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } @@ -339,8 +337,7 @@ describe("Subscriptions metadata on create", () => { WITH collect(edge) AS edges RETURN edges AS create_var2 } - WITH create_var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS create_var3 + RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } RETURN this0 { .title, actorsConnection: create_var3 } AS create_var4 } diff --git a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts index 01a018a56d1..fae2a0d26af 100644 --- a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts @@ -65,8 +65,7 @@ describe("QueryDirection in relationships connection", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { friendsConnection: var3 } AS this" `); @@ -112,8 +111,7 @@ describe("QueryDirection in relationships connection", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { friendsConnection: var3 } AS this" `); @@ -158,8 +156,7 @@ describe("QueryDirection in relationships connection", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { friendsConnection: var3 } AS this" `); diff --git a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts index 8245ea30a7c..06381ac4ba2 100644 --- a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts @@ -64,8 +64,7 @@ describe("Undirected connections", () => { WITH collect(edge) AS edges RETURN edges AS var2 } - WITH var2 AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS var3 + RETURN { edges: var2, totalCount: totalCount } AS var3 } RETURN this { friendsConnection: var3 } AS this" `); From bdbadd0343b4c1850af2314f2b54942f1d7b4bb7 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 11 Dec 2023 16:47:53 +0000 Subject: [PATCH 039/136] Improve transpile code of connections --- .../ast/operations/ConnectionReadOperation.ts | 158 ++++++++++-------- 1 file changed, 90 insertions(+), 68 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 2d42d60477f..ef20d937b69 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -108,6 +108,18 @@ export class ConnectionReadOperation extends Operation { ]); } + private addFiltersToClause( + clause: Cypher.With | Cypher.Match | Cypher.Yield, + context: QueryASTContext + ): void { + const predicates = this.filters.map((f) => f.getPredicate(context)); + const authPredicate = this.getAuthFilterPredicate(context); + const predicate = Cypher.and(...predicates, ...authPredicate); + if (predicate) { + clause.where(predicate); + } + } + public transpile(context: QueryASTContext): OperationTranspileResult { if (!context.target) throw new Error(); @@ -129,18 +141,13 @@ export class ConnectionReadOperation extends Operation { const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); - let withWhere: Cypher.Clause | undefined; - - const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); - const authPredicate = this.getAuthFilterPredicate(nestedContext); - const filters = Cypher.and(...predicates, ...authPredicate); - if (filters) { - if (authFilterSubqueries.length > 0) { - // This is to avoid unnecessary With * - withWhere = new Cypher.With("*").where(filters); - } else { - selectionClause.where(filters); - } + let withWhere: Cypher.With | undefined; + + if (authFilterSubqueries.length > 0) { + withWhere = new Cypher.With("*"); + this.addFiltersToClause(withWhere, nestedContext); + } else { + this.addFiltersToClause(selectionClause, nestedContext); } const edgeVar = new Cypher.NamedVariable("edge"); @@ -160,26 +167,6 @@ export class ConnectionReadOperation extends Operation { totalCount, ]); - let paginationWith: Cypher.With | undefined; - if (this.pagination || this.sortFields.length > 0) { - paginationWith = new Cypher.With("*"); - const paginationField = this.pagination && this.pagination.getPagination(); - if (paginationField?.limit) { - paginationWith.limit(paginationField.limit); - } - if (paginationField?.skip) { - paginationWith.skip(paginationField.skip); - } - if (this.sortFields.length > 0) { - const sortFields = this.getSortFields({ - context: nestedContext, - nodeVar: nestedContext.target, - edgeVar: nestedContext.relationship, - }); - paginationWith.orderBy(...sortFields); - } - } - const edgesVar2 = new Cypher.Variable(); let unwindClause: Cypher.With; if (nestedContext.relationship) { @@ -194,44 +181,11 @@ export class ConnectionReadOperation extends Operation { ]); } - const nodeProjectionMap = new Cypher.Map(); - - const edgeProjectionMap = new Cypher.Map(); - const relationship = nestedContext.relationship; - if (relationship) { - this.edgeFields - .map((f) => f.getProjectionField(relationship)) - .forEach((p) => { - if (typeof p === "string") { - edgeProjectionMap.set(p, relationship.property(p)); - } else { - edgeProjectionMap.set(p); - } - }); - } - - this.nodeFields - .map((f) => f.getProjectionField(nestedContext.target)) - .forEach((p) => { - if (typeof p === "string") { - nodeProjectionMap.set(p, nestedContext.target.property(p)); - } else { - nodeProjectionMap.set(p); - } - }); - - if (nodeProjectionMap.size === 0) { - const targetNodeName = this.target.name; - nodeProjectionMap.set({ - __resolveType: new Cypher.Literal(targetNodeName), - __id: Cypher.id(nestedContext.target), - }); - } - - edgeProjectionMap.set("node", nodeProjectionMap); - + const edgeProjectionMap = this.createProjectionMapForEdge(nestedContext); const withProjection = new Cypher.With([edgeProjectionMap, edgeVar]).with([Cypher.collect(edgeVar), edgesVar]); + const paginationWith = this.generateSortAndPaginationClause(nestedContext); + const unwindAndProjectionSubquery = new Cypher.Call( Cypher.concat( unwindClause, @@ -275,6 +229,74 @@ export class ConnectionReadOperation extends Operation { return filterTruthy(this.authFilters.map((f) => f.getPredicate(context))); } + private createProjectionMapForEdge(context: QueryASTContext): Cypher.Map { + const nodeProjectionMap = this.generateProjectionMapForFields(this.nodeFields, context.target); + if (nodeProjectionMap.size === 0) { + const targetNodeName = this.target.name; + nodeProjectionMap.set({ + __resolveType: new Cypher.Literal(targetNodeName), + __id: Cypher.id(context.target), + }); + } + + let edgeProjectionMap = new Cypher.Map(); + + if (context.relationship) { + edgeProjectionMap = this.generateProjectionMapForFields(this.edgeFields, context.relationship); + } + + edgeProjectionMap.set("node", nodeProjectionMap); + return edgeProjectionMap; + } + + private generateProjectionMapForFields(fields: Field[], target: Cypher.Variable): Cypher.Map { + const projectionMap = new Cypher.Map(); + fields + .map((f) => f.getProjectionField(target)) + .forEach((p) => { + if (typeof p === "string") { + projectionMap.set(p, target.property(p)); + } else { + projectionMap.set(p); + } + }); + + return projectionMap; + } + + private generateSortAndPaginationClause(context: QueryASTContext): Cypher.With | undefined { + const shouldGenerateSortWith = this.pagination || this.sortFields.length > 0; + if (!shouldGenerateSortWith) { + return undefined; + } + const paginationWith = new Cypher.With("*"); + this.addPaginationSubclauses(paginationWith); + this.addSortSubclause(paginationWith, context); + + return paginationWith; + } + + private addPaginationSubclauses(clause: Cypher.With): void { + const paginationField = this.pagination && this.pagination.getPagination(); + if (paginationField?.limit) { + clause.limit(paginationField.limit); + } + if (paginationField?.skip) { + clause.skip(paginationField.skip); + } + } + + private addSortSubclause(clause: Cypher.With, context: QueryASTContext): void { + if (this.sortFields.length > 0) { + const sortFields = this.getSortFields({ + context: context, + nodeVar: context.target, + edgeVar: context.relationship, + }); + clause.orderBy(...sortFields); + } + } + private getSortFields({ context, nodeVar, From c66caab894987a1e9d72754e30d8014d2283c835 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 11 Dec 2023 17:41:25 +0000 Subject: [PATCH 040/136] Remove intermediate with for collect in connection cypher --- .../ast/operations/ConnectionReadOperation.ts | 50 +++++++++---------- .../tests/tck/connections/alias.test.ts | 9 ++-- .../connections/filtering/composite.test.ts | 15 ++---- .../connections/filtering/node/and.test.ts | 6 +-- .../connections/filtering/node/arrays.test.ts | 12 ++--- .../filtering/node/equality.test.ts | 6 +-- .../filtering/node/numerical.test.ts | 12 ++--- .../tck/connections/filtering/node/or.test.ts | 3 +- .../connections/filtering/node/points.test.ts | 5 +- .../filtering/node/relationship.test.ts | 3 +- .../connections/filtering/node/string.test.ts | 21 +++----- .../filtering/relationship/and.test.ts | 6 +-- .../filtering/relationship/arrays.test.ts | 12 ++--- .../filtering/relationship/equality.test.ts | 6 +-- .../filtering/relationship/numerical.test.ts | 12 ++--- .../filtering/relationship/or.test.ts | 3 +- .../filtering/relationship/points.test.ts | 5 +- .../filtering/relationship/string.test.ts | 21 +++----- .../filtering/relationship/temporal.test.ts | 3 +- .../tck/connections/mixed-nesting.test.ts | 12 ++--- .../connections/projections/create.test.ts | 9 ++-- .../projections/projections.test.ts | 15 ++---- .../relationship-properties.test.ts | 30 ++++------- .../relationship_properties/connect.test.ts | 6 +-- .../relationship_properties/create.test.ts | 3 +- .../tests/tck/connections/sort.test.ts | 12 ++--- .../tests/tck/directives/alias.test.ts | 6 +-- .../arguments/roles-where.test.ts | 6 +-- .../where/connection-auth-filter.test.ts | 3 +- .../arguments/where/where.test.ts | 6 +-- .../projection-connection-union.test.ts | 3 +- .../projection-connection.test.ts | 24 +++------ .../tests/tck/directives/coalesce.test.ts | 6 +-- .../tck/directives/node/node-label.test.ts | 3 +- .../node/node-with-auth-projection.test.ts | 3 +- .../graphql/tests/tck/issues/1150.test.ts | 3 +- .../graphql/tests/tck/issues/1221.test.ts | 15 ++---- .../graphql/tests/tck/issues/1249.test.ts | 3 +- .../graphql/tests/tck/issues/1364.test.ts | 9 ++-- .../graphql/tests/tck/issues/1528.test.ts | 3 +- .../graphql/tests/tck/issues/1760.test.ts | 12 ++--- .../graphql/tests/tck/issues/1783.test.ts | 9 ++-- .../graphql/tests/tck/issues/2022.test.ts | 3 +- .../graphql/tests/tck/issues/2262.test.ts | 6 +-- .../graphql/tests/tck/issues/2437.test.ts | 3 +- .../graphql/tests/tck/issues/3394.test.ts | 6 +-- .../graphql/tests/tck/issues/4007.test.ts | 3 +- .../graphql/tests/tck/issues/4015.test.ts | 3 +- .../graphql/tests/tck/issues/4292.test.ts | 3 +- packages/graphql/tests/tck/issues/433.test.ts | 3 +- packages/graphql/tests/tck/issues/601.test.ts | 3 +- packages/graphql/tests/tck/issues/630.test.ts | 3 +- packages/graphql/tests/tck/issues/988.test.ts | 6 +-- .../tests/tck/operations/create.test.ts | 3 +- .../tests/tck/rfcs/query-limits.test.ts | 9 ++-- .../graphql/tests/tck/root-connection.test.ts | 15 ++---- packages/graphql/tests/tck/sort.test.ts | 12 ++--- .../tests/tck/subscriptions/create.test.ts | 9 ++-- .../query-direction-connection.test.ts | 9 ++-- .../undirected-connection.test.ts | 3 +- 60 files changed, 180 insertions(+), 333 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index ef20d937b69..7e5e0f11ef7 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -108,18 +108,6 @@ export class ConnectionReadOperation extends Operation { ]); } - private addFiltersToClause( - clause: Cypher.With | Cypher.Match | Cypher.Yield, - context: QueryASTContext - ): void { - const predicates = this.filters.map((f) => f.getPredicate(context)); - const authPredicate = this.getAuthFilterPredicate(context); - const predicate = Cypher.and(...predicates, ...authPredicate); - if (predicate) { - clause.where(predicate); - } - } - public transpile(context: QueryASTContext): OperationTranspileResult { if (!context.target) throw new Error(); @@ -162,7 +150,7 @@ export class ConnectionReadOperation extends Operation { edgeMap1.set("relationship", nestedContext.relationship); } - const withNodeAndTotalCount = new Cypher.With([Cypher.collect(edgeMap1), edgesVar]).with(edgesVar, [ + const withCollectEdgesAndTotalCount = new Cypher.With([Cypher.collect(edgeMap1), edgesVar]).with(edgesVar, [ Cypher.size(edgesVar), totalCount, ]); @@ -182,7 +170,7 @@ export class ConnectionReadOperation extends Operation { } const edgeProjectionMap = this.createProjectionMapForEdge(nestedContext); - const withProjection = new Cypher.With([edgeProjectionMap, edgeVar]).with([Cypher.collect(edgeVar), edgesVar]); + const withProjection = new Cypher.With([Cypher.collect(edgeProjectionMap), edgesVar]); const paginationWith = this.generateSortAndPaginationClause(nestedContext); @@ -205,18 +193,18 @@ export class ConnectionReadOperation extends Operation { context.returnVariable, ]); - const subClause = Cypher.concat( - ...extraMatches, - selectionClause, - ...authFilterSubqueries, - withWhere, - withNodeAndTotalCount, - unwindAndProjectionSubquery, - returnClause - ); - return { - clauses: [subClause], + clauses: [ + Cypher.concat( + ...extraMatches, + selectionClause, + ...authFilterSubqueries, + withWhere, + withCollectEdgesAndTotalCount, + unwindAndProjectionSubquery, + returnClause + ), + ], projectionExpr: context.returnVariable, }; } @@ -297,6 +285,18 @@ export class ConnectionReadOperation extends Operation { } } + private addFiltersToClause( + clause: Cypher.With | Cypher.Match | Cypher.Yield, + context: QueryASTContext + ): void { + const predicates = this.filters.map((f) => f.getPredicate(context)); + const authPredicate = this.getAuthFilterPredicate(context); + const predicate = Cypher.and(...predicates, ...authPredicate); + if (predicate) { + clause.where(predicate); + } + } + private getSortFields({ context, nodeVar, diff --git a/packages/graphql/tests/tck/connections/alias.test.ts b/packages/graphql/tests/tck/connections/alias.test.ts index 64de5c003b1..33c0c321e8b 100644 --- a/packages/graphql/tests/tck/connections/alias.test.ts +++ b/packages/graphql/tests/tck/connections/alias.test.ts @@ -72,8 +72,7 @@ describe("Connections Alias", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -124,8 +123,7 @@ describe("Connections Alias", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -140,8 +138,7 @@ describe("Connections Alias", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this5, edge.relationship AS this4 - WITH { screenTime: this4.screenTime, node: { name: this5.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this4.screenTime, node: { name: this5.name } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 diff --git a/packages/graphql/tests/tck/connections/filtering/composite.test.ts b/packages/graphql/tests/tck/connections/filtering/composite.test.ts index 37ff337784e..5d566062e10 100644 --- a/packages/graphql/tests/tck/connections/filtering/composite.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/composite.test.ts @@ -87,8 +87,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -151,8 +150,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -217,8 +215,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -285,8 +282,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -358,8 +354,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts index c12c11d3702..5c906d37965 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -130,8 +129,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts index 31858d3962b..d5ffac01c51 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts @@ -80,8 +80,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -130,8 +129,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -181,8 +179,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -229,8 +226,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts index f15585849ee..a05c0d4a9c5 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts @@ -79,8 +79,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -126,8 +125,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts index 93fa9e2b29e..7db3e9afd19 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -132,8 +131,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -183,8 +181,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -234,8 +231,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts index c7eca8f9df6..c5f1124a1d4 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> OR", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts index 340f6c0893a..a1dc80b3419 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts @@ -97,11 +97,10 @@ describe("Cypher -> Connections -> Filtering -> Node -> Points", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name, currentLocation: CASE + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, currentLocation: CASE WHEN this1.currentLocation IS NOT NULL THEN { point: this1.currentLocation } ELSE NULL - END } } AS edge - WITH collect(edge) AS edges + END } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts index b7706b83e95..9d25524adc6 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts @@ -77,8 +77,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Relationship", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this1.name } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts index 1c8fda81316..d61bf86253c 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts @@ -97,8 +97,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -144,8 +143,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -191,8 +189,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -238,8 +235,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -285,8 +281,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -332,8 +327,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -379,8 +373,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts index 8d4fd2d96c1..8dae794e0de 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -133,8 +132,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts index 8d08c2985ce..4b8f82a54c2 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts @@ -80,8 +80,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -136,8 +135,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -192,8 +190,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -239,8 +236,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts index 94672d532f7..32e69f6b648 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts @@ -79,8 +79,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -129,8 +128,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts index cb6e1d9c12e..44bba6d05ff 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts @@ -79,8 +79,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -129,8 +128,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -179,8 +177,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -229,8 +226,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts index 38574b66dae..867015de762 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> OR", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts index 4c10212bf27..de08fd5e2ee 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts @@ -95,11 +95,10 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Points", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, location: CASE + WITH collect({ screenTime: this0.screenTime, location: CASE WHEN this0.location IS NOT NULL THEN { point: this0.location } ELSE NULL - END, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + END, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts index 952d4426206..3bc16f8ab9b 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts @@ -97,8 +97,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -144,8 +143,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -191,8 +189,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -238,8 +235,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -285,8 +281,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -332,8 +327,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -379,8 +373,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { role: this0.role, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts index 12187b152d1..b93a0432b11 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts @@ -83,8 +83,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Temporal", () => WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { startDate: this0.startDate, endDateTime: apoc.date.convertFormat(toString(this0.endDateTime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ startDate: this0.startDate, endDateTime: apoc.date.convertFormat(toString(this0.endDateTime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts index 23a370a3cc3..b16f41d9392 100644 --- a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts +++ b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts @@ -90,8 +90,7 @@ describe("Mixed nesting", () => { WITH this3 { .title } AS this3 RETURN collect(this3) AS var4 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, movies: var4 } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, movies: var4 } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 @@ -167,14 +166,12 @@ describe("Mixed nesting", () => { WITH this5 { .name } AS this5 RETURN collect(this5) AS var6 } - WITH { node: { title: this3.title, actors: var6 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this3.title, actors: var6 } }) AS edges RETURN edges AS var7 } RETURN { edges: var7, totalCount: totalCount } AS var8 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var8 } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var8 } }) AS edges RETURN edges AS var9 } RETURN { edges: var9, totalCount: totalCount } AS var10 @@ -231,8 +228,7 @@ describe("Mixed nesting", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH { screenTime: this2.screenTime, node: { title: this3.title } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this2.screenTime, node: { title: this3.title } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 diff --git a/packages/graphql/tests/tck/connections/projections/create.test.ts b/packages/graphql/tests/tck/connections/projections/create.test.ts index 6513be3aaac..9342f8c7fbe 100644 --- a/packages/graphql/tests/tck/connections/projections/create.test.ts +++ b/packages/graphql/tests/tck/connections/projections/create.test.ts @@ -87,8 +87,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS edges RETURN edges AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 @@ -147,8 +146,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS edges RETURN edges AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 @@ -211,8 +209,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH { screenTime: create_this2.screenTime, node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS edges RETURN edges AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 diff --git a/packages/graphql/tests/tck/connections/projections/projections.test.ts b/packages/graphql/tests/tck/connections/projections/projections.test.ts index 8132cf979a0..31258ef1fe8 100644 --- a/packages/graphql/tests/tck/connections/projections/projections.test.ts +++ b/packages/graphql/tests/tck/connections/projections/projections.test.ts @@ -77,8 +77,7 @@ describe("Relay Cursor Connection projections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -124,8 +123,7 @@ describe("Relay Cursor Connection projections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -168,8 +166,7 @@ describe("Relay Cursor Connection projections", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH { node: { __resolveType: \\"Actor\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -312,8 +309,7 @@ describe("Relay Cursor Connection projections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -361,8 +357,7 @@ describe("Relay Cursor Connection projections", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/connections/relationship-properties.test.ts b/packages/graphql/tests/tck/connections/relationship-properties.test.ts index 76d06820a59..be047c88d19 100644 --- a/packages/graphql/tests/tck/connections/relationship-properties.test.ts +++ b/packages/graphql/tests/tck/connections/relationship-properties.test.ts @@ -80,8 +80,7 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -128,8 +127,7 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -178,8 +176,7 @@ describe("Relationship Properties Cypher", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this0.screenTime DESC - WITH { screenTime: this0.screenTime, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -225,8 +222,7 @@ describe("Relationship Properties Cypher", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this0.year DESC, this1.name ASC - WITH { year: this0.year, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ year: this0.year, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -267,8 +263,7 @@ describe("Relationship Properties Cypher", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this1.name ASC, this0.year DESC - WITH { year: this0.year, node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ year: this0.year, node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -327,14 +322,12 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH { screenTime: this2.screenTime, node: { title: this3.title } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this2.screenTime, node: { title: this3.title } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var5 } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var5 } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 @@ -414,20 +407,17 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this5, edge.relationship AS this4 - WITH { screenTime: this4.screenTime, node: { name: this5.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this4.screenTime, node: { name: this5.name } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } - WITH { screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var7 } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var7 } }) AS edges RETURN edges AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } - WITH { screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var9 } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var9 } }) AS edges RETURN edges AS var10 } RETURN { edges: var10, totalCount: totalCount } AS var11 diff --git a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts index 6ea6263b8f8..ab6b9b536cf 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts @@ -104,8 +104,7 @@ describe("Relationship Properties Connect Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges RETURN edges AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 @@ -191,8 +190,7 @@ describe("Relationship Properties Connect Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges RETURN edges AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 diff --git a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts index 74ce285b45b..0847099615f 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts @@ -107,8 +107,7 @@ describe("Relationship Properties Create Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this9, edge.relationship AS create_this8 - WITH { screenTime: create_this8.screenTime, node: { name: create_this9.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this8.screenTime, node: { name: create_this9.name } }) AS edges RETURN edges AS create_var10 } RETURN { edges: create_var10, totalCount: totalCount } AS create_var11 diff --git a/packages/graphql/tests/tck/connections/sort.test.ts b/packages/graphql/tests/tck/connections/sort.test.ts index 7f06e5e73ff..d8a129a2c4e 100644 --- a/packages/graphql/tests/tck/connections/sort.test.ts +++ b/packages/graphql/tests/tck/connections/sort.test.ts @@ -96,14 +96,12 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH { node: { name: this2.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this2.name } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } - WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, actorsConnection: var4 } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS this" @@ -171,14 +169,12 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH { node: { name: this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this3.name } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH { node: { title: this0.title, actorsConnection: var5 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, actorsConnection: var5 } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS this" diff --git a/packages/graphql/tests/tck/directives/alias.test.ts b/packages/graphql/tests/tck/directives/alias.test.ts index 08ccf3bb628..d64aa92a570 100644 --- a/packages/graphql/tests/tck/directives/alias.test.ts +++ b/packages/graphql/tests/tck/directives/alias.test.ts @@ -113,8 +113,7 @@ describe("Cypher alias directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { character: this0.characterPropInDb, screenTime: this0.screenTime, node: { title: this1.title, rating: this1.ratingPropInDb } } AS edge - WITH collect(edge) AS edges + WITH collect({ character: this0.characterPropInDb, screenTime: this0.screenTime, node: { title: this1.title, rating: this1.ratingPropInDb } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -206,8 +205,7 @@ describe("Cypher alias directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this12, edge.relationship AS create_this11 - WITH { character: create_this11.characterPropInDb, screenTime: create_this11.screenTime, node: { title: create_this12.title, rating: create_this12.ratingPropInDb } } AS edge - WITH collect(edge) AS edges + WITH collect({ character: create_this11.characterPropInDb, screenTime: create_this11.screenTime, node: { title: create_this12.title, rating: create_this12.ratingPropInDb } }) AS edges RETURN edges AS create_var13 } RETURN { edges: create_var13, totalCount: totalCount } AS create_var14 diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts index 045969a7409..2d13fa5096b 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts @@ -238,8 +238,7 @@ describe("Cypher Auth Where with Roles", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 @@ -299,8 +298,7 @@ describe("Cypher Auth Where with Roles", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index 8395458106c..f69b4be660b 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -582,8 +582,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH { node: { id: this0.id, contentConnection: var4 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this0.id, contentConnection: var4 } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS this" diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index 96bdb01d811..b17143c1304 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -227,8 +227,7 @@ describe("Cypher Auth Where", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 @@ -287,8 +286,7 @@ describe("Cypher Auth Where", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts index b9caee0dc74..244471937c1 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts @@ -110,8 +110,7 @@ describe("Cypher Auth Projection On Connections On Unions", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this4, edge.relationship AS this3 - WITH { node: { name: this4.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this4.name } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts index 6f1c0e17c14..94feb50d8bf 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts @@ -94,8 +94,7 @@ describe("Cypher Auth Projection On Connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 @@ -169,14 +168,12 @@ describe("Cypher Auth Projection On Connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this4, edge.relationship AS this3 - WITH { node: { name: this4.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this4.name } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 } - WITH { node: { content: this1.content, creatorConnection: var6 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content, creatorConnection: var6 } }) AS edges RETURN edges AS var7 } RETURN { edges: var7, totalCount: totalCount } AS var8 @@ -276,14 +273,12 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH { node: { content: this2.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this2.content } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH { node: { name: this0.name, postsConnection: var5 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this0.name, postsConnection: var5 } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS this" @@ -364,20 +359,17 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this5, edge.relationship AS this4 - WITH { node: { name: this5.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this5.name } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } - WITH { node: { content: this2.content, creatorConnection: var7 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this2.content, creatorConnection: var7 } }) AS edges RETURN edges AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } - WITH { node: { name: this0.name, postsConnection: var9 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this0.name, postsConnection: var9 } }) AS edges RETURN edges AS var10 } RETURN { edges: var10, totalCount: totalCount } AS this" diff --git a/packages/graphql/tests/tck/directives/coalesce.test.ts b/packages/graphql/tests/tck/directives/coalesce.test.ts index a97dabf7b6c..2b58b326fd4 100644 --- a/packages/graphql/tests/tck/directives/coalesce.test.ts +++ b/packages/graphql/tests/tck/directives/coalesce.test.ts @@ -221,8 +221,7 @@ describe("Cypher coalesce()", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { id: this1.id, status: this1.status } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this1.id, status: this1.status } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -286,8 +285,7 @@ describe("Cypher coalesce()", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { id: this1.id, statuses: this1.statuses } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this1.id, statuses: this1.statuses } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/directives/node/node-label.test.ts b/packages/graphql/tests/tck/directives/node/node-label.test.ts index aa0ef5bc416..969e6fc0eed 100644 --- a/packages/graphql/tests/tck/directives/node/node-label.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-label.test.ts @@ -121,8 +121,7 @@ describe("Label in Node directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts index 66bac44f10d..d1b3c61fbca 100644 --- a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts @@ -90,8 +90,7 @@ describe("Cypher Auth Projection On Connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { content: this1.content } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { content: this1.content } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/issues/1150.test.ts b/packages/graphql/tests/tck/issues/1150.test.ts index fc6427040f4..fca9356e7f4 100644 --- a/packages/graphql/tests/tck/issues/1150.test.ts +++ b/packages/graphql/tests/tck/issues/1150.test.ts @@ -138,8 +138,7 @@ describe("https://github.com/neo4j/graphql/issues/1150", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var6 } - WITH { node: { driveComponentConnection: var6 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { driveComponentConnection: var6 } }) AS edges RETURN edges AS var7 } RETURN { edges: var7, totalCount: totalCount } AS var8 diff --git a/packages/graphql/tests/tck/issues/1221.test.ts b/packages/graphql/tests/tck/issues/1221.test.ts index c047539b7a6..dd755ec3daa 100644 --- a/packages/graphql/tests/tck/issues/1221.test.ts +++ b/packages/graphql/tests/tck/issues/1221.test.ts @@ -107,14 +107,12 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this7, edge.relationship AS this6 - WITH { node: { fullName: this7.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { fullName: this7.fullName } }) AS edges RETURN edges AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } - WITH { node: { nameDetailsConnection: var9 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { nameDetailsConnection: var9 } }) AS edges RETURN edges AS var10 } RETURN { edges: var10, totalCount: totalCount } AS var11 @@ -242,20 +240,17 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this11, edge.relationship AS this10 - WITH { node: { fullName: this11.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { fullName: this11.fullName } }) AS edges RETURN edges AS var12 } RETURN { edges: var12, totalCount: totalCount } AS var13 } - WITH { node: { nameDetailsConnection: var13 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { nameDetailsConnection: var13 } }) AS edges RETURN edges AS var14 } RETURN { edges: var14, totalCount: totalCount } AS var15 } - WITH { node: { architectureConnection: var15 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { architectureConnection: var15 } }) AS edges RETURN edges AS var16 } RETURN { edges: var16, totalCount: totalCount } AS var17 diff --git a/packages/graphql/tests/tck/issues/1249.test.ts b/packages/graphql/tests/tck/issues/1249.test.ts index cd0a0826acf..c66f087951e 100644 --- a/packages/graphql/tests/tck/issues/1249.test.ts +++ b/packages/graphql/tests/tck/issues/1249.test.ts @@ -94,8 +94,7 @@ describe("https://github.com/neo4j/graphql/issues/1249", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH { supplierMaterialNumber: this2.supplierMaterialNumber, node: { supplierId: this3.supplierId } } AS edge - WITH collect(edge) AS edges + WITH collect({ supplierMaterialNumber: this2.supplierMaterialNumber, node: { supplierId: this3.supplierId } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 diff --git a/packages/graphql/tests/tck/issues/1364.test.ts b/packages/graphql/tests/tck/issues/1364.test.ts index 8cfd0150363..2b5519fcc79 100644 --- a/packages/graphql/tests/tck/issues/1364.test.ts +++ b/packages/graphql/tests/tck/issues/1364.test.ts @@ -113,8 +113,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { UNWIND result AS this1 RETURN head(collect(this1)) AS this1 } - WITH { node: { title: this0.title, totalGenres: this1 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, totalGenres: this1 } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS this" @@ -158,8 +157,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { } WITH * ORDER BY this1 ASC - WITH { node: { title: this0.title, totalGenres: this1 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, totalGenres: this1 } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS this" @@ -215,8 +213,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { UNWIND result AS this2 RETURN head(collect(this2)) AS this2 } - WITH { node: { title: this0.title, totalGenres: this1, totalActors: this2 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, totalGenres: this1, totalActors: this2 } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS this" diff --git a/packages/graphql/tests/tck/issues/1528.test.ts b/packages/graphql/tests/tck/issues/1528.test.ts index 00cb5c142a5..2876eeb23fb 100644 --- a/packages/graphql/tests/tck/issues/1528.test.ts +++ b/packages/graphql/tests/tck/issues/1528.test.ts @@ -93,8 +93,7 @@ describe("https://github.com/neo4j/graphql/issues/1528", () => { } WITH * ORDER BY this2 DESC - WITH { node: { title: this1.title, actorsCount: this2 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this1.title, actorsCount: this2 } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/issues/1760.test.ts b/packages/graphql/tests/tck/issues/1760.test.ts index db5abca3e1c..76b896c13e7 100644 --- a/packages/graphql/tests/tck/issues/1760.test.ts +++ b/packages/graphql/tests/tck/issues/1760.test.ts @@ -159,8 +159,7 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH { node: { fullName: this2.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { fullName: this2.fullName } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 @@ -185,14 +184,12 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this8, edge.relationship AS this7 - WITH { node: { fullName: this8.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { fullName: this8.fullName } }) AS edges RETURN edges AS var9 } RETURN { edges: var9, totalCount: totalCount } AS var10 } - WITH { node: { nameDetailsConnection: var10 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { nameDetailsConnection: var10 } }) AS edges RETURN edges AS var11 } RETURN { edges: var11, totalCount: totalCount } AS var12 @@ -207,8 +204,7 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this14, edge.relationship AS this13 - WITH { node: { id: this14.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this14.id } }) AS edges RETURN edges AS var15 } RETURN { edges: var15, totalCount: totalCount } AS var16 diff --git a/packages/graphql/tests/tck/issues/1783.test.ts b/packages/graphql/tests/tck/issues/1783.test.ts index 2bbdad2b7f6..ca0736750e0 100644 --- a/packages/graphql/tests/tck/issues/1783.test.ts +++ b/packages/graphql/tests/tck/issues/1783.test.ts @@ -132,8 +132,7 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this7, edge.relationship AS this6 - WITH { node: { fullName: this7.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { fullName: this7.fullName } }) AS edges RETURN edges AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 @@ -158,14 +157,12 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this13, edge.relationship AS this12 - WITH { node: { fullName: this13.fullName } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { fullName: this13.fullName } }) AS edges RETURN edges AS var14 } RETURN { edges: var14, totalCount: totalCount } AS var15 } - WITH { node: { nameDetailsConnection: var15 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { nameDetailsConnection: var15 } }) AS edges RETURN edges AS var16 } RETURN { edges: var16, totalCount: totalCount } AS var17 diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index db5fd34f29e..d83388efd80 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -115,8 +115,7 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { WITH this8 { .name, dbId: this8.id } AS this8 RETURN head(collect(this8)) AS var9 } - WITH { node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } }) AS edges RETURN edges AS var10 } RETURN { edges: var10, totalCount: totalCount } AS this" diff --git a/packages/graphql/tests/tck/issues/2262.test.ts b/packages/graphql/tests/tck/issues/2262.test.ts index abfca0a15fe..8b2222490a6 100644 --- a/packages/graphql/tests/tck/issues/2262.test.ts +++ b/packages/graphql/tests/tck/issues/2262.test.ts @@ -93,14 +93,12 @@ describe("https://github.com/neo4j/graphql/issues/2262", () => { WITH edge.node AS this3, edge.relationship AS this2 WITH * ORDER BY this3.uuid DESC - WITH { node: { uuid: this3.uuid } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { uuid: this3.uuid } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH { node: { uuid: this1.uuid, componentInputsConnection: var5 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { uuid: this1.uuid, componentInputsConnection: var5 } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 diff --git a/packages/graphql/tests/tck/issues/2437.test.ts b/packages/graphql/tests/tck/issues/2437.test.ts index fcfcef5c992..6cdf7a59738 100644 --- a/packages/graphql/tests/tck/issues/2437.test.ts +++ b/packages/graphql/tests/tck/issues/2437.test.ts @@ -94,8 +94,7 @@ describe("https://github.com/neo4j/graphql/issues/2437", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param2 - WITH { node: { uuid: this1.uuid } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { uuid: this1.uuid } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index c55e17e154c..fbc1b9f490d 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -122,8 +122,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH edge.node AS this0 WITH * ORDER BY this0.fg_item DESC - WITH { node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } }) AS edges RETURN edges AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" @@ -164,8 +163,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this1.fg_item DESC - WITH { node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/4007.test.ts b/packages/graphql/tests/tck/issues/4007.test.ts index 996e09ac54c..180a5fc6110 100644 --- a/packages/graphql/tests/tck/issues/4007.test.ts +++ b/packages/graphql/tests/tck/issues/4007.test.ts @@ -72,8 +72,7 @@ describe("https://github.com/neo4j/graphql/issues/4007", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { na: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { na: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/4015.test.ts b/packages/graphql/tests/tck/issues/4015.test.ts index 42a9be22d2d..f728762873c 100644 --- a/packages/graphql/tests/tck/issues/4015.test.ts +++ b/packages/graphql/tests/tck/issues/4015.test.ts @@ -76,8 +76,7 @@ describe("https://github.com/neo4j/graphql/issues/4015", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { surname: this1.surname, name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { surname: this1.surname, name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/4292.test.ts b/packages/graphql/tests/tck/issues/4292.test.ts index 499c240fc8f..0c483f1ea5d 100644 --- a/packages/graphql/tests/tck/issues/4292.test.ts +++ b/packages/graphql/tests/tck/issues/4292.test.ts @@ -254,8 +254,7 @@ describe("https://github.com/neo4j/graphql/issues/4292", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this13, edge.relationship AS this12 - WITH { active: this12.active, firstDay: this12.firstDay, lastDay: this12.lastDay, node: { __resolveType: \\"Person\\", __id: id(this13) } } AS edge - WITH collect(edge) AS edges + WITH collect({ active: this12.active, firstDay: this12.firstDay, lastDay: this12.lastDay, node: { __resolveType: \\"Person\\", __id: id(this13) } }) AS edges RETURN edges AS var25 } RETURN { edges: var25, totalCount: totalCount } AS var26 diff --git a/packages/graphql/tests/tck/issues/433.test.ts b/packages/graphql/tests/tck/issues/433.test.ts index 7f495e27b69..9b3dae9b805 100644 --- a/packages/graphql/tests/tck/issues/433.test.ts +++ b/packages/graphql/tests/tck/issues/433.test.ts @@ -73,8 +73,7 @@ describe("#413", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { name: this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this1.name } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/issues/601.test.ts b/packages/graphql/tests/tck/issues/601.test.ts index 8dbcdea1758..340d1da3605 100644 --- a/packages/graphql/tests/tck/issues/601.test.ts +++ b/packages/graphql/tests/tck/issues/601.test.ts @@ -111,8 +111,7 @@ describe("#601", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH { fileId: this2.fileId, uploadedAt: apoc.date.convertFormat(toString(this2.uploadedAt), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { __resolveType: \\"CustomerContact\\", __id: id(this3) } } AS edge - WITH collect(edge) AS edges + WITH collect({ fileId: this2.fileId, uploadedAt: apoc.date.convertFormat(toString(this2.uploadedAt), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { __resolveType: \\"CustomerContact\\", __id: id(this3) } }) AS edges RETURN edges AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 diff --git a/packages/graphql/tests/tck/issues/630.test.ts b/packages/graphql/tests/tck/issues/630.test.ts index a2229f5685b..a36dbfd49b8 100644 --- a/packages/graphql/tests/tck/issues/630.test.ts +++ b/packages/graphql/tests/tck/issues/630.test.ts @@ -87,8 +87,7 @@ describe("Cypher directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH { node: { __resolveType: \\"Actor\\", __id: id(this2) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this2) } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 diff --git a/packages/graphql/tests/tck/issues/988.test.ts b/packages/graphql/tests/tck/issues/988.test.ts index 4de6a1467e5..bdcab3e7444 100644 --- a/packages/graphql/tests/tck/issues/988.test.ts +++ b/packages/graphql/tests/tck/issues/988.test.ts @@ -151,8 +151,7 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this7, edge.relationship AS this6 - WITH { current: this6.current, node: { name: this7.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ current: this6.current, node: { name: this7.name } }) AS edges RETURN edges AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 @@ -166,8 +165,7 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this11, edge.relationship AS this10 - WITH { current: this10.current, node: { name: this11.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ current: this10.current, node: { name: this11.name } }) AS edges RETURN edges AS var12 } RETURN { edges: var12, totalCount: totalCount } AS var13 diff --git a/packages/graphql/tests/tck/operations/create.test.ts b/packages/graphql/tests/tck/operations/create.test.ts index dd15e1bb30f..e2f6a02adb4 100644 --- a/packages/graphql/tests/tck/operations/create.test.ts +++ b/packages/graphql/tests/tck/operations/create.test.ts @@ -423,8 +423,7 @@ describe("Cypher Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH { node: { name: create_this3.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: create_this3.name } }) AS edges RETURN edges AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 diff --git a/packages/graphql/tests/tck/rfcs/query-limits.test.ts b/packages/graphql/tests/tck/rfcs/query-limits.test.ts index fa881c8359e..6c59450ebc4 100644 --- a/packages/graphql/tests/tck/rfcs/query-limits.test.ts +++ b/packages/graphql/tests/tck/rfcs/query-limits.test.ts @@ -214,8 +214,7 @@ describe("tck/rfcs/query-limits", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH { node: { id: this1.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this1.id } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -270,8 +269,7 @@ describe("tck/rfcs/query-limits", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH { node: { id: this1.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this1.id } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -324,8 +322,7 @@ describe("tck/rfcs/query-limits", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param0 - WITH { node: { id: this1.id } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { id: this1.id } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index 6eb0564d307..43f9d26754b 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -70,8 +70,7 @@ describe("Root Connection Query tests", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this0 - WITH { node: { title: this0.title } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title } }) AS edges RETURN edges AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" @@ -110,8 +109,7 @@ describe("Root Connection Query tests", () => { WITH * ORDER BY this0.title ASC LIMIT $param0 - WITH { node: { title: this0.title } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title } }) AS edges RETURN edges AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" @@ -151,8 +149,7 @@ describe("Root Connection Query tests", () => { WITH * ORDER BY this0.title ASC LIMIT $param1 - WITH { node: { title: this0.title } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title } }) AS edges RETURN edges AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" @@ -208,14 +205,12 @@ describe("Root Connection Query tests", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH { node: { name: this2.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this2.name } }) AS edges RETURN edges AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } - WITH { node: { title: this0.title, actorsConnection: var4 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, actorsConnection: var4 } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS this" diff --git a/packages/graphql/tests/tck/sort.test.ts b/packages/graphql/tests/tck/sort.test.ts index 71aaeb2d737..f973d98bcec 100644 --- a/packages/graphql/tests/tck/sort.test.ts +++ b/packages/graphql/tests/tck/sort.test.ts @@ -482,14 +482,12 @@ describe("Cypher sort tests", () => { UNWIND sum AS this4 RETURN head(collect(this4)) AS this4 } - WITH { node: { name: this3.name, totalScreenTime: this4 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this3.name, totalScreenTime: this4 } }) AS edges RETURN edges AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 } - WITH { node: { title: this0.title, actorsConnection: var6 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this0.title, actorsConnection: var6 } }) AS edges RETURN edges AS var7 } RETURN { edges: var7, totalCount: totalCount } AS this" @@ -579,14 +577,12 @@ describe("Cypher sort tests", () => { UNWIND sum AS this5 RETURN head(collect(this5)) AS this5 } - WITH { node: { name: this4.name, totalScreenTime: this5 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: this4.name, totalScreenTime: this5 } }) AS edges RETURN edges AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } - WITH { node: { title: this1.title, actorsConnection: var7 } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { title: this1.title, actorsConnection: var7 } }) AS edges RETURN edges AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 diff --git a/packages/graphql/tests/tck/subscriptions/create.test.ts b/packages/graphql/tests/tck/subscriptions/create.test.ts index 0350384130f..e679ebebe46 100644 --- a/packages/graphql/tests/tck/subscriptions/create.test.ts +++ b/packages/graphql/tests/tck/subscriptions/create.test.ts @@ -128,8 +128,7 @@ describe("Subscriptions metadata on create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges RETURN edges AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 @@ -218,8 +217,7 @@ describe("Subscriptions metadata on create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH { node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { name: create_this1.name } }) AS edges RETURN edges AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 @@ -333,8 +331,7 @@ describe("Subscriptions metadata on create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH { screenTime: create_this0.screenTime, node: { name: create_this1.name } } AS edge - WITH collect(edge) AS edges + WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges RETURN edges AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 diff --git a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts index fae2a0d26af..8a8382e91a1 100644 --- a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts @@ -61,8 +61,7 @@ describe("QueryDirection in relationships connection", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -107,8 +106,7 @@ describe("QueryDirection in relationships connection", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 @@ -152,8 +150,7 @@ describe("QueryDirection in relationships connection", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 diff --git a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts index 06381ac4ba2..f6b17e37515 100644 --- a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts @@ -60,8 +60,7 @@ describe("Undirected connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH { node: { __resolveType: \\"User\\", __id: id(this1) } } AS edge - WITH collect(edge) AS edges + WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges RETURN edges AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 From 86b170a35cd4fb81600f757234c11bc7cbdccc2a Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 11 Dec 2023 17:44:21 +0000 Subject: [PATCH 041/136] Remove commented cypher code --- .../tests/integration/issues/1683.int.test.ts | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/packages/graphql/tests/integration/issues/1683.int.test.ts b/packages/graphql/tests/integration/issues/1683.int.test.ts index 7e190500fe3..0d6bcad8c81 100644 --- a/packages/graphql/tests/integration/issues/1683.int.test.ts +++ b/packages/graphql/tests/integration/issues/1683.int.test.ts @@ -65,31 +65,6 @@ describe("https://github.com/neo4j/graphql/issues/1683", () => { await driver.close(); }); - // MATCH (this:oJzvmvwxSystem) - // CALL { - // WITH this - // MATCH (this)<-[this0:UPDATED_BY]-(this1:GuBXKcPnGovernedData) - // WITH { node: { code: this1.code } } AS edge - // WITH collect(edge) AS edges - // WITH edges, size(edges) AS totalCount - // RETURN { edges: edges, totalCount: totalCount } AS var2 - // } - // RETURN this { .code, updatesDataConnection: var2 } AS this - - // MATCH (this:bsCwrZgmSystem) - // CALL { - // WITH this - // MATCH (this)<-[this0:UPDATED_BY]-(this1:RqkfUGLmGovernedData) - // WITH collect({ relationship: this0, node: this1 }) AS edges - // WITH edges, size(edges) AS totalCount - // UNWIND edges AS edge - // WITH edge.node AS this1, edge.relationship AS this0, totalCount - // WITH { node: { code: this1.code } } AS edge, totalCount - // WITH collect(edge) AS edges, totalCount - // RETURN { edges: edges, totalCount: totalCount } AS var2 - // } - // RETURN this { .code, updatesDataConnection: var2 } AS this - test("should return top level entity, even if no connections exist", async () => { const query = ` { From 80d06900786408b3309503174dc6cb9264752cfa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 22:02:01 +0000 Subject: [PATCH 042/136] chore(deps): update babel monorepo to v7.23.6 --- packages/package-tests/babel/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/package-tests/babel/package.json b/packages/package-tests/babel/package.json index 1817a88c2f9..ce351b374a5 100644 --- a/packages/package-tests/babel/package.json +++ b/packages/package-tests/babel/package.json @@ -13,8 +13,8 @@ "neo4j-driver": "^5.8.0" }, "devDependencies": { - "@babel/core": "7.23.5", + "@babel/core": "7.23.6", "@babel/node": "7.22.19", - "@babel/preset-env": "7.23.5" + "@babel/preset-env": "7.23.6" } } From 653ffc60dbf12846b85cdac0386e65fd5e482eb1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 22:12:18 +0000 Subject: [PATCH 043/136] fix(deps): update neo4j-ndl --- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 7a296d61938..5d655ce6798 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -50,8 +50,8 @@ "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", - "@neo4j-ndl/base": "2.0.8", - "@neo4j-ndl/react": "2.0.17", + "@neo4j-ndl/base": "2.0.9", + "@neo4j-ndl/react": "2.0.18", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.3.2", diff --git a/yarn.lock b/yarn.lock index b39b9d088b6..2d5996e575e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3518,21 +3518,21 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/base@npm:2.0.8, @neo4j-ndl/base@npm:^2.0.8": - version: 2.0.8 - resolution: "@neo4j-ndl/base@npm:2.0.8" - checksum: 817971a4e0c770a40af88733563f403024133a1bcba08eb19095a8dc94f1538ae3effaeaa1e8cac97ca01f50b4a072d47d020cb6ac4790002901b25a12e042e3 +"@neo4j-ndl/base@npm:2.0.9, @neo4j-ndl/base@npm:^2.0.9": + version: 2.0.9 + resolution: "@neo4j-ndl/base@npm:2.0.9" + checksum: dd37b74d83f505cf4032a5f9cd745b2d2f9df72862cbbfcbcc0d91b6060c531df68268d3288c3e5d2447c577331971e6a76754a24c289ae4b06af6b1c5f5cd59 languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.0.17": - version: 2.0.17 - resolution: "@neo4j-ndl/react@npm:2.0.17" +"@neo4j-ndl/react@npm:2.0.18": + version: 2.0.18 + resolution: "@neo4j-ndl/react@npm:2.0.18" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 "@neo4j-cypher/react-codemirror": ^1.0.1 - "@neo4j-ndl/base": ^2.0.8 + "@neo4j-ndl/base": ^2.0.9 "@table-nav/core": 0.0.7 "@table-nav/react": 0.0.7 "@tanstack/react-table": ^8.9.3 @@ -3552,7 +3552,7 @@ __metadata: peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: 4f294107ebe15d8e28e1c426764e7332c1c127f71b6ee0f224e07c53bd7251e7e508f60ddf18311a3996c2879c856b70a8655a97e2354ecaaaf7bf6d03416722 + checksum: af5507f02c38c3fe28de9acc1fdba1c95f01190417823f7de6a0770bf93596e1ed032c4b5bfdf29659bc32d8081dc8de54401e9882dc0370f9979db92a5f06b8 languageName: node linkType: hard @@ -3634,8 +3634,8 @@ __metadata: "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 - "@neo4j-ndl/base": 2.0.8 - "@neo4j-ndl/react": 2.0.17 + "@neo4j-ndl/base": 2.0.9 + "@neo4j-ndl/react": 2.0.18 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 From 8d45a673981047c129664c8e3deac28137ce7e40 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:41:14 +0000 Subject: [PATCH 044/136] chore(deps): update typescript-eslint monorepo to v6.14.0 --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 0a676bcc799..ee2857127bb 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.13.2", - "@typescript-eslint/parser": "6.13.2", + "@typescript-eslint/eslint-plugin": "6.14.0", + "@typescript-eslint/parser": "6.14.0", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.55.0", diff --git a/yarn.lock b/yarn.lock index 2d5996e575e..63ae9d1f2af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7938,15 +7938,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/eslint-plugin@npm:6.13.2" +"@typescript-eslint/eslint-plugin@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.14.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.13.2 - "@typescript-eslint/type-utils": 6.13.2 - "@typescript-eslint/utils": 6.13.2 - "@typescript-eslint/visitor-keys": 6.13.2 + "@typescript-eslint/scope-manager": 6.14.0 + "@typescript-eslint/type-utils": 6.14.0 + "@typescript-eslint/utils": 6.14.0 + "@typescript-eslint/visitor-keys": 6.14.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7959,25 +7959,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: e50cbbe7104eecef59faf3355ab981d9f353b19327f0b4607dfd829b4726f9e694b536fe43ab55f50bb00fbfdd2e4268a7e2a568b28d5fcd0d2a32a8d2466218 + checksum: ec688fd71b21576bfe0e4176889fddf3c13d8b07792461b84017d689ed11a9bffbf4d2ab61e9bdb254e43d2c1e159d5c2fc21bdfa6a6c2d64f9e1956a668fbe8 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/parser@npm:6.13.2" +"@typescript-eslint/parser@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/parser@npm:6.14.0" dependencies: - "@typescript-eslint/scope-manager": 6.13.2 - "@typescript-eslint/types": 6.13.2 - "@typescript-eslint/typescript-estree": 6.13.2 - "@typescript-eslint/visitor-keys": 6.13.2 + "@typescript-eslint/scope-manager": 6.14.0 + "@typescript-eslint/types": 6.14.0 + "@typescript-eslint/typescript-estree": 6.14.0 + "@typescript-eslint/visitor-keys": 6.14.0 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: aeafc414d295d7855384f10d57abb4f5f2ff35b57991b5c8854f43268761b3cc995e62af585dea1dc48295d762f466b565b5ae5699bfe642585d3f83ba8e1515 + checksum: 5fbe8d7431654c14ba6c9782d3728026ad5c90e02c9c4319f45df972e653cf5c15ba320dce70cdffa9fb7ce4c4263c37585e7bc1c909d1252d0a599880963063 languageName: node linkType: hard @@ -7991,22 +7991,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/scope-manager@npm:6.13.2" +"@typescript-eslint/scope-manager@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/scope-manager@npm:6.14.0" dependencies: - "@typescript-eslint/types": 6.13.2 - "@typescript-eslint/visitor-keys": 6.13.2 - checksum: ff8fd64ddf324e296e2e0e34a8f73149c9a5f14d1761ea8e8665fc5998faa2b0bbbd1a5d416aa10d725f13c804032d532f68e39a0ca6cc36d1c9b9c0aea94311 + "@typescript-eslint/types": 6.14.0 + "@typescript-eslint/visitor-keys": 6.14.0 + checksum: 0b577d42db925426a9838fe61703c226e18b697374fbe20cf9b93ba30fe58bf4a7f7f42491a4d24b7f3cc12d9a189fe3524c0e9b7708727e710d95b908250a14 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/type-utils@npm:6.13.2" +"@typescript-eslint/type-utils@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/type-utils@npm:6.14.0" dependencies: - "@typescript-eslint/typescript-estree": 6.13.2 - "@typescript-eslint/utils": 6.13.2 + "@typescript-eslint/typescript-estree": 6.14.0 + "@typescript-eslint/utils": 6.14.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8014,7 +8014,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: ba54e5746139f778c35e4058e523ec8c20b68cf6472b3a7784170328e48c228f0761d2fc7e43dab053ca7d85ac4378b6965567774e6afedf551e600638404215 + checksum: 09988f25279598840673c41ba44b03756f2dfb31284ab72af97c170711a0f31e5c53d6b120aa83f31438565e82aae1a1ca4d1ed0de4890654dd6a6a33d88202c languageName: node linkType: hard @@ -8025,10 +8025,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/types@npm:6.13.2" - checksum: 4493ff06fa07c68c5adbcbd842f6dd6f5c88f14d160b53c3379b6b703e6f62808fab7fdebcc06ff06a56f20ab432b6ceeb0afb8931dc97d4061cb417e787f2c1 +"@typescript-eslint/types@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/types@npm:6.14.0" + checksum: 624e6c5227f596dcc9757348d09c5a09b846a62938b8b4409614cf8108013b64ed8b270c32e87ea8890dd09ed896b82e92872c3574dbf07dcda11a168d69dd1f languageName: node linkType: hard @@ -8050,12 +8050,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/typescript-estree@npm:6.13.2" +"@typescript-eslint/typescript-estree@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.14.0" dependencies: - "@typescript-eslint/types": 6.13.2 - "@typescript-eslint/visitor-keys": 6.13.2 + "@typescript-eslint/types": 6.14.0 + "@typescript-eslint/visitor-keys": 6.14.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8064,24 +8064,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 0c18ee5ef594a2411a788fe9d7bc6d51a03bce38d9d764bcb24ab557e5bc1942c2ddf9bd6fb4877eb102b0ae488974fb7b7fe72daa70a2054bf04d3cc6803546 + checksum: 495d7616463685bfd8138ffa9fbc0a7f9130ff8a3f6f85775960b4f0a3fdc259ae53b104cdfe562b60310860b5a6c8387307790734555084aa087e3bb9c28a69 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/utils@npm:6.13.2" +"@typescript-eslint/utils@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/utils@npm:6.14.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.13.2 - "@typescript-eslint/types": 6.13.2 - "@typescript-eslint/typescript-estree": 6.13.2 + "@typescript-eslint/scope-manager": 6.14.0 + "@typescript-eslint/types": 6.14.0 + "@typescript-eslint/typescript-estree": 6.14.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: b66bcf2a945e9c55f3dccb48af49565863d974837ee23b2f01ce7f3fb2462eb8a5871784d4a2fcc80dac7d5cd4ed90c8d01431cd177c0249de89a448f6663fc8 + checksum: 36e8501cb85647947189f31017c36d6f6ac7ef0399fa0e18eb64f1b83e00f1e8ace1d9ac5015ef4d9c1b820179f1def8d61d7ea9e5d61433eb848cf5c49dc8b0 languageName: node linkType: hard @@ -8113,13 +8113,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.13.2": - version: 6.13.2 - resolution: "@typescript-eslint/visitor-keys@npm:6.13.2" +"@typescript-eslint/visitor-keys@npm:6.14.0": + version: 6.14.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.14.0" dependencies: - "@typescript-eslint/types": 6.13.2 + "@typescript-eslint/types": 6.14.0 eslint-visitor-keys: ^3.4.1 - checksum: 4b4def7acd7451e6a18dab3ee13f06504b3d23e51f195fced7c544f2203ee8a83426c82fa57ab6b58725c70fdedaf7a3eccb69793180be35756eed0f2c69fe04 + checksum: fc593c4e94d5739be7bd88e42313a301bc9806fad758b6a0a1bafd296ff41522be602caf4976beec84e363b0f56585bb98df3c157f70de984de721798501fd8a languageName: node linkType: hard @@ -19828,8 +19828,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.13.2 - "@typescript-eslint/parser": 6.13.2 + "@typescript-eslint/eslint-plugin": 6.14.0 + "@typescript-eslint/parser": 6.14.0 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.55.0 From eb61a9805e4eaebe8f3993930bef6a09d3f68c73 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 00:50:22 +0000 Subject: [PATCH 045/136] chore(deps): update dependency @apollo/gateway to v2.6.2 --- packages/graphql/package.json | 2 +- yarn.lock | 58 +++++++++++++++++------------------ 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/packages/graphql/package.json b/packages/graphql/package.json index d26f9d459bb..16f96320f1e 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -49,7 +49,7 @@ }, "author": "Neo4j Inc.", "devDependencies": { - "@apollo/gateway": "2.6.1", + "@apollo/gateway": "2.6.2", "@apollo/server": "4.9.5", "@faker-js/faker": "8.3.1", "@types/deep-equal": "1.0.4", diff --git a/yarn.lock b/yarn.lock index 63ae9d1f2af..35039d7b696 100644 --- a/yarn.lock +++ b/yarn.lock @@ -99,15 +99,15 @@ __metadata: languageName: node linkType: hard -"@apollo/composition@npm:2.6.1": - version: 2.6.1 - resolution: "@apollo/composition@npm:2.6.1" +"@apollo/composition@npm:2.6.2": + version: 2.6.2 + resolution: "@apollo/composition@npm:2.6.2" dependencies: - "@apollo/federation-internals": 2.6.1 - "@apollo/query-graphs": 2.6.1 + "@apollo/federation-internals": 2.6.2 + "@apollo/query-graphs": 2.6.2 peerDependencies: graphql: ^16.5.0 - checksum: 3332842e7b320457bedc7d6e99ee76ca16595e8d531cdec33a3deaf53a06932900edea839ec92d9a8b314caff8a5b4021efa21e14c98a291a5da84ee6b5530ca + checksum: c62e772e75db6ab0b282c7c2d1d249a6e08e3fb5472f9cc750775dcfdc03467cd8fb44919f701d9e4f5d6b49eb5e6b6984b0d32fbbba767a9f1b0895e2271095 languageName: node linkType: hard @@ -125,9 +125,9 @@ __metadata: languageName: node linkType: hard -"@apollo/federation-internals@npm:2.6.1": - version: 2.6.1 - resolution: "@apollo/federation-internals@npm:2.6.1" +"@apollo/federation-internals@npm:2.6.2": + version: 2.6.2 + resolution: "@apollo/federation-internals@npm:2.6.2" dependencies: "@types/uuid": ^9.0.0 chalk: ^4.1.0 @@ -135,7 +135,7 @@ __metadata: uuid: ^9.0.0 peerDependencies: graphql: ^16.5.0 - checksum: af7293ef180ba2ec5f6300d37ac4240f3cdd8aa966a7cae0e175e52835274f6c89b110b3ab55b9494b380ea02261e0e997be806cea4e4c7ec3a2a0f7b591f900 + checksum: 0b246190a6a9000881b718e88efafee6039ad2fe7858b83ec509dc6a9a83c44f1eff666308d14eb2597f73ca38e8453c6efb75e2240b83f960dc12a0f019153d languageName: node linkType: hard @@ -169,13 +169,13 @@ __metadata: languageName: node linkType: hard -"@apollo/gateway@npm:2.6.1": - version: 2.6.1 - resolution: "@apollo/gateway@npm:2.6.1" +"@apollo/gateway@npm:2.6.2": + version: 2.6.2 + resolution: "@apollo/gateway@npm:2.6.2" dependencies: - "@apollo/composition": 2.6.1 - "@apollo/federation-internals": 2.6.1 - "@apollo/query-planner": 2.6.1 + "@apollo/composition": 2.6.2 + "@apollo/federation-internals": 2.6.2 + "@apollo/query-planner": 2.6.2 "@apollo/server-gateway-interface": ^1.1.0 "@apollo/usage-reporting-protobuf": ^4.1.0 "@apollo/utils.createhash": ^2.0.0 @@ -193,7 +193,7 @@ __metadata: node-fetch: ^2.6.7 peerDependencies: graphql: ^16.5.0 - checksum: 01bfc84b7344db334efcc98fc18b9c0ea16389b8051449177c4fab1b746e76b9a7d67ddbf9fc08c48f42732c0579ca4a731272aa68b9bdc0ad839b2d74c1f3d3 + checksum: 48f1deaeb1f98cfe96e0d2139ad38670fe6de457b87a788aa6bd314f5ea9f0e6ab025997858e9e958ec4999758c2929a371befd8261b89c892a2e34ac7e04910 languageName: node linkType: hard @@ -220,33 +220,33 @@ __metadata: languageName: node linkType: hard -"@apollo/query-graphs@npm:2.6.1": - version: 2.6.1 - resolution: "@apollo/query-graphs@npm:2.6.1" +"@apollo/query-graphs@npm:2.6.2": + version: 2.6.2 + resolution: "@apollo/query-graphs@npm:2.6.2" dependencies: - "@apollo/federation-internals": 2.6.1 + "@apollo/federation-internals": 2.6.2 deep-equal: ^2.0.5 ts-graphviz: ^1.5.4 uuid: ^9.0.0 peerDependencies: graphql: ^16.5.0 - checksum: 932acd852c10e2dad8e67902e302602ecaeee5fd1bc98fe4c58bec45fadb20b7a5ba7384f33374e54c08c3e935254b3c88275b6bec9186c378fb89aa578a4853 + checksum: 57bec3b75a535ea832e67c640e773a0fa34e500fe6f8633e14b677cc188f687fff67490af6800679c5d240e57de9e2e682c4ac6c260bd81ba579b4836657b58c languageName: node linkType: hard -"@apollo/query-planner@npm:2.6.1": - version: 2.6.1 - resolution: "@apollo/query-planner@npm:2.6.1" +"@apollo/query-planner@npm:2.6.2": + version: 2.6.2 + resolution: "@apollo/query-planner@npm:2.6.2" dependencies: - "@apollo/federation-internals": 2.6.1 - "@apollo/query-graphs": 2.6.1 + "@apollo/federation-internals": 2.6.2 + "@apollo/query-graphs": 2.6.2 "@apollo/utils.keyvaluecache": ^2.1.0 chalk: ^4.1.0 deep-equal: ^2.0.5 pretty-format: ^29.0.0 peerDependencies: graphql: ^16.5.0 - checksum: 14c8cf1447241d6b2273be8de12c54e45cb963d49807ac9af4ac906e2edb70e8c962ae283c766700333cef56d14dcfaca8741d60ea2070d994fb1a8f50023f43 + checksum: 342220639874041841558637b0aeb85e7d75c41fdef993b4176950a6498ffa26ffc8220cf8998e1280bda12b1da59231d8dc438979bfda247fee5bd7a71d77a7 languageName: node linkType: hard @@ -3695,7 +3695,7 @@ __metadata: version: 0.0.0-use.local resolution: "@neo4j/graphql@workspace:packages/graphql" dependencies: - "@apollo/gateway": 2.6.1 + "@apollo/gateway": 2.6.2 "@apollo/server": 4.9.5 "@apollo/subgraph": ^2.2.3 "@faker-js/faker": 8.3.1 From c9ccfaf9306f11a2be28c4cad7f91d4000b63add Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 12 Dec 2023 10:28:49 +0000 Subject: [PATCH 046/136] Remove extra with on unwind subquery for connection --- .../ast/operations/ConnectionReadOperation.ts | 74 ++++++++++--------- .../tests/tck/connections/alias.test.ts | 9 +-- .../connections/filtering/composite.test.ts | 15 ++-- .../connections/filtering/node/and.test.ts | 6 +- .../connections/filtering/node/arrays.test.ts | 12 +-- .../filtering/node/equality.test.ts | 6 +- .../filtering/node/numerical.test.ts | 12 +-- .../tck/connections/filtering/node/or.test.ts | 3 +- .../connections/filtering/node/points.test.ts | 5 +- .../filtering/node/relationship.test.ts | 3 +- .../connections/filtering/node/string.test.ts | 21 ++---- .../filtering/relationship/and.test.ts | 6 +- .../filtering/relationship/arrays.test.ts | 12 +-- .../filtering/relationship/equality.test.ts | 6 +- .../filtering/relationship/numerical.test.ts | 12 +-- .../filtering/relationship/or.test.ts | 3 +- .../filtering/relationship/points.test.ts | 5 +- .../filtering/relationship/string.test.ts | 21 ++---- .../filtering/relationship/temporal.test.ts | 3 +- .../tck/connections/mixed-nesting.test.ts | 12 +-- .../connections/projections/create.test.ts | 9 +-- .../projections/projections.test.ts | 15 ++-- .../relationship-properties.test.ts | 30 +++----- .../relationship_properties/connect.test.ts | 6 +- .../relationship_properties/create.test.ts | 3 +- .../tests/tck/connections/sort.test.ts | 12 +-- .../tests/tck/directives/alias.test.ts | 6 +- .../arguments/roles-where.test.ts | 6 +- .../where/connection-auth-filter.test.ts | 3 +- .../arguments/where/where.test.ts | 6 +- .../projection-connection-union.test.ts | 3 +- .../projection-connection.test.ts | 24 ++---- .../tests/tck/directives/coalesce.test.ts | 6 +- .../tck/directives/node/node-label.test.ts | 3 +- .../node/node-with-auth-projection.test.ts | 3 +- .../graphql/tests/tck/issues/1150.test.ts | 3 +- .../graphql/tests/tck/issues/1221.test.ts | 15 ++-- .../graphql/tests/tck/issues/1249.test.ts | 3 +- .../graphql/tests/tck/issues/1364.test.ts | 9 +-- .../graphql/tests/tck/issues/1528.test.ts | 3 +- .../graphql/tests/tck/issues/1760.test.ts | 12 +-- .../graphql/tests/tck/issues/1783.test.ts | 9 +-- .../graphql/tests/tck/issues/2022.test.ts | 3 +- .../graphql/tests/tck/issues/2262.test.ts | 6 +- .../graphql/tests/tck/issues/2437.test.ts | 3 +- .../graphql/tests/tck/issues/3394.test.ts | 6 +- .../graphql/tests/tck/issues/4007.test.ts | 3 +- .../graphql/tests/tck/issues/4015.test.ts | 3 +- .../graphql/tests/tck/issues/4292.test.ts | 3 +- packages/graphql/tests/tck/issues/433.test.ts | 3 +- packages/graphql/tests/tck/issues/601.test.ts | 3 +- packages/graphql/tests/tck/issues/630.test.ts | 3 +- packages/graphql/tests/tck/issues/988.test.ts | 6 +- .../tests/tck/operations/create.test.ts | 3 +- .../tests/tck/rfcs/query-limits.test.ts | 9 +-- .../graphql/tests/tck/root-connection.test.ts | 15 ++-- packages/graphql/tests/tck/sort.test.ts | 12 +-- .../tests/tck/subscriptions/create.test.ts | 9 +-- .../query-direction-connection.test.ts | 9 +-- .../undirected-connection.test.ts | 3 +- 60 files changed, 193 insertions(+), 344 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 7e5e0f11ef7..382913e0b74 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -126,8 +126,11 @@ export class ConnectionReadOperation extends Operation { const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => new Cypher.Call(sq).innerWith(nestedContext.target) ); + const edgesVar = new Cypher.NamedVariable("edges"); + const totalCount = new Cypher.NamedVariable("totalCount"); + const edgesVar2 = new Cypher.Variable(); - const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(nestedContext); + const unwindSubquery = this.getUnwindSubquery(nestedContext, edgesVar, edgesVar2); let withWhere: Cypher.With | undefined; @@ -138,10 +141,6 @@ export class ConnectionReadOperation extends Operation { this.addFiltersToClause(selectionClause, nestedContext); } - const edgeVar = new Cypher.NamedVariable("edge"); - const edgesVar = new Cypher.NamedVariable("edges"); - const totalCount = new Cypher.NamedVariable("totalCount"); - const edgeMap1 = new Cypher.Map({ node: nestedContext.target, }); @@ -155,36 +154,6 @@ export class ConnectionReadOperation extends Operation { totalCount, ]); - const edgesVar2 = new Cypher.Variable(); - let unwindClause: Cypher.With; - if (nestedContext.relationship) { - unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with( - [edgeVar.property("node"), nestedContext.target], - [edgeVar.property("relationship"), nestedContext.relationship] - ); - } else { - unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with([ - edgeVar.property("node"), - nestedContext.target, - ]); - } - - const edgeProjectionMap = this.createProjectionMapForEdge(nestedContext); - const withProjection = new Cypher.With([Cypher.collect(edgeProjectionMap), edgesVar]); - - const paginationWith = this.generateSortAndPaginationClause(nestedContext); - - const unwindAndProjectionSubquery = new Cypher.Call( - Cypher.concat( - unwindClause, - ...prePaginationSubqueries, - paginationWith, - ...postPaginationSubqueries, - withProjection, - new Cypher.Return([edgesVar, edgesVar2]) - ) - ).innerWith(edgesVar); - const returnClause = new Cypher.Return([ new Cypher.Map({ edges: edgesVar2, @@ -201,7 +170,7 @@ export class ConnectionReadOperation extends Operation { ...authFilterSubqueries, withWhere, withCollectEdgesAndTotalCount, - unwindAndProjectionSubquery, + unwindSubquery, returnClause ), ], @@ -217,6 +186,39 @@ export class ConnectionReadOperation extends Operation { return filterTruthy(this.authFilters.map((f) => f.getPredicate(context))); } + private getUnwindSubquery( + context: QueryASTContext, + edgesVar: Cypher.Variable, + returnVar: Cypher.Variable + ) { + const edgeVar = new Cypher.NamedVariable("edge"); + const { prePaginationSubqueries, postPaginationSubqueries } = this.getPreAndPostSubqueries(context); + + let unwindClause: Cypher.With; + if (context.relationship) { + unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with( + [edgeVar.property("node"), context.target], + [edgeVar.property("relationship"), context.relationship] + ); + } else { + unwindClause = new Cypher.Unwind([edgesVar, edgeVar]).with([edgeVar.property("node"), context.target]); + } + + const edgeProjectionMap = this.createProjectionMapForEdge(context); + + const paginationWith = this.generateSortAndPaginationClause(context); + + return new Cypher.Call( + Cypher.concat( + unwindClause, + ...prePaginationSubqueries, + paginationWith, + ...postPaginationSubqueries, + new Cypher.Return([Cypher.collect(edgeProjectionMap), returnVar]) + ) + ).innerWith(edgesVar); + } + private createProjectionMapForEdge(context: QueryASTContext): Cypher.Map { const nodeProjectionMap = this.generateProjectionMapForFields(this.nodeFields, context.target); if (nodeProjectionMap.size === 0) { diff --git a/packages/graphql/tests/tck/connections/alias.test.ts b/packages/graphql/tests/tck/connections/alias.test.ts index 33c0c321e8b..d5a6e46e8e6 100644 --- a/packages/graphql/tests/tck/connections/alias.test.ts +++ b/packages/graphql/tests/tck/connections/alias.test.ts @@ -72,8 +72,7 @@ describe("Connections Alias", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -123,8 +122,7 @@ describe("Connections Alias", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -138,8 +136,7 @@ describe("Connections Alias", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this5, edge.relationship AS this4 - WITH collect({ screenTime: this4.screenTime, node: { name: this5.name } }) AS edges - RETURN edges AS var6 + RETURN collect({ screenTime: this4.screenTime, node: { name: this5.name } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } diff --git a/packages/graphql/tests/tck/connections/filtering/composite.test.ts b/packages/graphql/tests/tck/connections/filtering/composite.test.ts index 5d566062e10..eb457f2527b 100644 --- a/packages/graphql/tests/tck/connections/filtering/composite.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/composite.test.ts @@ -87,8 +87,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -150,8 +149,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -215,8 +213,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -282,8 +279,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -354,8 +350,7 @@ describe("Cypher -> Connections -> Filtering -> Composite", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts index 5c906d37965..d5ad9a066b4 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/and.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -129,8 +128,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts index d5ffac01c51..491268beaf6 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/arrays.test.ts @@ -80,8 +80,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -129,8 +128,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -179,8 +177,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -226,8 +223,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, favouriteColours: this1.favouriteColours } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts index a05c0d4a9c5..fd33fba8724 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/equality.test.ts @@ -79,8 +79,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -125,8 +124,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Equality", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts index 7db3e9afd19..0bdc9316130 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/numerical.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -131,8 +130,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -181,8 +179,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -231,8 +228,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Numerical", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, age: this1.age } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts index c5f1124a1d4..9a22042b0cf 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/or.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> OR", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { firstName: this1.firstName, lastName: this1.lastName } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts index a1dc80b3419..8459e2474b3 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/points.test.ts @@ -97,11 +97,10 @@ describe("Cypher -> Connections -> Filtering -> Node -> Points", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, currentLocation: CASE + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, currentLocation: CASE WHEN this1.currentLocation IS NOT NULL THEN { point: this1.currentLocation } ELSE NULL - END } }) AS edges - RETURN edges AS var2 + END } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts index 9d25524adc6..39807057a33 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/relationship.test.ts @@ -77,8 +77,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> Relationship", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { name: this1.name } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { name: this1.name } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } diff --git a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts index d61bf86253c..4ef8c226361 100644 --- a/packages/graphql/tests/tck/connections/filtering/node/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/node/string.test.ts @@ -97,8 +97,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -143,8 +142,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -189,8 +187,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -235,8 +232,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -281,8 +277,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -327,8 +322,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -373,8 +367,7 @@ describe("Cypher -> Connections -> Filtering -> Node -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts index 8dae794e0de..f6d9ef839fa 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/and.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -132,8 +131,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> AND", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts index 4b8f82a54c2..7c8fae7e14e 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/arrays.test.ts @@ -80,8 +80,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -135,8 +134,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -190,8 +188,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -236,8 +233,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Arrays", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts index 32e69f6b648..15a6a60eafe 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/equality.test.ts @@ -79,8 +79,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -128,8 +127,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Equality", () => WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts index 44bba6d05ff..01e9fe2f16b 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/numerical.test.ts @@ -79,8 +79,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -128,8 +127,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -177,8 +175,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -226,8 +223,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Numerical", () = WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts index 867015de762..236389c1825 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/or.test.ts @@ -81,8 +81,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> OR", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts index de08fd5e2ee..bc1eec7044e 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/points.test.ts @@ -95,11 +95,10 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Points", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, location: CASE + RETURN collect({ screenTime: this0.screenTime, location: CASE WHEN this0.location IS NOT NULL THEN { point: this0.location } ELSE NULL - END, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + END, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts index 3bc16f8ab9b..81f6fdf96a2 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/string.test.ts @@ -97,8 +97,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -143,8 +142,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -189,8 +187,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -235,8 +232,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -281,8 +277,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -327,8 +322,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -373,8 +367,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> String", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ role: this0.role, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ role: this0.role, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts index b93a0432b11..8007ca2a7a1 100644 --- a/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts +++ b/packages/graphql/tests/tck/connections/filtering/relationship/temporal.test.ts @@ -83,8 +83,7 @@ describe("Cypher -> Connections -> Filtering -> Relationship -> Temporal", () => WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ startDate: this0.startDate, endDateTime: apoc.date.convertFormat(toString(this0.endDateTime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ startDate: this0.startDate, endDateTime: apoc.date.convertFormat(toString(this0.endDateTime), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts index b16f41d9392..7b286002e6b 100644 --- a/packages/graphql/tests/tck/connections/mixed-nesting.test.ts +++ b/packages/graphql/tests/tck/connections/mixed-nesting.test.ts @@ -90,8 +90,7 @@ describe("Mixed nesting", () => { WITH this3 { .title } AS this3 RETURN collect(this3) AS var4 } - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, movies: var4 } }) AS edges - RETURN edges AS var5 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, movies: var4 } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 } @@ -166,13 +165,11 @@ describe("Mixed nesting", () => { WITH this5 { .name } AS this5 RETURN collect(this5) AS var6 } - WITH collect({ node: { title: this3.title, actors: var6 } }) AS edges - RETURN edges AS var7 + RETURN collect({ node: { title: this3.title, actors: var6 } }) AS var7 } RETURN { edges: var7, totalCount: totalCount } AS var8 } - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var8 } }) AS edges - RETURN edges AS var9 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var8 } }) AS var9 } RETURN { edges: var9, totalCount: totalCount } AS var10 } @@ -228,8 +225,7 @@ describe("Mixed nesting", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH collect({ screenTime: this2.screenTime, node: { title: this3.title } }) AS edges - RETURN edges AS var4 + RETURN collect({ screenTime: this2.screenTime, node: { title: this3.title } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } diff --git a/packages/graphql/tests/tck/connections/projections/create.test.ts b/packages/graphql/tests/tck/connections/projections/create.test.ts index 9342f8c7fbe..dde6173cd36 100644 --- a/packages/graphql/tests/tck/connections/projections/create.test.ts +++ b/packages/graphql/tests/tck/connections/projections/create.test.ts @@ -87,8 +87,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS edges - RETURN edges AS create_var4 + RETURN collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } @@ -146,8 +145,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS edges - RETURN edges AS create_var4 + RETURN collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } @@ -209,8 +207,7 @@ describe("Cypher -> Connections -> Projections -> Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS edges - RETURN edges AS create_var4 + RETURN collect({ screenTime: create_this2.screenTime, node: { name: create_this3.name } }) AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } diff --git a/packages/graphql/tests/tck/connections/projections/projections.test.ts b/packages/graphql/tests/tck/connections/projections/projections.test.ts index 31258ef1fe8..d1de0a310ec 100644 --- a/packages/graphql/tests/tck/connections/projections/projections.test.ts +++ b/packages/graphql/tests/tck/connections/projections/projections.test.ts @@ -77,8 +77,7 @@ describe("Relay Cursor Connection projections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -123,8 +122,7 @@ describe("Relay Cursor Connection projections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -166,8 +164,7 @@ describe("Relay Cursor Connection projections", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"Actor\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -309,8 +306,7 @@ describe("Relay Cursor Connection projections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -357,8 +353,7 @@ describe("Relay Cursor Connection projections", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH collect({ node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/connections/relationship-properties.test.ts b/packages/graphql/tests/tck/connections/relationship-properties.test.ts index be047c88d19..1a53442b58d 100644 --- a/packages/graphql/tests/tck/connections/relationship-properties.test.ts +++ b/packages/graphql/tests/tck/connections/relationship-properties.test.ts @@ -80,8 +80,7 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -127,8 +126,7 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -176,8 +174,7 @@ describe("Relationship Properties Cypher", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this0.screenTime DESC - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -222,8 +219,7 @@ describe("Relationship Properties Cypher", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this0.year DESC, this1.name ASC - WITH collect({ year: this0.year, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ year: this0.year, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -263,8 +259,7 @@ describe("Relationship Properties Cypher", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this1.name ASC, this0.year DESC - WITH collect({ year: this0.year, node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ year: this0.year, node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -322,13 +317,11 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH collect({ screenTime: this2.screenTime, node: { title: this3.title } }) AS edges - RETURN edges AS var4 + RETURN collect({ screenTime: this2.screenTime, node: { title: this3.title } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var5 } }) AS edges - RETURN edges AS var6 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var5 } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } @@ -407,18 +400,15 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this5, edge.relationship AS this4 - WITH collect({ screenTime: this4.screenTime, node: { name: this5.name } }) AS edges - RETURN edges AS var6 + RETURN collect({ screenTime: this4.screenTime, node: { name: this5.name } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } - WITH collect({ screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var7 } }) AS edges - RETURN edges AS var8 + RETURN collect({ screenTime: this2.screenTime, node: { title: this3.title, actorsConnection: var7 } }) AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } - WITH collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var9 } }) AS edges - RETURN edges AS var10 + RETURN collect({ screenTime: this0.screenTime, node: { name: this1.name, moviesConnection: var9 } }) AS var10 } RETURN { edges: var10, totalCount: totalCount } AS var11 } diff --git a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts index ab6b9b536cf..6d5a5329aa1 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/connect.test.ts @@ -104,8 +104,7 @@ describe("Relationship Properties Connect Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges - RETURN edges AS create_var2 + RETURN collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } @@ -190,8 +189,7 @@ describe("Relationship Properties Connect Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges - RETURN edges AS create_var2 + RETURN collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } diff --git a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts index 0847099615f..9a11eebdedb 100644 --- a/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts +++ b/packages/graphql/tests/tck/connections/relationship_properties/create.test.ts @@ -107,8 +107,7 @@ describe("Relationship Properties Create Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this9, edge.relationship AS create_this8 - WITH collect({ screenTime: create_this8.screenTime, node: { name: create_this9.name } }) AS edges - RETURN edges AS create_var10 + RETURN collect({ screenTime: create_this8.screenTime, node: { name: create_this9.name } }) AS create_var10 } RETURN { edges: create_var10, totalCount: totalCount } AS create_var11 } diff --git a/packages/graphql/tests/tck/connections/sort.test.ts b/packages/graphql/tests/tck/connections/sort.test.ts index d8a129a2c4e..57d8ecf9aa2 100644 --- a/packages/graphql/tests/tck/connections/sort.test.ts +++ b/packages/graphql/tests/tck/connections/sort.test.ts @@ -96,13 +96,11 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH collect({ node: { name: this2.name } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { name: this2.name } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } - WITH collect({ node: { title: this0.title, actorsConnection: var4 } }) AS edges - RETURN edges AS var5 + RETURN collect({ node: { title: this0.title, actorsConnection: var4 } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS this" `); @@ -169,13 +167,11 @@ describe("Relationship Properties Cypher", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH collect({ node: { name: this3.name } }) AS edges - RETURN edges AS var4 + RETURN collect({ node: { name: this3.name } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH collect({ node: { title: this0.title, actorsConnection: var5 } }) AS edges - RETURN edges AS var6 + RETURN collect({ node: { title: this0.title, actorsConnection: var5 } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/alias.test.ts b/packages/graphql/tests/tck/directives/alias.test.ts index d64aa92a570..5324df4c731 100644 --- a/packages/graphql/tests/tck/directives/alias.test.ts +++ b/packages/graphql/tests/tck/directives/alias.test.ts @@ -113,8 +113,7 @@ describe("Cypher alias directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ character: this0.characterPropInDb, screenTime: this0.screenTime, node: { title: this1.title, rating: this1.ratingPropInDb } }) AS edges - RETURN edges AS var2 + RETURN collect({ character: this0.characterPropInDb, screenTime: this0.screenTime, node: { title: this1.title, rating: this1.ratingPropInDb } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -205,8 +204,7 @@ describe("Cypher alias directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this12, edge.relationship AS create_this11 - WITH collect({ character: create_this11.characterPropInDb, screenTime: create_this11.screenTime, node: { title: create_this12.title, rating: create_this12.ratingPropInDb } }) AS edges - RETURN edges AS create_var13 + RETURN collect({ character: create_this11.characterPropInDb, screenTime: create_this11.screenTime, node: { title: create_this12.title, rating: create_this12.ratingPropInDb } }) AS create_var13 } RETURN { edges: create_var13, totalCount: totalCount } AS create_var14 } diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts index 2d13fa5096b..d33b0a7e154 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts @@ -238,8 +238,7 @@ describe("Cypher Auth Where with Roles", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { content: this1.content } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { content: this1.content } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } @@ -298,8 +297,7 @@ describe("Cypher Auth Where with Roles", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { content: this1.content } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { content: this1.content } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index f69b4be660b..95f7b89e63a 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -582,8 +582,7 @@ describe("Connection auth filter", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH collect({ node: { id: this0.id, contentConnection: var4 } }) AS edges - RETURN edges AS var5 + RETURN collect({ node: { id: this0.id, contentConnection: var4 } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index b17143c1304..5fa5be62e4c 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -227,8 +227,7 @@ describe("Cypher Auth Where", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { content: this1.content } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { content: this1.content } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } @@ -286,8 +285,7 @@ describe("Cypher Auth Where", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { content: this1.content } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { content: this1.content } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts index 244471937c1..aee46636174 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection-union.test.ts @@ -110,8 +110,7 @@ describe("Cypher Auth Projection On Connections On Unions", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this4, edge.relationship AS this3 - WITH collect({ node: { name: this4.name } }) AS edges - RETURN edges AS var5 + RETURN collect({ node: { name: this4.name } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 } diff --git a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts index 94feb50d8bf..3b80fbb2032 100644 --- a/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/projection-connection.test.ts @@ -94,8 +94,7 @@ describe("Cypher Auth Projection On Connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { content: this1.content } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { content: this1.content } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } @@ -168,13 +167,11 @@ describe("Cypher Auth Projection On Connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this4, edge.relationship AS this3 - WITH collect({ node: { name: this4.name } }) AS edges - RETURN edges AS var5 + RETURN collect({ node: { name: this4.name } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 } - WITH collect({ node: { content: this1.content, creatorConnection: var6 } }) AS edges - RETURN edges AS var7 + RETURN collect({ node: { content: this1.content, creatorConnection: var6 } }) AS var7 } RETURN { edges: var7, totalCount: totalCount } AS var8 } @@ -273,13 +270,11 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH collect({ node: { content: this2.content } }) AS edges - RETURN edges AS var4 + RETURN collect({ node: { content: this2.content } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH collect({ node: { name: this0.name, postsConnection: var5 } }) AS edges - RETURN edges AS var6 + RETURN collect({ node: { name: this0.name, postsConnection: var5 } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS this" `); @@ -359,18 +354,15 @@ describe("Cypher Auth Projection On top-level connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this5, edge.relationship AS this4 - WITH collect({ node: { name: this5.name } }) AS edges - RETURN edges AS var6 + RETURN collect({ node: { name: this5.name } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } - WITH collect({ node: { content: this2.content, creatorConnection: var7 } }) AS edges - RETURN edges AS var8 + RETURN collect({ node: { content: this2.content, creatorConnection: var7 } }) AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } - WITH collect({ node: { name: this0.name, postsConnection: var9 } }) AS edges - RETURN edges AS var10 + RETURN collect({ node: { name: this0.name, postsConnection: var9 } }) AS var10 } RETURN { edges: var10, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/directives/coalesce.test.ts b/packages/graphql/tests/tck/directives/coalesce.test.ts index 2b58b326fd4..6bd0cf81f42 100644 --- a/packages/graphql/tests/tck/directives/coalesce.test.ts +++ b/packages/graphql/tests/tck/directives/coalesce.test.ts @@ -221,8 +221,7 @@ describe("Cypher coalesce()", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { id: this1.id, status: this1.status } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { id: this1.id, status: this1.status } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -285,8 +284,7 @@ describe("Cypher coalesce()", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { id: this1.id, statuses: this1.statuses } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { id: this1.id, statuses: this1.statuses } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/directives/node/node-label.test.ts b/packages/graphql/tests/tck/directives/node/node-label.test.ts index 969e6fc0eed..3831d73378d 100644 --- a/packages/graphql/tests/tck/directives/node/node-label.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-label.test.ts @@ -121,8 +121,7 @@ describe("Label in Node directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts index d1b3c61fbca..973369ee3df 100644 --- a/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts +++ b/packages/graphql/tests/tck/directives/node/node-with-auth-projection.test.ts @@ -90,8 +90,7 @@ describe("Cypher Auth Projection On Connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { content: this1.content } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { content: this1.content } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } diff --git a/packages/graphql/tests/tck/issues/1150.test.ts b/packages/graphql/tests/tck/issues/1150.test.ts index fca9356e7f4..15b02b5c6e4 100644 --- a/packages/graphql/tests/tck/issues/1150.test.ts +++ b/packages/graphql/tests/tck/issues/1150.test.ts @@ -138,8 +138,7 @@ describe("https://github.com/neo4j/graphql/issues/1150", () => { WITH edges, size(edges) AS totalCount RETURN { edges: edges, totalCount: totalCount } AS var6 } - WITH collect({ node: { driveComponentConnection: var6 } }) AS edges - RETURN edges AS var7 + RETURN collect({ node: { driveComponentConnection: var6 } }) AS var7 } RETURN { edges: var7, totalCount: totalCount } AS var8 } diff --git a/packages/graphql/tests/tck/issues/1221.test.ts b/packages/graphql/tests/tck/issues/1221.test.ts index dd755ec3daa..830337307a3 100644 --- a/packages/graphql/tests/tck/issues/1221.test.ts +++ b/packages/graphql/tests/tck/issues/1221.test.ts @@ -107,13 +107,11 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this7, edge.relationship AS this6 - WITH collect({ node: { fullName: this7.fullName } }) AS edges - RETURN edges AS var8 + RETURN collect({ node: { fullName: this7.fullName } }) AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } - WITH collect({ node: { nameDetailsConnection: var9 } }) AS edges - RETURN edges AS var10 + RETURN collect({ node: { nameDetailsConnection: var9 } }) AS var10 } RETURN { edges: var10, totalCount: totalCount } AS var11 } @@ -240,18 +238,15 @@ describe("https://github.com/neo4j/graphql/issues/1221", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this11, edge.relationship AS this10 - WITH collect({ node: { fullName: this11.fullName } }) AS edges - RETURN edges AS var12 + RETURN collect({ node: { fullName: this11.fullName } }) AS var12 } RETURN { edges: var12, totalCount: totalCount } AS var13 } - WITH collect({ node: { nameDetailsConnection: var13 } }) AS edges - RETURN edges AS var14 + RETURN collect({ node: { nameDetailsConnection: var13 } }) AS var14 } RETURN { edges: var14, totalCount: totalCount } AS var15 } - WITH collect({ node: { architectureConnection: var15 } }) AS edges - RETURN edges AS var16 + RETURN collect({ node: { architectureConnection: var15 } }) AS var16 } RETURN { edges: var16, totalCount: totalCount } AS var17 } diff --git a/packages/graphql/tests/tck/issues/1249.test.ts b/packages/graphql/tests/tck/issues/1249.test.ts index c66f087951e..6303612cb94 100644 --- a/packages/graphql/tests/tck/issues/1249.test.ts +++ b/packages/graphql/tests/tck/issues/1249.test.ts @@ -94,8 +94,7 @@ describe("https://github.com/neo4j/graphql/issues/1249", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH collect({ supplierMaterialNumber: this2.supplierMaterialNumber, node: { supplierId: this3.supplierId } }) AS edges - RETURN edges AS var4 + RETURN collect({ supplierMaterialNumber: this2.supplierMaterialNumber, node: { supplierId: this3.supplierId } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } diff --git a/packages/graphql/tests/tck/issues/1364.test.ts b/packages/graphql/tests/tck/issues/1364.test.ts index 2b5519fcc79..3b5ae6c01f4 100644 --- a/packages/graphql/tests/tck/issues/1364.test.ts +++ b/packages/graphql/tests/tck/issues/1364.test.ts @@ -113,8 +113,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { UNWIND result AS this1 RETURN head(collect(this1)) AS this1 } - WITH collect({ node: { title: this0.title, totalGenres: this1 } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { title: this0.title, totalGenres: this1 } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS this" `); @@ -157,8 +156,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { } WITH * ORDER BY this1 ASC - WITH collect({ node: { title: this0.title, totalGenres: this1 } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { title: this0.title, totalGenres: this1 } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS this" `); @@ -213,8 +211,7 @@ describe("https://github.com/neo4j/graphql/issues/1364", () => { UNWIND result AS this2 RETURN head(collect(this2)) AS this2 } - WITH collect({ node: { title: this0.title, totalGenres: this1, totalActors: this2 } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { title: this0.title, totalGenres: this1, totalActors: this2 } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/1528.test.ts b/packages/graphql/tests/tck/issues/1528.test.ts index 2876eeb23fb..5fc763201bc 100644 --- a/packages/graphql/tests/tck/issues/1528.test.ts +++ b/packages/graphql/tests/tck/issues/1528.test.ts @@ -93,8 +93,7 @@ describe("https://github.com/neo4j/graphql/issues/1528", () => { } WITH * ORDER BY this2 DESC - WITH collect({ node: { title: this1.title, actorsCount: this2 } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { title: this1.title, actorsCount: this2 } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } diff --git a/packages/graphql/tests/tck/issues/1760.test.ts b/packages/graphql/tests/tck/issues/1760.test.ts index 76b896c13e7..b90b290b0b8 100644 --- a/packages/graphql/tests/tck/issues/1760.test.ts +++ b/packages/graphql/tests/tck/issues/1760.test.ts @@ -159,8 +159,7 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH collect({ node: { fullName: this2.fullName } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { fullName: this2.fullName } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } @@ -184,13 +183,11 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this8, edge.relationship AS this7 - WITH collect({ node: { fullName: this8.fullName } }) AS edges - RETURN edges AS var9 + RETURN collect({ node: { fullName: this8.fullName } }) AS var9 } RETURN { edges: var9, totalCount: totalCount } AS var10 } - WITH collect({ node: { nameDetailsConnection: var10 } }) AS edges - RETURN edges AS var11 + RETURN collect({ node: { nameDetailsConnection: var10 } }) AS var11 } RETURN { edges: var11, totalCount: totalCount } AS var12 } @@ -204,8 +201,7 @@ describe("https://github.com/neo4j/graphql/issues/1760", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this14, edge.relationship AS this13 - WITH collect({ node: { id: this14.id } }) AS edges - RETURN edges AS var15 + RETURN collect({ node: { id: this14.id } }) AS var15 } RETURN { edges: var15, totalCount: totalCount } AS var16 } diff --git a/packages/graphql/tests/tck/issues/1783.test.ts b/packages/graphql/tests/tck/issues/1783.test.ts index ca0736750e0..adf9276b2d1 100644 --- a/packages/graphql/tests/tck/issues/1783.test.ts +++ b/packages/graphql/tests/tck/issues/1783.test.ts @@ -132,8 +132,7 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this7, edge.relationship AS this6 - WITH collect({ node: { fullName: this7.fullName } }) AS edges - RETURN edges AS var8 + RETURN collect({ node: { fullName: this7.fullName } }) AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } @@ -157,13 +156,11 @@ describe("https://github.com/neo4j/graphql/issues/1783", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this13, edge.relationship AS this12 - WITH collect({ node: { fullName: this13.fullName } }) AS edges - RETURN edges AS var14 + RETURN collect({ node: { fullName: this13.fullName } }) AS var14 } RETURN { edges: var14, totalCount: totalCount } AS var15 } - WITH collect({ node: { nameDetailsConnection: var15 } }) AS edges - RETURN edges AS var16 + RETURN collect({ node: { nameDetailsConnection: var15 } }) AS var16 } RETURN { edges: var16, totalCount: totalCount } AS var17 } diff --git a/packages/graphql/tests/tck/issues/2022.test.ts b/packages/graphql/tests/tck/issues/2022.test.ts index d83388efd80..3ab59de2ad3 100644 --- a/packages/graphql/tests/tck/issues/2022.test.ts +++ b/packages/graphql/tests/tck/issues/2022.test.ts @@ -115,8 +115,7 @@ describe("https://github.com/neo4j/graphql/issues/2022", () => { WITH this8 { .name, dbId: this8.id } AS this8 RETURN head(collect(this8)) AS var9 } - WITH collect({ node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } }) AS edges - RETURN edges AS var10 + RETURN collect({ node: { dbId: this0.id, title: this0.title, auction: var6, owner: var9 } }) AS var10 } RETURN { edges: var10, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/issues/2262.test.ts b/packages/graphql/tests/tck/issues/2262.test.ts index 8b2222490a6..6ad8b5a6bec 100644 --- a/packages/graphql/tests/tck/issues/2262.test.ts +++ b/packages/graphql/tests/tck/issues/2262.test.ts @@ -93,13 +93,11 @@ describe("https://github.com/neo4j/graphql/issues/2262", () => { WITH edge.node AS this3, edge.relationship AS this2 WITH * ORDER BY this3.uuid DESC - WITH collect({ node: { uuid: this3.uuid } }) AS edges - RETURN edges AS var4 + RETURN collect({ node: { uuid: this3.uuid } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } - WITH collect({ node: { uuid: this1.uuid, componentInputsConnection: var5 } }) AS edges - RETURN edges AS var6 + RETURN collect({ node: { uuid: this1.uuid, componentInputsConnection: var5 } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } diff --git a/packages/graphql/tests/tck/issues/2437.test.ts b/packages/graphql/tests/tck/issues/2437.test.ts index 6cdf7a59738..6f122af6ea1 100644 --- a/packages/graphql/tests/tck/issues/2437.test.ts +++ b/packages/graphql/tests/tck/issues/2437.test.ts @@ -94,8 +94,7 @@ describe("https://github.com/neo4j/graphql/issues/2437", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param2 - WITH collect({ node: { uuid: this1.uuid } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { uuid: this1.uuid } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/issues/3394.test.ts b/packages/graphql/tests/tck/issues/3394.test.ts index fbc1b9f490d..e0580370e2c 100644 --- a/packages/graphql/tests/tck/issues/3394.test.ts +++ b/packages/graphql/tests/tck/issues/3394.test.ts @@ -122,8 +122,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH edge.node AS this0 WITH * ORDER BY this0.fg_item DESC - WITH collect({ node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } }) AS edges - RETURN edges AS var1 + RETURN collect({ node: { id: this0.fg_item_id, partNumber: this0.fg_item, description: this0.description } }) AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" `); @@ -163,8 +162,7 @@ describe("https://github.com/neo4j/graphql/issues/3394", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * ORDER BY this1.fg_item DESC - WITH collect({ node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { id: this1.fg_item_id, partNumber: this1.fg_item, description: this1.description } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/issues/4007.test.ts b/packages/graphql/tests/tck/issues/4007.test.ts index 180a5fc6110..c22e9275314 100644 --- a/packages/graphql/tests/tck/issues/4007.test.ts +++ b/packages/graphql/tests/tck/issues/4007.test.ts @@ -72,8 +72,7 @@ describe("https://github.com/neo4j/graphql/issues/4007", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { na: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { na: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/issues/4015.test.ts b/packages/graphql/tests/tck/issues/4015.test.ts index f728762873c..330302638ca 100644 --- a/packages/graphql/tests/tck/issues/4015.test.ts +++ b/packages/graphql/tests/tck/issues/4015.test.ts @@ -76,8 +76,7 @@ describe("https://github.com/neo4j/graphql/issues/4015", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { surname: this1.surname, name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { surname: this1.surname, name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/issues/4292.test.ts b/packages/graphql/tests/tck/issues/4292.test.ts index 0c483f1ea5d..63a37314dac 100644 --- a/packages/graphql/tests/tck/issues/4292.test.ts +++ b/packages/graphql/tests/tck/issues/4292.test.ts @@ -254,8 +254,7 @@ describe("https://github.com/neo4j/graphql/issues/4292", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this13, edge.relationship AS this12 - WITH collect({ active: this12.active, firstDay: this12.firstDay, lastDay: this12.lastDay, node: { __resolveType: \\"Person\\", __id: id(this13) } }) AS edges - RETURN edges AS var25 + RETURN collect({ active: this12.active, firstDay: this12.firstDay, lastDay: this12.lastDay, node: { __resolveType: \\"Person\\", __id: id(this13) } }) AS var25 } RETURN { edges: var25, totalCount: totalCount } AS var26 } diff --git a/packages/graphql/tests/tck/issues/433.test.ts b/packages/graphql/tests/tck/issues/433.test.ts index 9b3dae9b805..d5215801332 100644 --- a/packages/graphql/tests/tck/issues/433.test.ts +++ b/packages/graphql/tests/tck/issues/433.test.ts @@ -73,8 +73,7 @@ describe("#413", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { name: this1.name } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { name: this1.name } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/issues/601.test.ts b/packages/graphql/tests/tck/issues/601.test.ts index 340d1da3605..330bf50b354 100644 --- a/packages/graphql/tests/tck/issues/601.test.ts +++ b/packages/graphql/tests/tck/issues/601.test.ts @@ -111,8 +111,7 @@ describe("#601", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this3, edge.relationship AS this2 - WITH collect({ fileId: this2.fileId, uploadedAt: apoc.date.convertFormat(toString(this2.uploadedAt), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { __resolveType: \\"CustomerContact\\", __id: id(this3) } }) AS edges - RETURN edges AS var4 + RETURN collect({ fileId: this2.fileId, uploadedAt: apoc.date.convertFormat(toString(this2.uploadedAt), \\"iso_zoned_date_time\\", \\"iso_offset_date_time\\"), node: { __resolveType: \\"CustomerContact\\", __id: id(this3) } }) AS var4 } RETURN { edges: var4, totalCount: totalCount } AS var5 } diff --git a/packages/graphql/tests/tck/issues/630.test.ts b/packages/graphql/tests/tck/issues/630.test.ts index a36dbfd49b8..d5153cab424 100644 --- a/packages/graphql/tests/tck/issues/630.test.ts +++ b/packages/graphql/tests/tck/issues/630.test.ts @@ -87,8 +87,7 @@ describe("Cypher directive", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH collect({ node: { __resolveType: \\"Actor\\", __id: id(this2) } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { __resolveType: \\"Actor\\", __id: id(this2) } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } diff --git a/packages/graphql/tests/tck/issues/988.test.ts b/packages/graphql/tests/tck/issues/988.test.ts index bdcab3e7444..c37206851ee 100644 --- a/packages/graphql/tests/tck/issues/988.test.ts +++ b/packages/graphql/tests/tck/issues/988.test.ts @@ -151,8 +151,7 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this7, edge.relationship AS this6 - WITH collect({ current: this6.current, node: { name: this7.name } }) AS edges - RETURN edges AS var8 + RETURN collect({ current: this6.current, node: { name: this7.name } }) AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } @@ -165,8 +164,7 @@ describe("https://github.com/neo4j/graphql/issues/988", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this11, edge.relationship AS this10 - WITH collect({ current: this10.current, node: { name: this11.name } }) AS edges - RETURN edges AS var12 + RETURN collect({ current: this10.current, node: { name: this11.name } }) AS var12 } RETURN { edges: var12, totalCount: totalCount } AS var13 } diff --git a/packages/graphql/tests/tck/operations/create.test.ts b/packages/graphql/tests/tck/operations/create.test.ts index e2f6a02adb4..0dedf52fc3f 100644 --- a/packages/graphql/tests/tck/operations/create.test.ts +++ b/packages/graphql/tests/tck/operations/create.test.ts @@ -423,8 +423,7 @@ describe("Cypher Create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this3, edge.relationship AS create_this2 - WITH collect({ node: { name: create_this3.name } }) AS edges - RETURN edges AS create_var4 + RETURN collect({ node: { name: create_this3.name } }) AS create_var4 } RETURN { edges: create_var4, totalCount: totalCount } AS create_var5 } diff --git a/packages/graphql/tests/tck/rfcs/query-limits.test.ts b/packages/graphql/tests/tck/rfcs/query-limits.test.ts index 6c59450ebc4..a843f11b939 100644 --- a/packages/graphql/tests/tck/rfcs/query-limits.test.ts +++ b/packages/graphql/tests/tck/rfcs/query-limits.test.ts @@ -214,8 +214,7 @@ describe("tck/rfcs/query-limits", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH collect({ node: { id: this1.id } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { id: this1.id } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -269,8 +268,7 @@ describe("tck/rfcs/query-limits", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param1 - WITH collect({ node: { id: this1.id } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { id: this1.id } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -322,8 +320,7 @@ describe("tck/rfcs/query-limits", () => { WITH edge.node AS this1, edge.relationship AS this0 WITH * LIMIT $param0 - WITH collect({ node: { id: this1.id } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { id: this1.id } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/root-connection.test.ts b/packages/graphql/tests/tck/root-connection.test.ts index 43f9d26754b..814bef532d8 100644 --- a/packages/graphql/tests/tck/root-connection.test.ts +++ b/packages/graphql/tests/tck/root-connection.test.ts @@ -70,8 +70,7 @@ describe("Root Connection Query tests", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this0 - WITH collect({ node: { title: this0.title } }) AS edges - RETURN edges AS var1 + RETURN collect({ node: { title: this0.title } }) AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" `); @@ -109,8 +108,7 @@ describe("Root Connection Query tests", () => { WITH * ORDER BY this0.title ASC LIMIT $param0 - WITH collect({ node: { title: this0.title } }) AS edges - RETURN edges AS var1 + RETURN collect({ node: { title: this0.title } }) AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" `); @@ -149,8 +147,7 @@ describe("Root Connection Query tests", () => { WITH * ORDER BY this0.title ASC LIMIT $param1 - WITH collect({ node: { title: this0.title } }) AS edges - RETURN edges AS var1 + RETURN collect({ node: { title: this0.title } }) AS var1 } RETURN { edges: var1, totalCount: totalCount } AS this" `); @@ -205,13 +202,11 @@ describe("Root Connection Query tests", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this2, edge.relationship AS this1 - WITH collect({ node: { name: this2.name } }) AS edges - RETURN edges AS var3 + RETURN collect({ node: { name: this2.name } }) AS var3 } RETURN { edges: var3, totalCount: totalCount } AS var4 } - WITH collect({ node: { title: this0.title, actorsConnection: var4 } }) AS edges - RETURN edges AS var5 + RETURN collect({ node: { title: this0.title, actorsConnection: var4 } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS this" `); diff --git a/packages/graphql/tests/tck/sort.test.ts b/packages/graphql/tests/tck/sort.test.ts index f973d98bcec..6d2eab9ebad 100644 --- a/packages/graphql/tests/tck/sort.test.ts +++ b/packages/graphql/tests/tck/sort.test.ts @@ -482,13 +482,11 @@ describe("Cypher sort tests", () => { UNWIND sum AS this4 RETURN head(collect(this4)) AS this4 } - WITH collect({ node: { name: this3.name, totalScreenTime: this4 } }) AS edges - RETURN edges AS var5 + RETURN collect({ node: { name: this3.name, totalScreenTime: this4 } }) AS var5 } RETURN { edges: var5, totalCount: totalCount } AS var6 } - WITH collect({ node: { title: this0.title, actorsConnection: var6 } }) AS edges - RETURN edges AS var7 + RETURN collect({ node: { title: this0.title, actorsConnection: var6 } }) AS var7 } RETURN { edges: var7, totalCount: totalCount } AS this" `); @@ -577,13 +575,11 @@ describe("Cypher sort tests", () => { UNWIND sum AS this5 RETURN head(collect(this5)) AS this5 } - WITH collect({ node: { name: this4.name, totalScreenTime: this5 } }) AS edges - RETURN edges AS var6 + RETURN collect({ node: { name: this4.name, totalScreenTime: this5 } }) AS var6 } RETURN { edges: var6, totalCount: totalCount } AS var7 } - WITH collect({ node: { title: this1.title, actorsConnection: var7 } }) AS edges - RETURN edges AS var8 + RETURN collect({ node: { title: this1.title, actorsConnection: var7 } }) AS var8 } RETURN { edges: var8, totalCount: totalCount } AS var9 } diff --git a/packages/graphql/tests/tck/subscriptions/create.test.ts b/packages/graphql/tests/tck/subscriptions/create.test.ts index e679ebebe46..ebfbcd6666d 100644 --- a/packages/graphql/tests/tck/subscriptions/create.test.ts +++ b/packages/graphql/tests/tck/subscriptions/create.test.ts @@ -128,8 +128,7 @@ describe("Subscriptions metadata on create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges - RETURN edges AS create_var2 + RETURN collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } @@ -217,8 +216,7 @@ describe("Subscriptions metadata on create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH collect({ node: { name: create_this1.name } }) AS edges - RETURN edges AS create_var2 + RETURN collect({ node: { name: create_this1.name } }) AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } @@ -331,8 +329,7 @@ describe("Subscriptions metadata on create", () => { WITH edges UNWIND edges AS edge WITH edge.node AS create_this1, edge.relationship AS create_this0 - WITH collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS edges - RETURN edges AS create_var2 + RETURN collect({ screenTime: create_this0.screenTime, node: { name: create_this1.name } }) AS create_var2 } RETURN { edges: create_var2, totalCount: totalCount } AS create_var3 } diff --git a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts index 8a8382e91a1..52de48424f5 100644 --- a/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/query-direction-connection.test.ts @@ -61,8 +61,7 @@ describe("QueryDirection in relationships connection", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -106,8 +105,7 @@ describe("QueryDirection in relationships connection", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } @@ -150,8 +148,7 @@ describe("QueryDirection in relationships connection", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } diff --git a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts index f6b17e37515..4879717fe29 100644 --- a/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts +++ b/packages/graphql/tests/tck/undirected-relationships/undirected-connection.test.ts @@ -60,8 +60,7 @@ describe("Undirected connections", () => { WITH edges UNWIND edges AS edge WITH edge.node AS this1, edge.relationship AS this0 - WITH collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS edges - RETURN edges AS var2 + RETURN collect({ node: { __resolveType: \\"User\\", __id: id(this1) } }) AS var2 } RETURN { edges: var2, totalCount: totalCount } AS var3 } From 8870382fdeb2f3922cc160e1c59a036c238954eb Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 12 Dec 2023 10:41:38 +0000 Subject: [PATCH 047/136] Improve ConnectionReadOperation --- .../ast/operations/ConnectionReadOperation.ts | 26 +- .../where/connection-auth-filter.test.ts | 244 ++++++++++-------- 2 files changed, 150 insertions(+), 120 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts index 382913e0b74..d91fd0dc7b9 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ConnectionReadOperation.ts @@ -128,9 +128,13 @@ export class ConnectionReadOperation extends Operation { ); const edgesVar = new Cypher.NamedVariable("edges"); const totalCount = new Cypher.NamedVariable("totalCount"); - const edgesVar2 = new Cypher.Variable(); + const edgesProjectionVar = new Cypher.Variable(); - const unwindSubquery = this.getUnwindSubquery(nestedContext, edgesVar, edgesVar2); + const unwindAndProjectionSubquery = this.createUnwindAndProjectionSubquery( + nestedContext, + edgesVar, + edgesProjectionVar + ); let withWhere: Cypher.With | undefined; @@ -141,22 +145,22 @@ export class ConnectionReadOperation extends Operation { this.addFiltersToClause(selectionClause, nestedContext); } - const edgeMap1 = new Cypher.Map({ + const nodeAndRelationshipMap = new Cypher.Map({ node: nestedContext.target, }); if (nestedContext.relationship) { - edgeMap1.set("relationship", nestedContext.relationship); + nodeAndRelationshipMap.set("relationship", nestedContext.relationship); } - const withCollectEdgesAndTotalCount = new Cypher.With([Cypher.collect(edgeMap1), edgesVar]).with(edgesVar, [ - Cypher.size(edgesVar), - totalCount, - ]); + const withCollectEdgesAndTotalCount = new Cypher.With([Cypher.collect(nodeAndRelationshipMap), edgesVar]).with( + edgesVar, + [Cypher.size(edgesVar), totalCount] + ); const returnClause = new Cypher.Return([ new Cypher.Map({ - edges: edgesVar2, + edges: edgesProjectionVar, totalCount: totalCount, }), context.returnVariable, @@ -170,7 +174,7 @@ export class ConnectionReadOperation extends Operation { ...authFilterSubqueries, withWhere, withCollectEdgesAndTotalCount, - unwindSubquery, + unwindAndProjectionSubquery, returnClause ), ], @@ -186,7 +190,7 @@ export class ConnectionReadOperation extends Operation { return filterTruthy(this.authFilters.map((f) => f.getPredicate(context))); } - private getUnwindSubquery( + private createUnwindAndProjectionSubquery( context: QueryASTContext, edgesVar: Cypher.Variable, returnVar: Cypher.Variable diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts index 95f7b89e63a..01a668a9e8a 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/connection-auth-filter.test.ts @@ -93,13 +93,15 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH { node: { id: this0.id } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + RETURN collect({ node: { id: this0.id } }) AS var1 + } + RETURN { edges: var1, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -136,13 +138,15 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE (this0.name = $param0 AND ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub))) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount - WITH { node: { id: this0.id } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + RETURN collect({ node: { id: this0.id } }) AS var1 + } + RETURN { edges: var1, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -183,24 +187,26 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) - WITH this2 { .content } AS this2 - RETURN collect(this2) AS var4 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WITH * + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH this2 { .content } AS this2 + RETURN collect(this2) AS var4 + } + RETURN collect({ node: { id: this0.id, posts: var4 } }) AS var5 } - WITH { node: { id: this0.id, posts: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -244,25 +250,32 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) - WITH { node: { content: this2.content } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH collect({ node: this2, relationship: this1 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + RETURN collect({ node: { content: this2.content } }) AS var4 + } + RETURN { edges: var4, totalCount: totalCount } AS var5 + } + RETURN collect({ node: { id: this0.id, postsConnection: var5 } }) AS var6 } - WITH { node: { id: this0.id, postsConnection: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var6, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -306,25 +319,32 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE (this2.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) - WITH { node: { content: this2.content } } AS edge - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE (this2.id = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) + WITH collect({ node: this2, relationship: this1 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this2, edge.relationship AS this1 + RETURN collect({ node: { content: this2.content } }) AS var4 + } + RETURN { edges: var4, totalCount: totalCount } AS var5 + } + RETURN collect({ node: { id: this0.id, postsConnection: var5 } }) AS var6 } - WITH { node: { id: this0.id, postsConnection: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var6, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -365,24 +385,26 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WITH * - WHERE (this2.content = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) - WITH this2 { .content } AS this2 - RETURN collect(this2) AS var4 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WITH * + WHERE (this2.content = $param2 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub)))) + WITH this2 { .content } AS this2 + RETURN collect(this2) AS var4 + } + RETURN collect({ node: { id: this0.id, posts: var4 } }) AS var5 } - WITH { node: { id: this0.id, posts: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -425,28 +447,30 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { - WITH * - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) - WITH this2 { .id, __resolveType: \\"Post\\", __id: id(this2) } AS this2 - RETURN this2 AS var4 + WITH this0 + CALL { + WITH * + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH this2 { .id, __resolveType: \\"Post\\", __id: id(this2) } AS this2 + RETURN this2 AS var4 + } + WITH var4 + RETURN collect(var4) AS var4 } - WITH var4 - RETURN collect(var4) AS var4 + RETURN collect({ node: { id: this0.id, content: var4 } }) AS var5 } - WITH { node: { id: this0.id, content: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -492,29 +516,31 @@ describe("Connection auth filter", () => { expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` "MATCH (this0:User) WHERE ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)) - WITH collect(this0) AS edges + WITH collect({ node: this0 }) AS edges WITH edges, size(edges) AS totalCount - UNWIND edges AS this0 - WITH this0, totalCount CALL { - WITH this0 + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 CALL { WITH this0 - MATCH (this0)-[this1:HAS_POST]->(this2:Post) - OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) - WITH *, count(this3) AS creatorCount - WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) - WITH { node: { __resolveType: \\"Post\\", __id: id(this2), id: this2.id } } AS edge - RETURN edge + CALL { + WITH this0 + MATCH (this0)-[this1:HAS_POST]->(this2:Post) + OPTIONAL MATCH (this2)<-[:HAS_POST]-(this3:User) + WITH *, count(this3) AS creatorCount + WITH * + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND this3.id = $jwt.sub))) + WITH { node: { __resolveType: \\"Post\\", __id: id(this2), id: this2.id } } AS edge + RETURN edge + } + WITH collect(edge) AS edges + WITH edges, size(edges) AS totalCount + RETURN { edges: edges, totalCount: totalCount } AS var4 } - WITH collect(edge) AS edges - WITH edges, size(edges) AS totalCount - RETURN { edges: edges, totalCount: totalCount } AS var4 + RETURN collect({ node: { id: this0.id, contentConnection: var4 } }) AS var5 } - WITH { node: { id: this0.id, contentConnection: var4 } } AS edge, totalCount, this0 - WITH collect(edge) AS edges, totalCount - RETURN { edges: edges, totalCount: totalCount } AS this" + RETURN { edges: var5, totalCount: totalCount } AS this" `); expect(formatParams(result.params)).toMatchInlineSnapshot(` @@ -530,7 +556,7 @@ describe("Connection auth filter", () => { `); }); - test.only("Read Union Using Connection + User Defined Where", async () => { + test("Read Union Using Connection + User Defined Where", async () => { const query = gql` { usersConnection { From 5d1298499d4355658799506862e4d77595a76b23 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 12 Dec 2023 11:07:02 +0000 Subject: [PATCH 048/136] Fix unit test --- packages/graphql/src/schema/resolvers/query/read.test.ts | 6 +----- .../src/translate/queryAST/factory/OperationFactory.ts | 2 -- packages/graphql/src/translate/translate-read.ts | 2 -- 3 files changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/graphql/src/schema/resolvers/query/read.test.ts b/packages/graphql/src/schema/resolvers/query/read.test.ts index 14d8788a605..4722e3e6f6c 100644 --- a/packages/graphql/src/schema/resolvers/query/read.test.ts +++ b/packages/graphql/src/schema/resolvers/query/read.test.ts @@ -17,16 +17,12 @@ * limitations under the License. */ -import { NodeBuilder } from "../../../../tests/utils/builders/node-builder"; import { ConcreteEntity } from "../../../schema-model/entity/ConcreteEntity"; import { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; import { findResolver } from "./read"; describe("Read resolver", () => { test("should return the correct; type, args and resolve", () => { - const node = new NodeBuilder({ - name: "Movie", - }).instance(); const concreteEntity = new ConcreteEntity({ name: "Movie", labels: ["Movie"], @@ -38,7 +34,7 @@ describe("Read resolver", () => { }); const concreteEntityAdapter = new ConcreteEntityAdapter(concreteEntity); - const result = findResolver({ node, entityAdapter: concreteEntityAdapter }); + const result = findResolver({ entityAdapter: concreteEntityAdapter }); expect(result.type).toBe(`[Movie!]!`); expect(result.resolve).toBeInstanceOf(Function); expect(result.args).toMatchObject({ diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index c46d7317fef..00f1e1aec9c 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -601,10 +601,8 @@ export class OperationsFactory { } else { selection = new NodeSelection({ target, - // alias: varName, }); } - // Add selection here const operation = new ConnectionReadOperation({ relationship, directed, target, selection }); return this.hydrateConnectionOperationAST({ diff --git a/packages/graphql/src/translate/translate-read.ts b/packages/graphql/src/translate/translate-read.ts index 78d3a69de79..1fb8202650f 100644 --- a/packages/graphql/src/translate/translate-read.ts +++ b/packages/graphql/src/translate/translate-read.ts @@ -44,6 +44,4 @@ export function translateRead( debug(operationsTree.print()); const clause = operationsTree.build(context, varName); return clause.build(); - // const clause = operationsTree.buildNew(context, varName); - // return clause.build(); } From 968ccc43f0135b093296ab4a558d7cb5b75d12df Mon Sep 17 00:00:00 2001 From: angrykoala Date: Tue, 12 Dec 2023 17:33:59 +0000 Subject: [PATCH 049/136] Remove unused code --- .../queryAST/ast/operations/ReadOperation.ts | 34 +------------------ packages/graphql/tests/tck/sort.test.ts | 28 --------------- 2 files changed, 1 insertion(+), 61 deletions(-) diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts index f8e86eca960..91d7060ed6e 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts @@ -196,30 +196,6 @@ export class ReadOperation extends Operation { return Cypher.and(...this.filters.map((f) => f.getPredicate(queryASTContext))); } - protected getSelectionClauses( - context: QueryASTContext, - node: Cypher.Node | Cypher.Pattern - ): { - preSelection: Array; - selectionClause: Cypher.Match | Cypher.With | Cypher.Yield; - } { - let matchClause: Cypher.Match | Cypher.With = new Cypher.Match(node); - - let extraMatches = this.getChildren().flatMap((f) => { - return f.getSelection(context); - }); - - if (extraMatches.length > 0) { - extraMatches = [matchClause, ...extraMatches]; - matchClause = new Cypher.With("*"); - } - - return { - preSelection: extraMatches, - selectionClause: matchClause, - }; - } - public transpile(context: QueryASTContext): OperationTranspileResult { if (this.relationship) { return this.transpileNestedRelationship(this.relationship, context); @@ -318,7 +294,7 @@ export class ReadOperation extends Operation { return { clauses: [clause], - projectionExpr: context.returnVariable, // this.getReturnExpression(nestedContext), + projectionExpr: context.returnVariable, }; } @@ -330,14 +306,6 @@ export class ReadOperation extends Operation { return new Cypher.Return([projection, returnVariable]); } - protected getReturnExpression(context: QueryASTContext): Cypher.Expr { - const projection = this.getProjectionMap(context); - if (context.shouldCollect) { - return Cypher.collect(projection); - } - return projection; - } - private hasCypherSort(): boolean { return this.sortFields.some((s) => s instanceof CypherPropertySort); } diff --git a/packages/graphql/tests/tck/sort.test.ts b/packages/graphql/tests/tck/sort.test.ts index 6d2eab9ebad..09be3708b95 100644 --- a/packages/graphql/tests/tck/sort.test.ts +++ b/packages/graphql/tests/tck/sort.test.ts @@ -26,35 +26,7 @@ describe("Cypher sort tests", () => { let neoSchema: Neo4jGraphQL; beforeAll(() => { - // type Movie { - // id: ID - // title: String - // genres: [Genre!]! @relationship(type: "HAS_GENRE", direction: OUT) - // totalGenres: Int! - // @cypher( - // statement: """ - // MATCH (this)-[:HAS_GENRE]->(genre:Genre) - // RETURN count(DISTINCT genre) as result - // """ - // columnName: "result" - // ) - // } - - // type Genre { - // id: ID - // name: String - // totalMovies: Int! - // @cypher( - // statement: """ - // MATCH (this)<-[:HAS_GENRE]-(movie:Movie) - // RETURN count(DISTINCT movie) as result - // """ - // columnName: "result" - // ) - // } typeDefs = ` - - interface Production { id: ID! title: String! From 873340ff055d74ef1b713e24ef75c7a8c26e14f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 22:47:28 +0000 Subject: [PATCH 050/136] chore(deps): update github/codeql-action digest to 305f654 --- .github/workflows/reusable-codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-codeql-analysis.yml b/.github/workflows/reusable-codeql-analysis.yml index b0dafb9ee0e..bcadb81ed85 100644 --- a/.github/workflows/reusable-codeql-analysis.yml +++ b/.github/workflows/reusable-codeql-analysis.yml @@ -14,9 +14,9 @@ jobs: with: node-version: lts/* - name: Initialize CodeQL - uses: github/codeql-action/init@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2 + uses: github/codeql-action/init@305f6546310b9203e892c28c1484e82977f4f63d # v2 with: config-file: ./.github/codeql/codeql-config.yml languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@c0d1daa7f7e14667747d73a7dbbe8c074bc8bfe2 # v2 + uses: github/codeql-action/analyze@305f6546310b9203e892c28c1484e82977f4f63d # v2 From 89a9ec5d1fb05caab7c369a687b6d65d56774c6a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 22:57:10 +0000 Subject: [PATCH 051/136] chore(deps): update dependency ws to v8.15.1 --- .../graphql-amqp-subscriptions-engine/package.json | 2 +- packages/graphql/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index 6b8a8a24db1..b8bbc4a85c4 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -50,7 +50,7 @@ "supertest": "6.3.3", "ts-jest": "29.1.1", "typescript": "5.1.6", - "ws": "8.15.0" + "ws": "8.15.1" }, "dependencies": { "amqplib": "0.10.3", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 16f96320f1e..cd4948eae70 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -83,7 +83,7 @@ "ts-jest": "29.1.1", "ts-node": "10.9.2", "typescript": "5.1.6", - "ws": "8.15.0" + "ws": "8.15.1" }, "dependencies": { "@apollo/subgraph": "^2.2.3", diff --git a/yarn.lock b/yarn.lock index 35039d7b696..a0c42c12a4b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3587,7 +3587,7 @@ __metadata: supertest: 6.3.3 ts-jest: 29.1.1 typescript: 5.1.6 - ws: 8.15.0 + ws: 8.15.1 peerDependencies: "@neo4j/graphql": ^4.0.0-beta.0 languageName: unknown @@ -3746,7 +3746,7 @@ __metadata: ts-node: 10.9.2 typescript: 5.1.6 typescript-memoize: ^1.1.1 - ws: 8.15.0 + ws: 8.15.1 peerDependencies: graphql: ^16.0.0 neo4j-driver: ^5.8.0 @@ -26857,9 +26857,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.15.0": - version: 8.15.0 - resolution: "ws@npm:8.15.0" +"ws@npm:8.15.1": + version: 8.15.1 + resolution: "ws@npm:8.15.1" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -26868,7 +26868,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: ca15c590aa49bc0197223b8ab7d15e7362ae6c4011d91ed0e5cd5867cdd5497fd71470ea36314833b4b078929fe64dc4ba7748b1e58e50a0f8e41f147db2b464 + checksum: 8c67365f6e6134278ad635d558bfce466d7ef7543a043baea333aaa430429f0af8a130c0c36e7dd78f918d68167a659ba9b5067330b77c4b279e91533395952b languageName: node linkType: hard From a44c487349bc399f1d7ac53ae4530e3c05420ea8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:06:37 +0000 Subject: [PATCH 052/136] chore(deps): update github/codeql-action digest to 03e7845 --- .github/workflows/reusable-codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-codeql-analysis.yml b/.github/workflows/reusable-codeql-analysis.yml index bcadb81ed85..ffbe8893b3c 100644 --- a/.github/workflows/reusable-codeql-analysis.yml +++ b/.github/workflows/reusable-codeql-analysis.yml @@ -14,9 +14,9 @@ jobs: with: node-version: lts/* - name: Initialize CodeQL - uses: github/codeql-action/init@305f6546310b9203e892c28c1484e82977f4f63d # v2 + uses: github/codeql-action/init@03e7845b7bfcd5e7fb63d1ae8c61b0e791134fab # v2 with: config-file: ./.github/codeql/codeql-config.yml languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@305f6546310b9203e892c28c1484e82977f4f63d # v2 + uses: github/codeql-action/analyze@03e7845b7bfcd5e7fb63d1ae8c61b0e791134fab # v2 From e800c0dfc916aca19d09ad30fa99902c4bdb894a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 23:17:16 +0000 Subject: [PATCH 053/136] fix(deps): update neo4j-ndl to v2.1.0 --- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 33 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 5d655ce6798..b2ed23c7fa8 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -50,8 +50,8 @@ "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", - "@neo4j-ndl/base": "2.0.9", - "@neo4j-ndl/react": "2.0.18", + "@neo4j-ndl/base": "2.1.0", + "@neo4j-ndl/react": "2.1.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.3.2", diff --git a/yarn.lock b/yarn.lock index a0c42c12a4b..d2ecac699e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3518,21 +3518,21 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/base@npm:2.0.9, @neo4j-ndl/base@npm:^2.0.9": - version: 2.0.9 - resolution: "@neo4j-ndl/base@npm:2.0.9" - checksum: dd37b74d83f505cf4032a5f9cd745b2d2f9df72862cbbfcbcc0d91b6060c531df68268d3288c3e5d2447c577331971e6a76754a24c289ae4b06af6b1c5f5cd59 +"@neo4j-ndl/base@npm:2.1.0, @neo4j-ndl/base@npm:^2.1.0": + version: 2.1.0 + resolution: "@neo4j-ndl/base@npm:2.1.0" + checksum: 9ca490e7af2738c782acc4f7ba4d2cc1627a20f622fbb617df7ef681b23ac5ddd4155c09185fd40b688b56b07c42ee5e73971764408026906786ba2980146ab1 languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.0.18": - version: 2.0.18 - resolution: "@neo4j-ndl/react@npm:2.0.18" +"@neo4j-ndl/react@npm:2.1.0": + version: 2.1.0 + resolution: "@neo4j-ndl/react@npm:2.1.0" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 "@neo4j-cypher/react-codemirror": ^1.0.1 - "@neo4j-ndl/base": ^2.0.9 + "@neo4j-ndl/base": ^2.1.0 "@table-nav/core": 0.0.7 "@table-nav/react": 0.0.7 "@tanstack/react-table": ^8.9.3 @@ -3549,10 +3549,11 @@ __metadata: react-table: ^7.7.0 react-use: ^17.4.0 tinycolor2: ^1.4.2 + usehooks-ts: 2.9.1 peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: af5507f02c38c3fe28de9acc1fdba1c95f01190417823f7de6a0770bf93596e1ed032c4b5bfdf29659bc32d8081dc8de54401e9882dc0370f9979db92a5f06b8 + checksum: 06ef1dd3e3e8fb83672293b4ba3df2c40a4496c282074a8fab46b1d080930e5de09f49defc2bc5bd4cd5592a96c5a9ee2dfa74d2d7009ba499b674a46af0a76d languageName: node linkType: hard @@ -3634,8 +3635,8 @@ __metadata: "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 - "@neo4j-ndl/base": 2.0.9 - "@neo4j-ndl/react": 2.0.18 + "@neo4j-ndl/base": 2.1.0 + "@neo4j-ndl/react": 2.1.0 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 @@ -26031,6 +26032,16 @@ __metadata: languageName: node linkType: hard +"usehooks-ts@npm:2.9.1": + version: 2.9.1 + resolution: "usehooks-ts@npm:2.9.1" + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + checksum: 36f1e4142ce23bc019b81d2e93aefd7f2c350abcf255598c21627114a69a2f2f116b35dc3a353375f09c6e4c9b704a04f104e3d10e98280545c097feca66c30a + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:^1.0.2, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" From d65dd351a6145ace168feb7c832a8a58beed7322 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 23:00:28 +0000 Subject: [PATCH 054/136] chore(deps): update dependency eslint-plugin-import to v2.29.1 --- package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index ee2857127bb..0f813a2afeb 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "eslint-formatter-summary": "1.1.0", "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-eslint-comments": "3.2.0", - "eslint-plugin-import": "2.29.0", + "eslint-plugin-import": "2.29.1", "eslint-plugin-jest": "27.6.0", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-react": "7.33.2", diff --git a/yarn.lock b/yarn.lock index d2ecac699e5..ce3bf37a643 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13228,9 +13228,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:2.29.0": - version: 2.29.0 - resolution: "eslint-plugin-import@npm:2.29.0" +"eslint-plugin-import@npm:2.29.1": + version: 2.29.1 + resolution: "eslint-plugin-import@npm:2.29.1" dependencies: array-includes: ^3.1.7 array.prototype.findlastindex: ^1.2.3 @@ -13248,10 +13248,10 @@ __metadata: object.groupby: ^1.0.1 object.values: ^1.1.7 semver: ^6.3.1 - tsconfig-paths: ^3.14.2 + tsconfig-paths: ^3.15.0 peerDependencies: eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - checksum: 19ee541fb95eb7a796f3daebe42387b8d8262bbbcc4fd8a6e92f63a12035f3d2c6cb8bc0b6a70864fa14b1b50ed6b8e6eed5833e625e16cb6bb98b665beff269 + checksum: e65159aef808136d26d029b71c8c6e4cb5c628e65e5de77f1eb4c13a379315ae55c9c3afa847f43f4ff9df7e54515c77ffc6489c6a6f81f7dd7359267577468c languageName: node linkType: hard @@ -19838,7 +19838,7 @@ __metadata: eslint-formatter-summary: 1.1.0 eslint-import-resolver-typescript: 3.6.1 eslint-plugin-eslint-comments: 3.2.0 - eslint-plugin-import: 2.29.0 + eslint-plugin-import: 2.29.1 eslint-plugin-jest: 27.6.0 eslint-plugin-jsx-a11y: 6.8.0 eslint-plugin-react: 7.33.2 @@ -25336,15 +25336,15 @@ __metadata: languageName: node linkType: hard -"tsconfig-paths@npm:^3.14.2": - version: 3.14.2 - resolution: "tsconfig-paths@npm:3.14.2" +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" dependencies: "@types/json5": ^0.0.29 json5: ^1.0.2 minimist: ^1.2.6 strip-bom: ^3.0.0 - checksum: a6162eaa1aed680537f93621b82399c7856afd10ec299867b13a0675e981acac4e0ec00896860480efc59fc10fd0b16fdc928c0b885865b52be62cadac692447 + checksum: 59f35407a390d9482b320451f52a411a256a130ff0e7543d18c6f20afab29ac19fbe55c360a93d6476213cc335a4d76ce90f67df54c4e9037f7d240920832201 languageName: node linkType: hard From 332c90261f138263a7e3531e5d49d6f359242408 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 23:10:01 +0000 Subject: [PATCH 055/136] fix(deps): update neo4j-ndl to v2.2.0 --- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index b2ed23c7fa8..3c97804cefb 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -50,8 +50,8 @@ "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", - "@neo4j-ndl/base": "2.1.0", - "@neo4j-ndl/react": "2.1.0", + "@neo4j-ndl/base": "2.2.0", + "@neo4j-ndl/react": "2.2.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.3.2", diff --git a/yarn.lock b/yarn.lock index ce3bf37a643..e3fa5bcb5c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3518,21 +3518,21 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/base@npm:2.1.0, @neo4j-ndl/base@npm:^2.1.0": - version: 2.1.0 - resolution: "@neo4j-ndl/base@npm:2.1.0" - checksum: 9ca490e7af2738c782acc4f7ba4d2cc1627a20f622fbb617df7ef681b23ac5ddd4155c09185fd40b688b56b07c42ee5e73971764408026906786ba2980146ab1 +"@neo4j-ndl/base@npm:2.2.0, @neo4j-ndl/base@npm:^2.2.0": + version: 2.2.0 + resolution: "@neo4j-ndl/base@npm:2.2.0" + checksum: 22078b0c26bc33e8ca1458b190e735cfbadf6421d2378e0b96a73b7abd1660fb549a5cda16fb5b13a89e121911a7f87f8d5865635343d1c774be05da7494a509 languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.1.0": - version: 2.1.0 - resolution: "@neo4j-ndl/react@npm:2.1.0" +"@neo4j-ndl/react@npm:2.2.0": + version: 2.2.0 + resolution: "@neo4j-ndl/react@npm:2.2.0" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 "@neo4j-cypher/react-codemirror": ^1.0.1 - "@neo4j-ndl/base": ^2.1.0 + "@neo4j-ndl/base": ^2.2.0 "@table-nav/core": 0.0.7 "@table-nav/react": 0.0.7 "@tanstack/react-table": ^8.9.3 @@ -3553,7 +3553,7 @@ __metadata: peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: 06ef1dd3e3e8fb83672293b4ba3df2c40a4496c282074a8fab46b1d080930e5de09f49defc2bc5bd4cd5592a96c5a9ee2dfa74d2d7009ba499b674a46af0a76d + checksum: 88b079fedf3ac571d44daf6f495a420a813e89893cbadf5b053268f7c73f985f08b4523c767f6febab4bc3ed9a01c60d613fa5ddbcc83fdf4a504eb2c696f9f4 languageName: node linkType: hard @@ -3635,8 +3635,8 @@ __metadata: "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 - "@neo4j-ndl/base": 2.1.0 - "@neo4j-ndl/react": 2.1.0 + "@neo4j-ndl/base": 2.2.0 + "@neo4j-ndl/react": 2.2.0 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 From 387e455bb9aebb94663b05baed6c8694ec304e80 Mon Sep 17 00:00:00 2001 From: MacondoExpress Date: Fri, 15 Dec 2023 14:42:48 +0000 Subject: [PATCH 056/136] Typename_IN filters behind experimental flag (#4409) * add schema support for typename_IN * initial support to typename filter using label predicate * clean up * fix bug 4405 * add test for 4405 issue * update factory to support shared filters, add tests to typename_IN * remove unwanted path from experimental filter * lint fixes * add experimental flag to the ContextBuilder * update schema tests * Create mighty-windows-knock.md * minor fix --- .changeset/mighty-windows-knock.md | 25 + packages/graphql/src/classes/Neo4jGraphQL.ts | 1 + .../InterfaceEntityOperations.ts | 4 + .../graphql/src/schema/create-global-nodes.ts | 2 +- .../src/schema/generation/where-input.ts | 12 + .../composition/wrap-query-and-mutation.ts | 4 + .../resolvers/query/global-node.test.ts | 9 +- .../src/schema/resolvers/query/global-node.ts | 4 +- .../create-authorization-after-predicate.ts | 4 +- .../create-authorization-before-predicate.ts | 4 +- .../utils/populate-where-params.ts | 4 +- .../property-filters/TypenameFilter.ts | 51 ++ .../queryAST/factory/FilterFactory.ts | 132 +++- .../queryAST/factory/OperationFactory.ts | 30 +- .../queryAST/factory/QueryASTFactory.ts | 4 +- .../queryAST/utils/get-concrete-where.ts | 4 +- .../src/translate/translate-aggregate.ts | 2 +- .../graphql/src/translate/translate-create.ts | 2 +- .../graphql/src/translate/translate-read.ts | 2 +- .../graphql/src/translate/unwind-create.ts | 2 +- .../translate/where/create-where-predicate.ts | 4 +- .../experimental/typename-in-auth.int.test.ts | 448 +++++++++++++ .../experimental/typename-in.int.test.ts | 215 ++++++ .../tests/integration/issues/4405.int.test.ts | 136 ++++ .../experimental-schema/comments.test.ts | 6 + .../directive-preserve.test.ts | 12 + .../directives/default.test.ts | 5 + .../directives/filterable.test.ts | 5 + .../directives/private.test.ts | 5 + .../directives/relationship-aggregate.test.ts | 10 + .../relationship-nested-operations.test.ts | 48 ++ .../directives/selectable.test.ts | 12 + .../directives/settable.test.ts | 24 + .../experimental-schema/inheritance.test.ts | 5 + .../interface-relationships.test.ts | 30 + .../experimental-schema/interfaces.test.ts | 10 + .../interfaces/aggregations.test.ts | 11 + .../interfaces/typename-in.test.ts | 611 ++++++++++++++++++ .../experimental-schema/issues/2377.test.ts | 5 + .../experimental-schema/issues/2993.test.ts | 10 + .../experimental-schema/issues/3439.test.ts | 24 + .../schema/experimental-schema/math.test.ts | 5 + .../nested-aggregation-on-interface.test.ts | 12 + .../schema/experimental-schema/plural.test.ts | 5 + .../experimental-schema/subscriptions.test.ts | 11 + .../union-interface-relationship.test.ts | 6 + .../tck/experimental/typename-in-auth.test.ts | 338 ++++++++++ .../tck/experimental/typename-in.test.ts | 311 +++++++++ .../graphql/tests/tck/issues/4405.test.ts | 139 ++++ .../tests/utils/builders/context-builder.ts | 1 + 50 files changed, 2700 insertions(+), 66 deletions(-) create mode 100644 .changeset/mighty-windows-knock.md create mode 100644 packages/graphql/src/translate/queryAST/ast/filters/property-filters/TypenameFilter.ts create mode 100644 packages/graphql/tests/integration/experimental/typename-in-auth.int.test.ts create mode 100644 packages/graphql/tests/integration/experimental/typename-in.int.test.ts create mode 100644 packages/graphql/tests/integration/issues/4405.int.test.ts create mode 100644 packages/graphql/tests/schema/experimental-schema/interfaces/typename-in.test.ts create mode 100644 packages/graphql/tests/tck/experimental/typename-in-auth.test.ts create mode 100644 packages/graphql/tests/tck/experimental/typename-in.test.ts create mode 100644 packages/graphql/tests/tck/issues/4405.test.ts diff --git a/.changeset/mighty-windows-knock.md b/.changeset/mighty-windows-knock.md new file mode 100644 index 00000000000..d2f4446951f --- /dev/null +++ b/.changeset/mighty-windows-knock.md @@ -0,0 +1,25 @@ +--- +"@neo4j/graphql": patch +--- + +Add support for typename_IN filters for interfaces under the experimental flag: + +``` +interface Show { + title: String! +} +type Movie implements Show { + title: String! +} +type Series implements Show { + title: String! +} +``` + +``` +query actedInWhere { + shows(where: { typename_IN: [Series] }) { + title + } +} +``` diff --git a/packages/graphql/src/classes/Neo4jGraphQL.ts b/packages/graphql/src/classes/Neo4jGraphQL.ts index b6d799cfc9c..2ed6ec0819a 100644 --- a/packages/graphql/src/classes/Neo4jGraphQL.ts +++ b/packages/graphql/src/classes/Neo4jGraphQL.ts @@ -285,6 +285,7 @@ class Neo4jGraphQL { features: this.features, authorization: this.authorization, jwtPayloadFieldsMap: this.jwtFieldsMap, + experimental: this.experimental, }; const resolversComposition = { 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 be896ff4ec3..266ec9ba5f0 100644 --- a/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts +++ b/packages/graphql/src/schema-model/entity/model-adapters/InterfaceEntityOperations.ts @@ -88,6 +88,10 @@ export class InterfaceEntityOperations { return `${this.InterfaceEntityAdapter.name}Where`; } + public get implementationEnumTypename(): string { + return `${this.InterfaceEntityAdapter.name}Implementation`; + } + public get whereOnImplementationsWhereInputTypeName(): string { return `${this.InterfaceEntityAdapter.name}ImplementationsWhere`; } diff --git a/packages/graphql/src/schema/create-global-nodes.ts b/packages/graphql/src/schema/create-global-nodes.ts index 456caaf164e..b2bbe1381d5 100644 --- a/packages/graphql/src/schema/create-global-nodes.ts +++ b/packages/graphql/src/schema/create-global-nodes.ts @@ -38,7 +38,7 @@ export function addGlobalNodeFields( if (globalNodes.length === 0) return false; const fetchById = (id: string, context: Neo4jGraphQLComposedContext, info: GraphQLResolveInfo) => { - const resolver = globalNodeResolver({ nodes: globalNodes, entities: globalEntities }); + const resolver = globalNodeResolver({ entities: globalEntities }); return resolver.resolve(null, { id }, context, info); }; diff --git a/packages/graphql/src/schema/generation/where-input.ts b/packages/graphql/src/schema/generation/where-input.ts index 79215f9212e..9c089c1137a 100644 --- a/packages/graphql/src/schema/generation/where-input.ts +++ b/packages/graphql/src/schema/generation/where-input.ts @@ -99,6 +99,18 @@ export function withWhereInputType({ AND: whereInputType.NonNull.List, NOT: whereInputType, }); + + const enumValues = Object.fromEntries( + entityAdapter.concreteEntities.map((concreteEntity) => [ + concreteEntity.name, + { value: concreteEntity.name }, + ]) + ); + const interfaceImplementation = composer.createEnumTC({ + name: entityAdapter.operations.implementationEnumTypename, + values: enumValues, + }); + whereInputType.addFields({ typename_IN: { type: interfaceImplementation.NonNull.List } }); } else { const implementationsWhereInputType = makeImplementationsWhereInput({ interfaceEntityAdapter: entityAdapter, diff --git a/packages/graphql/src/schema/resolvers/composition/wrap-query-and-mutation.ts b/packages/graphql/src/schema/resolvers/composition/wrap-query-and-mutation.ts index 0bbc2416118..fcd806a3069 100644 --- a/packages/graphql/src/schema/resolvers/composition/wrap-query-and-mutation.ts +++ b/packages/graphql/src/schema/resolvers/composition/wrap-query-and-mutation.ts @@ -44,6 +44,7 @@ export type WrapResolverArguments = { dbInfo?: Neo4jDatabaseInfo; features: ContextFeatures; authorization?: Neo4jGraphQLAuthorization; + experimental: boolean; }; /** @@ -63,6 +64,7 @@ export interface Neo4jGraphQLComposedContext extends Neo4jGraphQLContext { subscriptionsEnabled: boolean; executor: Executor; authorization: AuthorizationContext; + experimental: boolean; neo4jDatabaseInfo?: Neo4jDatabaseInfo; fulltext?: FulltextContext; } @@ -79,6 +81,7 @@ export const wrapQueryAndMutation = dbInfo, authorization, features, + experimental, }: WrapResolverArguments) => (next: GraphQLFieldResolver) => async (root, args, context: Neo4jGraphQLContext, info: GraphQLResolveInfo) => { @@ -125,6 +128,7 @@ export const wrapQueryAndMutation = executor, neo4jDatabaseInfo, authorization: authorizationContext, + experimental, // Consider anything in here overrides ...context, }; diff --git a/packages/graphql/src/schema/resolvers/query/global-node.test.ts b/packages/graphql/src/schema/resolvers/query/global-node.test.ts index 938b442ef30..1195a268d45 100644 --- a/packages/graphql/src/schema/resolvers/query/global-node.test.ts +++ b/packages/graphql/src/schema/resolvers/query/global-node.test.ts @@ -18,17 +18,10 @@ */ import { globalNodeResolver } from "./global-node"; -import { NodeBuilder } from "../../../../tests/utils/builders/node-builder"; describe("Global node resolver", () => { test("should return the correct type, args and resolve", () => { - const node = new NodeBuilder({ - name: "Movie", - primitiveFields: [], - isGlobalNode: true, - }).instance(); - - const result = globalNodeResolver({ nodes: [node], entities: [] }); + const result = globalNodeResolver({ entities: [] }); expect(result.type).toBe("Node"); expect(result.resolve).toBeInstanceOf(Function); expect(result.args).toMatchObject({ diff --git a/packages/graphql/src/schema/resolvers/query/global-node.ts b/packages/graphql/src/schema/resolvers/query/global-node.ts index fa7f161301b..12521db7787 100644 --- a/packages/graphql/src/schema/resolvers/query/global-node.ts +++ b/packages/graphql/src/schema/resolvers/query/global-node.ts @@ -20,7 +20,6 @@ import type { GraphQLResolveInfo } from "graphql"; import type { FieldsByTypeName } from "graphql-parse-resolve-info"; import { parseResolveInfo } from "graphql-parse-resolve-info"; -import type { Node } from "../../../classes"; import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; import { translateRead } from "../../../translate"; import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context"; @@ -29,7 +28,7 @@ import getNeo4jResolveTree from "../../../utils/get-neo4j-resolve-tree"; import { fromGlobalId } from "../../../utils/global-ids"; import type { Neo4jGraphQLComposedContext } from "../composition/wrap-query-and-mutation"; -export function globalNodeResolver({ nodes, entities }: { nodes: Node[]; entities: ConcreteEntityAdapter[] }) { +export function globalNodeResolver({ entities }: { entities: ConcreteEntityAdapter[] }) { async function resolve( _root: any, args: { id: string }, @@ -40,7 +39,6 @@ export function globalNodeResolver({ nodes, entities }: { nodes: Node[]; entitie if (!typeName || !field || !id) return null; - const node = nodes.find((n) => n.name === typeName); const entityAdapter = entities.find((n) => n.name === typeName); if (!entityAdapter) return null; diff --git a/packages/graphql/src/translate/authorization/create-authorization-after-predicate.ts b/packages/graphql/src/translate/authorization/create-authorization-after-predicate.ts index ea41cd89b0f..5c8e6f55d7d 100644 --- a/packages/graphql/src/translate/authorization/create-authorization-after-predicate.ts +++ b/packages/graphql/src/translate/authorization/create-authorization-after-predicate.ts @@ -49,7 +49,7 @@ export function createAuthorizationAfterPredicate({ if (!isConcreteEntity(entity)) { throw new Error("Expected authorization rule to be applied on a concrete entity"); } - const factory = new QueryASTFactory(context.schemaModel); + const factory = new QueryASTFactory(context.schemaModel, context.experimental); const queryASTEnv = new QueryASTEnv(); const queryASTContext = new QueryASTContext({ @@ -109,7 +109,7 @@ export function createAuthorizationAfterPredicateField({ if (!isConcreteEntity(entity)) { throw new Error("Expected authorization rule to be applied on a concrete entity"); } - const factory = new QueryASTFactory(context.schemaModel); + const factory = new QueryASTFactory(context.schemaModel, context.experimental); const queryASTEnv = new QueryASTEnv(); const queryASTContext = new QueryASTContext({ diff --git a/packages/graphql/src/translate/authorization/create-authorization-before-predicate.ts b/packages/graphql/src/translate/authorization/create-authorization-before-predicate.ts index 1ccd616b17a..a0cb42b85b8 100644 --- a/packages/graphql/src/translate/authorization/create-authorization-before-predicate.ts +++ b/packages/graphql/src/translate/authorization/create-authorization-before-predicate.ts @@ -49,7 +49,7 @@ export function createAuthorizationBeforePredicate({ if (!isConcreteEntity(entity)) { throw new Error("Expected authorization rule to be applied on a concrete entity"); } - const factory = new QueryASTFactory(context.schemaModel); + const factory = new QueryASTFactory(context.schemaModel, context.experimental); const queryASTEnv = new QueryASTEnv(); const queryASTContext = new QueryASTContext({ @@ -111,7 +111,7 @@ export function createAuthorizationBeforePredicateField({ if (!isConcreteEntity(entity)) { throw new Error("Expected authorization rule to be applied on a concrete entity"); } - const factory = new QueryASTFactory(context.schemaModel); + const factory = new QueryASTFactory(context.schemaModel, context.experimental); const queryASTEnv = new QueryASTEnv(); const queryASTContext = new QueryASTContext({ diff --git a/packages/graphql/src/translate/authorization/utils/populate-where-params.ts b/packages/graphql/src/translate/authorization/utils/populate-where-params.ts index 994ebe2f97c..434cbfacd48 100644 --- a/packages/graphql/src/translate/authorization/utils/populate-where-params.ts +++ b/packages/graphql/src/translate/authorization/utils/populate-where-params.ts @@ -32,11 +32,11 @@ export function populateWhereParams({ const parsed: GraphQLWhereArg = {}; Object.entries(where).forEach(([k, v]) => { - if (Array.isArray(v)) { + if (k === "AND" || k === "OR") { parsed[k] = v.map((w) => populateWhereParams({ where: w, context })); } else if (v === null) { parsed[k] = v; - } else if (typeof v === "object") { + } else if (typeof v === "object" && !Array.isArray(v)) { parsed[k] = populateWhereParams({ where: v, context }); } else if (typeof v === "string") { parsed[k] = parseContextParamProperty(v, context); diff --git a/packages/graphql/src/translate/queryAST/ast/filters/property-filters/TypenameFilter.ts b/packages/graphql/src/translate/queryAST/ast/filters/property-filters/TypenameFilter.ts new file mode 100644 index 00000000000..6df5eacd55b --- /dev/null +++ b/packages/graphql/src/translate/queryAST/ast/filters/property-filters/TypenameFilter.ts @@ -0,0 +1,51 @@ +/* + * 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 Cypher from "@neo4j/cypher-builder"; +import type { QueryASTContext } from "../../QueryASTContext"; +import type { QueryASTNode } from "../../QueryASTNode"; +import { Filter } from "../Filter"; +import type { ConcreteEntityAdapter } from "../../../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +import { hasTarget } from "../../../utils/context-has-target"; + +export class TypenameFilter extends Filter { + private readonly acceptedEntities: ConcreteEntityAdapter[]; + + constructor(acceptedEntities: ConcreteEntityAdapter[]) { + super(); + this.acceptedEntities = acceptedEntities; + } + + public getChildren(): QueryASTNode[] { + return []; + } + + public print(): string { + const acceptedEntities = this.acceptedEntities.map((e) => e.name); + return `${super.print()} [${acceptedEntities.join(", ")}]`; + } + + public getPredicate(queryASTContext: QueryASTContext): Cypher.Predicate { + if (!hasTarget(queryASTContext)) throw new Error("No parent node found!"); + const labelPredicate = this.acceptedEntities.map((e) => { + return queryASTContext.target.hasLabels(e.name); + }); + return Cypher.or(...labelPredicate); + } +} diff --git a/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts b/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts index 9bc4e7bda2e..6caa2e34062 100644 --- a/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts @@ -39,6 +39,7 @@ import { CountFilter } from "../ast/filters/aggregation/CountFilter"; import { DurationFilter } from "../ast/filters/property-filters/DurationFilter"; import { PointFilter } from "../ast/filters/property-filters/PointFilter"; import { PropertyFilter } from "../ast/filters/property-filters/PropertyFilter"; +import { TypenameFilter } from "../ast/filters/property-filters/TypenameFilter"; import { getConcreteEntities } from "../utils/get-concrete-entities"; import { isConcreteEntity } from "../utils/is-concrete-entity"; import { isInterfaceEntity } from "../utils/is-interface-entity"; @@ -57,11 +58,12 @@ type AggregateWhereInput = { }; export class FilterFactory { - private queryASTFactory: QueryASTFactory; + protected experimental: boolean; constructor(queryASTFactory: QueryASTFactory) { - this.queryASTFactory = queryASTFactory; + this.experimental = queryASTFactory.experimental; } + /** * Get all the entities explicitly required by the where "on" object. If it's a concrete entity it will return itself. **/ @@ -235,20 +237,102 @@ export class FilterFactory { }): ConnectionFilter { return new ConnectionFilter(options); } + /** + * By removing the _on field is possible to create a single filter to be applied to all the concrete entities. + * */ + private createExperimentalInterfaceFilters(entity: InterfaceEntityAdapter, where: Record): Filter[] { + const filters = filterTruthy( + Object.entries(where).flatMap(([key, value]): Filter | undefined => { + if (isLogicalOperator(key)) { + const nestedFilters = asArray(value).flatMap((nestedWhere) => { + return this.createExperimentalInterfaceFilters(entity, nestedWhere); + }); + return new LogicalFilter({ + operation: key, + filters: nestedFilters, + }); + } + if (key === "typename_IN") { + const acceptedEntities = entity.concreteEntities.filter((ce) => { + return asArray(value).some((v) => v === ce.name); + }); + const typenameFilter = new TypenameFilter(acceptedEntities); + return typenameFilter; + } + + const { fieldName, operator, isNot } = parseWhereField(key); + + const attr = entity.findAttribute(fieldName); + + if (fieldName === "id" && !attr && !isUnionEntity(entity)) { + const relayAttribute = entity.globalIdField; + if (relayAttribute) { + const relayIdData = fromGlobalId(value as string); + if (relayIdData) { + const { typeName, field } = relayIdData; + let id = relayIdData.id; + + if (typeName !== entity.name || !field || !id) { + throw new Error(`Cannot query Relay Id on "${entity.name}"`); + } + const idAttribute = entity.findAttribute(field); + if (!idAttribute) throw new Error(`Attribute ${field} not found`); + + if (idAttribute.typeHelper.isNumeric()) { + id = Number(id); + if (Number.isNaN(id)) { + throw new Error("Can't parse non-numeric relay id"); + } + } + return this.createPropertyFilter({ + attribute: idAttribute, + comparisonValue: id, + isNot, + operator, + }); + } + } + } + if (!attr) throw new Error(`Attribute ${fieldName} not found`); + return this.createPropertyFilter({ + attribute: attr, + comparisonValue: value, + isNot, + operator, + }); + }) + ); + + return this.wrapMultipleFiltersInLogical(filters); + } + + // TODO: remove _on implementation logic from this method when _on will be completely deprecated. // TODO: rename and refactor this, createNodeFilters is misleading for non-connection operations public createNodeFilters(entity: EntityAdapter, where: Record): Filter[] { + // if typename is allowed we can compute only the shared filter without recomputing the filters for each concrete entity + // if typename filters are allowed we are getting rid of the _on and the implicit typename filter. + const typenameFilterAllowed = this.experimental && isInterfaceEntity(entity); + if (typenameFilterAllowed) { + return this.createExperimentalInterfaceFilters(entity, where); + } const whereFields = this.getConcreteFiltersWhere(entity, where); const filters = filterTruthy( Object.entries(whereFields).flatMap(([key, value]): Filter | undefined => { + if (isLogicalOperator(key)) { + const nestedFilters = asArray(value).flatMap((nestedWhere) => { + return this.createNodeFilters(entity, nestedWhere); + }); + return new LogicalFilter({ + operation: key, + filters: nestedFilters, + }); + } if (key === "_on" && isObject(value)) { return this.getConcreteFilter(entity, value); } - if (isLogicalOperator(key)) { - return this.createNodeLogicalFilter(key, value, entity); - } const { fieldName, operator, isNot, isConnection, isAggregate } = parseWhereField(key); let relationship: RelationshipAdapter | undefined; @@ -333,7 +417,13 @@ export class FilterFactory { public createEdgeFilters(relationship: RelationshipAdapter, where: GraphQLWhereArg): Filter[] { const filterASTs = Object.entries(where).map(([key, value]): Filter => { if (isLogicalOperator(key)) { - return this.createEdgeLogicalFilter(key, value, relationship); + const nestedFilters = asArray(value).flatMap((nestedWhere) => { + return this.createEdgeFilters(relationship, nestedWhere); + }); + return new LogicalFilter({ + operation: key, + filters: nestedFilters, + }); } const { fieldName, operator, isNot } = parseWhereField(key); const attribute = relationship.findAttribute(fieldName); @@ -351,34 +441,6 @@ export class FilterFactory { return this.wrapMultipleFiltersInLogical(filterTruthy(filterASTs)); } - private createNodeLogicalFilter( - operation: "OR" | "AND" | "NOT", - where: GraphQLWhereArg[] | GraphQLWhereArg, - entity: EntityAdapter - ): LogicalFilter { - const nestedFilters = asArray(where).flatMap((nestedWhere) => { - return this.createNodeFilters(entity, nestedWhere); - }); - return new LogicalFilter({ - operation, - filters: nestedFilters, - }); - } - - private createEdgeLogicalFilter( - operation: "OR" | "AND" | "NOT", - where: GraphQLWhereArg[] | GraphQLWhereArg, - relationship: RelationshipAdapter - ): LogicalFilter { - const nestedFilters = asArray(where).flatMap((nestedWhere) => { - return this.createEdgeFilters(relationship, nestedWhere); - }); - return new LogicalFilter({ - operation, - filters: nestedFilters, - }); - } - private getAggregationNestedFilters( where: AggregateWhereInput, relationship: RelationshipAdapter @@ -514,7 +576,7 @@ export class FilterFactory { for (const concreteEntity of concreteEntities) { const concreteEntityWhere: Record = where[concreteEntity.name]; if (concreteEntityWhere) { - const concreteEntityFilters = this.createNodeFilters(concreteEntity, concreteEntityWhere); + const concreteEntityFilters = this.createNodeFilters(entity, concreteEntityWhere); nodeFilters.push(...concreteEntityFilters); } } diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index 00f1e1aec9c..d403a6b964d 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -66,6 +66,7 @@ import { findFieldsByNameInFieldsByTypeNameField } from "./parsers/find-fields-b import { getFieldsByTypeName } from "./parsers/get-fields-by-type-name"; import { parseInterfaceOperationField, parseOperationField } from "./parsers/parse-operation-fields"; import { parseSelectionSetField } from "./parsers/parse-selection-set-fields"; +import type { Filter } from "../ast/filters/Filter"; const TOP_LEVEL_NODE_NAME = "this"; export class OperationsFactory { @@ -73,12 +74,14 @@ export class OperationsFactory { private fieldFactory: FieldFactory; private sortAndPaginationFactory: SortAndPaginationFactory; private authorizationFactory: AuthorizationFactory; + private experimental: boolean; constructor(queryASTFactory: QueryASTFactory) { this.filterFactory = queryASTFactory.filterFactory; this.fieldFactory = queryASTFactory.fieldFactory; this.sortAndPaginationFactory = queryASTFactory.sortAndPaginationFactory; this.authorizationFactory = queryASTFactory.authorizationFactory; + this.experimental = queryASTFactory.experimental; } public createTopLevelOperation( @@ -281,7 +284,18 @@ export class OperationsFactory { whereArgs: resolveTreeWhere, }); } else { - const concreteEntities = getConcreteEntitiesInOnArgumentOfWhere(entity, resolveTreeWhere); + // if typename is allowed and therefore _on is disabled we can compute only the shared filter without recomputing the filters for each concrete entity + // if typename filters are allowed we are getting rid of the _on and the implicit typename filter. + const typenameFilterAllowed = this.experimental && isInterfaceEntity(entity); + + const concreteEntities = typenameFilterAllowed + ? entity.concreteEntities + : getConcreteEntitiesInOnArgumentOfWhere(entity, resolveTreeWhere); + + const sharedFilters = typenameFilterAllowed + ? this.filterFactory.createNodeFilters(entity, resolveTreeWhere) + : undefined; + const concreteReadOperations = concreteEntities.map((concreteEntity: ConcreteEntityAdapter) => { // Duplicate from normal read let selection: EntitySelection; @@ -313,6 +327,7 @@ export class OperationsFactory { resolveTree, context, whereArgs: whereArgs, + sharedFilters, }); }); @@ -853,6 +868,7 @@ export class OperationsFactory { context, sortArgs, fieldsByTypeName, + sharedFilters, }: { entity: ConcreteEntityAdapter; operation: T; @@ -860,6 +876,7 @@ export class OperationsFactory { whereArgs: Record; sortArgs?: Record; fieldsByTypeName: FieldsByTypeName; + sharedFilters?: Filter[]; }): T { const concreteProjectionFields = { ...fieldsByTypeName[entity.name] }; // Get the abstract types of the interface @@ -873,7 +890,7 @@ export class OperationsFactory { ]); const fields = this.fieldFactory.createFields(entity, projectionFields, context); - const filters = this.filterFactory.createNodeFilters(entity, whereArgs); + const filters = sharedFilters ? sharedFilters : this.filterFactory.createNodeFilters(entity, whereArgs); const authFilters = this.authorizationFactory.createEntityAuthFilters(entity, ["READ"], context); const authValidate = this.authorizationFactory.createEntityAuthValidate(entity, ["READ"], context, "BEFORE"); @@ -921,18 +938,21 @@ export class OperationsFactory { return operation; } + private hydrateReadOperation({ entity, operation, resolveTree, context, whereArgs, + sharedFilters, }: { entity: ConcreteEntityAdapter; operation: T; resolveTree: ResolveTree; context: Neo4jGraphQLTranslationContext; - whereArgs: Record; + whereArgs: Record | Filter[]; + sharedFilters?: Filter[]; }): T { return this.hydrateOperation({ entity, @@ -941,6 +961,7 @@ export class OperationsFactory { whereArgs, fieldsByTypeName: resolveTree.fieldsByTypeName, sortArgs: (resolveTree.args.options as Record) || {}, + sharedFilters, }); } @@ -988,8 +1009,7 @@ export class OperationsFactory { context, "BEFORE" ); - - const filters = this.filterFactory.createNodeFilters(entity, whereArgs); // Aggregation filters only apply to target node + const filters = this.filterFactory.createNodeFilters(entity, whereArgs); operation.setFields(fields); operation.setNodeFields(nodeFields); diff --git a/packages/graphql/src/translate/queryAST/factory/QueryASTFactory.ts b/packages/graphql/src/translate/queryAST/factory/QueryASTFactory.ts index 003c041723b..be1ab8a4801 100644 --- a/packages/graphql/src/translate/queryAST/factory/QueryASTFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/QueryASTFactory.ts @@ -37,9 +37,11 @@ export class QueryASTFactory { public fieldFactory: FieldFactory; public sortAndPaginationFactory: SortAndPaginationFactory; public authorizationFactory: AuthorizationFactory; + public experimental: boolean; - constructor(schemaModel: Neo4jGraphQLSchemaModel) { + constructor(schemaModel: Neo4jGraphQLSchemaModel, experimental: boolean) { this.schemaModel = schemaModel; + this.experimental = experimental; this.filterFactory = new FilterFactory(this); this.fieldFactory = new FieldFactory(this); this.sortAndPaginationFactory = new SortAndPaginationFactory(); diff --git a/packages/graphql/src/translate/queryAST/utils/get-concrete-where.ts b/packages/graphql/src/translate/queryAST/utils/get-concrete-where.ts index ec98969f749..b1ac33035f4 100644 --- a/packages/graphql/src/translate/queryAST/utils/get-concrete-where.ts +++ b/packages/graphql/src/translate/queryAST/utils/get-concrete-where.ts @@ -48,7 +48,9 @@ export function getConcreteWhere( return whereArgs[concreteTarget.name] ?? {}; } else { // interface may have shared filters, inject them as if they were present under _on - const sharedInterfaceFilters = Object.entries(whereArgs).filter(([key]) => key !== "_on"); + const sharedInterfaceFilters = Object.entries(whereArgs).filter( + ([key]) => key !== "_on" && key !== "typename_IN" + ); const _on: Record | undefined = isObject(whereArgs["_on"]) ? whereArgs["_on"] : undefined; // if concrete target is present in _on then merge its filters with the shared ones, if _on it's not defined then returns the shared filters diff --git a/packages/graphql/src/translate/translate-aggregate.ts b/packages/graphql/src/translate/translate-aggregate.ts index c7b09afce77..44a147e6b67 100644 --- a/packages/graphql/src/translate/translate-aggregate.ts +++ b/packages/graphql/src/translate/translate-aggregate.ts @@ -35,7 +35,7 @@ export function translateAggregate({ }): Cypher.CypherResult { const { resolveTree } = context; // TODO: Rename QueryAST to OperationsTree - const queryASTFactory = new QueryASTFactory(context.schemaModel); + const queryASTFactory = new QueryASTFactory(context.schemaModel, context.experimental); if (!entityAdapter) throw new Error("Entity not found"); const queryAST = queryASTFactory.createQueryAST(resolveTree, entityAdapter, context); diff --git a/packages/graphql/src/translate/translate-create.ts b/packages/graphql/src/translate/translate-create.ts index 402e59e5b3d..8c28e6ff798 100644 --- a/packages/graphql/src/translate/translate-create.ts +++ b/packages/graphql/src/translate/translate-create.ts @@ -119,7 +119,7 @@ export default async function translateCreate({ throw new Error(`Transpilation error: ${node.name} is not a concrete entity`); } - const queryAST = new QueryASTFactory(context.schemaModel).createQueryAST( + const queryAST = new QueryASTFactory(context.schemaModel, context.experimental).createQueryAST( resolveTree, concreteEntityAdapter, context diff --git a/packages/graphql/src/translate/translate-read.ts b/packages/graphql/src/translate/translate-read.ts index 1fb8202650f..6d78547f942 100644 --- a/packages/graphql/src/translate/translate-read.ts +++ b/packages/graphql/src/translate/translate-read.ts @@ -37,7 +37,7 @@ export function translateRead( varName = "this" ): Cypher.CypherResult { const { resolveTree } = context; - const operationsTreeFactory = new QueryASTFactory(context.schemaModel); + const operationsTreeFactory = new QueryASTFactory(context.schemaModel, context.experimental); if (!entityAdapter) throw new Error("Entity not found"); const operationsTree = operationsTreeFactory.createQueryAST(resolveTree, entityAdapter, context); diff --git a/packages/graphql/src/translate/unwind-create.ts b/packages/graphql/src/translate/unwind-create.ts index 7127ab4892b..8a10e216afe 100644 --- a/packages/graphql/src/translate/unwind-create.ts +++ b/packages/graphql/src/translate/unwind-create.ts @@ -60,7 +60,7 @@ export default async function unwindCreate({ throw new Error(`Transpilation error: ${node.name} is not a concrete entity`); } - const queryAST = new QueryASTFactory(context.schemaModel).createQueryAST( + const queryAST = new QueryASTFactory(context.schemaModel, context.experimental).createQueryAST( resolveTree, concreteEntityAdapter, context diff --git a/packages/graphql/src/translate/where/create-where-predicate.ts b/packages/graphql/src/translate/where/create-where-predicate.ts index d48ed0ff7c4..640f2e6e810 100644 --- a/packages/graphql/src/translate/where/create-where-predicate.ts +++ b/packages/graphql/src/translate/where/create-where-predicate.ts @@ -73,7 +73,7 @@ export function createWhereNodePredicate({ predicate: Cypher.Predicate | undefined; preComputedSubqueries?: Cypher.CompositeClause | undefined; } { - const factory = new QueryASTFactory(context.schemaModel); + const factory = new QueryASTFactory(context.schemaModel, context.experimental); const queryASTEnv = new QueryASTEnv(); const queryASTContext = new QueryASTContext({ @@ -100,7 +100,7 @@ export function createWhereEdgePredicate({ predicate: Cypher.Predicate | undefined; preComputedSubqueries?: Cypher.CompositeClause | undefined; } { - const factory = new QueryASTFactory(context.schemaModel); + const factory = new QueryASTFactory(context.schemaModel, context.experimental); const queryASTEnv = new QueryASTEnv(); const queryASTContext = new QueryASTContext({ diff --git a/packages/graphql/tests/integration/experimental/typename-in-auth.int.test.ts b/packages/graphql/tests/integration/experimental/typename-in-auth.int.test.ts new file mode 100644 index 00000000000..025d8c28ee4 --- /dev/null +++ b/packages/graphql/tests/integration/experimental/typename-in-auth.int.test.ts @@ -0,0 +1,448 @@ +/* + * 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 Neo4j from "../neo4j"; +import { createBearerToken } from "../../utils/create-bearer-token"; + +describe("typename_IN with auth", () => { + let schema: GraphQLSchema; + let neo4j: Neo4j; + let driver: Driver; + let typeDefs: string; + const secret = "secret"; + + const Movie = new UniqueType("Movie"); + const Actor = new UniqueType("Actor"); + const Series = new UniqueType("Series"); + const Cartoon = new UniqueType("Cartoon"); + + async function graphqlQuery(query: string, token: string) { + return graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ token }), + }); + } + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + + typeDefs = ` + interface Production { + title: String! + cost: Float! + } + + type ${Movie.name} implements Production { + title: String! + cost: Float! + runtime: Int! + } + + type ${Series.name} implements Production { + title: String! + cost: Float! + episodes: Int! + } + + type ${Cartoon.name} implements Production { + title: String! + cost: Float! + cartoonist: String! + } + + interface ActedIn @relationshipProperties { + screenTime: Int! + } + + type ${Actor.name} { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + `; + + const session = await neo4j.getSession(); + + try { + await session.run(` + CREATE(a:${Actor.name} { name: "Keanu" }) + CREATE(a)-[:ACTED_IN]->(m:${Movie.name} { title: "The Matrix" }) + CREATE(a)-[:ACTED_IN]->(s:${Series.name} { title: "The Matrix animated series" }) + CREATE(a)-[:ACTED_IN]->(c:${Cartoon.name} { title: "Matrix the cartoon" }) + `); + } finally { + await session.close(); + } + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + await cleanNodes(session, [Movie, Series, Cartoon]); + await session.close(); + await driver.close(); + }); + + test("should pass with a correct validate typename predicate", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Movie.name}] }] } } + } + } + } + ] + ) + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + name + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: expect.toIncludeSameMembers([ + { + name: "Keanu", + }, + ]), + }); + }); + + test("should fail with an incorrect validate typename predicate", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Series.name}] }] } } + } + } + } + ] + ) + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + name + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + + expect(queryResult.errors?.[0]?.message).toContain("Forbidden"); + }); + + test("should pass with a correct validate typename predicate (field level)", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + { + name: String! @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Movie.name}] }] } } + } + } + } + ] + ) + } + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + name + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: expect.toIncludeSameMembers([ + { + name: "Keanu", + }, + ]), + }); + }); + + test("should fail with an incorrect validate typename predicate (field level)", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + { + name: String! @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Series.name}] }] } } + } + } + } + ] + ) + } + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + name + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + + expect(queryResult.errors?.[0]?.message).toContain("Forbidden"); + }); + + test("should pass with an incorrect validate typename predicate (field level), when field is not selected", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + { + name: String! @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Series.name}] }] } } + } + } + } + ] + ) + } + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + actedIn { + title + } + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: expect.toIncludeSameMembers([ + { + actedIn: expect.arrayContaining([ + { + title: "The Matrix", + }, + ]), + }, + ]), + }); + }); + + test("should return data with a correct filter typename predicate", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + @authorization( + filter: [ + { + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Movie.name}] }] } } + } + } + } + ] + ) + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + name + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: expect.toIncludeSameMembers([ + { + name: "Keanu", + }, + ]), + }); + }); + + test("should not return data with an incorrect filter typename predicate", async () => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type ${Actor.name} + @authorization( + filter: [ + { + where: { + node: { + actedInConnection_SOME: { node: { AND: [ { title: "The Matrix" }, {typename_IN: [${Series.name}] }] } } + } + } + } + ] + ) + `; + const neoGraphql = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + driver, + experimental: true, + features: { + authorization: { + key: secret, + }, + }, + }); + schema = await neoGraphql.getSchema(); + const query = ` + { + ${Actor.plural} { + name + } + } + `; + const token = createBearerToken(secret, {}); + + const queryResult = await graphqlQuery(query, token); + + expect(queryResult.data).toEqual({ [Actor.plural]: expect.toBeArrayOfSize(0) }); + }); +}); diff --git a/packages/graphql/tests/integration/experimental/typename-in.int.test.ts b/packages/graphql/tests/integration/experimental/typename-in.int.test.ts new file mode 100644 index 00000000000..85b0aa48174 --- /dev/null +++ b/packages/graphql/tests/integration/experimental/typename-in.int.test.ts @@ -0,0 +1,215 @@ +/* + * 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 Neo4j from "../neo4j"; + +describe("typename_IN", () => { + let schema: GraphQLSchema; + let neo4j: Neo4j; + let driver: Driver; + let typeDefs: string; + + const Movie = new UniqueType("Movie"); + const Actor = new UniqueType("Actor"); + const Series = new UniqueType("Series"); + const Cartoon = new UniqueType("Cartoon"); + + async function graphqlQuery(query: string, token?: string) { + return graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ token }), + }); + } + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + + typeDefs = ` + interface Production { + title: String! + cost: Float! + } + + type ${Movie.name} implements Production { + title: String! + cost: Float! + runtime: Int! + } + + type ${Series.name} implements Production { + title: String! + cost: Float! + episodes: Int! + } + + type ${Cartoon.name} implements Production { + title: String! + cost: Float! + cartoonist: String! + } + + interface ActedIn @relationshipProperties { + screenTime: Int! + } + + type ${Actor.name} { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + `; + + const session = await neo4j.getSession(); + + try { + await session.run(` + CREATE(a:${Actor.name} { name: "Keanu" }) + CREATE(a)-[:ACTED_IN]->(m:${Movie.name} { title: "The Matrix" }) + CREATE(a)-[:ACTED_IN]->(s:${Series.name} { title: "The Matrix animated series" }) + CREATE(a)-[:ACTED_IN]->(c:${Cartoon.name} { title: "Matrix the cartoon" }) + `); + } finally { + await session.close(); + } + + const neoGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + experimental: true, + }); + schema = await neoGraphql.getSchema(); + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + await cleanNodes(session, [Movie, Series, Cartoon]); + await session.close(); + await driver.close(); + }); + + test("top-level", async () => { + const query = ` + { + productions(where: { OR: [{ AND: [{ title: "The Matrix" }, { typename_IN: [${Movie.name}] }] }, { typename_IN: [${Series.name}] }]}) { + __typename + title + } + } + `; + + const queryResult = await graphqlQuery(query); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + productions: expect.toIncludeSameMembers([ + { + __typename: Movie.name, + title: "The Matrix", + }, + { + __typename: Series.name, + title: "The Matrix animated series", + }, + ]), + }); + }); + + test("nested", async () => { + const query = ` + { + ${Actor.plural} { + actedIn(where: { OR: [ + { AND: [{ title: "The Matrix" }, { typename_IN: [${Movie.name}] }] } + { typename_IN: [${Series.name}] } + ] }) { + __typename + title + } + } + } + `; + + const queryResult = await graphqlQuery(query); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: [ + { + actedIn: expect.toIncludeSameMembers([ + { + __typename: Movie.name, + title: "The Matrix", + }, + { + __typename: Series.name, + title: "The Matrix animated series", + }, + ]), + }, + ], + }); + }); + + test("aggregation", async () => { + const query = ` + { + productionsAggregate(where: { OR: [ { typename_IN: [${Movie.name}, ${Series.name}] } { typename_IN: [${Cartoon.name}] } ] }) { + count + } + } + `; + + const queryResult = await graphqlQuery(query); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + productionsAggregate: { + count: 3, + }, + }); + }); + + test("nested aggregation", async () => { + const query = ` + { + ${Actor.plural} { + actedInAggregate(where: { NOT: { typename_IN: [${Movie.name}, ${Series.name}] } }) { + count + } + } + } + `; + + const queryResult = await graphqlQuery(query); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: expect.arrayContaining([ + { + actedInAggregate: { + count: 1, + }, + }, + ]), + }); + }); +}); diff --git a/packages/graphql/tests/integration/issues/4405.int.test.ts b/packages/graphql/tests/integration/issues/4405.int.test.ts new file mode 100644 index 00000000000..5b7af981a94 --- /dev/null +++ b/packages/graphql/tests/integration/issues/4405.int.test.ts @@ -0,0 +1,136 @@ +/* + * 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 { Driver } from "neo4j-driver"; +import Neo4j from "../neo4j"; +import { Neo4jGraphQL } from "../../../src/classes"; +import { graphql } from "graphql"; +import { UniqueType } from "../../utils/graphql-types"; +import { cleanNodes } from "../../utils/clean-nodes"; + +describe("https://github.com/neo4j/graphql/issues/4405", () => { + let driver: Driver; + let neo4j: Neo4j; + let neo4jGraphql: Neo4jGraphQL; + const Movie = new UniqueType("Movie"); + const Actor = new UniqueType("Actor"); + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + const typeDefs = /* GraphQL */ ` + type ${Movie.name} { + title: String + } + + type ${Actor.name} + @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { node: { actedInConnection_SOME: { node: { title_IN: ["Matrix", "John Wick"] } } } } + } + ] + ) { + name: String! + actedIn: [${Movie.name}!]! @relationship(type: "ACTED_IN", direction: OUT) + } + `; + neo4jGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + features: { + authorization: { + key: "secret", + }, + }, + }); + + const session = await neo4j.getSession(); + try { + await session.run( + ` + CREATE (m:${Movie.name} {title: "Matrix" })<-[:ACTED_IN]-(a:${Actor.name} { name: "Keanu"}) + CREATE (a)-[:ACTED_IN]->(:${Movie.name} {title: "John Wick" }) + CREATE (m2:${Movie.name} {title: "Hunger games" })<-[:ACTED_IN]-(a2:${Actor.name} { name: "Laurence"}) + + `, + {} + ); + } finally { + await session.close(); + } + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + try { + await cleanNodes(session, [Movie.name, Actor.name]); + } finally { + await session.close(); + } + await driver.close(); + }); + + test("should not raise if title is the filter array value", async () => { + const schema = await neo4jGraphql.getSchema(); + + const query = /* GraphQL */ ` + query Actors { + ${Actor.plural}(where: { name: "Keanu"}) { + name + } + } + `; + + const response = await graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ jwt: { uid: "user-1" } }), + }); + expect(response.errors).toBeFalsy(); + expect(response.data?.[Actor.plural]).toStrictEqual( + expect.arrayContaining([ + { + name: "Keanu", + }, + ]) + ); + }); + + test("should raise if title is not in the filter array value", async () => { + const schema = await neo4jGraphql.getSchema(); + + const query = /* GraphQL */ ` + query Actors { + ${Actor.plural}(where: { name: "Laurence"}) { + name + } + } + `; + + const response = await graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ jwt: { uid: "user-1" } }), + }); + expect(response.errors?.[0]?.message).toContain("Forbidden"); + }); +}); diff --git a/packages/graphql/tests/schema/experimental-schema/comments.test.ts b/packages/graphql/tests/schema/experimental-schema/comments.test.ts index c0fed31a04a..a4e8d92a47d 100644 --- a/packages/graphql/tests/schema/experimental-schema/comments.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/comments.test.ts @@ -1098,6 +1098,11 @@ describe("Comments", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -1138,6 +1143,7 @@ describe("Comments", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { 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 28dc4af3189..504ee386512 100644 --- a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts @@ -1521,6 +1521,11 @@ describe("Directive-preserve", () => { _on: ProductionImplementationsDisconnectInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -1576,6 +1581,7 @@ describe("Directive-preserve", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -2516,6 +2522,11 @@ describe("Directive-preserve", () => { _on: ProductionImplementationsDisconnectInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -2571,6 +2582,7 @@ describe("Directive-preserve", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { 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 0534c6bae67..9f2ddcd7c3c 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/default.test.ts @@ -215,6 +215,10 @@ describe("@default directive", () => { toBeOverridden: StringAggregateSelectionNonNullable! } + enum UserInterfaceImplementation { + User + } + input UserInterfaceOptions { limit: Int offset: Int @@ -256,6 +260,7 @@ describe("@default directive", () => { toBeOverridden_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") toBeOverridden_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") toBeOverridden_STARTS_WITH: String + typename_IN: [UserInterfaceImplementation!] } input UserOptions { 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 e8f336072c9..bb00512ee19 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/filterable.test.ts @@ -7362,6 +7362,10 @@ describe("@filterable directive", () => { username: String! } + enum PersonImplementation { + Actor + } + input PersonImplementationsConnectInput { Actor: [ActorConnectInput!] } @@ -7419,6 +7423,7 @@ describe("@filterable directive", () => { AND: [PersonWhere!] NOT: PersonWhere OR: [PersonWhere!] + typename_IN: [PersonImplementation!] username: String username_CONTAINS: String username_ENDS_WITH: String 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 4e70a7f29df..a089aa8d6d5 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/private.test.ts @@ -146,6 +146,10 @@ describe("@private directive", () => { id: IDAggregateSelectionNullable! } + enum UserInterfaceImplementation { + User + } + input UserInterfaceOptions { limit: Int offset: Int @@ -176,6 +180,7 @@ describe("@private directive", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [UserInterfaceImplementation!] } input UserOptions { 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 9899f0dc978..65698ea852e 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 @@ -1446,6 +1446,10 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorCreateInput } + enum PersonImplementation { + Actor + } + input PersonImplementationsUpdateInput { Actor: ActorUpdateInput } @@ -1487,6 +1491,7 @@ describe("@relationship directive, aggregate argument", () => { password_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") password_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") password_STARTS_WITH: String + typename_IN: [PersonImplementation!] username: String username_CONTAINS: String username_ENDS_WITH: String @@ -1882,6 +1887,10 @@ describe("@relationship directive, aggregate argument", () => { Actor: ActorCreateInput } + enum PersonImplementation { + Actor + } + input PersonImplementationsUpdateInput { Actor: ActorUpdateInput } @@ -1923,6 +1932,7 @@ describe("@relationship directive, aggregate argument", () => { password_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") password_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") password_STARTS_WITH: String + typename_IN: [PersonImplementation!] username: String username_CONTAINS: String username_ENDS_WITH: String 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 7213b559ad9..f8a44943b42 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 @@ -8734,6 +8734,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } + enum PersonImplementation { + PersonOne + PersonTwo + } + type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -8893,6 +8898,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -9183,6 +9189,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + enum PersonImplementation { + PersonOne + PersonTwo + } + type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -9342,6 +9353,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -9631,6 +9643,11 @@ describe("Relationship nested operations", () => { node: PersonWhere! } + enum PersonImplementation { + PersonOne + PersonTwo + } + type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -9790,6 +9807,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -10066,6 +10084,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } + enum PersonImplementation { + PersonOne + PersonTwo + } + input PersonImplementationsUpdateInput { PersonOne: PersonOneUpdateInput PersonTwo: PersonTwoUpdateInput @@ -10235,6 +10258,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -10515,6 +10539,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } + enum PersonImplementation { + PersonOne + PersonTwo + } + type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -10674,6 +10703,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -10954,6 +10984,11 @@ describe("Relationship nested operations", () => { name: StringAggregateSelectionNullable! } + enum PersonImplementation { + PersonOne + PersonTwo + } + type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -11113,6 +11148,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -11505,6 +11541,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + enum PersonImplementation { + PersonOne + PersonTwo + } + input PersonImplementationsUpdateInput { PersonOne: PersonOneUpdateInput PersonTwo: PersonTwoUpdateInput @@ -11674,6 +11715,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { @@ -12042,6 +12084,11 @@ describe("Relationship nested operations", () => { PersonTwo: PersonTwoCreateInput } + enum PersonImplementation { + PersonOne + PersonTwo + } + type PersonOne implements Person { name: String someExtraProp: [Int!]! @@ -12201,6 +12248,7 @@ describe("Relationship nested operations", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { 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 bfb7ad8a19a..a1616e1ff1a 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts @@ -3067,6 +3067,11 @@ describe("@selectable", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -3119,6 +3124,7 @@ describe("@selectable", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -3601,6 +3607,11 @@ describe("@selectable", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -3653,6 +3664,7 @@ describe("@selectable", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { 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 0b9b2d27f59..e653d9222cf 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts @@ -5554,6 +5554,11 @@ describe("@settable", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -5606,6 +5611,7 @@ describe("@settable", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -6075,6 +6081,11 @@ describe("@settable", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionOptions { limit: Int offset: Int @@ -6116,6 +6127,7 @@ describe("@settable", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -6839,6 +6851,11 @@ describe("@settable", () => { actors: [ProductionActorsDisconnectFieldInput!] } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -6924,6 +6941,7 @@ describe("@settable", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -7767,6 +7785,11 @@ describe("@settable", () => { actors: [ProductionActorsDisconnectFieldInput!] } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -7864,6 +7887,7 @@ describe("@settable", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { diff --git a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts index cad158581c0..31a123f91b5 100644 --- a/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/inheritance.test.ts @@ -385,6 +385,10 @@ describe("inheritance", () => { where: PersonFriendsConnectionWhere } + enum PersonImplementation { + Actor + } + input PersonImplementationsConnectInput { Actor: [ActorConnectInput!] } @@ -455,6 +459,7 @@ describe("inheritance", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [PersonImplementation!] } type Query { 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 0ba86e54146..f8e7a944142 100644 --- a/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interface-relationships.test.ts @@ -419,6 +419,11 @@ describe("Interface Relationships", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -459,6 +464,7 @@ describe("Interface Relationships", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -1575,6 +1581,11 @@ describe("Interface Relationships", () => { actors: [ProductionActorsDisconnectFieldInput!] } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -1660,6 +1671,7 @@ describe("Interface Relationships", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -2229,6 +2241,11 @@ describe("Interface Relationships", () => { interface2: [Interface1Interface2DisconnectFieldInput!] } + enum Interface1Implementation { + Type1Interface1 + Type2Interface1 + } + input Interface1ImplementationsConnectInput { Type1Interface1: [Type1Interface1ConnectInput!] Type2Interface1: [Type2Interface1ConnectInput!] @@ -2360,6 +2377,7 @@ describe("Interface Relationships", () => { Return Interface1s where some of the related Interface1Interface2Connections match this filter \\"\\"\\" interface2Connection_SOME: Interface1Interface2ConnectionWhere + typename_IN: [Interface1Implementation!] } interface Interface2 { @@ -2380,6 +2398,11 @@ describe("Interface Relationships", () => { Type2Interface2: Type2Interface2CreateInput } + enum Interface2Implementation { + Type1Interface2 + Type2Interface2 + } + input Interface2ImplementationsUpdateInput { Type1Interface2: Type1Interface2UpdateInput Type2Interface2: Type2Interface2UpdateInput @@ -2420,6 +2443,7 @@ describe("Interface Relationships", () => { field2_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") field2_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") field2_STARTS_WITH: String + typename_IN: [Interface2Implementation!] } type Mutation { @@ -3597,6 +3621,11 @@ describe("Interface Relationships", () => { creator: ContentCreatorDisconnectFieldInput } + enum ContentImplementation { + Comment + Post + } + input ContentImplementationsConnectInput { Comment: [CommentConnectInput!] Post: [PostConnectInput!] @@ -3670,6 +3699,7 @@ describe("Interface Relationships", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [ContentImplementation!] } type CreateCommentsMutationResponse { diff --git a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts index bd927609f56..e26b066f4e5 100644 --- a/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/interfaces.test.ts @@ -162,6 +162,10 @@ describe("Interfaces", () => { id: IDAggregateSelectionNullable! } + enum MovieNodeImplementation { + Movie + } + input MovieNodeMoviesConnectFieldInput { connect: [MovieConnectInput!] \\"\\"\\" @@ -256,6 +260,7 @@ describe("Interfaces", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [MovieNodeImplementation!] } input MovieOptions { @@ -524,6 +529,10 @@ describe("Interfaces", () => { id: IDAggregateSelectionNullable! } + enum MovieNodeImplementation { + Movie + } + input MovieNodeMoviesConnectFieldInput { connect: [MovieConnectInput!] \\"\\"\\" @@ -618,6 +627,7 @@ describe("Interfaces", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [MovieNodeImplementation!] } input MovieOptions { 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 a6dc7efeeb7..6c39982c0a9 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,10 @@ describe("Interface Top Level Aggregations", () => { title: StringAggregateSelectionNonNullable! } + enum ProductionImplementation { + Movie + } + input ProductionOptions { limit: Int offset: Int @@ -238,6 +242,7 @@ describe("Interface Top Level Aggregations", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -705,6 +710,11 @@ describe("Interface Top Level Aggregations", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -759,6 +769,7 @@ describe("Interface Top Level Aggregations", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { 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 new file mode 100644 index 00000000000..55fbe71a7f6 --- /dev/null +++ b/packages/graphql/tests/schema/experimental-schema/interfaces/typename-in.test.ts @@ -0,0 +1,611 @@ +/* + * 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 { printSchemaWithDirectives } from "@graphql-tools/utils"; +import { gql } from "graphql-tag"; +import { lexicographicSortSchema } from "graphql/utilities"; +import { Neo4jGraphQL } from "../../../../src"; + +describe("typename_IN", () => { + test("typename_IN", async () => { + const typeDefs = gql` + interface Production { + title: String! + cost: Float! + } + + type Movie implements Production { + title: String! + cost: Float! + runtime: Int! + } + + type Series implements Production { + title: String! + cost: Float! + episodes: Int! + } + + type Actor { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT) + } + `; + const neoSchema = new Neo4jGraphQL({ typeDefs, experimental: true }); + const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); + expect(printedSchema).toMatchInlineSnapshot(` + "schema { + query: Query + mutation: Mutation + } + + type Actor { + actedIn(directed: Boolean = true, options: ProductionOptions, where: ProductionWhere): [Production!]! + actedInAggregate(directed: Boolean = true, where: ProductionWhere): ActorProductionActedInAggregationSelection + actedInConnection(after: String, directed: Boolean = true, first: Int, sort: [ActorActedInConnectionSort!], where: ActorActedInConnectionWhere): ActorActedInConnection! + name: String! + } + + input ActorActedInConnectFieldInput { + where: ProductionConnectWhere + } + + type ActorActedInConnection { + edges: [ActorActedInRelationship!]! + pageInfo: PageInfo! + totalCount: Int! + } + + input ActorActedInConnectionSort { + node: ProductionSort + } + + input ActorActedInConnectionWhere { + AND: [ActorActedInConnectionWhere!] + NOT: ActorActedInConnectionWhere + OR: [ActorActedInConnectionWhere!] + node: ProductionWhere + node_NOT: ProductionWhere @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + } + + input ActorActedInCreateFieldInput { + node: ProductionCreateInput! + } + + input ActorActedInDeleteFieldInput { + where: ActorActedInConnectionWhere + } + + input ActorActedInDisconnectFieldInput { + where: ActorActedInConnectionWhere + } + + input ActorActedInFieldInput { + connect: [ActorActedInConnectFieldInput!] + create: [ActorActedInCreateFieldInput!] + } + + type ActorActedInRelationship { + cursor: String! + node: Production! + } + + input ActorActedInUpdateConnectionInput { + node: ProductionUpdateInput + } + + input ActorActedInUpdateFieldInput { + connect: [ActorActedInConnectFieldInput!] + create: [ActorActedInCreateFieldInput!] + delete: [ActorActedInDeleteFieldInput!] + disconnect: [ActorActedInDisconnectFieldInput!] + update: ActorActedInUpdateConnectionInput + where: ActorActedInConnectionWhere + } + + type ActorAggregateSelection { + count: Int! + name: StringAggregateSelectionNonNullable! + } + + input ActorConnectInput { + actedIn: [ActorActedInConnectFieldInput!] + } + + input ActorCreateInput { + actedIn: ActorActedInFieldInput + name: String! + } + + input ActorDeleteInput { + actedIn: [ActorActedInDeleteFieldInput!] + } + + input ActorDisconnectInput { + actedIn: [ActorActedInDisconnectFieldInput!] + } + + type ActorEdge { + cursor: String! + node: Actor! + } + + input ActorOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more ActorSort objects to sort Actors by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [ActorSort!] + } + + type ActorProductionActedInAggregationSelection { + count: Int! + node: ActorProductionActedInNodeAggregateSelection + } + + type ActorProductionActedInNodeAggregateSelection { + cost: FloatAggregateSelectionNonNullable! + title: StringAggregateSelectionNonNullable! + } + + input ActorRelationInput { + actedIn: [ActorActedInCreateFieldInput!] + } + + \\"\\"\\" + Fields to sort Actors by. The order in which sorts are applied is not guaranteed when specifying many fields in one ActorSort object. + \\"\\"\\" + input ActorSort { + name: SortDirection + } + + input ActorUpdateInput { + actedIn: [ActorActedInUpdateFieldInput!] + name: String + } + + input ActorWhere { + AND: [ActorWhere!] + NOT: ActorWhere + OR: [ActorWhere!] + actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") + \\"\\"\\" + Return Actors where all of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_ALL: ActorActedInConnectionWhere + \\"\\"\\" + Return Actors where none of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_NONE: ActorActedInConnectionWhere + actedInConnection_NOT: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_NONE\` instead.\\") + \\"\\"\\" + Return Actors where one of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_SINGLE: ActorActedInConnectionWhere + \\"\\"\\" + Return Actors where some of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_SOME: ActorActedInConnectionWhere + name: String + name_CONTAINS: String + name_ENDS_WITH: String + name_IN: [String!] + name_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_STARTS_WITH: String + } + + type ActorsConnection { + edges: [ActorEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + type CreateActorsMutationResponse { + actors: [Actor!]! + info: CreateInfo! + } + + \\"\\"\\" + Information about the number of nodes and relationships created during a create mutation + \\"\\"\\" + type CreateInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesCreated: Int! + relationshipsCreated: Int! + } + + type CreateMoviesMutationResponse { + info: CreateInfo! + movies: [Movie!]! + } + + type CreateSeriesMutationResponse { + info: CreateInfo! + series: [Series!]! + } + + \\"\\"\\" + Information about the number of nodes and relationships deleted during a delete mutation + \\"\\"\\" + type DeleteInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesDeleted: Int! + relationshipsDeleted: Int! + } + + type FloatAggregateSelectionNonNullable { + average: Float! + max: Float! + min: Float! + sum: Float! + } + + type IntAggregateSelectionNonNullable { + average: Float! + max: Int! + min: Int! + sum: Int! + } + + type Movie implements Production { + cost: Float! + runtime: Int! + title: String! + } + + type MovieAggregateSelection { + cost: FloatAggregateSelectionNonNullable! + count: Int! + runtime: IntAggregateSelectionNonNullable! + title: StringAggregateSelectionNonNullable! + } + + input MovieCreateInput { + cost: Float! + runtime: Int! + title: String! + } + + type MovieEdge { + cursor: String! + node: Movie! + } + + input MovieOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more MovieSort objects to sort Movies by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [MovieSort!] + } + + \\"\\"\\" + Fields to sort Movies by. The order in which sorts are applied is not guaranteed when specifying many fields in one MovieSort object. + \\"\\"\\" + input MovieSort { + cost: SortDirection + runtime: SortDirection + title: SortDirection + } + + input MovieUpdateInput { + cost: Float + cost_ADD: Float + cost_DIVIDE: Float + cost_MULTIPLY: Float + cost_SUBTRACT: Float + runtime: Int + runtime_DECREMENT: Int + runtime_INCREMENT: Int + title: String + } + + input MovieWhere { + AND: [MovieWhere!] + NOT: MovieWhere + OR: [MovieWhere!] + cost: Float + cost_GT: Float + cost_GTE: Float + cost_IN: [Float!] + cost_LT: Float + cost_LTE: Float + cost_NOT: Float @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + cost_NOT_IN: [Float!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + runtime: Int + runtime_GT: Int + runtime_GTE: Int + runtime_IN: [Int!] + runtime_LT: Int + runtime_LTE: Int + runtime_NOT: Int @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + runtime_NOT_IN: [Int!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title: String + title_CONTAINS: String + title_ENDS_WITH: String + title_IN: [String!] + title_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_STARTS_WITH: String + } + + type MoviesConnection { + edges: [MovieEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + type Mutation { + createActors(input: [ActorCreateInput!]!): CreateActorsMutationResponse! + createMovies(input: [MovieCreateInput!]!): CreateMoviesMutationResponse! + createSeries(input: [SeriesCreateInput!]!): CreateSeriesMutationResponse! + deleteActors(delete: ActorDeleteInput, where: ActorWhere): DeleteInfo! + deleteMovies(where: MovieWhere): DeleteInfo! + deleteSeries(where: SeriesWhere): DeleteInfo! + updateActors(connect: ActorConnectInput, create: ActorRelationInput, delete: ActorDeleteInput, disconnect: ActorDisconnectInput, update: ActorUpdateInput, where: ActorWhere): UpdateActorsMutationResponse! + updateMovies(update: MovieUpdateInput, where: MovieWhere): UpdateMoviesMutationResponse! + updateSeries(update: SeriesUpdateInput, where: SeriesWhere): UpdateSeriesMutationResponse! + } + + \\"\\"\\"Pagination information (Relay)\\"\\"\\" + type PageInfo { + endCursor: String + hasNextPage: Boolean! + hasPreviousPage: Boolean! + startCursor: String + } + + interface Production { + cost: Float! + title: String! + } + + type ProductionAggregateSelection { + cost: FloatAggregateSelectionNonNullable! + count: Int! + title: StringAggregateSelectionNonNullable! + } + + input ProductionConnectWhere { + node: ProductionWhere! + } + + input ProductionCreateInput { + Movie: MovieCreateInput + Series: SeriesCreateInput + } + + enum ProductionImplementation { + Movie + Series + } + + input ProductionImplementationsUpdateInput { + Movie: MovieUpdateInput + Series: SeriesUpdateInput + } + + input ProductionOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more ProductionSort objects to sort Productions by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [ProductionSort] + } + + \\"\\"\\" + Fields to sort Productions by. The order in which sorts are applied is not guaranteed when specifying many fields in one ProductionSort object. + \\"\\"\\" + input ProductionSort { + cost: SortDirection + title: SortDirection + } + + input ProductionUpdateInput { + _on: ProductionImplementationsUpdateInput + cost: Float + cost_ADD: Float + cost_DIVIDE: Float + cost_MULTIPLY: Float + cost_SUBTRACT: Float + title: String + } + + input ProductionWhere { + AND: [ProductionWhere!] + NOT: ProductionWhere + OR: [ProductionWhere!] + cost: Float + cost_GT: Float + cost_GTE: Float + cost_IN: [Float!] + cost_LT: Float + cost_LTE: Float + cost_NOT: Float @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + cost_NOT_IN: [Float!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title: String + title_CONTAINS: String + title_ENDS_WITH: String + title_IN: [String!] + title_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] + } + + type Query { + actors(options: ActorOptions, where: ActorWhere): [Actor!]! + actorsAggregate(where: ActorWhere): ActorAggregateSelection! + actorsConnection(after: String, first: Int, sort: [ActorSort], where: ActorWhere): ActorsConnection! + 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! + series(options: SeriesOptions, where: SeriesWhere): [Series!]! + seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! + seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! + } + + type Series implements Production { + cost: Float! + episodes: Int! + title: String! + } + + type SeriesAggregateSelection { + cost: FloatAggregateSelectionNonNullable! + count: Int! + episodes: IntAggregateSelectionNonNullable! + title: StringAggregateSelectionNonNullable! + } + + type SeriesConnection { + edges: [SeriesEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + input SeriesCreateInput { + cost: Float! + episodes: Int! + title: String! + } + + type SeriesEdge { + cursor: String! + node: Series! + } + + input SeriesOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more SeriesSort objects to sort Series by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [SeriesSort!] + } + + \\"\\"\\" + Fields to sort Series by. The order in which sorts are applied is not guaranteed when specifying many fields in one SeriesSort object. + \\"\\"\\" + input SeriesSort { + cost: SortDirection + episodes: SortDirection + title: SortDirection + } + + input SeriesUpdateInput { + cost: Float + cost_ADD: Float + cost_DIVIDE: Float + cost_MULTIPLY: Float + cost_SUBTRACT: Float + episodes: Int + episodes_DECREMENT: Int + episodes_INCREMENT: Int + title: String + } + + input SeriesWhere { + AND: [SeriesWhere!] + NOT: SeriesWhere + OR: [SeriesWhere!] + cost: Float + cost_GT: Float + cost_GTE: Float + cost_IN: [Float!] + cost_LT: Float + cost_LTE: Float + cost_NOT: Float @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + cost_NOT_IN: [Float!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + episodes: Int + episodes_GT: Int + episodes_GTE: Int + episodes_IN: [Int!] + episodes_LT: Int + episodes_LTE: Int + episodes_NOT: Int @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + episodes_NOT_IN: [Int!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title: String + title_CONTAINS: String + title_ENDS_WITH: String + title_IN: [String!] + title_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_STARTS_WITH: String + } + + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" + enum SortDirection { + \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" + ASC + \\"\\"\\"Sort by field values in descending order.\\"\\"\\" + DESC + } + + type StringAggregateSelectionNonNullable { + longest: String! + shortest: String! + } + + type UpdateActorsMutationResponse { + actors: [Actor!]! + info: UpdateInfo! + } + + \\"\\"\\" + Information about the number of nodes and relationships created and deleted during an update mutation + \\"\\"\\" + type UpdateInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesCreated: Int! + nodesDeleted: Int! + relationshipsCreated: Int! + relationshipsDeleted: Int! + } + + type UpdateMoviesMutationResponse { + info: UpdateInfo! + movies: [Movie!]! + } + + type UpdateSeriesMutationResponse { + info: UpdateInfo! + series: [Series!]! + }" + `); + }); +}); 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 d86a42d7874..74e7e1fb7cd 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts @@ -388,6 +388,10 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { name: StringAggregateSelectionNullable! } + enum ResourceEntityImplementation { + Resource + } + input ResourceEntityOptions { limit: Int offset: Int @@ -442,6 +446,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { type_IN: [ResourceType!] type_NOT: ResourceType @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") type_NOT_IN: [ResourceType!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + typename_IN: [ResourceEntityImplementation!] } input ResourceOnCreateInput { 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 9a28707a9e0..cf1894d2648 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts @@ -153,6 +153,10 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { _on: ProfileImplementationsDisconnectInput } + enum ProfileImplementation { + User + } + input ProfileImplementationsConnectInput { User: [UserConnectInput!] } @@ -206,6 +210,7 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { id_NOT_IN: [ID!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [ProfileImplementation!] userName: String userName_CONTAINS: String userName_ENDS_WITH: String @@ -577,6 +582,10 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { _on: ProfileImplementationsDisconnectInput } + enum ProfileImplementation { + User + } + input ProfileImplementationsConnectInput { User: [UserConnectInput!] } @@ -629,6 +638,7 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { id_NOT_IN: [ID!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [ProfileImplementation!] userName: String userName_CONTAINS: String userName_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts index 174cf3a4afb..789f9efffad 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/3439.test.ts @@ -400,6 +400,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { id: StringAggregateSelectionNonNullable! } + enum INodeImplementation { + Movie + Series + } + input INodeOptions { limit: Int offset: Int @@ -430,6 +435,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { id_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: String + typename_IN: [INodeImplementation!] } interface IProduct { @@ -470,6 +476,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + enum IProductImplementation { + Movie + Series + } + input IProductImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -563,6 +574,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [IProductImplementation!] } type Movie implements INode & IProduct { @@ -1815,6 +1827,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { where: IProductGenreConnectionWhere } + enum IProductImplementation { + Movie + Series + } + input IProductImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -1908,6 +1925,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [IProductImplementation!] } type Movie implements IProduct { @@ -2902,6 +2920,11 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name: String! } + enum IProductImplementation { + Movie + Series + } + input IProductImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -2980,6 +3003,7 @@ describe("https://github.com/neo4j/graphql/issues/3439", () => { name_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [IProductImplementation!] } type Movie implements IProduct { diff --git a/packages/graphql/tests/schema/experimental-schema/math.test.ts b/packages/graphql/tests/schema/experimental-schema/math.test.ts index 95be8ee3b73..364fd3cda3d 100644 --- a/packages/graphql/tests/schema/experimental-schema/math.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/math.test.ts @@ -1664,6 +1664,10 @@ describe("Algebraic", () => { _on: ProductionImplementationsDisconnectInput } + enum ProductionImplementation { + Movie + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] } @@ -1707,6 +1711,7 @@ describe("Algebraic", () => { AND: [ProductionWhere!] NOT: ProductionWhere OR: [ProductionWhere!] + typename_IN: [ProductionImplementation!] viewers: Int viewers_GT: Int viewers_GTE: Int 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 0731ebf8663..c53e8d3bf88 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 @@ -430,6 +430,11 @@ describe("nested aggregation on interface", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -484,6 +489,7 @@ describe("nested aggregation on interface", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { @@ -1044,6 +1050,11 @@ describe("nested aggregation on interface", () => { Series: SeriesCreateInput } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsUpdateInput { Movie: MovieUpdateInput Series: SeriesUpdateInput @@ -1098,6 +1109,7 @@ describe("nested aggregation on interface", () => { title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") title_STARTS_WITH: String + typename_IN: [ProductionImplementation!] } type Query { diff --git a/packages/graphql/tests/schema/experimental-schema/plural.test.ts b/packages/graphql/tests/schema/experimental-schema/plural.test.ts index 2297b2b1a61..c616a4401f8 100644 --- a/packages/graphql/tests/schema/experimental-schema/plural.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/plural.test.ts @@ -58,6 +58,10 @@ describe("Experimental Plural option", () => { name: StringAggregateSelectionNullable! } + enum AnimalImplementation { + Dog + } + input AnimalOptions { limit: Int offset: Int @@ -88,6 +92,7 @@ describe("Experimental Plural option", () => { name_NOT_IN: [String] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") name_STARTS_WITH: String + typename_IN: [AnimalImplementation!] } type Cat { diff --git a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts index 5e30f9f616d..b8091c1ff33 100644 --- a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts @@ -5766,6 +5766,10 @@ describe("Subscriptions", () => { movies: CreatureMoviesDisconnectFieldInput } + enum CreatureImplementation { + Person + } + input CreatureImplementationsConnectInput { Person: [PersonConnectInput!] } @@ -5858,6 +5862,7 @@ describe("Subscriptions", () => { OR: [CreatureWhere!] moviesConnection: CreatureMoviesConnectionWhere moviesConnection_NOT: CreatureMoviesConnectionWhere + typename_IN: [CreatureImplementation!] } \\"\\"\\" @@ -6294,6 +6299,11 @@ describe("Subscriptions", () => { id: ID } + enum ProductionImplementation { + Movie + Series + } + input ProductionImplementationsConnectInput { Movie: [MovieConnectInput!] Series: [SeriesConnectInput!] @@ -6368,6 +6378,7 @@ describe("Subscriptions", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + typename_IN: [ProductionImplementation!] } type Query { 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 56744f2f329..905d0c3647e 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 @@ -1815,6 +1815,11 @@ describe("Union Interface Relationships", () => { _on: ReviewerImplementationsDisconnectInput } + enum ReviewerImplementation { + Influencer + Person + } + input ReviewerImplementationsConnectInput { Person: [PersonConnectInput!] } @@ -1879,6 +1884,7 @@ describe("Union Interface Relationships", () => { reviewerId_LTE: Int reviewerId_NOT: Int @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") reviewerId_NOT_IN: [Int] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + typename_IN: [ReviewerImplementation!] } \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" diff --git a/packages/graphql/tests/tck/experimental/typename-in-auth.test.ts b/packages/graphql/tests/tck/experimental/typename-in-auth.test.ts new file mode 100644 index 00000000000..3e7c2ce1603 --- /dev/null +++ b/packages/graphql/tests/tck/experimental/typename-in-auth.test.ts @@ -0,0 +1,338 @@ +/* + * 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 { gql } from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; + +describe("typename_IN with auth", () => { + let typeDefs: string; + let neoSchema: Neo4jGraphQL; + + beforeAll(() => { + typeDefs = /* GraphQL */ ` + interface Production { + title: String! + cost: Float! + } + + type Movie implements Production { + title: String! + cost: Float! + runtime: Int! + } + + type Series implements Production { + title: String! + cost: Float! + episodes: Int! + } + + type Cartoon implements Production { + title: String! + cost: Float! + cartoonist: String! + } + type Actor { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + + interface ActedIn @relationshipProperties { + screenTime: Int! + } + `; + }); + + describe("validate", () => { + beforeAll(() => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type Actor + @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { + node: { title: "The Matrix", typename_IN: [Series] } + } + } + } + } + ] + ) + `; + + neoSchema = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + experimental: true, + }); + }); + + test("read", async () => { + const query = gql` + { + actors { + actedIn { + title + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this)-[this1:ACTED_IN]->(this0) WHERE ((($param1 IS NOT NULL AND this0.title = $param1) AND this0:Series) AND (this0:Movie OR this0:Series OR this0:Cartoon)) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + CALL { + WITH this + CALL { + WITH * + MATCH (this)-[this2:ACTED_IN]->(this3:Movie) + WITH this3 { .title, __resolveType: \\"Movie\\", __id: id(this3) } AS this3 + RETURN this3 AS var4 + UNION + WITH * + MATCH (this)-[this5:ACTED_IN]->(this6:Series) + WITH this6 { .title, __resolveType: \\"Series\\", __id: id(this6) } AS this6 + RETURN this6 AS var4 + UNION + WITH * + MATCH (this)-[this7:ACTED_IN]->(this8:Cartoon) + WITH this8 { .title, __resolveType: \\"Cartoon\\", __id: id(this8) } AS this8 + RETURN this8 AS var4 + } + WITH var4 + RETURN collect(var4) AS var4 + } + RETURN this { actedIn: var4 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": false, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + + test("connection read", async () => { + const query = gql` + { + actorsConnection { + edges { + node { + actedIn { + title + } + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this0:Actor) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this0)-[this2:ACTED_IN]->(this1) WHERE ((($param1 IS NOT NULL AND this1.title = $param1) AND this1:Series) AND (this1:Movie OR this1:Series OR this1:Cartoon)) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH collect({ node: this0 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + CALL { + WITH * + MATCH (this0)-[this3:ACTED_IN]->(this4:Movie) + WITH this4 { .title, __resolveType: \\"Movie\\", __id: id(this4) } AS this4 + RETURN this4 AS var5 + UNION + WITH * + MATCH (this0)-[this6:ACTED_IN]->(this7:Series) + WITH this7 { .title, __resolveType: \\"Series\\", __id: id(this7) } AS this7 + RETURN this7 AS var5 + UNION + WITH * + MATCH (this0)-[this8:ACTED_IN]->(this9:Cartoon) + WITH this9 { .title, __resolveType: \\"Cartoon\\", __id: id(this9) } AS this9 + RETURN this9 AS var5 + } + WITH var5 + RETURN collect(var5) AS var5 + } + RETURN collect({ node: { actedIn: var5 } }) AS var10 + } + RETURN { edges: var10, totalCount: totalCount } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": false, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + }); + + describe("filter", () => { + beforeAll(() => { + const authTypeDefs = + typeDefs + + /* GraphQL */ ` + extend type Actor + @authorization( + filter: [ + { + where: { + node: { + actedInConnection_SOME: { + node: { title: "The Matrix", typename_IN: [Series] } + } + } + } + } + ] + ) + `; + + neoSchema = new Neo4jGraphQL({ + typeDefs: authTypeDefs, + experimental: true, + }); + }); + + test("read", async () => { + const query = gql` + { + actors { + actedIn { + title + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + WITH * + WHERE ($isAuthenticated = true AND size([(this)-[this1:ACTED_IN]->(this0) WHERE ((($param1 IS NOT NULL AND this0.title = $param1) AND this0:Series) AND (this0:Movie OR this0:Series OR this0:Cartoon)) | 1]) > 0) + CALL { + WITH this + CALL { + WITH * + MATCH (this)-[this2:ACTED_IN]->(this3:Movie) + WITH this3 { .title, __resolveType: \\"Movie\\", __id: id(this3) } AS this3 + RETURN this3 AS var4 + UNION + WITH * + MATCH (this)-[this5:ACTED_IN]->(this6:Series) + WITH this6 { .title, __resolveType: \\"Series\\", __id: id(this6) } AS this6 + RETURN this6 AS var4 + UNION + WITH * + MATCH (this)-[this7:ACTED_IN]->(this8:Cartoon) + WITH this8 { .title, __resolveType: \\"Cartoon\\", __id: id(this8) } AS this8 + RETURN this8 AS var4 + } + WITH var4 + RETURN collect(var4) AS var4 + } + RETURN this { actedIn: var4 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": false, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + + test("connection read", async () => { + const query = gql` + { + actorsConnection { + edges { + node { + actedIn { + title + } + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this0:Actor) + WHERE ($isAuthenticated = true AND size([(this0)-[this2:ACTED_IN]->(this1) WHERE ((($param1 IS NOT NULL AND this1.title = $param1) AND this1:Series) AND (this1:Movie OR this1:Series OR this1:Cartoon)) | 1]) > 0) + WITH collect({ node: this0 }) AS edges + WITH edges, size(edges) AS totalCount + CALL { + WITH edges + UNWIND edges AS edge + WITH edge.node AS this0 + CALL { + WITH this0 + CALL { + WITH * + MATCH (this0)-[this3:ACTED_IN]->(this4:Movie) + WITH this4 { .title, __resolveType: \\"Movie\\", __id: id(this4) } AS this4 + RETURN this4 AS var5 + UNION + WITH * + MATCH (this0)-[this6:ACTED_IN]->(this7:Series) + WITH this7 { .title, __resolveType: \\"Series\\", __id: id(this7) } AS this7 + RETURN this7 AS var5 + UNION + WITH * + MATCH (this0)-[this8:ACTED_IN]->(this9:Cartoon) + WITH this9 { .title, __resolveType: \\"Cartoon\\", __id: id(this9) } AS this9 + RETURN this9 AS var5 + } + WITH var5 + RETURN collect(var5) AS var5 + } + RETURN collect({ node: { actedIn: var5 } }) AS var10 + } + RETURN { edges: var10, totalCount: totalCount } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": false, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + }); +}); diff --git a/packages/graphql/tests/tck/experimental/typename-in.test.ts b/packages/graphql/tests/tck/experimental/typename-in.test.ts new file mode 100644 index 00000000000..03753f624fc --- /dev/null +++ b/packages/graphql/tests/tck/experimental/typename-in.test.ts @@ -0,0 +1,311 @@ +/* + * 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 { gql } from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; + +describe("typename_IN", () => { + let typeDefs: string; + let neoSchema: Neo4jGraphQL; + + beforeAll(() => { + typeDefs = /* GraphQL */ ` + interface Production { + title: String! + cost: Float! + } + + type Movie implements Production { + title: String! + cost: Float! + runtime: Int! + } + + type Series implements Production { + title: String! + cost: Float! + episodes: Int! + } + + type Cartoon implements Production { + title: String! + cost: Float! + cartoonist: String! + } + + interface ActedIn @relationshipProperties { + screenTime: Int! + } + + type Actor { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + `; + + neoSchema = new Neo4jGraphQL({ + typeDefs, + experimental: true, + }); + }); + + test("top-level", async () => { + const query = gql` + { + productions( + where: { + OR: [{ AND: [{ title: "The Matrix" }, { typename_IN: [Series] }] }, { typename_IN: [Movie] }] + } + ) { + title + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + MATCH (this0:Movie) + WHERE ((this0.title = $param0 AND this0:Series) OR this0:Movie) + WITH this0 { .title, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 + RETURN this0 AS this + UNION + MATCH (this1:Series) + WHERE ((this1.title = $param1 AND this1:Series) OR this1:Movie) + WITH this1 { .title, __resolveType: \\"Series\\", __id: id(this1) } AS this1 + RETURN this1 AS this + UNION + MATCH (this2:Cartoon) + WHERE ((this2.title = $param2 AND this2:Series) OR this2:Movie) + WITH this2 { .title, __resolveType: \\"Cartoon\\", __id: id(this2) } AS this2 + RETURN this2 AS this + } + WITH this + RETURN this AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Matrix\\", + \\"param1\\": \\"The Matrix\\", + \\"param2\\": \\"The Matrix\\" + }" + `); + }); + + test("top-level + connection where", async () => { + const query = gql` + { + actors( + where: { + actedInConnection_SOME: { + OR: [ + { edge: { screenTime: 2 } } + { node: { OR: [{ title: "The Matrix" }, { typename_IN: [Series] }] } } + ] + } + } + ) { + actedIn { + title + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + WHERE EXISTS { + MATCH (this)-[this0:ACTED_IN]->(this1) + WHERE ((this0.screenTime = $param0 OR (this1.title = $param1 OR this1:Series)) AND (this1:Movie OR this1:Series OR this1:Cartoon)) + } + CALL { + WITH this + CALL { + WITH * + MATCH (this)-[this2:ACTED_IN]->(this3:Movie) + WITH this3 { .title, __resolveType: \\"Movie\\", __id: id(this3) } AS this3 + RETURN this3 AS var4 + UNION + WITH * + MATCH (this)-[this5:ACTED_IN]->(this6:Series) + WITH this6 { .title, __resolveType: \\"Series\\", __id: id(this6) } AS this6 + RETURN this6 AS var4 + UNION + WITH * + MATCH (this)-[this7:ACTED_IN]->(this8:Cartoon) + WITH this8 { .title, __resolveType: \\"Cartoon\\", __id: id(this8) } AS this8 + RETURN this8 AS var4 + } + WITH var4 + RETURN collect(var4) AS var4 + } + RETURN this { actedIn: var4 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": { + \\"low\\": 2, + \\"high\\": 0 + }, + \\"param1\\": \\"The Matrix\\" + }" + `); + }); + + test("nested", async () => { + const query = gql` + { + actors { + actedIn( + where: { + OR: [ + { AND: [{ title: "The Matrix" }, { typename_IN: [Series] }] } + { typename_IN: [Movie] } + ] + } + ) { + title + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + CALL { + WITH this + CALL { + WITH * + MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + WHERE ((this1.title = $param0 AND this1:Series) OR this1:Movie) + WITH this1 { .title, __resolveType: \\"Movie\\", __id: id(this1) } AS this1 + RETURN this1 AS var2 + UNION + WITH * + MATCH (this)-[this3:ACTED_IN]->(this4:Series) + WHERE ((this4.title = $param1 AND this4:Series) OR this4:Movie) + WITH this4 { .title, __resolveType: \\"Series\\", __id: id(this4) } AS this4 + RETURN this4 AS var2 + UNION + WITH * + MATCH (this)-[this5:ACTED_IN]->(this6:Cartoon) + WHERE ((this6.title = $param2 AND this6:Series) OR this6:Movie) + WITH this6 { .title, __resolveType: \\"Cartoon\\", __id: id(this6) } AS this6 + RETURN this6 AS var2 + } + WITH var2 + RETURN collect(var2) AS var2 + } + RETURN this { actedIn: var2 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Matrix\\", + \\"param1\\": \\"The Matrix\\", + \\"param2\\": \\"The Matrix\\" + }" + `); + }); + + test("aggregation", async () => { + const query = gql` + { + productionsAggregate(where: { OR: [{ title: "the matrix" }, { typename_IN: [Movie, Series] }] }) { + count + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + CALL { + MATCH (this0:Movie) + RETURN this0 AS node + UNION + MATCH (this1:Series) + RETURN this1 AS node + UNION + MATCH (this2:Cartoon) + RETURN this2 AS node + } + WITH * + WHERE (node.title = $param0 OR (node:Movie OR node:Series)) + RETURN count(node) AS this3 + } + RETURN { count: this3 }" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"the matrix\\" + }" + `); + }); + + test("nested aggregation", async () => { + const query = gql` + { + actors { + actedInAggregate(where: { typename_IN: [Movie, Series] }) { + count + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + CALL { + WITH this + CALL { + WITH this + MATCH (this)-[this0:ACTED_IN]->(this1:Movie) + RETURN this1 AS node, this0 AS edge + UNION + WITH this + MATCH (this)-[this2:ACTED_IN]->(this3:Series) + RETURN this3 AS node, this2 AS edge + UNION + WITH this + MATCH (this)-[this4:ACTED_IN]->(this5:Cartoon) + RETURN this5 AS node, this4 AS edge + } + WITH * + WHERE (node:Movie OR node:Series) + RETURN count(node) AS this6 + } + RETURN this { actedInAggregate: { count: this6 } } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(`"{}"`); + }); +}); diff --git a/packages/graphql/tests/tck/issues/4405.test.ts b/packages/graphql/tests/tck/issues/4405.test.ts new file mode 100644 index 00000000000..98fc4e5dd26 --- /dev/null +++ b/packages/graphql/tests/tck/issues/4405.test.ts @@ -0,0 +1,139 @@ +/* + * 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 gql from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { createBearerToken } from "../../utils/create-bearer-token"; +import { translateQuery, formatCypher, formatParams } from "../utils/tck-test-utils"; + +describe("https://github.com/neo4j/graphql/issues/4405", () => { + test("authorization should work when the filter value is an array", async () => { + const typeDefs = /* GraphQL */ ` + type Movie { + title: String + } + + type Actor + @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { node: { actedInConnection_SOME: { node: { title_IN: ["Matrix"] } } } } + } + ] + ) { + name: String! + actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) + } + `; + + const neoSchema = new Neo4jGraphQL({ typeDefs, features: { authorization: { key: "secret" } } }); + + const query = gql` + query actors { + actors { + name + } + } + `; + + const token = createBearerToken("secret", { roles: ["admin"], id: "something", email: "something" }); + const result = await translateQuery(neoSchema, query, { token }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this)-[this1:ACTED_IN]->(this0:Movie) WHERE ($param1 IS NOT NULL AND this0.title IN $param1) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + RETURN this { .name } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": true, + \\"param1\\": [ + \\"Matrix\\" + ] + }" + `); + }); + + test("authorization should work when the filter value is an array, inside logical", async () => { + const typeDefs = /* GraphQL */ ` + type Movie { + title: String + } + + type Actor + @authorization( + validate: [ + { + when: [BEFORE] + operations: [READ] + where: { + node: { + actedInConnection_SOME: { + node: { + OR: [{ title_IN: ["Matrix"] }, { title_IN: ["Forrest Gump", "Top Gun"] }] + } + } + } + } + } + ] + ) { + name: String! + actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) + } + `; + + const neoSchema = new Neo4jGraphQL({ typeDefs, features: { authorization: { key: "secret" } } }); + + const query = gql` + query actors { + actors { + name + } + } + `; + + const token = createBearerToken("secret", { roles: ["admin"], id: "something", email: "something" }); + const result = await translateQuery(neoSchema, query, { token }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this)-[this1:ACTED_IN]->(this0:Movie) WHERE (($param1 IS NOT NULL AND this0.title IN $param1) OR ($param2 IS NOT NULL AND this0.title IN $param2)) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + RETURN this { .name } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": true, + \\"param1\\": [ + \\"Matrix\\" + ], + \\"param2\\": [ + \\"Forrest Gump\\", + \\"Top Gun\\" + ] + }" + `); + }); +}); diff --git a/packages/graphql/tests/utils/builders/context-builder.ts b/packages/graphql/tests/utils/builders/context-builder.ts index d4ebd62db5f..3baad14ee0e 100644 --- a/packages/graphql/tests/utils/builders/context-builder.ts +++ b/packages/graphql/tests/utils/builders/context-builder.ts @@ -50,6 +50,7 @@ export class ContextBuilder extends Builder Date: Sat, 16 Dec 2023 01:35:45 +0000 Subject: [PATCH 057/136] chore(deps): update dependency @types/react-dom to v18.2.18 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 3c97804cefb..b924259473f 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -75,7 +75,7 @@ "@types/codemirror": "5.60.15", "@types/lodash.debounce": "4.0.9", "@types/prettier": "2.7.3", - "@types/react-dom": "18.2.17", + "@types/react-dom": "18.2.18", "@types/webpack": "5.28.5", "autoprefixer": "10.4.16", "compression-webpack-plugin": "10.0.0", diff --git a/yarn.lock b/yarn.lock index e3fa5bcb5c3..44d7fcac0ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3644,7 +3644,7 @@ __metadata: "@types/codemirror": 5.60.15 "@types/lodash.debounce": 4.0.9 "@types/prettier": 2.7.3 - "@types/react-dom": 18.2.17 + "@types/react-dom": 18.2.18 "@types/webpack": 5.28.5 autoprefixer: 10.4.16 classnames: 2.3.2 @@ -7719,12 +7719,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:18.2.17": - version: 18.2.17 - resolution: "@types/react-dom@npm:18.2.17" +"@types/react-dom@npm:18.2.18": + version: 18.2.18 + resolution: "@types/react-dom@npm:18.2.18" dependencies: "@types/react": "*" - checksum: 7a4e704ed4be6e0c3ccd8a22ff69386fe548304bf4db090513f42e059ff4c65f7a427790320051524d6578a2e4c9667bb7a80a4c989b72361c019fbe851d9385 + checksum: 8e3da404c980e2b2a76da3852f812ea6d8b9d0e7f5923fbaf3bfbbbfa1d59116ff91c129de8f68e9b7668a67ae34484fe9df74d5a7518cf8591ec07a0c4dad57 languageName: node linkType: hard From 51a828113d716d22609befdf2ed9b8e0c78a5456 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 16 Dec 2023 01:44:50 +0000 Subject: [PATCH 058/136] chore(deps): update dependency eslint to v8.56.0 --- package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 0f813a2afeb..4b2bcabeaf7 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@typescript-eslint/parser": "6.14.0", "concurrently": "8.2.2", "dotenv": "16.3.1", - "eslint": "8.55.0", + "eslint": "8.56.0", "eslint-config-prettier": "9.1.0", "eslint-formatter-summary": "1.1.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/yarn.lock b/yarn.lock index 44d7fcac0ac..ac71347f9d6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2129,10 +2129,10 @@ __metadata: languageName: node linkType: hard -"@eslint/js@npm:8.55.0": - version: 8.55.0 - resolution: "@eslint/js@npm:8.55.0" - checksum: fa33ef619f0646ed15649b0c2e313e4d9ccee8425884bdbfc78020d6b6b64c0c42fa9d83061d0e6158e1d4274f03f0f9008786540e2efab8fcdc48082259908c +"@eslint/js@npm:8.56.0": + version: 8.56.0 + resolution: "@eslint/js@npm:8.56.0" + checksum: 5804130574ef810207bdf321c265437814e7a26f4e6fac9b496de3206afd52f533e09ec002a3be06cd9adcc9da63e727f1883938e663c4e4751c007d5b58e539 languageName: node linkType: hard @@ -13361,14 +13361,14 @@ __metadata: languageName: node linkType: hard -"eslint@npm:8.55.0": - version: 8.55.0 - resolution: "eslint@npm:8.55.0" +"eslint@npm:8.56.0": + version: 8.56.0 + resolution: "eslint@npm:8.56.0" dependencies: "@eslint-community/eslint-utils": ^4.2.0 "@eslint-community/regexpp": ^4.6.1 "@eslint/eslintrc": ^2.1.4 - "@eslint/js": 8.55.0 + "@eslint/js": 8.56.0 "@humanwhocodes/config-array": ^0.11.13 "@humanwhocodes/module-importer": ^1.0.1 "@nodelib/fs.walk": ^1.2.8 @@ -13405,7 +13405,7 @@ __metadata: text-table: ^0.2.0 bin: eslint: bin/eslint.js - checksum: 83f82a604559dc1faae79d28fdf3dfc9e592ca221052e2ea516e1b379b37e77e4597705a16880e2f5ece4f79087c1dd13fd7f6e9746f794a401175519db18b41 + checksum: 883436d1e809b4a25d9eb03d42f584b84c408dbac28b0019f6ea07b5177940bf3cca86208f749a6a1e0039b63e085ee47aca1236c30721e91f0deef5cc5a5136 languageName: node linkType: hard @@ -19833,7 +19833,7 @@ __metadata: "@typescript-eslint/parser": 6.14.0 concurrently: 8.2.2 dotenv: 16.3.1 - eslint: 8.55.0 + eslint: 8.56.0 eslint-config-prettier: 9.1.0 eslint-formatter-summary: 1.1.0 eslint-import-resolver-typescript: 3.6.1 From 8171adc0405821405d4ff016bdd0491ed1fe70a0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 16 Dec 2023 10:04:29 +0000 Subject: [PATCH 059/136] chore(deps): update ibmjava:8-jre docker digest to 3a7e8f0 --- .../graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile b/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile index c23ed74a407..8be96cdb153 100644 --- a/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile +++ b/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile @@ -1,4 +1,4 @@ -FROM ibmjava:8-jre@sha256:956d16bfd2e8f53ab8a9aa0fe82f9750532f8b87a1cfcf6fc27bb3b24deb3726 +FROM ibmjava:8-jre@sha256:3a7e8f0c0919898521abac9932fdd4bc7feac50201d0ebb4e675e214b0c7b86f WORKDIR /usr/local/qpid RUN apt-get update && apt-get install -y curl \ && curl https://dlcdn.apache.org/qpid/broker-j/8.0.6/binaries/apache-qpid-broker-j-8.0.6-bin.tar.gz \ From a396246078c963c8651b4f3bfdfe729457e4fcd9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 16 Dec 2023 13:35:26 +0000 Subject: [PATCH 060/136] chore(deps): update ibmjava:8-jre docker digest to c518a62 --- .../graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile b/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile index 8be96cdb153..de3be7f65b4 100644 --- a/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile +++ b/packages/graphql-amqp-subscriptions-engine/qpid-docker/Dockerfile @@ -1,4 +1,4 @@ -FROM ibmjava:8-jre@sha256:3a7e8f0c0919898521abac9932fdd4bc7feac50201d0ebb4e675e214b0c7b86f +FROM ibmjava:8-jre@sha256:c518a629aec5fd4b00334c2ac88622cfb5830ccfab17c194f09f1de582e36ca0 WORKDIR /usr/local/qpid RUN apt-get update && apt-get install -y curl \ && curl https://dlcdn.apache.org/qpid/broker-j/8.0.6/binaries/apache-qpid-broker-j-8.0.6-bin.tar.gz \ From 28a15d682258f2095a51768cee1602270a03cee8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Dec 2023 01:24:34 +0000 Subject: [PATCH 061/136] chore(deps): update rabbitmq docker digest to fbaa5a8 --- .../workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml index 9864bed2518..893e2710fb7 100644 --- a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml +++ b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml @@ -26,7 +26,7 @@ jobs: ports: - 7687:7687 rabbitmq: - image: rabbitmq@sha256:b669305108158abf3d7790a7f6f5a56b7de9598a926b6672281a7edf11460a2d + image: rabbitmq@sha256:fbaa5a8b16e856d86b28797135a5333df96a40c8ce3facc092911f47e439666e env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest From 21a77590e341166d6b5da6a62cae8a6a53dbfb6b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Dec 2023 03:23:26 +0000 Subject: [PATCH 062/136] chore(deps): update rabbitmq:3.12-management docker digest to 39068aa --- examples/neo-place/docker-compose.yml | 2 +- examples/subscriptions/apollo_rabbitmq/docker-compose.yml | 2 +- packages/graphql-amqp-subscriptions-engine/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/neo-place/docker-compose.yml b/examples/neo-place/docker-compose.yml index d578a9e8296..62b4a158221 100644 --- a/examples/neo-place/docker-compose.yml +++ b/examples/neo-place/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:f8237ef62feb8fc61fe949170fa15379c45c784e1b8f1e9a4a0b9fbf7c5c8bf1 + image: rabbitmq:3.12-management@sha256:39068aaebbb59af29794455c4f08db633a9d6273b7a2a8ffeb70f00f5c48df9b ports: - "5672:5672" - "15672:15672" diff --git a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml index d578a9e8296..62b4a158221 100644 --- a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml +++ b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:f8237ef62feb8fc61fe949170fa15379c45c784e1b8f1e9a4a0b9fbf7c5c8bf1 + image: rabbitmq:3.12-management@sha256:39068aaebbb59af29794455c4f08db633a9d6273b7a2a8ffeb70f00f5c48df9b ports: - "5672:5672" - "15672:15672" diff --git a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml index fbbe8d8c20d..9f339825294 100644 --- a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml +++ b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' # This is just for local testing services: rabbitmq: - image: rabbitmq:3.12-management@sha256:f8237ef62feb8fc61fe949170fa15379c45c784e1b8f1e9a4a0b9fbf7c5c8bf1 + image: rabbitmq:3.12-management@sha256:39068aaebbb59af29794455c4f08db633a9d6273b7a2a8ffeb70f00f5c48df9b ports: - "5672:5672" - "15672:15672" From 94db095206891d907c3457f9a8e0773bcf57efb2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 00:41:20 +0000 Subject: [PATCH 063/136] chore(deps): update dependency @types/node to v20.10.5 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- packages/introspector/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index b8bbc4a85c4..d28fb834a14 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -40,7 +40,7 @@ "@types/cors": "2.8.17", "@types/debug": "4.1.12", "@types/jest": "29.5.11", - "@types/node": "20.10.4", + "@types/node": "20.10.5", "camelcase": "6.3.0", "graphql-ws": "5.14.2", "jest": "29.7.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index cd4948eae70..a0a34c907cf 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -56,7 +56,7 @@ "@types/is-uuid": "1.0.2", "@types/jest": "29.5.11", "@types/jsonwebtoken": "9.0.5", - "@types/node": "20.10.4", + "@types/node": "20.10.5", "@types/pluralize": "0.0.33", "@types/randomstring": "1.1.11", "@types/semver": "7.5.6", diff --git a/packages/introspector/package.json b/packages/introspector/package.json index b14d2e537c8..77a6542485f 100644 --- a/packages/introspector/package.json +++ b/packages/introspector/package.json @@ -38,7 +38,7 @@ "devDependencies": { "@neo4j/graphql": "^4.0.0", "@types/jest": "29.5.11", - "@types/node": "20.10.4", + "@types/node": "20.10.5", "@types/pluralize": "0.0.33", "jest": "29.7.0", "ts-jest": "29.1.1", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index d44649b137c..949384c2a82 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@types/jest": "29.5.11", - "@types/node": "20.10.4", + "@types/node": "20.10.5", "camelcase": "6.3.0", "graphql-tag": "2.12.6", "jest": "29.7.0", diff --git a/yarn.lock b/yarn.lock index ac71347f9d6..b70d70454dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3575,7 +3575,7 @@ __metadata: "@types/cors": 2.8.17 "@types/debug": 4.1.12 "@types/jest": 29.5.11 - "@types/node": 20.10.4 + "@types/node": 20.10.5 amqplib: 0.10.3 body-parser: ^1.20.2 camelcase: 6.3.0 @@ -3604,7 +3604,7 @@ __metadata: "@graphql-tools/merge": ^9.0.0 "@neo4j/graphql": ^4.4.4 "@types/jest": 29.5.11 - "@types/node": 20.10.4 + "@types/node": 20.10.5 camelcase: 6.3.0 graphql-tag: 2.12.6 jest: 29.7.0 @@ -3709,7 +3709,7 @@ __metadata: "@types/is-uuid": 1.0.2 "@types/jest": 29.5.11 "@types/jsonwebtoken": 9.0.5 - "@types/node": 20.10.4 + "@types/node": 20.10.5 "@types/pluralize": 0.0.33 "@types/randomstring": 1.1.11 "@types/semver": 7.5.6 @@ -3766,7 +3766,7 @@ __metadata: dependencies: "@neo4j/graphql": ^4.0.0 "@types/jest": 29.5.11 - "@types/node": 20.10.4 + "@types/node": 20.10.5 "@types/pluralize": 0.0.33 camelcase: ^6.3.0 debug: ^4.3.4 @@ -7640,12 +7640,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.10.4": - version: 20.10.4 - resolution: "@types/node@npm:20.10.4" +"@types/node@npm:20.10.5": + version: 20.10.5 + resolution: "@types/node@npm:20.10.5" dependencies: undici-types: ~5.26.4 - checksum: 054b296417e771ab524bea63cf3289559c6bdf290d45428f7cc68e9b00030ff7a0ece47b8c99a26b4f47a443919813bcf42beadff2f0bea7d8125fa541d92eb0 + checksum: e216b679f545a8356960ce985a0e53c3a58fff0eacd855e180b9e223b8db2b5bd07b744a002b8c1f0c37f9194648ab4578533b5c12df2ec10cc02f61d20948d2 languageName: node linkType: hard From 3a8bf0c35cd224f6827329418f2c57790af414b2 Mon Sep 17 00:00:00 2001 From: angrykoala Date: Mon, 18 Dec 2023 14:26:24 +0100 Subject: [PATCH 064/136] Add release PRs to test workflows --- .github/workflows/performance-tests.yml | 1 + .github/workflows/pull-requests.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/performance-tests.yml b/.github/workflows/performance-tests.yml index d404e7a2899..30be1de0843 100644 --- a/.github/workflows/performance-tests.yml +++ b/.github/workflows/performance-tests.yml @@ -5,6 +5,7 @@ on: branches: - dev - master + - "*.*.*" paths: - "packages/graphql/tests/tck/**" diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index b117c83e0a0..1bdaa62cd0a 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -9,6 +9,7 @@ on: branches: - dev - master + - "*.*.*" paths-ignore: - "docs/**" From c16f4ea92e1e9b1a2a9e74e588a45fe32987ddf9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 22:09:31 +0000 Subject: [PATCH 065/136] chore(deps): update actions/setup-node digest to b39b52d --- .github/workflows/changesets.yml | 2 +- .github/workflows/lint-markdown.yml | 2 +- .github/workflows/performance-tests.yml | 2 +- .github/workflows/pull-requests.yml | 2 +- .github/workflows/reusable-api-library-tests.yml | 6 +++--- .github/workflows/reusable-aura-tests.yml | 4 ++-- .github/workflows/reusable-codeql-analysis.yml | 2 +- .github/workflows/reusable-federation-tests.yml | 2 +- .../reusable-integration-tests-on-prem-nightly.yml | 2 +- .github/workflows/reusable-integration-tests-on-prem.yml | 2 +- .github/workflows/reusable-package-tests.yml | 2 +- .../reusable-subscriptions-plugin-amqp-e2e-test.yml | 2 +- .github/workflows/reusable-toolbox-tests.yml | 2 +- .github/workflows/reusable-unit-tests.yml | 2 +- .github/workflows/toolbox-build.yml | 2 +- .github/workflows/toolbox-deploy.yml | 2 +- .github/workflows/toolbox-publish.yml | 2 +- .github/workflows/toolbox-teardown.yml | 2 +- 18 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/changesets.yml b/.github/workflows/changesets.yml index 5072dad78d0..0e10a041562 100644 --- a/.github/workflows/changesets.yml +++ b/.github/workflows/changesets.yml @@ -30,7 +30,7 @@ jobs: persist-credentials: false - name: Setup Node.js - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* diff --git a/.github/workflows/lint-markdown.yml b/.github/workflows/lint-markdown.yml index 432fe1ccc78..d761150cced 100644 --- a/.github/workflows/lint-markdown.yml +++ b/.github/workflows/lint-markdown.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* - name: Install markdownlint diff --git a/.github/workflows/performance-tests.yml b/.github/workflows/performance-tests.yml index 30be1de0843..6d6f58b1fc2 100644 --- a/.github/workflows/performance-tests.yml +++ b/.github/workflows/performance-tests.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Setup Node.js - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index 1bdaa62cd0a..8bf0126663c 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -19,7 +19,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: 18.13.0 cache: yarn diff --git a/.github/workflows/reusable-api-library-tests.yml b/.github/workflows/reusable-api-library-tests.yml index 9098da99311..e075e9bda3b 100644 --- a/.github/workflows/reusable-api-library-tests.yml +++ b/.github/workflows/reusable-api-library-tests.yml @@ -48,7 +48,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn @@ -85,7 +85,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn @@ -107,7 +107,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/reusable-aura-tests.yml b/.github/workflows/reusable-aura-tests.yml index 9ca743d6ce8..eee4496f399 100644 --- a/.github/workflows/reusable-aura-tests.yml +++ b/.github/workflows/reusable-aura-tests.yml @@ -29,7 +29,7 @@ jobs: uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 with: ref: ${{ inputs.BRANCH || github.ref }} - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn @@ -64,7 +64,7 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/reusable-codeql-analysis.yml b/.github/workflows/reusable-codeql-analysis.yml index ffbe8893b3c..bef84ace705 100644 --- a/.github/workflows/reusable-codeql-analysis.yml +++ b/.github/workflows/reusable-codeql-analysis.yml @@ -10,7 +10,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* - name: Initialize CodeQL diff --git a/.github/workflows/reusable-federation-tests.yml b/.github/workflows/reusable-federation-tests.yml index dc59fe2c450..ba4aeb37135 100644 --- a/.github/workflows/reusable-federation-tests.yml +++ b/.github/workflows/reusable-federation-tests.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/reusable-integration-tests-on-prem-nightly.yml b/.github/workflows/reusable-integration-tests-on-prem-nightly.yml index f2d06131ab1..761d3d4a3f6 100644 --- a/.github/workflows/reusable-integration-tests-on-prem-nightly.yml +++ b/.github/workflows/reusable-integration-tests-on-prem-nightly.yml @@ -78,7 +78,7 @@ jobs: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - name: Setting up Node.js with version ${{ matrix.node }} - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: ${{ matrix.node }} cache: yarn diff --git a/.github/workflows/reusable-integration-tests-on-prem.yml b/.github/workflows/reusable-integration-tests-on-prem.yml index 124f7a1815d..a0c995e0018 100644 --- a/.github/workflows/reusable-integration-tests-on-prem.yml +++ b/.github/workflows/reusable-integration-tests-on-prem.yml @@ -53,7 +53,7 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/reusable-package-tests.yml b/.github/workflows/reusable-package-tests.yml index 98fe65896f2..a7a97ee82b6 100644 --- a/.github/workflows/reusable-package-tests.yml +++ b/.github/workflows/reusable-package-tests.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: 18.13.0 cache: yarn diff --git a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml index 893e2710fb7..bb7dd6818e1 100644 --- a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml +++ b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml @@ -37,7 +37,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/reusable-toolbox-tests.yml b/.github/workflows/reusable-toolbox-tests.yml index eef6527dfbf..1b892af32eb 100644 --- a/.github/workflows/reusable-toolbox-tests.yml +++ b/.github/workflows/reusable-toolbox-tests.yml @@ -20,7 +20,7 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/reusable-unit-tests.yml b/.github/workflows/reusable-unit-tests.yml index 01ca66b6eee..06b05e4ed19 100644 --- a/.github/workflows/reusable-unit-tests.yml +++ b/.github/workflows/reusable-unit-tests.yml @@ -30,7 +30,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* cache: yarn diff --git a/.github/workflows/toolbox-build.yml b/.github/workflows/toolbox-build.yml index 1ea45714b3c..9a1a8902ccc 100644 --- a/.github/workflows/toolbox-build.yml +++ b/.github/workflows/toolbox-build.yml @@ -14,7 +14,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* - name: Install dependencies diff --git a/.github/workflows/toolbox-deploy.yml b/.github/workflows/toolbox-deploy.yml index b76547eb176..04362145a56 100644 --- a/.github/workflows/toolbox-deploy.yml +++ b/.github/workflows/toolbox-deploy.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* - name: Install dependencies diff --git a/.github/workflows/toolbox-publish.yml b/.github/workflows/toolbox-publish.yml index 8da0670ccfd..2ecbcef7f50 100644 --- a/.github/workflows/toolbox-publish.yml +++ b/.github/workflows/toolbox-publish.yml @@ -39,7 +39,7 @@ jobs: number=$(> "$GITHUB_OUTPUT" - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* - name: Publish the Toolbox to surge.sh diff --git a/.github/workflows/toolbox-teardown.yml b/.github/workflows/toolbox-teardown.yml index 6015fb2f185..498aeb11fdc 100644 --- a/.github/workflows/toolbox-teardown.yml +++ b/.github/workflows/toolbox-teardown.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4 + - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4 with: node-version: lts/* - name: Teardown graphql-toolbox From ca43439f29936513110caca74932b83fc8d8bcd9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 22:18:34 +0000 Subject: [PATCH 066/136] chore(deps): update dependency tailwindcss to v3.3.7 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index b924259473f..44d3483f6e5 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -95,7 +95,7 @@ "postcss-loader": "7.3.3", "randomstring": "1.3.0", "style-loader": "3.3.3", - "tailwindcss": "3.3.6", + "tailwindcss": "3.3.7", "terser-webpack-plugin": "5.3.9", "ts-jest": "29.1.1", "ts-loader": "9.5.1", diff --git a/yarn.lock b/yarn.lock index b70d70454dd..d29fce8d750 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3676,7 +3676,7 @@ __metadata: react: 18.2.0 react-dom: 18.2.0 style-loader: 3.3.3 - tailwindcss: 3.3.6 + tailwindcss: 3.3.7 terser-webpack-plugin: 5.3.9 thememirror: 2.0.1 ts-jest: 29.1.1 @@ -24784,9 +24784,9 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:3.3.6": - version: 3.3.6 - resolution: "tailwindcss@npm:3.3.6" +"tailwindcss@npm:3.3.7": + version: 3.3.7 + resolution: "tailwindcss@npm:3.3.7" dependencies: "@alloc/quick-lru": ^5.2.0 arg: ^5.0.2 @@ -24813,7 +24813,7 @@ __metadata: bin: tailwind: lib/cli.js tailwindcss: lib/cli.js - checksum: 44632ac471248ecebcee1a2f15a0c3e9b8383513e71692b586aa2fe56dca12828ff70de3d340c898f27b27480e8475e5eb345fb2ebb813028bb2393578a34337 + checksum: 73728e03ac00bb90a09436895b663473336da4a539ca22df41c62948fd4e45c5feda71d6f33c03666045dbb1806ee36658caf604256d20196ebf580ec0987c2d languageName: node linkType: hard From 1fab69b2af016768682fb0e122b0d14c7bd8ced1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 01:35:40 +0000 Subject: [PATCH 067/136] chore(deps): update typescript-eslint monorepo to v6.15.0 --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 4b2bcabeaf7..839044c29c0 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.14.0", - "@typescript-eslint/parser": "6.14.0", + "@typescript-eslint/eslint-plugin": "6.15.0", + "@typescript-eslint/parser": "6.15.0", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.56.0", diff --git a/yarn.lock b/yarn.lock index d29fce8d750..53f337ebd00 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7939,15 +7939,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.14.0" +"@typescript-eslint/eslint-plugin@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.15.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.14.0 - "@typescript-eslint/type-utils": 6.14.0 - "@typescript-eslint/utils": 6.14.0 - "@typescript-eslint/visitor-keys": 6.14.0 + "@typescript-eslint/scope-manager": 6.15.0 + "@typescript-eslint/type-utils": 6.15.0 + "@typescript-eslint/utils": 6.15.0 + "@typescript-eslint/visitor-keys": 6.15.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7960,25 +7960,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: ec688fd71b21576bfe0e4176889fddf3c13d8b07792461b84017d689ed11a9bffbf4d2ab61e9bdb254e43d2c1e159d5c2fc21bdfa6a6c2d64f9e1956a668fbe8 + checksum: f7ae7e01f9d1bd6150598ea1a191348a7ba08b25f146d3bc3b19d434bdb8071cf831577a31c62935e67716addb37b0eda02f4a47bfefc1bb5458843256ec0933 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/parser@npm:6.14.0" +"@typescript-eslint/parser@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/parser@npm:6.15.0" dependencies: - "@typescript-eslint/scope-manager": 6.14.0 - "@typescript-eslint/types": 6.14.0 - "@typescript-eslint/typescript-estree": 6.14.0 - "@typescript-eslint/visitor-keys": 6.14.0 + "@typescript-eslint/scope-manager": 6.15.0 + "@typescript-eslint/types": 6.15.0 + "@typescript-eslint/typescript-estree": 6.15.0 + "@typescript-eslint/visitor-keys": 6.15.0 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 5fbe8d7431654c14ba6c9782d3728026ad5c90e02c9c4319f45df972e653cf5c15ba320dce70cdffa9fb7ce4c4263c37585e7bc1c909d1252d0a599880963063 + checksum: 6f71b48f208e4d56025cbe3a5b287fe9c31484469e8b2a14a0ab5453cb56223a3c099beb70d298e0ce80de8a23e90aec65865ff8e939233cd0f1c3ffba12f3db languageName: node linkType: hard @@ -7992,22 +7992,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/scope-manager@npm:6.14.0" +"@typescript-eslint/scope-manager@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/scope-manager@npm:6.15.0" dependencies: - "@typescript-eslint/types": 6.14.0 - "@typescript-eslint/visitor-keys": 6.14.0 - checksum: 0b577d42db925426a9838fe61703c226e18b697374fbe20cf9b93ba30fe58bf4a7f7f42491a4d24b7f3cc12d9a189fe3524c0e9b7708727e710d95b908250a14 + "@typescript-eslint/types": 6.15.0 + "@typescript-eslint/visitor-keys": 6.15.0 + checksum: 12316149aae3ad5c7e3411ed7da7fb7d9324df83482d64a93eecbd11063451660cea0fa42ceb026984df7974d770d5f7bc6c77c33e95bc0db0c44e4413f8b756 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/type-utils@npm:6.14.0" +"@typescript-eslint/type-utils@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/type-utils@npm:6.15.0" dependencies: - "@typescript-eslint/typescript-estree": 6.14.0 - "@typescript-eslint/utils": 6.14.0 + "@typescript-eslint/typescript-estree": 6.15.0 + "@typescript-eslint/utils": 6.15.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8015,7 +8015,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 09988f25279598840673c41ba44b03756f2dfb31284ab72af97c170711a0f31e5c53d6b120aa83f31438565e82aae1a1ca4d1ed0de4890654dd6a6a33d88202c + checksum: bd582fc6cca3b9048200fd30a042131cbb50e800acca1d31618ca4a9d9b6bc29fefd6920f7622a546c07a4d1a1c73745acfa09890e732a8a124731c3d5a821d1 languageName: node linkType: hard @@ -8026,10 +8026,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/types@npm:6.14.0" - checksum: 624e6c5227f596dcc9757348d09c5a09b846a62938b8b4409614cf8108013b64ed8b270c32e87ea8890dd09ed896b82e92872c3574dbf07dcda11a168d69dd1f +"@typescript-eslint/types@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/types@npm:6.15.0" + checksum: 604cf287a339a55c9a82a6e301cf353bb256427b6e29b12ee8901b37d34581761a0dac3ae7e9d78925854e260e5d690ec472b54ca972339820f3db8512864875 languageName: node linkType: hard @@ -8051,12 +8051,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.14.0" +"@typescript-eslint/typescript-estree@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.15.0" dependencies: - "@typescript-eslint/types": 6.14.0 - "@typescript-eslint/visitor-keys": 6.14.0 + "@typescript-eslint/types": 6.15.0 + "@typescript-eslint/visitor-keys": 6.15.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8065,24 +8065,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 495d7616463685bfd8138ffa9fbc0a7f9130ff8a3f6f85775960b4f0a3fdc259ae53b104cdfe562b60310860b5a6c8387307790734555084aa087e3bb9c28a69 + checksum: fbd11a5acaee3166174fad4cc78cff2ad646411a60ca14e5a50598373302c7bedd76d073ed385b002eb3d6d2a44aea2dd5c74aa65fbef8441a2e079064e67640 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/utils@npm:6.14.0" +"@typescript-eslint/utils@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/utils@npm:6.15.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.14.0 - "@typescript-eslint/types": 6.14.0 - "@typescript-eslint/typescript-estree": 6.14.0 + "@typescript-eslint/scope-manager": 6.15.0 + "@typescript-eslint/types": 6.15.0 + "@typescript-eslint/typescript-estree": 6.15.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 36e8501cb85647947189f31017c36d6f6ac7ef0399fa0e18eb64f1b83e00f1e8ace1d9ac5015ef4d9c1b820179f1def8d61d7ea9e5d61433eb848cf5c49dc8b0 + checksum: 02aefaeb1539e0a5e5cbbc4d4f92ce505f433b7f8403cb10522c0a6965572a0ea94d32d487113fa64a33967ae7d0de5a62ffea83721100596e54c5ef04288cbe languageName: node linkType: hard @@ -8114,13 +8114,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.14.0": - version: 6.14.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.14.0" +"@typescript-eslint/visitor-keys@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.15.0" dependencies: - "@typescript-eslint/types": 6.14.0 + "@typescript-eslint/types": 6.15.0 eslint-visitor-keys: ^3.4.1 - checksum: fc593c4e94d5739be7bd88e42313a301bc9806fad758b6a0a1bafd296ff41522be602caf4976beec84e363b0f56585bb98df3c157f70de984de721798501fd8a + checksum: 1bccc4d4eea6fd10a4ab1daa9e1aaaf790d5f4dd5d02c6e3eb6e83414c086d8d5f14ac44c9fb587b2f7e0dad3e7aeae603158d89dec9ae89652024331bb84fea languageName: node linkType: hard @@ -19829,8 +19829,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.14.0 - "@typescript-eslint/parser": 6.14.0 + "@typescript-eslint/eslint-plugin": 6.15.0 + "@typescript-eslint/parser": 6.15.0 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.56.0 From 521be6457848f11913353eeac07c6748838c6635 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 22:13:41 +0000 Subject: [PATCH 068/136] chore(deps): update node.js to 8d0f16f --- packages/apollo-federation-subgraph-compatibility/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/apollo-federation-subgraph-compatibility/Dockerfile b/packages/apollo-federation-subgraph-compatibility/Dockerfile index 811732484d7..238a02b55db 100644 --- a/packages/apollo-federation-subgraph-compatibility/Dockerfile +++ b/packages/apollo-federation-subgraph-compatibility/Dockerfile @@ -1,4 +1,4 @@ -FROM node:lts@sha256:445acd9b2ef7e9de665424053bf95652e0b8995ef36500557d48faf29300170a +FROM node:lts@sha256:8d0f16fe841577f9317ab49011c6d819e1fa81f8d4af7ece7ae0ac815e07ac84 WORKDIR /app From 892839e52ed685f88f1e3a892a7a180385c3a345 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 22:22:22 +0000 Subject: [PATCH 069/136] chore(deps): update node.js to d0acb10 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 14f0cd34a35..d2d3df4d5de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20.10.0-buster-slim@sha256:b46831a79b7bd8d8d38b2bd50273b7611f0e168c840a97a1137a0cf243850086 +FROM node:20.10.0-buster-slim@sha256:d0acb10d0062944abd19d56d79f4953de6bba167b04c961c6eba6054fbc4990c WORKDIR /app From a35df06e6a1ad3255ffcef9910d29fc2d4d379d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 00:02:51 +0000 Subject: [PATCH 070/136] chore(deps): update rabbitmq docker digest to 0742852 --- .../workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml index bb7dd6818e1..0e27f58ae52 100644 --- a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml +++ b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml @@ -26,7 +26,7 @@ jobs: ports: - 7687:7687 rabbitmq: - image: rabbitmq@sha256:fbaa5a8b16e856d86b28797135a5333df96a40c8ce3facc092911f47e439666e + image: rabbitmq@sha256:0742852455ad44e67b04e0d6a422a778a9d9ec3e78a6a9ae2c5cca7d0fa55aa9 env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest From 99c22c3a8be73cc07bdb27ad1f8d2820f4d2ca5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 00:11:39 +0000 Subject: [PATCH 071/136] chore(deps): update rabbitmq:3.12-management docker digest to 4d150af --- examples/neo-place/docker-compose.yml | 2 +- examples/subscriptions/apollo_rabbitmq/docker-compose.yml | 2 +- packages/graphql-amqp-subscriptions-engine/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/neo-place/docker-compose.yml b/examples/neo-place/docker-compose.yml index 62b4a158221..9835c43f557 100644 --- a/examples/neo-place/docker-compose.yml +++ b/examples/neo-place/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:39068aaebbb59af29794455c4f08db633a9d6273b7a2a8ffeb70f00f5c48df9b + image: rabbitmq:3.12-management@sha256:4d150aff57f588bbee11332c252232a12cb8e50ec3a60ebb3452899ecb3d1b27 ports: - "5672:5672" - "15672:15672" diff --git a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml index 62b4a158221..9835c43f557 100644 --- a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml +++ b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:39068aaebbb59af29794455c4f08db633a9d6273b7a2a8ffeb70f00f5c48df9b + image: rabbitmq:3.12-management@sha256:4d150aff57f588bbee11332c252232a12cb8e50ec3a60ebb3452899ecb3d1b27 ports: - "5672:5672" - "15672:15672" diff --git a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml index 9f339825294..42db7eeb6bc 100644 --- a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml +++ b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' # This is just for local testing services: rabbitmq: - image: rabbitmq:3.12-management@sha256:39068aaebbb59af29794455c4f08db633a9d6273b7a2a8ffeb70f00f5c48df9b + image: rabbitmq:3.12-management@sha256:4d150aff57f588bbee11332c252232a12cb8e50ec3a60ebb3452899ecb3d1b27 ports: - "5672:5672" - "15672:15672" From b9db5d72fe8fe33278eaa9c959b8cb12ceb23496 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 04:13:26 +0000 Subject: [PATCH 072/136] chore(deps): update rabbitmq:3.12-management docker digest to 4bf95a7 --- examples/neo-place/docker-compose.yml | 2 +- examples/subscriptions/apollo_rabbitmq/docker-compose.yml | 2 +- packages/graphql-amqp-subscriptions-engine/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/neo-place/docker-compose.yml b/examples/neo-place/docker-compose.yml index 9835c43f557..fb54b775d12 100644 --- a/examples/neo-place/docker-compose.yml +++ b/examples/neo-place/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:4d150aff57f588bbee11332c252232a12cb8e50ec3a60ebb3452899ecb3d1b27 + image: rabbitmq:3.12-management@sha256:4bf95a7d58e27e928a669229bd1d7e2b446fb9b1eb9275833d4bf55160f8ecec ports: - "5672:5672" - "15672:15672" diff --git a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml index 9835c43f557..fb54b775d12 100644 --- a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml +++ b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:4d150aff57f588bbee11332c252232a12cb8e50ec3a60ebb3452899ecb3d1b27 + image: rabbitmq:3.12-management@sha256:4bf95a7d58e27e928a669229bd1d7e2b446fb9b1eb9275833d4bf55160f8ecec ports: - "5672:5672" - "15672:15672" diff --git a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml index 42db7eeb6bc..2a5aa2ec20d 100644 --- a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml +++ b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' # This is just for local testing services: rabbitmq: - image: rabbitmq:3.12-management@sha256:4d150aff57f588bbee11332c252232a12cb8e50ec3a60ebb3452899ecb3d1b27 + image: rabbitmq:3.12-management@sha256:4bf95a7d58e27e928a669229bd1d7e2b446fb9b1eb9275833d4bf55160f8ecec ports: - "5672:5672" - "15672:15672" From ca6e8e38eca56a3ab141f024cc07f53dc109fdb8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 04:22:40 +0000 Subject: [PATCH 073/136] chore(deps): update dependency html-webpack-plugin to v5.6.0 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 44d3483f6e5..10f8b75c9c7 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -86,7 +86,7 @@ "fork-ts-checker-webpack-plugin": "9.0.2", "html-inline-script-webpack-plugin": "3.2.1", "html-webpack-inline-source-plugin": "0.0.10", - "html-webpack-plugin": "5.5.4", + "html-webpack-plugin": "5.6.0", "jest": "29.7.0", "jest-environment-jsdom": "29.7.0", "node-polyfill-webpack-plugin": "2.0.1", diff --git a/yarn.lock b/yarn.lock index 53f337ebd00..7d0e53f8f1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3662,7 +3662,7 @@ __metadata: graphql-query-complexity: 0.12.0 html-inline-script-webpack-plugin: 3.2.1 html-webpack-inline-source-plugin: 0.0.10 - html-webpack-plugin: 5.5.4 + html-webpack-plugin: 5.6.0 jest: 29.7.0 jest-environment-jsdom: 29.7.0 neo4j-driver: 5.15.0 @@ -15445,9 +15445,9 @@ __metadata: languageName: node linkType: hard -"html-webpack-plugin@npm:5.5.4": - version: 5.5.4 - resolution: "html-webpack-plugin@npm:5.5.4" +"html-webpack-plugin@npm:5.6.0": + version: 5.6.0 + resolution: "html-webpack-plugin@npm:5.6.0" dependencies: "@types/html-minifier-terser": ^6.0.0 html-minifier-terser: ^6.0.2 @@ -15455,8 +15455,14 @@ __metadata: pretty-error: ^4.0.0 tapable: ^2.0.0 peerDependencies: + "@rspack/core": 0.x || 1.x webpack: ^5.20.0 - checksum: b49befb73d67a3716fd0e6f7776b108d2b0b7050fb8221f05cd114cbae13c03150a13b7cdf5e76170be040ce7936a1cf76f7a4bfd9ebe1552b72d7889a74c374 + peerDependenciesMeta: + "@rspack/core": + optional: true + webpack: + optional: true + checksum: 32a6e41da538e798fd0be476637d7611a5e8a98a3508f031996e9eb27804dcdc282cb01f847cf5d066f21b49cfb8e21627fcf977ffd0c9bea81cf80e5a65070d languageName: node linkType: hard From 4352a86cc3248d3865989a2a8bf256a5cfbe47fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 22:27:45 +0000 Subject: [PATCH 074/136] chore(deps): update rabbitmq:3.12-management docker digest to 6033d0c --- examples/neo-place/docker-compose.yml | 2 +- examples/subscriptions/apollo_rabbitmq/docker-compose.yml | 2 +- packages/graphql-amqp-subscriptions-engine/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/neo-place/docker-compose.yml b/examples/neo-place/docker-compose.yml index fb54b775d12..5184f0c9c31 100644 --- a/examples/neo-place/docker-compose.yml +++ b/examples/neo-place/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:4bf95a7d58e27e928a669229bd1d7e2b446fb9b1eb9275833d4bf55160f8ecec + image: rabbitmq:3.12-management@sha256:6033d0c2f4e9eb49dda9623067a96d317bc7b550513bd18532fbd3cd9a941c1b ports: - "5672:5672" - "15672:15672" diff --git a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml index fb54b775d12..5184f0c9c31 100644 --- a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml +++ b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:4bf95a7d58e27e928a669229bd1d7e2b446fb9b1eb9275833d4bf55160f8ecec + image: rabbitmq:3.12-management@sha256:6033d0c2f4e9eb49dda9623067a96d317bc7b550513bd18532fbd3cd9a941c1b ports: - "5672:5672" - "15672:15672" diff --git a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml index 2a5aa2ec20d..92fd61b37ca 100644 --- a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml +++ b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' # This is just for local testing services: rabbitmq: - image: rabbitmq:3.12-management@sha256:4bf95a7d58e27e928a669229bd1d7e2b446fb9b1eb9275833d4bf55160f8ecec + image: rabbitmq:3.12-management@sha256:6033d0c2f4e9eb49dda9623067a96d317bc7b550513bd18532fbd3cd9a941c1b ports: - "5672:5672" - "15672:15672" From f1b8520a68ddda85904cd676ddaa6f6cd3bf5da1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 22:36:44 +0000 Subject: [PATCH 075/136] chore(deps): update dependency graphql-ws to v5.14.3 --- .../graphql-amqp-subscriptions-engine/package.json | 2 +- packages/graphql/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index d28fb834a14..f4533247d6f 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -42,7 +42,7 @@ "@types/jest": "29.5.11", "@types/node": "20.10.5", "camelcase": "6.3.0", - "graphql-ws": "5.14.2", + "graphql-ws": "5.14.3", "jest": "29.7.0", "neo4j-driver": "5.15.0", "pluralize": "8.0.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index a0a34c907cf..67326ca9c91 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -65,7 +65,7 @@ "dedent": "1.5.1", "graphql-middleware": "6.1.35", "graphql-tag": "2.12.6", - "graphql-ws": "5.14.2", + "graphql-ws": "5.14.3", "is-uuid": "1.0.2", "jest": "29.7.0", "jest-extended": "4.0.2", diff --git a/yarn.lock b/yarn.lock index 7d0e53f8f1e..ebca88c0f45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3580,7 +3580,7 @@ __metadata: body-parser: ^1.20.2 camelcase: 6.3.0 cors: ^2.8.5 - graphql-ws: 5.14.2 + graphql-ws: 5.14.3 jest: 29.7.0 neo4j-driver: 5.15.0 pluralize: 8.0.0 @@ -3725,7 +3725,7 @@ __metadata: graphql-parse-resolve-info: ^4.12.3 graphql-relay: ^0.10.0 graphql-tag: 2.12.6 - graphql-ws: 5.14.2 + graphql-ws: 5.14.3 is-uuid: 1.0.2 jest: 29.7.0 jest-extended: 4.0.2 @@ -15002,12 +15002,12 @@ __metadata: languageName: node linkType: hard -"graphql-ws@npm:5.14.2": - version: 5.14.2 - resolution: "graphql-ws@npm:5.14.2" +"graphql-ws@npm:5.14.3": + version: 5.14.3 + resolution: "graphql-ws@npm:5.14.3" peerDependencies: graphql: ">=0.11 <=16" - checksum: ee9affa2478b9d262405986f07616267b4db10ae45cf32fffb551572fb5bf5e1e3aa6652375511b3ff640d382c74c1327ce75ff1ee2fa8b964b3ef3d55d97f75 + checksum: c5bfdeb6d06f528e2222e71bf830b2f4f3e5b95419453d3b650cef9fe012e0126f121e4858d950edf3db1fb209a056b592643751624d1bc1fc71ecbe546d53d5 languageName: node linkType: hard From 4ddd81a688ec346541a952bf19b2240b608372f2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:49:13 +0000 Subject: [PATCH 076/136] chore(deps): update dependency tailwindcss to v3.4.0 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 10f8b75c9c7..4fcbcabf9af 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -95,7 +95,7 @@ "postcss-loader": "7.3.3", "randomstring": "1.3.0", "style-loader": "3.3.3", - "tailwindcss": "3.3.7", + "tailwindcss": "3.4.0", "terser-webpack-plugin": "5.3.9", "ts-jest": "29.1.1", "ts-loader": "9.5.1", diff --git a/yarn.lock b/yarn.lock index ebca88c0f45..93ea558df8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3676,7 +3676,7 @@ __metadata: react: 18.2.0 react-dom: 18.2.0 style-loader: 3.3.3 - tailwindcss: 3.3.7 + tailwindcss: 3.4.0 terser-webpack-plugin: 5.3.9 thememirror: 2.0.1 ts-jest: 29.1.1 @@ -24790,9 +24790,9 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:3.3.7": - version: 3.3.7 - resolution: "tailwindcss@npm:3.3.7" +"tailwindcss@npm:3.4.0": + version: 3.4.0 + resolution: "tailwindcss@npm:3.4.0" dependencies: "@alloc/quick-lru": ^5.2.0 arg: ^5.0.2 @@ -24819,7 +24819,7 @@ __metadata: bin: tailwind: lib/cli.js tailwindcss: lib/cli.js - checksum: 73728e03ac00bb90a09436895b663473336da4a539ca22df41c62948fd4e45c5feda71d6f33c03666045dbb1806ee36658caf604256d20196ebf580ec0987c2d + checksum: d7f05beb1cf98d169b9b65ef674a82dd16c97757194f9bacee4c536cf74f3852e0008a74f7af8578f4a1e9639fac262fd8ef89efe3e6e06667243640422f9462 languageName: node linkType: hard From df4af94f2037a599251486931aaf8fb7b2d9e4b5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 01:58:43 +0000 Subject: [PATCH 077/136] chore(deps): update reviewdog/action-actionlint action to v1.40.0 --- .github/workflows/lint-github-actions.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint-github-actions.yml b/.github/workflows/lint-github-actions.yml index a2ccf0684ab..292b1b71165 100644 --- a/.github/workflows/lint-github-actions.yml +++ b/.github/workflows/lint-github-actions.yml @@ -16,7 +16,7 @@ jobs: steps: - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - uses: reviewdog/action-actionlint@82693e9e3b239f213108d6e412506f8b54003586 # v1.39.1 + - uses: reviewdog/action-actionlint@9ccda195fd3a290c8596db7f1958c897deaa8c76 # v1.40.0 with: reporter: github-check fail_on_error: true From 75792e67f5056f808afe6ec55c9f8e31a9e77c4a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 02:08:52 +0000 Subject: [PATCH 078/136] chore(deps): update reviewdog/action-eslint action to v1.21.0 --- .github/workflows/pull-requests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index 8bf0126663c..dd6b460485a 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -25,7 +25,7 @@ jobs: cache: yarn - name: Install dependencies run: yarn --immutable - - uses: reviewdog/action-eslint@10ca150f51dbbb963467c37a03c873ba1fa75f91 # v1.20.0 + - uses: reviewdog/action-eslint@279acb08336462ec76183a2d9ef1dd43e4c6b391 # v1.21.0 with: fail_on_error: true eslint_flags: "." From 876d2c449eacaadad176add5a2502a958328c072 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Dec 2023 02:18:51 +0000 Subject: [PATCH 079/136] chore(deps): update srvaroa/labeler action to v1.9.0 --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 14d966b0591..5ac07b63b5f 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -13,6 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: srvaroa/labeler@7d6ef903be9638aad7ada1206470d932dc4bfc50 # v1.8.2 + - uses: srvaroa/labeler@ff8cb30f062faad05978491eebd6c75fef132272 # v1.9.0 env: GITHUB_TOKEN: ${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }} From 551c0cc4389f23eebd06928be7f50d12e9f48c0f Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Thu, 21 Dec 2023 15:39:31 +0100 Subject: [PATCH 080/136] Experimental: Union relationship filters (#4440) * feat: add missing relationship filters for union relationships --- .../create-relationship-concrete-fields.ts | 100 +++ .../create-relationship-fields.ts | 82 +-- .../create-relationship-union-fields.ts | 32 +- .../generation/connect-or-create-input.ts | 2 + .../src/schema/generation/where-input.ts | 13 +- .../ast/filters/RelationshipFilter.ts | 22 +- .../queryAST/factory/AuthFilterFactory.ts | 7 +- .../queryAST/factory/FilterFactory.ts | 85 ++- .../union-relationship-filtering.int.test.ts | 229 ++++++ .../experimental-schema/comments.test.ts | 10 + .../directive-preserve.test.ts | 10 + .../directives/relationship-aggregate.test.ts | 20 + .../relationship-nested-operations.test.ts | 120 ++++ .../directives/selectable.test.ts | 20 + .../directives/settable.test.ts | 40 ++ .../experimental-schema/subscriptions.test.ts | 20 + .../union-interface-relationship.test.ts | 10 + .../union-relationship-filtering.test.ts | 675 ++++++++++++++++++ .../experimental/interface-filtering.test.ts | 2 +- .../union-relationship-filtering.test.ts | 141 ++++ 20 files changed, 1520 insertions(+), 120 deletions(-) create mode 100644 packages/graphql/src/schema/create-relationship-fields/create-relationship-concrete-fields.ts create mode 100644 packages/graphql/tests/integration/experimental/union-relationship-filtering.int.test.ts create mode 100644 packages/graphql/tests/schema/experimental-schema/union-relationship-filtering.test.ts create mode 100644 packages/graphql/tests/tck/experimental/union-relationship-filtering.test.ts diff --git a/packages/graphql/src/schema/create-relationship-fields/create-relationship-concrete-fields.ts b/packages/graphql/src/schema/create-relationship-fields/create-relationship-concrete-fields.ts new file mode 100644 index 00000000000..cbf4bc71470 --- /dev/null +++ b/packages/graphql/src/schema/create-relationship-fields/create-relationship-concrete-fields.ts @@ -0,0 +1,100 @@ +/* + * 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 { DirectiveNode } from "graphql"; +import type { Directive, InterfaceTypeComposer, ObjectTypeComposer, SchemaComposer } from "graphql-compose"; +import type { Subgraph } from "../../classes/Subgraph"; +import type { RelationshipAdapter } from "../../schema-model/relationship/model-adapters/RelationshipAdapter"; +import { augmentObjectOrInterfaceTypeWithRelationshipField } from "../generation/augment-object-or-interface"; +import { augmentConnectInputTypeWithConnectFieldInput } from "../generation/connect-input"; +import { withConnectOrCreateInputType } from "../generation/connect-or-create-input"; +import { augmentCreateInputTypeWithRelationshipsInput } from "../generation/create-input"; +import { augmentDeleteInputTypeWithDeleteFieldInput } from "../generation/delete-input"; +import { augmentDisconnectInputTypeWithDisconnectFieldInput } from "../generation/disconnect-input"; +import { withRelationInputType } from "../generation/relation-input"; +import { augmentUpdateInputTypeWithUpdateFieldInput } from "../generation/update-input"; +import { withSourceWhereInputType } from "../generation/where-input"; + +export function createRelationshipConcreteFields({ + relationshipAdapter, + composeNode, + schemaComposer, + userDefinedFieldDirectives, + deprecatedDirectives, + subgraph, +}: { + relationshipAdapter: RelationshipAdapter; + composeNode: ObjectTypeComposer | InterfaceTypeComposer; + schemaComposer: SchemaComposer; + userDefinedFieldDirectives: Map; + deprecatedDirectives: Directive[]; + subgraph?: Subgraph; +}) { + withSourceWhereInputType({ relationshipAdapter, composer: schemaComposer, deprecatedDirectives }); + + withConnectOrCreateInputType({ + relationshipAdapter, + composer: schemaComposer, + userDefinedFieldDirectives, + deprecatedDirectives, + }); + + composeNode.addFields( + augmentObjectOrInterfaceTypeWithRelationshipField(relationshipAdapter, userDefinedFieldDirectives, subgraph) + ); + + withRelationInputType({ + relationshipAdapter, + composer: schemaComposer, + deprecatedDirectives, + userDefinedFieldDirectives, + }); + + augmentCreateInputTypeWithRelationshipsInput({ + relationshipAdapter, + composer: schemaComposer, + deprecatedDirectives, + userDefinedFieldDirectives, + }); + + augmentConnectInputTypeWithConnectFieldInput({ + relationshipAdapter, + composer: schemaComposer, + deprecatedDirectives, + }); + + augmentUpdateInputTypeWithUpdateFieldInput({ + relationshipAdapter, + composer: schemaComposer, + deprecatedDirectives, + userDefinedFieldDirectives, + }); + + augmentDeleteInputTypeWithDeleteFieldInput({ + relationshipAdapter, + composer: schemaComposer, + deprecatedDirectives, + }); + + augmentDisconnectInputTypeWithDisconnectFieldInput({ + relationshipAdapter, + composer: schemaComposer, + deprecatedDirectives, + }); +} diff --git a/packages/graphql/src/schema/create-relationship-fields/create-relationship-fields.ts b/packages/graphql/src/schema/create-relationship-fields/create-relationship-fields.ts index 4f35b54fadd..d6627f00b69 100644 --- a/packages/graphql/src/schema/create-relationship-fields/create-relationship-fields.ts +++ b/packages/graphql/src/schema/create-relationship-fields/create-relationship-fields.ts @@ -22,21 +22,13 @@ import type { Directive, InterfaceTypeComposer, SchemaComposer } from "graphql-c import { ObjectTypeComposer } from "graphql-compose"; import type { Subgraph } from "../../classes/Subgraph"; import { DEPRECATED } from "../../constants"; -import type { ConcreteEntityAdapter } from "../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +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 { FieldAggregationComposer } from "../aggregations/field-aggregation-composer"; import { addDirectedArgument } from "../directed-argument"; -import { augmentObjectOrInterfaceTypeWithRelationshipField } from "../generation/augment-object-or-interface"; -import { augmentConnectInputTypeWithConnectFieldInput } from "../generation/connect-input"; -import { withConnectOrCreateInputType } from "../generation/connect-or-create-input"; -import { augmentCreateInputTypeWithRelationshipsInput } from "../generation/create-input"; -import { augmentDeleteInputTypeWithDeleteFieldInput } from "../generation/delete-input"; -import { augmentDisconnectInputTypeWithDisconnectFieldInput } from "../generation/disconnect-input"; -import { withRelationInputType } from "../generation/relation-input"; -import { augmentUpdateInputTypeWithUpdateFieldInput } from "../generation/update-input"; -import { withSourceWhereInputType } from "../generation/where-input"; import { graphqlDirectivesToCompose } from "../to-compose"; +import { createRelationshipConcreteFields } from "./create-relationship-concrete-fields"; import { createRelationshipInterfaceFields } from "./create-relationship-interface-fields"; import { createRelationshipUnionFields } from "./create-relationship-union-fields"; @@ -70,10 +62,11 @@ export function createRelationshipFields({ if (relationshipTarget instanceof UnionEntityAdapter) { createRelationshipUnionFields({ - relationship: relationshipAdapter, + relationshipAdapter, composeNode, schemaComposer, userDefinedFieldDirectives, + experimental, }); return; @@ -87,6 +80,7 @@ export function createRelationshipFields({ ); } + // NOTE: Non-experimental path for InterfaceEntityAdapter if (!experimental && relationshipTarget instanceof InterfaceEntityAdapter) { createRelationshipInterfaceFields({ relationship: relationshipAdapter, @@ -121,6 +115,7 @@ export function createRelationshipFields({ } } + // NOTE: Experimental path for InterfaceEntityAdapter // Specifically placed the check for InterfaceEntityAdapter here // so that we exit the function at this point, after the aggregation fields have been added above if (relationshipTarget instanceof InterfaceEntityAdapter) { @@ -134,60 +129,15 @@ export function createRelationshipFields({ return; } - // ======== only on relationships to concrete entities: - withSourceWhereInputType({ relationshipAdapter, composer: schemaComposer, deprecatedDirectives }); - - // ======== only on relationships to concrete | unions: - // TODO: refactor - withConnectOrCreateInputType({ - relationshipAdapter, - composer: schemaComposer, - userDefinedFieldDirectives, - deprecatedDirectives, - }); - - // ======== all relationships: - composeNode.addFields( - augmentObjectOrInterfaceTypeWithRelationshipField(relationshipAdapter, userDefinedFieldDirectives, subgraph) - ); - - withRelationInputType({ - relationshipAdapter, - composer: schemaComposer, - deprecatedDirectives, - userDefinedFieldDirectives, - }); - - augmentCreateInputTypeWithRelationshipsInput({ - relationshipAdapter, - composer: schemaComposer, - deprecatedDirectives, - userDefinedFieldDirectives, - }); - - augmentConnectInputTypeWithConnectFieldInput({ - relationshipAdapter, - composer: schemaComposer, - deprecatedDirectives, - }); - - augmentUpdateInputTypeWithUpdateFieldInput({ - relationshipAdapter, - composer: schemaComposer, - deprecatedDirectives, - userDefinedFieldDirectives, - }); - - augmentDeleteInputTypeWithDeleteFieldInput({ - relationshipAdapter, - composer: schemaComposer, - deprecatedDirectives, - }); - - augmentDisconnectInputTypeWithDisconnectFieldInput({ - relationshipAdapter, - composer: schemaComposer, - deprecatedDirectives, - }); + if (relationshipTarget instanceof ConcreteEntityAdapter) { + createRelationshipConcreteFields({ + relationshipAdapter, + composeNode, + schemaComposer, + userDefinedFieldDirectives, + deprecatedDirectives, + subgraph, + }); + } }); } diff --git a/packages/graphql/src/schema/create-relationship-fields/create-relationship-union-fields.ts b/packages/graphql/src/schema/create-relationship-fields/create-relationship-union-fields.ts index e98b9443bbe..0e96a3e7d36 100644 --- a/packages/graphql/src/schema/create-relationship-fields/create-relationship-union-fields.ts +++ b/packages/graphql/src/schema/create-relationship-fields/create-relationship-union-fields.ts @@ -18,7 +18,7 @@ */ import type { DirectiveNode } from "graphql"; -import type { ObjectTypeComposer, SchemaComposer, InterfaceTypeComposer } from "graphql-compose"; +import type { InterfaceTypeComposer, ObjectTypeComposer, SchemaComposer } from "graphql-compose"; import type { RelationshipAdapter } from "../../schema-model/relationship/model-adapters/RelationshipAdapter"; import { augmentObjectOrInterfaceTypeWithRelationshipField } from "../generation/augment-object-or-interface"; import { augmentConnectInputTypeWithConnectFieldInput } from "../generation/connect-input"; @@ -28,64 +28,74 @@ import { augmentDeleteInputTypeWithDeleteFieldInput } from "../generation/delete import { augmentDisconnectInputTypeWithDisconnectFieldInput } from "../generation/disconnect-input"; import { withRelationInputType } from "../generation/relation-input"; import { augmentUpdateInputTypeWithUpdateFieldInput } from "../generation/update-input"; +import { withSourceWhereInputType } from "../generation/where-input"; export function createRelationshipUnionFields({ - relationship, + relationshipAdapter, composeNode, schemaComposer, userDefinedFieldDirectives, + experimental, }: { - relationship: RelationshipAdapter; + relationshipAdapter: RelationshipAdapter; composeNode: ObjectTypeComposer | InterfaceTypeComposer; schemaComposer: SchemaComposer; userDefinedFieldDirectives: Map; + experimental: boolean; }) { + if (experimental) { + // ======== only on relationships to concrete | unions: + withSourceWhereInputType({ relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [] }); + } + // ======== only on relationships to concrete | unions: withConnectOrCreateInputType({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, userDefinedFieldDirectives, deprecatedDirectives: [], }); // ======== all relationships: - composeNode.addFields(augmentObjectOrInterfaceTypeWithRelationshipField(relationship, userDefinedFieldDirectives)); + composeNode.addFields( + augmentObjectOrInterfaceTypeWithRelationshipField(relationshipAdapter, userDefinedFieldDirectives) + ); withRelationInputType({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [], userDefinedFieldDirectives, }); augmentCreateInputTypeWithRelationshipsInput({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [], userDefinedFieldDirectives, }); augmentUpdateInputTypeWithUpdateFieldInput({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [], userDefinedFieldDirectives, }); augmentConnectInputTypeWithConnectFieldInput({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [], }); augmentDeleteInputTypeWithDeleteFieldInput({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [], }); augmentDisconnectInputTypeWithDisconnectFieldInput({ - relationshipAdapter: relationship, + relationshipAdapter, composer: schemaComposer, deprecatedDirectives: [], }); diff --git a/packages/graphql/src/schema/generation/connect-or-create-input.ts b/packages/graphql/src/schema/generation/connect-or-create-input.ts index 8d7095fd52e..eb83916de86 100644 --- a/packages/graphql/src/schema/generation/connect-or-create-input.ts +++ b/packages/graphql/src/schema/generation/connect-or-create-input.ts @@ -128,6 +128,7 @@ export function withConnectOrCreateInputType({ return connectOrCreateInput; } + function makeConnectOrCreateInputType({ relationshipAdapter, composer, @@ -204,6 +205,7 @@ function withRelationshipConnectOrCreateInputType({ const connectOrCreateInput = composer.createInputTC({ name: typeName, fields }); return connectOrCreateInput; } + function makeUnionConnectOrCreateInputTypeFields({ relationshipAdapter, composer, diff --git a/packages/graphql/src/schema/generation/where-input.ts b/packages/graphql/src/schema/generation/where-input.ts index 9c089c1137a..1f2b5158d4a 100644 --- a/packages/graphql/src/schema/generation/where-input.ts +++ b/packages/graphql/src/schema/generation/where-input.ts @@ -157,22 +157,25 @@ export function withSourceWhereInputType({ deprecatedDirectives: Directive[]; }): InputTypeComposer | undefined { const relationshipTarget = relationshipAdapter.target; - if (!(relationshipTarget instanceof ConcreteEntityAdapter)) { - throw new Error("Expected concrete target"); + if (relationshipTarget instanceof InterfaceEntityAdapter) { + throw new Error("Unexpected interface target"); } const relationshipSource = relationshipAdapter.source; - if (relationshipSource instanceof UnionEntityAdapter) { - throw new Error("Unexpected union source"); - } const whereInput = composer.getITC(relationshipSource.operations.whereInputTypeName); const fields = augmentWhereInputTypeWithRelationshipFields(relationshipAdapter, deprecatedDirectives); whereInput.addFields(fields); + // TODO: Current unions are not supported as relationship targets beyond the above fields + if (relationshipTarget instanceof UnionEntityAdapter) { + return; + } + const whereAggregateInput = withAggregateInputType({ relationshipAdapter, entityAdapter: relationshipTarget, composer: composer, }); + if (relationshipAdapter.isFilterableByAggregate()) { whereInput.addFields({ [relationshipAdapter.operations.aggregateTypeName]: { diff --git a/packages/graphql/src/translate/queryAST/ast/filters/RelationshipFilter.ts b/packages/graphql/src/translate/queryAST/ast/filters/RelationshipFilter.ts index e3f4a86d865..9826688c89f 100644 --- a/packages/graphql/src/translate/queryAST/ast/filters/RelationshipFilter.ts +++ b/packages/graphql/src/translate/queryAST/ast/filters/RelationshipFilter.ts @@ -18,22 +18,25 @@ */ import Cypher from "@neo4j/cypher-builder"; -import type { RelationshipWhereOperator } from "../../../where/types"; -import { Filter } from "./Filter"; -import type { QueryASTContext } from "../QueryASTContext"; -import type { RelationshipAdapter } from "../../../../schema-model/relationship/model-adapters/RelationshipAdapter"; -import type { QueryASTNode } from "../QueryASTNode"; import { Memoize } from "typescript-memoize"; +import type { ConcreteEntityAdapter } from "../../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; +import type { InterfaceEntityAdapter } from "../../../../schema-model/entity/model-adapters/InterfaceEntityAdapter"; +import type { RelationshipAdapter } from "../../../../schema-model/relationship/model-adapters/RelationshipAdapter"; import { filterTruthy } from "../../../../utils/utils"; +import type { RelationshipWhereOperator } from "../../../where/types"; import { hasTarget } from "../../utils/context-has-target"; -import { wrapSubqueriesInCypherCalls } from "../../utils/wrap-subquery-in-calls"; import { createNodeFromEntity } from "../../utils/create-node-from-entity"; +import { wrapSubqueriesInCypherCalls } from "../../utils/wrap-subquery-in-calls"; +import type { QueryASTContext } from "../QueryASTContext"; +import type { QueryASTNode } from "../QueryASTNode"; +import { Filter } from "./Filter"; export class RelationshipFilter extends Filter { protected targetNodeFilters: Filter[] = []; protected relationship: RelationshipAdapter; protected operator: RelationshipWhereOperator; protected isNot: boolean; + protected target: ConcreteEntityAdapter | InterfaceEntityAdapter; // TODO: remove this, this is not good protected subqueryPredicate: Cypher.Predicate | undefined; @@ -45,15 +48,18 @@ export class RelationshipFilter extends Filter { relationship, operator, isNot, + target, }: { relationship: RelationshipAdapter; operator: RelationshipWhereOperator; isNot: boolean; + target: ConcreteEntityAdapter | InterfaceEntityAdapter; }) { super(); this.relationship = relationship; this.isNot = isNot; this.operator = operator; + this.target = target; // Note: This is just to keep naming with previous Cypher, it is safe to remove this.countVariable = new Cypher.NamedVariable(`${this.relationship.name}Count`); @@ -73,7 +79,7 @@ export class RelationshipFilter extends Filter { @Memoize() protected getNestedContext(context: QueryASTContext): QueryASTContext { - const relatedEntity = this.relationship.target; + const relatedEntity = this.target; const target = createNodeFromEntity(relatedEntity, context.neo4jGraphQLContext); const relationship = new Cypher.Relationship({ type: this.relationship.type, @@ -134,7 +140,7 @@ export class RelationshipFilter extends Filter { public getSubqueries(context: QueryASTContext): Cypher.Clause[] { // NOTE: not using getNestedContext because this should not be memoized in ALL operations - const relatedEntity = this.relationship.target; + const relatedEntity = this.target; const target = createNodeFromEntity(relatedEntity, context.neo4jGraphQLContext); const relationship = new Cypher.Relationship({ type: this.relationship.type, diff --git a/packages/graphql/src/translate/queryAST/factory/AuthFilterFactory.ts b/packages/graphql/src/translate/queryAST/factory/AuthFilterFactory.ts index 08c697c9250..d2eeb79f67f 100644 --- a/packages/graphql/src/translate/queryAST/factory/AuthFilterFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/AuthFilterFactory.ts @@ -17,6 +17,7 @@ * limitations under the License. */ +import { asArray } from "@graphql-tools/utils"; import Cypher from "@neo4j/cypher-builder"; import type { AttributeAdapter } from "../../../schema-model/attribute/model-adapters/AttributeAdapter"; import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-adapters/ConcreteEntityAdapter"; @@ -27,18 +28,17 @@ import type { AuthorizationOperation } from "../../../types/authorization"; import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context"; import { isLogicalOperator } from "../../utils/logical-operators"; import type { RelationshipWhereOperator, WhereOperator } from "../../where/types"; +import type { ConnectionFilter } from "../ast/filters/ConnectionFilter"; import type { Filter } from "../ast/filters/Filter"; import { LogicalFilter } from "../ast/filters/LogicalFilter"; import type { RelationshipFilter } from "../ast/filters/RelationshipFilter"; +import { AuthConnectionFilter } from "../ast/filters/authorization-filters/AuthConnectionFilter"; import { AuthRelationshipFilter } from "../ast/filters/authorization-filters/AuthRelationshipFilter"; import { JWTFilter } from "../ast/filters/authorization-filters/JWTFilter"; import { ParamPropertyFilter } from "../ast/filters/property-filters/ParamPropertyFilter"; import { PropertyFilter } from "../ast/filters/property-filters/PropertyFilter"; import { FilterFactory } from "./FilterFactory"; import { parseWhereField } from "./parsers/parse-where-field"; -import type { ConnectionFilter } from "../ast/filters/ConnectionFilter"; -import { AuthConnectionFilter } from "../ast/filters/authorization-filters/AuthConnectionFilter"; -import { asArray } from "@graphql-tools/utils"; export class AuthFilterFactory extends FilterFactory { // PopulatedWhere has the values as Cypher variables @@ -188,6 +188,7 @@ export class AuthFilterFactory extends FilterFactory { protected createRelationshipFilterTreeNode(options: { relationship: RelationshipAdapter; + target: ConcreteEntityAdapter | InterfaceEntityAdapter; isNot: boolean; operator: RelationshipWhereOperator; }): RelationshipFilter { diff --git a/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts b/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts index 6caa2e34062..8e66f5bc05f 100644 --- a/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/FilterFactory.ts @@ -189,10 +189,10 @@ export class FilterFactory { } private createRelationshipFilter( - where: GraphQLWhereArg, relationship: RelationshipAdapter, + where: GraphQLWhereArg, filterOps: { isNot: boolean; operator: RelationshipWhereOperator | undefined } - ): RelationshipFilter | undefined { + ): RelationshipFilter[] { /** * The logic below can be confusing, but it's to handle the following cases: * 1. where: { actors: null } -> in this case we want to return an Exists filter as showed by tests packages/graphql/tests/tck/null.test.ts @@ -200,35 +200,60 @@ export class FilterFactory { **/ const isNull = where === null; if (!isNull && Object.keys(where).length === 0) { - return; + return []; } - // this is because if isNull it's true we want to wrap the Exist subclause in a NOT, but if it's isNull it's true and isNot it's true they negate each other + // this is because if isNull is true we want to wrap the Exist subclause in a NOT, but if isNull is true and isNot is true they negate each other const isNot = isNull ? !filterOps.isNot : filterOps.isNot; - const relationshipFilter = this.createRelationshipFilterTreeNode({ - relationship: relationship, - isNot, - operator: filterOps.operator || "SOME", - }); + if (isInterfaceEntity(relationship.target) && !where.node?._on) { + const relationshipFilter = this.createRelationshipFilterTreeNode({ + relationship, + target: relationship.target, + isNot, + operator: filterOps.operator || "SOME", + }); - if (!isNull) { - const targetNode = relationship.target; - const targetNodeFilters = this.createNodeFilters(targetNode, where); - relationshipFilter.addTargetNodeFilter(...targetNodeFilters); - } + if (!isNull) { + const targetNode = relationship.target; + const targetNodeFilters = this.createNodeFilters(targetNode, where); + relationshipFilter.addTargetNodeFilter(...targetNodeFilters); + } - return relationshipFilter; + return [relationshipFilter]; + } else { + const filteredEntities = this.filterConcreteEntities(relationship.target, where); + const relationshipFilters: RelationshipFilter[] = []; + for (const concreteEntity of filteredEntities) { + const relationshipFilter = this.createRelationshipFilterTreeNode({ + relationship, + target: concreteEntity, + isNot, + operator: filterOps.operator || "SOME", + }); + + if (!isNull) { + const entityWhere = where[concreteEntity.name] ?? where; + const targetNodeFilters = this.createNodeFilters(concreteEntity, entityWhere); + relationshipFilter.addTargetNodeFilter(...targetNodeFilters); + } + + relationshipFilters.push(relationshipFilter); + } + return relationshipFilters; + } } - // This allow to override this creation in AuthorizationFilterFactory + // This allows to override this creation in AuthorizationFilterFactory protected createRelationshipFilterTreeNode(options: { relationship: RelationshipAdapter; + target: ConcreteEntityAdapter | InterfaceEntityAdapter; isNot: boolean; operator: RelationshipWhereOperator; }): RelationshipFilter { return new RelationshipFilter(options); } - // This allow to override this creation in AuthorizationFilterFactory + + // This allows to override this creation in AuthorizationFilterFactory protected createConnectionFilterTreeNode(options: { relationship: RelationshipAdapter; target: ConcreteEntityAdapter | InterfaceEntityAdapter; @@ -317,9 +342,8 @@ export class FilterFactory { return this.createExperimentalInterfaceFilters(entity, where); } const whereFields = this.getConcreteFiltersWhere(entity, where); - const filters = filterTruthy( - Object.entries(whereFields).flatMap(([key, value]): Filter | undefined => { + Object.entries(whereFields).flatMap(([key, value]): Filter | Filter[] | undefined => { if (isLogicalOperator(key)) { const nestedFilters = asArray(value).flatMap((nestedWhere) => { return this.createNodeFilters(entity, nestedWhere); @@ -329,6 +353,7 @@ export class FilterFactory { filters: nestedFilters, }); } + if (key === "_on" && isObject(value)) { return this.getConcreteFilter(entity, value); } @@ -341,7 +366,9 @@ export class FilterFactory { } if (isConnection) { - if (!relationship) throw new Error(`Relationship not found for connection ${fieldName}`); + if (!relationship) { + throw new Error(`Relationship not found for connection ${fieldName}`); + } if (operator && !isRelationshipOperator(operator)) { throw new Error(`Invalid operator ${operator} for relationship`); } @@ -353,9 +380,11 @@ export class FilterFactory { return this.wrapMultipleFiltersInLogical(connectionFilters)[0]; } if (isAggregate) { - if (!relationship) throw new Error(`Relationship not found for connection ${fieldName}`); + if (!relationship) { + throw new Error(`Relationship not found for connection ${fieldName}`); + } - return this.createAggregationFilter(value as AggregateWhereInput, relationship); + return this.createAggregationFilter(relationship, value as AggregateWhereInput); } if (relationship) { @@ -363,7 +392,7 @@ export class FilterFactory { throw new Error(`Invalid operator ${operator} for relationship`); } - return this.createRelationshipFilter(value as GraphQLWhereArg, relationship, { + return this.createRelationshipFilter(relationship, value as GraphQLWhereArg, { isNot, operator, }); @@ -383,7 +412,9 @@ export class FilterFactory { throw new Error(`Cannot query Relay Id on "${entity.name}"`); } const idAttribute = entity.findAttribute(field); - if (!idAttribute) throw new Error(`Attribute ${field} not found`); + if (!idAttribute) { + throw new Error(`Attribute ${field} not found`); + } if (idAttribute.typeHelper.isNumeric()) { id = Number(id); @@ -401,7 +432,9 @@ export class FilterFactory { } } - if (!attr) throw new Error(`Attribute ${fieldName} not found`); + if (!attr) { + throw new Error(`Attribute ${fieldName} not found`); + } return this.createPropertyFilter({ attribute: attr, comparisonValue: value, @@ -488,7 +521,7 @@ export class FilterFactory { return this.wrapMultipleFiltersInLogical(nestedFilters); } - private createAggregationFilter(where: AggregateWhereInput, relationship: RelationshipAdapter): AggregationFilter { + private createAggregationFilter(relationship: RelationshipAdapter, where: AggregateWhereInput): AggregationFilter { const aggregationFilter = new AggregationFilter(relationship); const nestedFilters = this.getAggregationNestedFilters(where, relationship); aggregationFilter.addFilters(...nestedFilters); diff --git a/packages/graphql/tests/integration/experimental/union-relationship-filtering.int.test.ts b/packages/graphql/tests/integration/experimental/union-relationship-filtering.int.test.ts new file mode 100644 index 00000000000..eeec2d01e51 --- /dev/null +++ b/packages/graphql/tests/integration/experimental/union-relationship-filtering.int.test.ts @@ -0,0 +1,229 @@ +/* + * 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 { createBearerToken } from "../../utils/create-bearer-token"; +import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; + +describe("Union filtering", () => { + const secret = "the-secret"; + + let schema: GraphQLSchema; + let neo4j: Neo4j; + let driver: Driver; + let typeDefs: string; + + const Movie = new UniqueType("Movie"); + const Series = new UniqueType("Series"); + const Actor = new UniqueType("Actor"); + + async function graphqlQuery(query: string, token: string) { + return graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ token }), + }); + } + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + + typeDefs = /* GraphQL */ ` + union Production = ${Movie} | ${Series} + + type ${Movie} { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type ${Series} { + title: String! + actors: [${Actor}!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type ${Actor} { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + + interface ActedIn @relationshipProperties { + screenTime: Int! + } + `; + + const session = await neo4j.getSession(); + + try { + await session.run(` + CREATE(m1:${Movie} { title: "The Office" }) + CREATE(m2:${Movie} { title: "The Office 2" }) + CREATE(m3:${Movie} { title: "NOT The Office 2" }) + CREATE(s1:${Series} { title: "The Office 2" }) + CREATE(s2:${Series} { title: "NOT The Office" }) + CREATE(a1:${Actor} {name: "Keanu"}) + CREATE(a2:${Actor} {name: "Michael"}) + CREATE(a3:${Actor} {name: "John"}) + MERGE(a1)-[:ACTED_IN]->(m1) + MERGE(a1)-[:ACTED_IN]->(s2) + MERGE(a2)-[:ACTED_IN]->(m2) + MERGE(a2)-[:ACTED_IN]->(m3) + MERGE(a2)-[:ACTED_IN]->(s1) + MERGE(a3)-[:ACTED_IN]->(s1) + MERGE(a3)-[:ACTED_IN]->(s2) + `); + } finally { + await session.close(); + } + + const neoGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + features: { + authorization: { + key: secret, + }, + }, + experimental: true, + }); + schema = await neoGraphql.getSchema(); + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + await cleanNodes(session, [Movie, Series, Actor]); + await session.close(); + await driver.close(); + }); + + test("allow for filtering on top-level union relationships", async () => { + const query = /* GraphQL */ ` + query { + productions(where: { ${Movie}: { title: "The Office" }, ${Series}: { title: "The Office 2" } }) { + ... on ${Movie} { + title + } + ... on ${Series} { + title + } + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + productions: expect.toIncludeSameMembers([ + { + title: "The Office", + }, + { + title: "The Office 2", + }, + ]), + }); + }); + + test("allow for filtering on nested-level relationship unions", async () => { + const query = /* GraphQL */ ` + query { + ${Actor.plural}(where: { + actedIn_SOME: { ${Movie}: { title_CONTAINS: "Office" }} + }) { + name + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphqlQuery(query, token); + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.plural]: expect.toIncludeSameMembers([ + { + name: "Keanu", + }, + { + name: "Michael", + }, + ]), + }); + }); + + test("allow updating an actor name based on a union relationship filter", async () => { + const query = /* GraphQL */ ` + mutation updateName($name: String!) { + ${Actor.operations.update}( + where: { actedIn_SOME: { ${Movie}: { title: "The Office" } }}, + update: { name: $name } + ) { + ${Actor.plural} { + name + actedIn { + __typename + ... on ${Movie} { + title + } + ... on ${Series} { + title + } + } + } + } + } + `; + + const token = createBearerToken(secret, {}); + const queryResult = await graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues({ token }), + variableValues: { + name: "Michael Scott", + }, + }); + + expect(queryResult.errors).toBeUndefined(); + expect(queryResult.data).toEqual({ + [Actor.operations.update]: { + [Actor.plural]: [ + { + name: "Michael Scott", + actedIn: [ + { + __typename: Movie.name, + title: "The Office", + }, + { + __typename: Series.name, + title: "NOT The Office", + }, + ], + }, + ], + }, + }); + }); +}); diff --git a/packages/graphql/tests/schema/experimental-schema/comments.test.ts b/packages/graphql/tests/schema/experimental-schema/comments.test.ts index a4e8d92a47d..ab1b5351cfa 100644 --- a/packages/graphql/tests/schema/experimental-schema/comments.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/comments.test.ts @@ -1606,6 +1606,7 @@ describe("Comments", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + search: SearchWhere @deprecated(reason: \\"Use \`search_SOME\` instead.\\") searchConnection: MovieSearchConnectionWhere @deprecated(reason: \\"Use \`searchConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieSearchConnections match this filter @@ -1624,6 +1625,15 @@ describe("Comments", () => { Return Movies where some of the related MovieSearchConnections match this filter \\"\\"\\" searchConnection_SOME: MovieSearchConnectionWhere + \\"\\"\\"Return Movies where all of the related Searches match this filter\\"\\"\\" + search_ALL: SearchWhere + \\"\\"\\"Return Movies where none of the related Searches match this filter\\"\\"\\" + search_NONE: SearchWhere + search_NOT: SearchWhere @deprecated(reason: \\"Use \`search_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related Searches match this filter\\"\\"\\" + search_SINGLE: SearchWhere + \\"\\"\\"Return Movies where some of the related Searches match this filter\\"\\"\\" + search_SOME: SearchWhere } type MoviesConnection { 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 504ee386512..3944795f8f5 100644 --- a/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directive-preserve.test.ts @@ -3517,6 +3517,7 @@ describe("Directive-preserve", () => { AND: [UserWhere!] NOT: UserWhere OR: [UserWhere!] + content: ContentWhere @deprecated(reason: \\"Use \`content_SOME\` instead.\\") contentConnection: UserContentConnectionWhere @deprecated(reason: \\"Use \`contentConnection_SOME\` instead.\\") \\"\\"\\" Return Users where all of the related UserContentConnections match this filter @@ -3535,6 +3536,15 @@ describe("Directive-preserve", () => { Return Users where some of the related UserContentConnections match this filter \\"\\"\\" contentConnection_SOME: UserContentConnectionWhere @deprecated(reason: \\"Do not use user.content\\") + \\"\\"\\"Return Users where all of the related Contents match this filter\\"\\"\\" + content_ALL: ContentWhere + \\"\\"\\"Return Users where none of the related Contents match this filter\\"\\"\\" + content_NONE: ContentWhere + content_NOT: ContentWhere @deprecated(reason: \\"Use \`content_NONE\` instead.\\") + \\"\\"\\"Return Users where one of the related Contents match this filter\\"\\"\\" + content_SINGLE: ContentWhere + \\"\\"\\"Return Users where some of the related Contents match this filter\\"\\"\\" + content_SOME: ContentWhere name: String name_CONTAINS: String name_ENDS_WITH: String 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 65698ea852e..5e41c590628 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 @@ -2338,6 +2338,7 @@ describe("@relationship directive, aggregate argument", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: CastMemberWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -2356,6 +2357,15 @@ describe("@relationship directive, aggregate argument", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related CastMembers match this filter\\"\\"\\" + actors_ALL: CastMemberWhere + \\"\\"\\"Return Movies where none of the related CastMembers match this filter\\"\\"\\" + actors_NONE: CastMemberWhere + actors_NOT: CastMemberWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related CastMembers match this filter\\"\\"\\" + actors_SINGLE: CastMemberWhere + \\"\\"\\"Return Movies where some of the related CastMembers match this filter\\"\\"\\" + actors_SOME: CastMemberWhere title: String title_CONTAINS: String title_ENDS_WITH: String @@ -2861,6 +2871,7 @@ describe("@relationship directive, aggregate argument", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: CastMemberWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -2879,6 +2890,15 @@ describe("@relationship directive, aggregate argument", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related CastMembers match this filter\\"\\"\\" + actors_ALL: CastMemberWhere + \\"\\"\\"Return Movies where none of the related CastMembers match this filter\\"\\"\\" + actors_NONE: CastMemberWhere + actors_NOT: CastMemberWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related CastMembers match this filter\\"\\"\\" + actors_SINGLE: CastMemberWhere + \\"\\"\\"Return Movies where some of the related CastMembers match this filter\\"\\"\\" + actors_SOME: CastMemberWhere title: String title_CONTAINS: String title_ENDS_WITH: String 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 f8a44943b42..850c7c51181 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 @@ -4180,6 +4180,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -4198,6 +4199,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -4610,6 +4620,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -4628,6 +4639,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -5040,6 +5060,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -5058,6 +5079,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -5455,6 +5485,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -5473,6 +5504,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -5871,6 +5911,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -5889,6 +5930,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -6287,6 +6337,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -6305,6 +6356,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -6671,6 +6731,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -6689,6 +6750,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -7119,6 +7189,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -7137,6 +7208,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -7733,6 +7813,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -7751,6 +7832,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -7761,6 +7851,7 @@ describe("Relationship nested operations", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + producers: PersonWhere @deprecated(reason: \\"Use \`producers_SOME\` instead.\\") producersConnection: MovieProducersConnectionWhere @deprecated(reason: \\"Use \`producersConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieProducersConnections match this filter @@ -7779,6 +7870,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieProducersConnections match this filter \\"\\"\\" producersConnection_SOME: MovieProducersConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + producers_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + producers_NONE: PersonWhere + producers_NOT: PersonWhere @deprecated(reason: \\"Use \`producers_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + producers_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + producers_SOME: PersonWhere } type MoviesConnection { @@ -8257,6 +8357,7 @@ describe("Relationship nested operations", () => { AND: [MovieWhere!] NOT: MovieWhere OR: [MovieWhere!] + actors: PersonWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -8275,6 +8376,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + actors_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + actors_NONE: PersonWhere + actors_NOT: PersonWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + actors_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + actors_SOME: PersonWhere id: ID id_CONTAINS: ID id_ENDS_WITH: ID @@ -8285,6 +8395,7 @@ describe("Relationship nested operations", () => { id_NOT_IN: [ID] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_NOT_STARTS_WITH: ID @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") id_STARTS_WITH: ID + producers: PersonWhere @deprecated(reason: \\"Use \`producers_SOME\` instead.\\") producersConnection: MovieProducersConnectionWhere @deprecated(reason: \\"Use \`producersConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieProducersConnections match this filter @@ -8303,6 +8414,15 @@ describe("Relationship nested operations", () => { Return Movies where some of the related MovieProducersConnections match this filter \\"\\"\\" producersConnection_SOME: MovieProducersConnectionWhere + \\"\\"\\"Return Movies where all of the related People match this filter\\"\\"\\" + producers_ALL: PersonWhere + \\"\\"\\"Return Movies where none of the related People match this filter\\"\\"\\" + producers_NONE: PersonWhere + producers_NOT: PersonWhere @deprecated(reason: \\"Use \`producers_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related People match this filter\\"\\"\\" + producers_SINGLE: PersonWhere + \\"\\"\\"Return Movies where some of the related People match this filter\\"\\"\\" + producers_SOME: PersonWhere } type MoviesConnection { 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 a1616e1ff1a..afaa4a028d9 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/selectable.test.ts @@ -1878,6 +1878,7 @@ describe("@selectable", () => { AND: [ActorWhere!] NOT: ActorWhere OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") \\"\\"\\" Return Actors where all of the related ActorActedInConnections match this filter @@ -1896,6 +1897,15 @@ describe("@selectable", () => { Return Actors where some of the related ActorActedInConnections match this filter \\"\\"\\" actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -2417,6 +2427,7 @@ describe("@selectable", () => { AND: [ActorWhere!] NOT: ActorWhere OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") \\"\\"\\" Return Actors where all of the related ActorActedInConnections match this filter @@ -2435,6 +2446,15 @@ describe("@selectable", () => { Return Actors where some of the related ActorActedInConnections match this filter \\"\\"\\" actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere name: String name_CONTAINS: String name_ENDS_WITH: String 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 e653d9222cf..bec896df0d4 100644 --- a/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/directives/settable.test.ts @@ -2989,6 +2989,7 @@ describe("@settable", () => { AND: [ActorWhere!] NOT: ActorWhere OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") \\"\\"\\" Return Actors where all of the related ActorActedInConnections match this filter @@ -3007,6 +3008,15 @@ describe("@settable", () => { Return Actors where some of the related ActorActedInConnections match this filter \\"\\"\\" actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -3497,6 +3507,7 @@ describe("@settable", () => { AND: [ActorWhere!] NOT: ActorWhere OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") \\"\\"\\" Return Actors where all of the related ActorActedInConnections match this filter @@ -3515,6 +3526,15 @@ describe("@settable", () => { Return Actors where some of the related ActorActedInConnections match this filter \\"\\"\\" actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -4011,6 +4031,7 @@ describe("@settable", () => { AND: [ActorWhere!] NOT: ActorWhere OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") \\"\\"\\" Return Actors where all of the related ActorActedInConnections match this filter @@ -4029,6 +4050,15 @@ describe("@settable", () => { Return Actors where some of the related ActorActedInConnections match this filter \\"\\"\\" actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere name: String name_CONTAINS: String name_ENDS_WITH: String @@ -4717,6 +4747,7 @@ describe("@settable", () => { AND: [ActorWhere!] NOT: ActorWhere OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") \\"\\"\\" Return Actors where all of the related ActorActedInConnections match this filter @@ -4735,6 +4766,15 @@ describe("@settable", () => { Return Actors where some of the related ActorActedInConnections match this filter \\"\\"\\" actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere name: String name_CONTAINS: String name_ENDS_WITH: String diff --git a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts index b8091c1ff33..2f5539df586 100644 --- a/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/subscriptions.test.ts @@ -1854,6 +1854,7 @@ describe("Subscriptions", () => { actorCount_LTE: Int actorCount_NOT: Int @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") actorCount_NOT_IN: [Int] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -1872,6 +1873,15 @@ describe("Subscriptions", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related Actors match this filter\\"\\"\\" + actors_ALL: ActorWhere + \\"\\"\\"Return Movies where none of the related Actors match this filter\\"\\"\\" + actors_NONE: ActorWhere + actors_NOT: ActorWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related Actors match this filter\\"\\"\\" + actors_SINGLE: ActorWhere + \\"\\"\\"Return Movies where some of the related Actors match this filter\\"\\"\\" + actors_SOME: ActorWhere averageRating: Float averageRating_GT: Float averageRating_GTE: Float @@ -5007,6 +5017,7 @@ describe("Subscriptions", () => { actorCount_LTE: Int actorCount_NOT: Int @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") actorCount_NOT_IN: [Int] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + actors: ActorWhere @deprecated(reason: \\"Use \`actors_SOME\` instead.\\") actorsConnection: MovieActorsConnectionWhere @deprecated(reason: \\"Use \`actorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieActorsConnections match this filter @@ -5025,6 +5036,15 @@ describe("Subscriptions", () => { Return Movies where some of the related MovieActorsConnections match this filter \\"\\"\\" actorsConnection_SOME: MovieActorsConnectionWhere + \\"\\"\\"Return Movies where all of the related Actors match this filter\\"\\"\\" + actors_ALL: ActorWhere + \\"\\"\\"Return Movies where none of the related Actors match this filter\\"\\"\\" + actors_NONE: ActorWhere + actors_NOT: ActorWhere @deprecated(reason: \\"Use \`actors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related Actors match this filter\\"\\"\\" + actors_SINGLE: ActorWhere + \\"\\"\\"Return Movies where some of the related Actors match this filter\\"\\"\\" + actors_SOME: ActorWhere averageRating: Float averageRating_GT: Float averageRating_GTE: Float 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 905d0c3647e..bc5eb4f0465 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 @@ -1255,6 +1255,7 @@ describe("Union Interface Relationships", () => { actors_SINGLE: ActorWhere \\"\\"\\"Return Movies where some of the related Actors match this filter\\"\\"\\" actors_SOME: ActorWhere + directors: DirectorWhere @deprecated(reason: \\"Use \`directors_SOME\` instead.\\") directorsConnection: MovieDirectorsConnectionWhere @deprecated(reason: \\"Use \`directorsConnection_SOME\` instead.\\") \\"\\"\\" Return Movies where all of the related MovieDirectorsConnections match this filter @@ -1273,6 +1274,15 @@ describe("Union Interface Relationships", () => { Return Movies where some of the related MovieDirectorsConnections match this filter \\"\\"\\" directorsConnection_SOME: MovieDirectorsConnectionWhere + \\"\\"\\"Return Movies where all of the related Directors match this filter\\"\\"\\" + directors_ALL: DirectorWhere + \\"\\"\\"Return Movies where none of the related Directors match this filter\\"\\"\\" + directors_NONE: DirectorWhere + directors_NOT: DirectorWhere @deprecated(reason: \\"Use \`directors_NONE\` instead.\\") + \\"\\"\\"Return Movies where one of the related Directors match this filter\\"\\"\\" + directors_SINGLE: DirectorWhere + \\"\\"\\"Return Movies where some of the related Directors match this filter\\"\\"\\" + directors_SOME: DirectorWhere imdbId: Int imdbId_GT: Int imdbId_GTE: Int diff --git a/packages/graphql/tests/schema/experimental-schema/union-relationship-filtering.test.ts b/packages/graphql/tests/schema/experimental-schema/union-relationship-filtering.test.ts new file mode 100644 index 00000000000..edb38bc4eda --- /dev/null +++ b/packages/graphql/tests/schema/experimental-schema/union-relationship-filtering.test.ts @@ -0,0 +1,675 @@ +/* + * 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 { printSchemaWithDirectives } from "@graphql-tools/utils"; +import { lexicographicSortSchema } from "graphql"; +import { Neo4jGraphQL } from "../../../src"; + +describe("Union Relationships Filtering", () => { + test("Union Relationships Filtering", async () => { + const typeDefs = ` + type Movie { + title: String! + isan: String! @unique + } + type Series { + title: String! + isan: String! @unique + } + union Production = Movie | Series + interface ActedIn @relationshipProperties { + screenTime: Int! + } + type Actor { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + `; + + const neoSchema = new Neo4jGraphQL({ typeDefs, experimental: true }); + const printedSchema = printSchemaWithDirectives(lexicographicSortSchema(await neoSchema.getSchema())); + + expect(printedSchema).toMatchInlineSnapshot(` + "schema { + query: Query + mutation: Mutation + } + + interface ActedIn { + screenTime: Int! + } + + input ActedInCreateInput { + screenTime: Int! + } + + input ActedInSort { + screenTime: SortDirection + } + + input ActedInUpdateInput { + screenTime: Int + screenTime_DECREMENT: Int + screenTime_INCREMENT: Int + } + + input ActedInWhere { + AND: [ActedInWhere!] + NOT: ActedInWhere + OR: [ActedInWhere!] + screenTime: Int + screenTime_GT: Int + screenTime_GTE: Int + screenTime_IN: [Int!] + screenTime_LT: Int + screenTime_LTE: Int + screenTime_NOT: Int @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + screenTime_NOT_IN: [Int!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + } + + type Actor { + actedIn(directed: Boolean = true, options: QueryOptions, where: ProductionWhere): [Production!]! + actedInConnection(after: String, directed: Boolean = true, first: Int, sort: [ActorActedInConnectionSort!], where: ActorActedInConnectionWhere): ActorActedInConnection! + name: String! + } + + input ActorActedInConnectInput { + Movie: [ActorActedInMovieConnectFieldInput!] + Series: [ActorActedInSeriesConnectFieldInput!] + } + + input ActorActedInConnectOrCreateInput { + Movie: [ActorActedInMovieConnectOrCreateFieldInput!] + Series: [ActorActedInSeriesConnectOrCreateFieldInput!] + } + + type ActorActedInConnection { + edges: [ActorActedInRelationship!]! + pageInfo: PageInfo! + totalCount: Int! + } + + input ActorActedInConnectionSort { + edge: ActedInSort + } + + input ActorActedInConnectionWhere { + Movie: ActorActedInMovieConnectionWhere + Series: ActorActedInSeriesConnectionWhere + } + + input ActorActedInCreateFieldInput { + Movie: [ActorActedInMovieCreateFieldInput!] + Series: [ActorActedInSeriesCreateFieldInput!] + } + + input ActorActedInCreateInput { + Movie: ActorActedInMovieFieldInput + Series: ActorActedInSeriesFieldInput + } + + input ActorActedInDeleteInput { + Movie: [ActorActedInMovieDeleteFieldInput!] + Series: [ActorActedInSeriesDeleteFieldInput!] + } + + input ActorActedInDisconnectInput { + Movie: [ActorActedInMovieDisconnectFieldInput!] + Series: [ActorActedInSeriesDisconnectFieldInput!] + } + + input ActorActedInMovieConnectFieldInput { + edge: ActedInCreateInput! + where: MovieConnectWhere + } + + input ActorActedInMovieConnectOrCreateFieldInput { + onCreate: ActorActedInMovieConnectOrCreateFieldInputOnCreate! + where: MovieConnectOrCreateWhere! + } + + input ActorActedInMovieConnectOrCreateFieldInputOnCreate { + edge: ActedInCreateInput! + node: MovieOnCreateInput! + } + + input ActorActedInMovieConnectionWhere { + AND: [ActorActedInMovieConnectionWhere!] + NOT: ActorActedInMovieConnectionWhere + OR: [ActorActedInMovieConnectionWhere!] + edge: ActedInWhere + edge_NOT: ActedInWhere @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + node: MovieWhere + node_NOT: MovieWhere @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + } + + input ActorActedInMovieCreateFieldInput { + edge: ActedInCreateInput! + node: MovieCreateInput! + } + + input ActorActedInMovieDeleteFieldInput { + where: ActorActedInMovieConnectionWhere + } + + input ActorActedInMovieDisconnectFieldInput { + where: ActorActedInMovieConnectionWhere + } + + input ActorActedInMovieFieldInput { + connect: [ActorActedInMovieConnectFieldInput!] + connectOrCreate: [ActorActedInMovieConnectOrCreateFieldInput!] + create: [ActorActedInMovieCreateFieldInput!] + } + + input ActorActedInMovieUpdateConnectionInput { + edge: ActedInUpdateInput + node: MovieUpdateInput + } + + input ActorActedInMovieUpdateFieldInput { + connect: [ActorActedInMovieConnectFieldInput!] + connectOrCreate: [ActorActedInMovieConnectOrCreateFieldInput!] + create: [ActorActedInMovieCreateFieldInput!] + delete: [ActorActedInMovieDeleteFieldInput!] + disconnect: [ActorActedInMovieDisconnectFieldInput!] + update: ActorActedInMovieUpdateConnectionInput + where: ActorActedInMovieConnectionWhere + } + + type ActorActedInRelationship implements ActedIn { + cursor: String! + node: Production! + screenTime: Int! + } + + input ActorActedInSeriesConnectFieldInput { + edge: ActedInCreateInput! + where: SeriesConnectWhere + } + + input ActorActedInSeriesConnectOrCreateFieldInput { + onCreate: ActorActedInSeriesConnectOrCreateFieldInputOnCreate! + where: SeriesConnectOrCreateWhere! + } + + input ActorActedInSeriesConnectOrCreateFieldInputOnCreate { + edge: ActedInCreateInput! + node: SeriesOnCreateInput! + } + + input ActorActedInSeriesConnectionWhere { + AND: [ActorActedInSeriesConnectionWhere!] + NOT: ActorActedInSeriesConnectionWhere + OR: [ActorActedInSeriesConnectionWhere!] + edge: ActedInWhere + edge_NOT: ActedInWhere @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + node: SeriesWhere + node_NOT: SeriesWhere @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + } + + input ActorActedInSeriesCreateFieldInput { + edge: ActedInCreateInput! + node: SeriesCreateInput! + } + + input ActorActedInSeriesDeleteFieldInput { + where: ActorActedInSeriesConnectionWhere + } + + input ActorActedInSeriesDisconnectFieldInput { + where: ActorActedInSeriesConnectionWhere + } + + input ActorActedInSeriesFieldInput { + connect: [ActorActedInSeriesConnectFieldInput!] + connectOrCreate: [ActorActedInSeriesConnectOrCreateFieldInput!] + create: [ActorActedInSeriesCreateFieldInput!] + } + + input ActorActedInSeriesUpdateConnectionInput { + edge: ActedInUpdateInput + node: SeriesUpdateInput + } + + input ActorActedInSeriesUpdateFieldInput { + connect: [ActorActedInSeriesConnectFieldInput!] + connectOrCreate: [ActorActedInSeriesConnectOrCreateFieldInput!] + create: [ActorActedInSeriesCreateFieldInput!] + delete: [ActorActedInSeriesDeleteFieldInput!] + disconnect: [ActorActedInSeriesDisconnectFieldInput!] + update: ActorActedInSeriesUpdateConnectionInput + where: ActorActedInSeriesConnectionWhere + } + + input ActorActedInUpdateInput { + Movie: [ActorActedInMovieUpdateFieldInput!] + Series: [ActorActedInSeriesUpdateFieldInput!] + } + + type ActorAggregateSelection { + count: Int! + name: StringAggregateSelectionNonNullable! + } + + input ActorConnectInput { + actedIn: ActorActedInConnectInput + } + + input ActorConnectOrCreateInput { + actedIn: ActorActedInConnectOrCreateInput + } + + input ActorCreateInput { + actedIn: ActorActedInCreateInput + name: String! + } + + input ActorDeleteInput { + actedIn: ActorActedInDeleteInput + } + + input ActorDisconnectInput { + actedIn: ActorActedInDisconnectInput + } + + type ActorEdge { + cursor: String! + node: Actor! + } + + input ActorOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more ActorSort objects to sort Actors by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [ActorSort!] + } + + input ActorRelationInput { + actedIn: ActorActedInCreateFieldInput + } + + \\"\\"\\" + Fields to sort Actors by. The order in which sorts are applied is not guaranteed when specifying many fields in one ActorSort object. + \\"\\"\\" + input ActorSort { + name: SortDirection + } + + input ActorUpdateInput { + actedIn: ActorActedInUpdateInput + name: String + } + + input ActorWhere { + AND: [ActorWhere!] + NOT: ActorWhere + OR: [ActorWhere!] + actedIn: ProductionWhere @deprecated(reason: \\"Use \`actedIn_SOME\` instead.\\") + actedInConnection: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_SOME\` instead.\\") + \\"\\"\\" + Return Actors where all of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_ALL: ActorActedInConnectionWhere + \\"\\"\\" + Return Actors where none of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_NONE: ActorActedInConnectionWhere + actedInConnection_NOT: ActorActedInConnectionWhere @deprecated(reason: \\"Use \`actedInConnection_NONE\` instead.\\") + \\"\\"\\" + Return Actors where one of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_SINGLE: ActorActedInConnectionWhere + \\"\\"\\" + Return Actors where some of the related ActorActedInConnections match this filter + \\"\\"\\" + actedInConnection_SOME: ActorActedInConnectionWhere + \\"\\"\\"Return Actors where all of the related Productions match this filter\\"\\"\\" + actedIn_ALL: ProductionWhere + \\"\\"\\"Return Actors where none of the related Productions match this filter\\"\\"\\" + actedIn_NONE: ProductionWhere + actedIn_NOT: ProductionWhere @deprecated(reason: \\"Use \`actedIn_NONE\` instead.\\") + \\"\\"\\"Return Actors where one of the related Productions match this filter\\"\\"\\" + actedIn_SINGLE: ProductionWhere + \\"\\"\\"Return Actors where some of the related Productions match this filter\\"\\"\\" + actedIn_SOME: ProductionWhere + name: String + name_CONTAINS: String + name_ENDS_WITH: String + name_IN: [String!] + name_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + name_STARTS_WITH: String + } + + type ActorsConnection { + edges: [ActorEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + type CreateActorsMutationResponse { + actors: [Actor!]! + info: CreateInfo! + } + + \\"\\"\\" + Information about the number of nodes and relationships created during a create mutation + \\"\\"\\" + type CreateInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesCreated: Int! + relationshipsCreated: Int! + } + + type CreateMoviesMutationResponse { + info: CreateInfo! + movies: [Movie!]! + } + + type CreateSeriesMutationResponse { + info: CreateInfo! + series: [Series!]! + } + + \\"\\"\\" + Information about the number of nodes and relationships deleted during a delete mutation + \\"\\"\\" + type DeleteInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesDeleted: Int! + relationshipsDeleted: Int! + } + + type Movie { + isan: String! + title: String! + } + + type MovieAggregateSelection { + count: Int! + isan: StringAggregateSelectionNonNullable! + title: StringAggregateSelectionNonNullable! + } + + input MovieConnectOrCreateWhere { + node: MovieUniqueWhere! + } + + input MovieConnectWhere { + node: MovieWhere! + } + + input MovieCreateInput { + isan: String! + title: String! + } + + type MovieEdge { + cursor: String! + node: Movie! + } + + input MovieOnCreateInput { + isan: String! + title: String! + } + + input MovieOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more MovieSort objects to sort Movies by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [MovieSort!] + } + + \\"\\"\\" + Fields to sort Movies by. The order in which sorts are applied is not guaranteed when specifying many fields in one MovieSort object. + \\"\\"\\" + input MovieSort { + isan: SortDirection + title: SortDirection + } + + input MovieUniqueWhere { + isan: String + } + + input MovieUpdateInput { + isan: String + title: String + } + + input MovieWhere { + AND: [MovieWhere!] + NOT: MovieWhere + OR: [MovieWhere!] + isan: String + isan_CONTAINS: String + isan_ENDS_WITH: String + isan_IN: [String!] + isan_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_STARTS_WITH: String + title: String + title_CONTAINS: String + title_ENDS_WITH: String + title_IN: [String!] + title_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_STARTS_WITH: String + } + + type MoviesConnection { + edges: [MovieEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + type Mutation { + createActors(input: [ActorCreateInput!]!): CreateActorsMutationResponse! + createMovies(input: [MovieCreateInput!]!): CreateMoviesMutationResponse! + createSeries(input: [SeriesCreateInput!]!): CreateSeriesMutationResponse! + deleteActors(delete: ActorDeleteInput, where: ActorWhere): DeleteInfo! + deleteMovies(where: MovieWhere): DeleteInfo! + deleteSeries(where: SeriesWhere): DeleteInfo! + updateActors(connect: ActorConnectInput, connectOrCreate: ActorConnectOrCreateInput, create: ActorRelationInput, delete: ActorDeleteInput, disconnect: ActorDisconnectInput, update: ActorUpdateInput, where: ActorWhere): UpdateActorsMutationResponse! + updateMovies(update: MovieUpdateInput, where: MovieWhere): UpdateMoviesMutationResponse! + updateSeries(update: SeriesUpdateInput, where: SeriesWhere): UpdateSeriesMutationResponse! + } + + \\"\\"\\"Pagination information (Relay)\\"\\"\\" + type PageInfo { + endCursor: String + hasNextPage: Boolean! + hasPreviousPage: Boolean! + startCursor: String + } + + union Production = Movie | Series + + input ProductionWhere { + Movie: MovieWhere + Series: SeriesWhere + } + + type Query { + actors(options: ActorOptions, where: ActorWhere): [Actor!]! + actorsAggregate(where: ActorWhere): ActorAggregateSelection! + actorsConnection(after: String, first: Int, sort: [ActorSort], where: ActorWhere): ActorsConnection! + movies(options: MovieOptions, where: MovieWhere): [Movie!]! + moviesAggregate(where: MovieWhere): MovieAggregateSelection! + moviesConnection(after: String, first: Int, sort: [MovieSort], where: MovieWhere): MoviesConnection! + productions(options: QueryOptions, where: ProductionWhere): [Production!]! + series(options: SeriesOptions, where: SeriesWhere): [Series!]! + seriesAggregate(where: SeriesWhere): SeriesAggregateSelection! + seriesConnection(after: String, first: Int, sort: [SeriesSort], where: SeriesWhere): SeriesConnection! + } + + \\"\\"\\"Input type for options that can be specified on a query operation.\\"\\"\\" + input QueryOptions { + limit: Int + offset: Int + } + + type Series { + isan: String! + title: String! + } + + type SeriesAggregateSelection { + count: Int! + isan: StringAggregateSelectionNonNullable! + title: StringAggregateSelectionNonNullable! + } + + input SeriesConnectOrCreateWhere { + node: SeriesUniqueWhere! + } + + input SeriesConnectWhere { + node: SeriesWhere! + } + + type SeriesConnection { + edges: [SeriesEdge!]! + pageInfo: PageInfo! + totalCount: Int! + } + + input SeriesCreateInput { + isan: String! + title: String! + } + + type SeriesEdge { + cursor: String! + node: Series! + } + + input SeriesOnCreateInput { + isan: String! + title: String! + } + + input SeriesOptions { + limit: Int + offset: Int + \\"\\"\\" + Specify one or more SeriesSort objects to sort Series by. The sorts will be applied in the order in which they are arranged in the array. + \\"\\"\\" + sort: [SeriesSort!] + } + + \\"\\"\\" + Fields to sort Series by. The order in which sorts are applied is not guaranteed when specifying many fields in one SeriesSort object. + \\"\\"\\" + input SeriesSort { + isan: SortDirection + title: SortDirection + } + + input SeriesUniqueWhere { + isan: String + } + + input SeriesUpdateInput { + isan: String + title: String + } + + input SeriesWhere { + AND: [SeriesWhere!] + NOT: SeriesWhere + OR: [SeriesWhere!] + isan: String + isan_CONTAINS: String + isan_ENDS_WITH: String + isan_IN: [String!] + isan_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + isan_STARTS_WITH: String + title: String + title_CONTAINS: String + title_ENDS_WITH: String + title_IN: [String!] + title_NOT: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_CONTAINS: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_ENDS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_IN: [String!] @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_NOT_STARTS_WITH: String @deprecated(reason: \\"Negation filters will be deprecated, use the NOT operator to achieve the same behavior\\") + title_STARTS_WITH: String + } + + \\"\\"\\"An enum for sorting in either ascending or descending order.\\"\\"\\" + enum SortDirection { + \\"\\"\\"Sort by field values in ascending order.\\"\\"\\" + ASC + \\"\\"\\"Sort by field values in descending order.\\"\\"\\" + DESC + } + + type StringAggregateSelectionNonNullable { + longest: String! + shortest: String! + } + + type UpdateActorsMutationResponse { + actors: [Actor!]! + info: UpdateInfo! + } + + \\"\\"\\" + Information about the number of nodes and relationships created and deleted during an update mutation + \\"\\"\\" + type UpdateInfo { + bookmark: String @deprecated(reason: \\"This field has been deprecated because bookmarks are now handled by the driver.\\") + nodesCreated: Int! + nodesDeleted: Int! + relationshipsCreated: Int! + relationshipsDeleted: Int! + } + + type UpdateMoviesMutationResponse { + info: UpdateInfo! + movies: [Movie!]! + } + + type UpdateSeriesMutationResponse { + info: UpdateInfo! + series: [Series!]! + }" + `); + }); +}); diff --git a/packages/graphql/tests/tck/experimental/interface-filtering.test.ts b/packages/graphql/tests/tck/experimental/interface-filtering.test.ts index 75a09cbcbb8..76bb8dd16b9 100644 --- a/packages/graphql/tests/tck/experimental/interface-filtering.test.ts +++ b/packages/graphql/tests/tck/experimental/interface-filtering.test.ts @@ -23,7 +23,7 @@ import { Neo4jGraphQL } from "../../../src"; import { createBearerToken } from "../../utils/create-bearer-token"; import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; -describe("Interface top level operations", () => { +describe("Interface filtering operations", () => { const secret = "secret"; let typeDefs: DocumentNode; let neoSchema: Neo4jGraphQL; diff --git a/packages/graphql/tests/tck/experimental/union-relationship-filtering.test.ts b/packages/graphql/tests/tck/experimental/union-relationship-filtering.test.ts new file mode 100644 index 00000000000..d010af3ac26 --- /dev/null +++ b/packages/graphql/tests/tck/experimental/union-relationship-filtering.test.ts @@ -0,0 +1,141 @@ +/* + * 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 { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { createBearerToken } from "../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; + +describe("Union relationship filtering operations", () => { + const secret = "secret"; + let typeDefs: DocumentNode; + let neoSchema: Neo4jGraphQL; + + beforeEach(() => { + typeDefs = gql` + union Production = Movie | Series + + type Movie { + title: String! + cost: Float + runtime: Int + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Series { + title: String! + episodes: Int + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") + } + + type Actor { + name: String! + actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") + } + + interface ActedIn @relationshipProperties { + screenTime: Int + } + `; + + neoSchema = new Neo4jGraphQL({ + typeDefs, + features: { authorization: { key: secret } }, + experimental: true, + }); + }); + + test("Union filter (top level)", async () => { + const query = gql` + query actedInWhere { + productions(where: { Movie: { title: "The Office" }, Series: { title: "The Office 2" } }) { + ... on Movie { + title + } + ... on Series { + title + } + } + } + `; + + const token = createBearerToken(secret); + const result = await translateQuery(neoSchema, query, { token }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + MATCH (this0:Movie) + WHERE this0.title = $param0 + WITH this0 { .title, __resolveType: \\"Movie\\", __id: id(this0) } AS this0 + RETURN this0 AS this + UNION + MATCH (this1:Series) + WHERE this1.title = $param1 + WITH this1 { .title, __resolveType: \\"Series\\", __id: id(this1) } AS this1 + RETURN this1 AS this + } + WITH this + RETURN this AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Office\\", + \\"param1\\": \\"The Office 2\\" + }" + `); + }); + + test("Filtering on nested-level relationship unions", async () => { + const query = gql` + query actedInWhere { + actors( + where: { + actedIn_SOME: { Movie: { title_CONTAINS: "The Office" }, Series: { title_ENDS_WITH: "Office" } } + } + ) { + name + } + } + `; + + const token = createBearerToken(secret); + const result = await translateQuery(neoSchema, query, { token }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + WHERE (EXISTS { + MATCH (this)-[:ACTED_IN]->(this0:Movie) + WHERE this0.title CONTAINS $param0 + } AND EXISTS { + MATCH (this)-[:ACTED_IN]->(this1:Series) + WHERE this1.title ENDS WITH $param1 + }) + RETURN this { .name } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"The Office\\", + \\"param1\\": \\"Office\\" + }" + `); + }); +}); From 3e2e5f2d368da40f3f792d16d8538fb2a572c05b Mon Sep 17 00:00:00 2001 From: angrykoala Date: Thu, 21 Dec 2023 16:17:33 +0100 Subject: [PATCH 081/136] Small improvement on CompositeConnectionPartial (#4433) * WIP unify CompositeConnectionPartial * Remove custom code for top level interface connection --------- Co-authored-by: Darrell Warde <8117355+darrellwarde@users.noreply.github.com> --- .../composite/CompositeConnectionPartial.ts | 68 ++++++------------- .../composite/CompositeReadOperation.ts | 36 +--------- .../queryAST/factory/OperationFactory.ts | 4 +- .../arguments/where/where.test.ts | 4 +- 4 files changed, 27 insertions(+), 85 deletions(-) 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 151a251232a..4f6de7dba2c 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeConnectionPartial.ts @@ -18,11 +18,9 @@ */ import Cypher from "@neo4j/cypher-builder"; -import { createNodeFromEntity } from "../../../utils/create-node-from-entity"; import { wrapSubqueriesInCypherCalls } from "../../../utils/wrap-subquery-in-calls"; import type { QueryASTContext } from "../../QueryASTContext"; import type { Pagination } from "../../pagination/Pagination"; -import type { Sort } from "../../sort/Sort"; import { ConnectionReadOperation } from "../ConnectionReadOperation"; import type { OperationTranspileResult } from "../operations"; @@ -30,18 +28,18 @@ 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"); - const node = createNodeFromEntity(this.target, context.neo4jGraphQLContext); - const relationship = new Cypher.Relationship({ type: this.relationship.type }); - const relDirection = this.relationship.getCypherDirection(this.directed); - const pattern = new Cypher.Pattern(context.target) - .withoutLabels() - .related(relationship) - .withDirection(relDirection) - .to(node); + // eslint-disable-next-line prefer-const + let { selection: clause, nestedContext } = this.selection.apply(context); - const nestedContext = context.push({ target: node, relationship }); - const { preSelection, selectionClause: clause } = this.getSelectionClauses(nestedContext, pattern); + let extraMatches: Array = this.getChildren().flatMap((f) => { + return f.getSelection(nestedContext); + }); + + if (extraMatches.length > 0) { + extraMatches = [clause, ...extraMatches]; + clause = new Cypher.With("*"); + } const predicates = this.filters.map((f) => f.getPredicate(nestedContext)); @@ -51,17 +49,19 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { const filters = Cypher.and(...predicates, ...authPredicate); - const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [node]); + const nodeProjectionSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.nodeFields, [ + nestedContext.target, + ]); const nodeProjectionMap = new Cypher.Map(); // This bit is different than normal connection ops const targetNodeName = this.target.name; nodeProjectionMap.set({ __resolveType: new Cypher.Literal(targetNodeName), - __id: Cypher.id(node), + __id: Cypher.id(nestedContext.target), }); - const nodeProjectionFields = this.nodeFields.map((f) => f.getProjectionField(node)); + const nodeProjectionFields = this.nodeFields.map((f) => f.getProjectionField(nestedContext.target)); const nodeSortProjectionFields = this.sortFields.flatMap((f) => f.node.map((ef) => ef.getProjectionField(nestedContext)) ); @@ -70,7 +70,7 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { uniqueNodeProjectionFields.forEach((p) => { if (typeof p === "string") { - nodeProjectionMap.set(p, node.property(p)); + nodeProjectionMap.set(p, nestedContext.target.property(p)); } else { nodeProjectionMap.set(p); } @@ -80,7 +80,7 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { const edgeProjectionMap = new Cypher.Map(); - const edgeProjectionFields = this.edgeFields.map((f) => f.getProjectionField(relationship)); + const edgeProjectionFields = this.edgeFields.map((f) => f.getProjectionField(nestedContext.relationship!)); const edgeSortProjectionFields = this.sortFields.flatMap((f) => f.edge.map((ef) => ef.getProjectionField(nestedContext)) ); @@ -89,7 +89,7 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { uniqueEdgeProjectionFields.forEach((p) => { if (typeof p === "string") { - edgeProjectionMap.set(p, relationship.property(p)); + edgeProjectionMap.set(p, nestedContext.relationship!.property(p)); } else { edgeProjectionMap.set(p); } @@ -110,7 +110,8 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { const projectionClauses = new Cypher.With([edgeProjectionMap, edgeVar]).return(context.returnVariable); const subClause = Cypher.concat( - ...preSelection, + // ...preSelection, + ...extraMatches, clause, ...authFilterSubqueries, withWhere, @@ -124,37 +125,8 @@ export class CompositeConnectionPartial extends ConnectionReadOperation { }; } - // Sort is handled by CompositeConnectionReadOperation - public addSort(sortElement: { node: Sort[]; edge: Sort[] }): void { - this.sortFields.push(sortElement); - } - // Pagination is handled by CompositeConnectionReadOperation public addPagination(_pagination: Pagination): void { return undefined; } - - private getSelectionClauses( - context: QueryASTContext, - node: Cypher.Node | Cypher.Pattern - ): { - preSelection: Array; - selectionClause: Cypher.Match | Cypher.With; - } { - let matchClause: Cypher.Match | Cypher.With = new Cypher.Match(node); - - let extraMatches = this.getChildren().flatMap((f) => { - return f.getSelection(context); - }); - - if (extraMatches.length > 0) { - extraMatches = [matchClause, ...extraMatches]; - matchClause = new Cypher.With("*"); - } - - return { - preSelection: extraMatches, - selectionClause: matchClause, - }; - } } diff --git a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts index 604f254ab36..7326bd3e15d 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/composite/CompositeReadOperation.ts @@ -55,40 +55,7 @@ export class CompositeReadOperation extends Operation { return this.children; } - private transpileTopLevelCompositeRead(context: QueryASTContext): OperationTranspileResult { - const nestedSubqueries = this.children.flatMap((c) => { - const result = c.transpile(context); - return result.clauses; - }); - const nestedSubquery = new Cypher.Call(new Cypher.Union(...nestedSubqueries)).with(context.returnVariable); - if (this.sortFields.length > 0) { - nestedSubquery.orderBy(...this.getSortFields(context, context.returnVariable)); - } - if (this.pagination) { - const paginationField = this.pagination.getPagination(); - if (paginationField) { - if (paginationField.skip) { - nestedSubquery.skip(paginationField.skip); - } - if (paginationField.limit) { - nestedSubquery.limit(paginationField.limit); - } - } - } - - nestedSubquery.return([context.returnVariable, context.returnVariable]); - - return { - clauses: [nestedSubquery], - projectionExpr: context.returnVariable, - }; - } - public transpile(context: QueryASTContext): OperationTranspileResult { - if (!this.relationship) { - return this.transpileTopLevelCompositeRead(context); - } - const parentNode = context.target; const nestedSubqueries = this.children.flatMap((c) => { const result = c.transpile(context); @@ -101,6 +68,9 @@ export class CompositeReadOperation extends Operation { }); let aggrExpr: Cypher.Expr = Cypher.collect(context.returnVariable); + if (!this.relationship) { + aggrExpr = context.returnVariable; + } if (this.relationship && !this.relationship.isList) { aggrExpr = Cypher.head(aggrExpr); } diff --git a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts index d403a6b964d..29f6bfdc6d3 100644 --- a/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts +++ b/packages/graphql/src/translate/queryAST/factory/OperationFactory.ts @@ -33,6 +33,7 @@ import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphq import { filterTruthy, isObject, isString } from "../../../utils/utils"; import { checkEntityAuthentication } from "../../authorization/check-authentication"; import { FulltextScoreField } from "../ast/fields/FulltextScoreField"; +import type { Filter } from "../ast/filters/Filter"; import type { AuthorizationFilters } from "../ast/filters/authorization-filters/AuthorizationFilters"; import { FulltextScoreFilter } from "../ast/filters/property-filters/FulltextScoreFilter"; import { AggregationOperation } from "../ast/operations/AggregationOperation"; @@ -66,7 +67,6 @@ import { findFieldsByNameInFieldsByTypeNameField } from "./parsers/find-fields-b import { getFieldsByTypeName } from "./parsers/get-fields-by-type-name"; import { parseInterfaceOperationField, parseOperationField } from "./parsers/parse-operation-fields"; import { parseSelectionSetField } from "./parsers/parse-selection-set-fields"; -import type { Filter } from "../ast/filters/Filter"; const TOP_LEVEL_NODE_NAME = "this"; export class OperationsFactory { @@ -558,6 +558,7 @@ export class OperationsFactory { const selection = new RelationshipSelection({ relationship, directed, + targetOverride: concreteEntity, }); const connectionPartial = new CompositeConnectionPartial({ @@ -938,7 +939,6 @@ export class OperationsFactory { return operation; } - private hydrateReadOperation({ entity, operation, diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index 5fa5be62e4c..32307d0c14f 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -17,11 +17,11 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import { gql } from "graphql-tag"; import { Neo4jGraphQL } from "../../../../../../src"; -import { formatCypher, translateQuery, formatParams } from "../../../../utils/tck-test-utils"; import { createBearerToken } from "../../../../../utils/create-bearer-token"; +import { formatCypher, formatParams, translateQuery } from "../../../../utils/tck-test-utils"; describe("Cypher Auth Where", () => { const secret = "secret"; From 2bb8f8b628c52c102c2db988685fc54f08521488 Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Fri, 22 Dec 2023 11:07:29 +0100 Subject: [PATCH 082/136] Allow update and create on timestamp fields (#4449) * fix: add specific checks for timestamp annotation operations * test: update schema test snapshots * fix: update tck so DateTime usage is nullable --- .changeset/early-foxes-tickle.md | 7 ++ .../model-adapters/AttributeAdapter.ts | 84 +++++++++++++++---- .../timestamp-annotation.test.ts | 10 ++- .../timestamp-annotation.ts | 4 + .../model-adapters/RelationshipAdapter.ts | 8 +- .../model-adapters/RelationshipOperations.ts | 2 +- .../create-connect-or-create-field.ts | 4 +- .../src/schema/generation/connect-input.ts | 2 +- .../src/schema/generation/relation-input.ts | 2 +- .../src/schema/generation/update-input.ts | 8 +- .../schema/directives/timestamps.test.ts | 2 + .../experimental-schema/issues/2377.test.ts | 3 + .../experimental-schema/issues/2993.test.ts | 10 +++ .../graphql/tests/schema/issues/2377.test.ts | 3 + .../graphql/tests/schema/issues/2993.test.ts | 5 ++ .../connect-or-create.test.ts | 6 +- 16 files changed, 123 insertions(+), 37 deletions(-) create mode 100644 .changeset/early-foxes-tickle.md diff --git a/.changeset/early-foxes-tickle.md b/.changeset/early-foxes-tickle.md new file mode 100644 index 00000000000..42b030b52b6 --- /dev/null +++ b/.changeset/early-foxes-tickle.md @@ -0,0 +1,7 @@ +--- +"@neo4j/graphql": patch +--- + +Fix: allow non-generated mutations on timestamp fields + +Before this patch, it wasn't possible to update a field with a timestamp directive even when the directive specified that only the UPDATE or CREATE operation field should be generated by the database. diff --git a/packages/graphql/src/schema-model/attribute/model-adapters/AttributeAdapter.ts b/packages/graphql/src/schema-model/attribute/model-adapters/AttributeAdapter.ts index 8a4be357070..9823e02575a 100644 --- a/packages/graphql/src/schema-model/attribute/model-adapters/AttributeAdapter.ts +++ b/packages/graphql/src/schema-model/attribute/model-adapters/AttributeAdapter.ts @@ -156,12 +156,23 @@ export class AttributeAdapter { } isOnCreateField(): boolean { + if (!this.isNonGeneratedField()) { + return false; + } + + if (this.annotations.settable?.onCreate === false) { + return false; + } + + if (this.timestampCreateIsGenerated()) { + return false; + } + return ( - this.isNonGeneratedField() && - (this.typeHelper.isScalar() || - this.typeHelper.isSpatial() || - this.typeHelper.isEnum() || - this.typeHelper.isAbstract()) + this.typeHelper.isScalar() || + this.typeHelper.isSpatial() || + this.typeHelper.isEnum() || + this.typeHelper.isAbstract() ); } @@ -192,22 +203,65 @@ export class AttributeAdapter { } isCreateInputField(): boolean { - return this.isNonGeneratedField() && this.annotations.settable?.onCreate !== false; + return ( + this.isNonGeneratedField() && + this.annotations.settable?.onCreate !== false && + !this.timestampCreateIsGenerated() + ); } - isNonGeneratedField(): boolean { + isUpdateInputField(): boolean { return ( - this.isCypher() === false && - this.isCustomResolvable() === false && - (this.typeHelper.isEnum() || this.typeHelper.isScalar() || this.typeHelper.isSpatial()) && - !this.annotations.id && - !this.annotations.populatedBy && - !this.annotations.timestamp + this.isNonGeneratedField() && + this.annotations.settable?.onUpdate !== false && + !this.timestampUpdateIsGenerated() ); } - isUpdateInputField(): boolean { - return this.isNonGeneratedField() && this.annotations.settable?.onUpdate !== false; + timestampCreateIsGenerated(): boolean { + if (!this.annotations.timestamp) { + // The timestamp directive is not set on the field + return false; + } + + if (this.annotations.timestamp.operations.includes("CREATE")) { + // The timestamp directive is set to generate on create + return true; + } + + // The timestamp directive is not set to generate on create + return false; + } + + isNonGeneratedField(): boolean { + if (this.isCypher() || this.isCustomResolvable()) { + return false; + } + + if (this.annotations.id || this.annotations.populatedBy) { + return false; + } + + if (this.typeHelper.isEnum() || this.typeHelper.isScalar() || this.typeHelper.isSpatial()) { + return true; + } + + return false; + } + + timestampUpdateIsGenerated(): boolean { + if (!this.annotations.timestamp) { + // The timestamp directive is not set on the field + return false; + } + + if (this.annotations.timestamp.operations.includes("UPDATE")) { + // The timestamp directive is set to generate on update + return true; + } + + // The timestamp directive is not set to generate on update + return false; } isArrayMethodField(): boolean { diff --git a/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.test.ts b/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.test.ts index becc917c0e0..3d356a52ee1 100644 --- a/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.test.ts +++ b/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.test.ts @@ -18,27 +18,29 @@ */ import { makeDirectiveNode } from "@graphql-tools/utils"; -import { parseTimestampAnnotation } from "./timestamp-annotation"; import { timestampDirective } from "../../../graphql/directives"; +import { parseTimestampAnnotation } from "./timestamp-annotation"; const tests = [ { name: "should parse correctly when CREATE operation is passed", directive: makeDirectiveNode("timestamp", { operations: ["CREATE"] }, timestampDirective), operations: ["CREATE"], - expected: { operations: ["CREATE"] }, }, { name: "should parse correctly when UPDATE operation is passed", directive: makeDirectiveNode("timestamp", { operations: ["UPDATE"] }, timestampDirective), operations: ["UPDATE"], - expected: { operations: ["UPDATE"] }, }, { name: "should parse correctly when CREATE and UPDATE operations are passed", directive: makeDirectiveNode("timestamp", { operations: ["CREATE", "UPDATE"] }, timestampDirective), operations: ["CREATE", "UPDATE"], - expected: { operations: ["CREATE", "UPDATE"] }, + }, + { + name: "should parse correctly when CREATE and UPDATE operations are passed", + directive: makeDirectiveNode("timestamp", { operations: [] }, timestampDirective), + operations: ["CREATE", "UPDATE"], }, ]; diff --git a/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.ts b/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.ts index 739de85d914..88b8f7cd1ee 100644 --- a/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.ts +++ b/packages/graphql/src/schema-model/parser/annotations-parser/timestamp-annotation.ts @@ -24,6 +24,10 @@ import { parseArguments } from "../parse-arguments"; export function parseTimestampAnnotation(directive: DirectiveNode): TimestampAnnotation { const { operations } = parseArguments<{ operations: string[] }>(timestampDirective, directive); + if (operations.length === 0) { + operations.push("CREATE", "UPDATE"); + } + return new TimestampAnnotation({ operations, }); diff --git a/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipAdapter.ts b/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipAdapter.ts index e1abcf3bb56..135d98e97a2 100644 --- a/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipAdapter.ts +++ b/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipAdapter.ts @@ -258,13 +258,9 @@ export class RelationshipAdapter { return this.nestedOperations.size > 0 && !onlyConnectOrCreateAndNoUniqueFields; } - public get nonGeneratedProperties(): AttributeAdapter[] { - return Array.from(this.attributes.values()).filter((attribute) => attribute.isNonGeneratedField()); + public get hasNonNullCreateInputFields(): boolean { + return this.createInputFields.some((property) => property.typeHelper.isRequired()); } - public get hasNonNullNonGeneratedProperties(): boolean { - return this.nonGeneratedProperties.some((property) => property.typeHelper.isRequired()); - } - /** * Categories * = a grouping of attributes diff --git a/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipOperations.ts b/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipOperations.ts index 345b8b2fb84..ba5e1e398a6 100644 --- a/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipOperations.ts +++ b/packages/graphql/src/schema-model/relationship/model-adapters/RelationshipOperations.ts @@ -236,7 +236,7 @@ export class RelationshipOperations { public get edgeCreateInputTypeName(): string { return `${this.relationship.propertiesTypeName}CreateInput${ - this.relationship.hasNonNullNonGeneratedProperties ? `!` : "" + this.relationship.hasNonNullCreateInputFields ? `!` : "" }`; } public get createInputTypeName(): string { diff --git a/packages/graphql/src/schema/create-relationship-fields/create-connect-or-create-field.ts b/packages/graphql/src/schema/create-relationship-fields/create-connect-or-create-field.ts index d1829c758c8..4523b7da37e 100644 --- a/packages/graphql/src/schema/create-relationship-fields/create-connect-or-create-field.ts +++ b/packages/graphql/src/schema/create-relationship-fields/create-connect-or-create-field.ts @@ -51,13 +51,13 @@ export function createOnCreateITC({ const onCreateFields: InputTypeComposerFieldConfigMapDefinition = { node: onCreateInput.NonNull, }; - if (relationshipAdapter.nonGeneratedProperties.length > 0) { + if (relationshipAdapter.createInputFields.length > 0) { const edgeFieldType = withCreateInputType({ entityAdapter: relationshipAdapter, userDefinedFieldDirectives, composer: schemaComposer, }); - onCreateFields["edge"] = relationshipAdapter.hasNonNullNonGeneratedProperties + onCreateFields["edge"] = relationshipAdapter.hasNonNullCreateInputFields ? edgeFieldType.NonNull : edgeFieldType; } diff --git a/packages/graphql/src/schema/generation/connect-input.ts b/packages/graphql/src/schema/generation/connect-input.ts index 9bab884ed7c..f595b914237 100644 --- a/packages/graphql/src/schema/generation/connect-input.ts +++ b/packages/graphql/src/schema/generation/connect-input.ts @@ -220,7 +220,7 @@ function makeConnectFieldInputTypeFields({ ifUnionMemberEntity?: ConcreteEntityAdapter; }): InputTypeComposerFieldConfigMapDefinition { const fields = {}; - const hasNonGeneratedProperties = relationshipAdapter.nonGeneratedProperties.length > 0; + const hasNonGeneratedProperties = relationshipAdapter.createInputFields.length > 0; if (hasNonGeneratedProperties) { fields["edge"] = relationshipAdapter.operations.edgeCreateInputTypeName; } diff --git a/packages/graphql/src/schema/generation/relation-input.ts b/packages/graphql/src/schema/generation/relation-input.ts index ca5d0ebb47c..fa7a622b8d3 100644 --- a/packages/graphql/src/schema/generation/relation-input.ts +++ b/packages/graphql/src/schema/generation/relation-input.ts @@ -224,7 +224,7 @@ function makeCreateFieldInputTypeFields({ userDefinedFieldDirectives: Map; }): InputTypeComposerFieldConfigMapDefinition { const fields = {}; - const hasNonGeneratedProperties = relationshipAdapter.nonGeneratedProperties.length > 0; + const hasNonGeneratedProperties = relationshipAdapter.createInputFields.length > 0; if (hasNonGeneratedProperties) { fields["edge"] = relationshipAdapter.operations.edgeCreateInputTypeName; } diff --git a/packages/graphql/src/schema/generation/update-input.ts b/packages/graphql/src/schema/generation/update-input.ts index 2616303bf83..5a89343bf53 100644 --- a/packages/graphql/src/schema/generation/update-input.ts +++ b/packages/graphql/src/schema/generation/update-input.ts @@ -32,12 +32,12 @@ import { UnionEntityAdapter } from "../../schema-model/entity/model-adapters/Uni import { RelationshipAdapter } from "../../schema-model/relationship/model-adapters/RelationshipAdapter"; import { concreteEntityToUpdateInputFields, withArrayOperators, withMathOperators } from "../to-compose"; import { withConnectFieldInputType } from "./connect-input"; -import { withDisconnectFieldInputType } from "./disconnect-input"; +import { withConnectOrCreateFieldInputType } from "./connect-or-create-input"; import { withDeleteFieldInputType } from "./delete-input"; +import { withDisconnectFieldInputType } from "./disconnect-input"; import { makeImplementationsUpdateInput } from "./implementation-inputs"; -import { makeConnectionWhereInputType } from "./where-input"; -import { withConnectOrCreateFieldInputType } from "./connect-or-create-input"; import { withCreateFieldInputType } from "./relation-input"; +import { makeConnectionWhereInputType } from "./where-input"; export function withUpdateInputType({ entityAdapter, @@ -428,7 +428,7 @@ function makeUpdateConnectionFieldInputTypeFields({ // fields["node"] = updateInputType; fields["node"] = relationshipAdapter.target.operations.updateInputTypeName; } - const hasNonGeneratedProperties = relationshipAdapter.nonGeneratedProperties.length > 0; + const hasNonGeneratedProperties = relationshipAdapter.updateInputFields.length > 0; if (hasNonGeneratedProperties) { fields["edge"] = relationshipAdapter.operations.edgeUpdateInputTypeName; } diff --git a/packages/graphql/tests/schema/directives/timestamps.test.ts b/packages/graphql/tests/schema/directives/timestamps.test.ts index 496f7636170..9667ec5f6f7 100644 --- a/packages/graphql/tests/schema/directives/timestamps.test.ts +++ b/packages/graphql/tests/schema/directives/timestamps.test.ts @@ -91,6 +91,7 @@ describe("Timestamps", () => { input MovieCreateInput { id: ID + updatedAt: DateTime! } type MovieEdge { @@ -117,6 +118,7 @@ describe("Timestamps", () => { } input MovieUpdateInput { + createdAt: DateTime id: ID } 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 74e7e1fb7cd..0c81fdffe9f 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2377.test.ts @@ -357,6 +357,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { properties: [Property!] tags: [Tag!] type: ResourceType! + updatedAt: DateTime! } input ResourceDeleteInput { @@ -456,6 +457,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { properties: [Property!] tags: [Tag!] type: ResourceType! + updatedAt: DateTime! } input ResourceOptions { @@ -506,6 +508,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { input ResourceUpdateInput { containedBy: [ResourceContainedByUpdateFieldInput!] + createdAt: DateTime externalIds: [ID!] externalIds_POP: Int externalIds_PUSH: [ID!] 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 cf1894d2648..d05a6a1d3d1 100644 --- a/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/experimental-schema/issues/2993.test.ts @@ -89,6 +89,10 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { since: SortDirection } + input FOLLOWSUpdateInput { + since: DateTime + } + input FOLLOWSWhere { AND: [FOLLOWSWhere!] NOT: FOLLOWSWhere @@ -348,6 +352,7 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input UserFollowingUpdateConnectionInput { + edge: FOLLOWSUpdateInput node: ProfileUpdateInput } @@ -518,6 +523,10 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { since: SortDirection } + input FOLLOWSUpdateInput { + since: DateTime + } + input FOLLOWSWhere { AND: [FOLLOWSWhere!] NOT: FOLLOWSWhere @@ -776,6 +785,7 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input UserFollowingUpdateConnectionInput { + edge: FOLLOWSUpdateInput node: ProfileUpdateInput } diff --git a/packages/graphql/tests/schema/issues/2377.test.ts b/packages/graphql/tests/schema/issues/2377.test.ts index 6a1291292f3..c10fe0854dd 100644 --- a/packages/graphql/tests/schema/issues/2377.test.ts +++ b/packages/graphql/tests/schema/issues/2377.test.ts @@ -355,6 +355,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { properties: [Property!] tags: [Tag!] type: ResourceType! + updatedAt: DateTime! } input ResourceDeleteInput { @@ -387,6 +388,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { properties: [Property!] tags: [Tag!] type: ResourceType! + updatedAt: DateTime! } input ResourceOptions { @@ -437,6 +439,7 @@ describe("https://github.com/neo4j/graphql/issues/2377", () => { input ResourceUpdateInput { containedBy: [ResourceContainedByUpdateFieldInput!] + createdAt: DateTime externalIds: [ID!] externalIds_POP: Int externalIds_PUSH: [ID!] diff --git a/packages/graphql/tests/schema/issues/2993.test.ts b/packages/graphql/tests/schema/issues/2993.test.ts index b12aba88cb4..70090ad2674 100644 --- a/packages/graphql/tests/schema/issues/2993.test.ts +++ b/packages/graphql/tests/schema/issues/2993.test.ts @@ -84,6 +84,10 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { since: SortDirection } + input FOLLOWSUpdateInput { + since: DateTime + } + input FOLLOWSWhere { AND: [FOLLOWSWhere!] NOT: FOLLOWSWhere @@ -330,6 +334,7 @@ describe("https://github.com/neo4j/graphql/issues/2993", () => { } input UserFollowingUpdateConnectionInput { + edge: FOLLOWSUpdateInput node: ProfileUpdateInput } diff --git a/packages/graphql/tests/tck/connections/connect-or-create/connect-or-create.test.ts b/packages/graphql/tests/tck/connections/connect-or-create/connect-or-create.test.ts index 55f7b24d239..604e6138df6 100644 --- a/packages/graphql/tests/tck/connections/connect-or-create/connect-or-create.test.ts +++ b/packages/graphql/tests/tck/connections/connect-or-create/connect-or-create.test.ts @@ -17,10 +17,10 @@ * limitations under the License. */ -import { gql } from "graphql-tag"; import type { DocumentNode } from "graphql"; +import gql from "graphql-tag"; import { Neo4jGraphQL } from "../../../../src"; -import { formatCypher, translateQuery, formatParams } from "../../utils/tck-test-utils"; +import { formatCypher, formatParams, translateQuery } from "../../utils/tck-test-utils"; describe("Create or Connect", () => { describe("Simple", () => { @@ -464,7 +464,7 @@ describe("Create or Connect", () => { interface ActedIn @relationshipProperties { id: ID! @id createdAt: DateTime! @timestamp(operations: [CREATE]) - updatedAt: DateTime! @timestamp(operations: [UPDATE]) + updatedAt: DateTime @timestamp(operations: [UPDATE]) screentime: Int! } `; From cb8646aa7c983ed0ea99137be8e887dfcb93dcd6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 23 Dec 2023 01:32:14 +0000 Subject: [PATCH 083/136] chore(deps): update github/codeql-action digest to 1500a13 --- .github/workflows/reusable-codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-codeql-analysis.yml b/.github/workflows/reusable-codeql-analysis.yml index bef84ace705..340bf2990b7 100644 --- a/.github/workflows/reusable-codeql-analysis.yml +++ b/.github/workflows/reusable-codeql-analysis.yml @@ -14,9 +14,9 @@ jobs: with: node-version: lts/* - name: Initialize CodeQL - uses: github/codeql-action/init@03e7845b7bfcd5e7fb63d1ae8c61b0e791134fab # v2 + uses: github/codeql-action/init@1500a131381b66de0c52ac28abb13cd79f4b7ecc # v2 with: config-file: ./.github/codeql/codeql-config.yml languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@03e7845b7bfcd5e7fb63d1ae8c61b0e791134fab # v2 + uses: github/codeql-action/analyze@1500a131381b66de0c52ac28abb13cd79f4b7ecc # v2 From 223bf736f3f892093eb9a79afd44919d03ca0821 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 22:41:25 +0000 Subject: [PATCH 084/136] fix(deps): update dependency classnames to v2.3.3 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 4fcbcabf9af..fd52b3a254f 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -54,7 +54,7 @@ "@neo4j-ndl/react": "2.2.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", - "classnames": "2.3.2", + "classnames": "2.3.3", "cm6-graphql": "0.0.12", "codemirror": "6.0.1", "dotenv-webpack": "8.0.1", diff --git a/yarn.lock b/yarn.lock index 93ea558df8b..538b64c1c96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3647,7 +3647,7 @@ __metadata: "@types/react-dom": 18.2.18 "@types/webpack": 5.28.5 autoprefixer: 10.4.16 - classnames: 2.3.2 + classnames: 2.3.3 cm6-graphql: 0.0.12 codemirror: 6.0.1 compression-webpack-plugin: 10.0.0 @@ -10475,7 +10475,14 @@ __metadata: languageName: node linkType: hard -"classnames@npm:2.3.2, classnames@npm:^2.2.6, classnames@npm:^2.3.1": +"classnames@npm:2.3.3": + version: 2.3.3 + resolution: "classnames@npm:2.3.3" + checksum: 0cb4db9cc3b8d2363c81f857f85b30351605fe683c89d140939aed4e06895a9570be737494ef3907e7069e2b98ed25ba3960fbf087b33309a18707fc38565e95 + languageName: node + linkType: hard + +"classnames@npm:^2.2.6, classnames@npm:^2.3.1": version: 2.3.2 resolution: "classnames@npm:2.3.2" checksum: 2c62199789618d95545c872787137262e741f9db13328e216b093eea91c85ef2bfb152c1f9e63027204e2559a006a92eb74147d46c800a9f96297ae1d9f96f4e From 916d88d3126ab852a3e3918e3c7cb68af1d7fb02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 25 Dec 2023 22:51:02 +0000 Subject: [PATCH 085/136] chore(deps): update typescript-eslint monorepo to v6.16.0 --- package.json | 4 +- yarn.lock | 123 ++++++++++++++++++++++++++------------------------- 2 files changed, 64 insertions(+), 63 deletions(-) diff --git a/package.json b/package.json index 839044c29c0..c2166caa638 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.15.0", - "@typescript-eslint/parser": "6.15.0", + "@typescript-eslint/eslint-plugin": "6.16.0", + "@typescript-eslint/parser": "6.16.0", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.56.0", diff --git a/yarn.lock b/yarn.lock index 538b64c1c96..66b30035597 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7939,15 +7939,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.15.0" +"@typescript-eslint/eslint-plugin@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.16.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.15.0 - "@typescript-eslint/type-utils": 6.15.0 - "@typescript-eslint/utils": 6.15.0 - "@typescript-eslint/visitor-keys": 6.15.0 + "@typescript-eslint/scope-manager": 6.16.0 + "@typescript-eslint/type-utils": 6.16.0 + "@typescript-eslint/utils": 6.16.0 + "@typescript-eslint/visitor-keys": 6.16.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7960,25 +7960,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f7ae7e01f9d1bd6150598ea1a191348a7ba08b25f146d3bc3b19d434bdb8071cf831577a31c62935e67716addb37b0eda02f4a47bfefc1bb5458843256ec0933 + checksum: d426a77970dab8e1c3d8320fa50da4dd31c9c36fc91fc0870049d5da96a165290f0c1337b742e6150ad076b5a0ac8ea3eaa6919a2d6d672395b9c2ef8da23449 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/parser@npm:6.15.0" +"@typescript-eslint/parser@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/parser@npm:6.16.0" dependencies: - "@typescript-eslint/scope-manager": 6.15.0 - "@typescript-eslint/types": 6.15.0 - "@typescript-eslint/typescript-estree": 6.15.0 - "@typescript-eslint/visitor-keys": 6.15.0 + "@typescript-eslint/scope-manager": 6.16.0 + "@typescript-eslint/types": 6.16.0 + "@typescript-eslint/typescript-estree": 6.16.0 + "@typescript-eslint/visitor-keys": 6.16.0 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 6f71b48f208e4d56025cbe3a5b287fe9c31484469e8b2a14a0ab5453cb56223a3c099beb70d298e0ce80de8a23e90aec65865ff8e939233cd0f1c3ffba12f3db + checksum: 5048a4fe63a8edf3b23c4355c7399d39c266a5f92d2c271e0ff3122eff5cd81d6535c871912b9cea991d87c91d264420ad0253b7816206f34356c290b7671188 languageName: node linkType: hard @@ -7992,22 +7992,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/scope-manager@npm:6.15.0" +"@typescript-eslint/scope-manager@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/scope-manager@npm:6.16.0" dependencies: - "@typescript-eslint/types": 6.15.0 - "@typescript-eslint/visitor-keys": 6.15.0 - checksum: 12316149aae3ad5c7e3411ed7da7fb7d9324df83482d64a93eecbd11063451660cea0fa42ceb026984df7974d770d5f7bc6c77c33e95bc0db0c44e4413f8b756 + "@typescript-eslint/types": 6.16.0 + "@typescript-eslint/visitor-keys": 6.16.0 + checksum: a3380f2cd4dd0928dfcacc45057018cbe11f86cccb53a848d4eb4d15b363e95b11aae453b4a7822701667816fabd4b6393839447a342e55f8cfaa6740c635098 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/type-utils@npm:6.15.0" +"@typescript-eslint/type-utils@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/type-utils@npm:6.16.0" dependencies: - "@typescript-eslint/typescript-estree": 6.15.0 - "@typescript-eslint/utils": 6.15.0 + "@typescript-eslint/typescript-estree": 6.16.0 + "@typescript-eslint/utils": 6.16.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8015,7 +8015,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: bd582fc6cca3b9048200fd30a042131cbb50e800acca1d31618ca4a9d9b6bc29fefd6920f7622a546c07a4d1a1c73745acfa09890e732a8a124731c3d5a821d1 + checksum: f322ff7c670f35991982574f9182fd8eb1aee91f52b73249de73805039e5848692713a0bd25e265b2f8a62eadb6d5a08134c94c51690f8bf9a0d1e3efaa8a45a languageName: node linkType: hard @@ -8026,10 +8026,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/types@npm:6.15.0" - checksum: 604cf287a339a55c9a82a6e301cf353bb256427b6e29b12ee8901b37d34581761a0dac3ae7e9d78925854e260e5d690ec472b54ca972339820f3db8512864875 +"@typescript-eslint/types@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/types@npm:6.16.0" + checksum: 74f8e4412cd52272952bfba8db9c1f7fd991f0f3924d6f63aff4e92614a8a581ea9c0df715190567d176a72b55099f3ef03d5462d4f6a78695d2b659cf5bfe34 languageName: node linkType: hard @@ -8051,38 +8051,39 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.15.0" +"@typescript-eslint/typescript-estree@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.16.0" dependencies: - "@typescript-eslint/types": 6.15.0 - "@typescript-eslint/visitor-keys": 6.15.0 + "@typescript-eslint/types": 6.16.0 + "@typescript-eslint/visitor-keys": 6.16.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 + minimatch: 9.0.3 semver: ^7.5.4 ts-api-utils: ^1.0.1 peerDependenciesMeta: typescript: optional: true - checksum: fbd11a5acaee3166174fad4cc78cff2ad646411a60ca14e5a50598373302c7bedd76d073ed385b002eb3d6d2a44aea2dd5c74aa65fbef8441a2e079064e67640 + checksum: 20ed8b8f7bf8173d5b68e9b0b86178607a5054adeb9daba87b7c1aa245b2f42ad04b93ee669d74920229eaf430cff146d67c6366a01cc338593a81bf812e6132 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/utils@npm:6.15.0" +"@typescript-eslint/utils@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/utils@npm:6.16.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.15.0 - "@typescript-eslint/types": 6.15.0 - "@typescript-eslint/typescript-estree": 6.15.0 + "@typescript-eslint/scope-manager": 6.16.0 + "@typescript-eslint/types": 6.16.0 + "@typescript-eslint/typescript-estree": 6.16.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 02aefaeb1539e0a5e5cbbc4d4f92ce505f433b7f8403cb10522c0a6965572a0ea94d32d487113fa64a33967ae7d0de5a62ffea83721100596e54c5ef04288cbe + checksum: d7efa112a1356024cde5306d032c6028d41671ece7ecda5c726cbfed26a9f3f8d317388a3c743cfaeeee1766db303c4a489b6825ad8275ee148d060afa57af4d languageName: node linkType: hard @@ -8114,13 +8115,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.15.0": - version: 6.15.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.15.0" +"@typescript-eslint/visitor-keys@npm:6.16.0": + version: 6.16.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.16.0" dependencies: - "@typescript-eslint/types": 6.15.0 + "@typescript-eslint/types": 6.16.0 eslint-visitor-keys: ^3.4.1 - checksum: 1bccc4d4eea6fd10a4ab1daa9e1aaaf790d5f4dd5d02c6e3eb6e83414c086d8d5f14ac44c9fb587b2f7e0dad3e7aeae603158d89dec9ae89652024331bb84fea + checksum: 2863e6d145a79bb12485b39417e30710996d8576894d67a484fde7cef417e3c67fd9fd99cb57736f0667e4425ddb2ab1f0954340ec5f4e08b8cb2ce7378a1977 languageName: node linkType: hard @@ -19121,6 +19122,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:9.0.3, minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: ^2.0.1 + checksum: 253487976bf485b612f16bf57463520a14f512662e592e95c571afdab1442a6a6864b6c88f248ce6fc4ff0b6de04ac7aa6c8bb51e868e99d1d65eb0658a708b5 + languageName: node + linkType: hard + "minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -19139,15 +19149,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" - dependencies: - brace-expansion: ^2.0.1 - checksum: 253487976bf485b612f16bf57463520a14f512662e592e95c571afdab1442a6a6864b6c88f248ce6fc4ff0b6de04ac7aa6c8bb51e868e99d1d65eb0658a708b5 - languageName: node - linkType: hard - "minimist-options@npm:4.1.0, minimist-options@npm:^4.0.2": version: 4.1.0 resolution: "minimist-options@npm:4.1.0" @@ -19842,8 +19843,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.15.0 - "@typescript-eslint/parser": 6.15.0 + "@typescript-eslint/eslint-plugin": 6.16.0 + "@typescript-eslint/parser": 6.16.0 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.56.0 From a974758ebedaaa64f2cf9f931ea8aaa93dc454d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 22:54:47 +0000 Subject: [PATCH 086/136] chore(deps): update dependency ws to v8.16.0 --- .../graphql-amqp-subscriptions-engine/package.json | 2 +- packages/graphql/package.json | 2 +- yarn.lock | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index f4533247d6f..234f7a09877 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -50,7 +50,7 @@ "supertest": "6.3.3", "ts-jest": "29.1.1", "typescript": "5.1.6", - "ws": "8.15.1" + "ws": "8.16.0" }, "dependencies": { "amqplib": "0.10.3", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 67326ca9c91..f88374ae8ff 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -83,7 +83,7 @@ "ts-jest": "29.1.1", "ts-node": "10.9.2", "typescript": "5.1.6", - "ws": "8.15.1" + "ws": "8.16.0" }, "dependencies": { "@apollo/subgraph": "^2.2.3", diff --git a/yarn.lock b/yarn.lock index 66b30035597..867ade87ccd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3588,7 +3588,7 @@ __metadata: supertest: 6.3.3 ts-jest: 29.1.1 typescript: 5.1.6 - ws: 8.15.1 + ws: 8.16.0 peerDependencies: "@neo4j/graphql": ^4.0.0-beta.0 languageName: unknown @@ -3747,7 +3747,7 @@ __metadata: ts-node: 10.9.2 typescript: 5.1.6 typescript-memoize: ^1.1.1 - ws: 8.15.1 + ws: 8.16.0 peerDependencies: graphql: ^16.0.0 neo4j-driver: ^5.8.0 @@ -26882,9 +26882,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.15.1": - version: 8.15.1 - resolution: "ws@npm:8.15.1" +"ws@npm:8.16.0": + version: 8.16.0 + resolution: "ws@npm:8.16.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -26893,7 +26893,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 8c67365f6e6134278ad635d558bfce466d7ef7543a043baea333aaa430429f0af8a130c0c36e7dd78f918d68167a659ba9b5067330b77c4b279e91533395952b + checksum: feb3eecd2bae82fa8a8beef800290ce437d8b8063bdc69712725f21aef77c49cb2ff45c6e5e7fce622248f9c7abaee506bae0a9064067ffd6935460c7357321b languageName: node linkType: hard From fb94296de4cad03cb2034d47dec9fb1e9b622f9c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Dec 2023 23:04:05 +0000 Subject: [PATCH 087/136] fix(deps): update dependency classnames to v2.4.0 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index fd52b3a254f..4fd46851148 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -54,7 +54,7 @@ "@neo4j-ndl/react": "2.2.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", - "classnames": "2.3.3", + "classnames": "2.4.0", "cm6-graphql": "0.0.12", "codemirror": "6.0.1", "dotenv-webpack": "8.0.1", diff --git a/yarn.lock b/yarn.lock index 867ade87ccd..73cc8ccac33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3647,7 +3647,7 @@ __metadata: "@types/react-dom": 18.2.18 "@types/webpack": 5.28.5 autoprefixer: 10.4.16 - classnames: 2.3.3 + classnames: 2.4.0 cm6-graphql: 0.0.12 codemirror: 6.0.1 compression-webpack-plugin: 10.0.0 @@ -10476,10 +10476,10 @@ __metadata: languageName: node linkType: hard -"classnames@npm:2.3.3": - version: 2.3.3 - resolution: "classnames@npm:2.3.3" - checksum: 0cb4db9cc3b8d2363c81f857f85b30351605fe683c89d140939aed4e06895a9570be737494ef3907e7069e2b98ed25ba3960fbf087b33309a18707fc38565e95 +"classnames@npm:2.4.0": + version: 2.4.0 + resolution: "classnames@npm:2.4.0" + checksum: be22a483a5b853895d8b6b44ad78944a3d1aee6181a697dc038e948202023203f0acb6013000b635ce6b491a072d3e76ad16c8586e178c9f5d788f6797a6cdd8 languageName: node linkType: hard From decc1bbe605f5daec51754aea38a0d7c7ec07c67 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Dec 2023 22:42:28 +0000 Subject: [PATCH 088/136] chore(deps): update dependency postcss-loader to v7.3.4 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 29 ++++++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 4fd46851148..43f3552b57e 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -92,7 +92,7 @@ "node-polyfill-webpack-plugin": "2.0.1", "parse5": "7.1.2", "postcss": "8.4.32", - "postcss-loader": "7.3.3", + "postcss-loader": "7.3.4", "randomstring": "1.3.0", "style-loader": "3.3.3", "tailwindcss": "3.4.0", diff --git a/yarn.lock b/yarn.lock index 73cc8ccac33..279f43a8432 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3669,7 +3669,7 @@ __metadata: node-polyfill-webpack-plugin: 2.0.1 parse5: 7.1.2 postcss: 8.4.32 - postcss-loader: 7.3.3 + postcss-loader: 7.3.4 prettier: 3.0.0 process: 0.11.10 randomstring: 1.3.0 @@ -11265,7 +11265,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^8.0.0, cosmiconfig@npm:^8.2.0": +"cosmiconfig@npm:^8.0.0, cosmiconfig@npm:^8.2.0, cosmiconfig@npm:^8.3.5": version: 8.3.6 resolution: "cosmiconfig@npm:8.3.6" dependencies: @@ -17402,7 +17402,7 @@ __metadata: languageName: node linkType: hard -"jiti@npm:^1.18.2, jiti@npm:^1.19.1": +"jiti@npm:^1.19.1": version: 1.20.0 resolution: "jiti@npm:1.20.0" bin: @@ -17411,6 +17411,15 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^1.20.0": + version: 1.21.0 + resolution: "jiti@npm:1.21.0" + bin: + jiti: bin/jiti.js + checksum: a7bd5d63921c170eaec91eecd686388181c7828e1fa0657ab374b9372bfc1f383cf4b039e6b272383d5cb25607509880af814a39abdff967322459cca41f2961 + languageName: node + linkType: hard + "jose@npm:^4.14.6": version: 4.15.2 resolution: "jose@npm:4.15.2" @@ -21565,17 +21574,17 @@ __metadata: languageName: node linkType: hard -"postcss-loader@npm:7.3.3": - version: 7.3.3 - resolution: "postcss-loader@npm:7.3.3" +"postcss-loader@npm:7.3.4": + version: 7.3.4 + resolution: "postcss-loader@npm:7.3.4" dependencies: - cosmiconfig: ^8.2.0 - jiti: ^1.18.2 - semver: ^7.3.8 + cosmiconfig: ^8.3.5 + jiti: ^1.20.0 + semver: ^7.5.4 peerDependencies: postcss: ^7.0.0 || ^8.0.1 webpack: ^5.0.0 - checksum: c724044d6ae56334535c26bb4efc9c151431d44d60bc8300157c760747281a242757d8dab32db72738434531175b38a408cb0b270bb96207c07584dcfcd899ff + checksum: f109eb266580eb296441a1ae057f93629b9b79ad962bdd3fc134417180431606a5419b6f5848c31e6d92c818e71fe96e4335a85cc5332c2f7b14e2869951e5b3 languageName: node linkType: hard From e8c8b148a64954f53dce0024ef061bc47bdae4bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 01:49:53 +0000 Subject: [PATCH 089/136] fix(deps): update dependency classnames to v2.5.0 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 43f3552b57e..7f790136ffd 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -54,7 +54,7 @@ "@neo4j-ndl/react": "2.2.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", - "classnames": "2.4.0", + "classnames": "2.5.0", "cm6-graphql": "0.0.12", "codemirror": "6.0.1", "dotenv-webpack": "8.0.1", diff --git a/yarn.lock b/yarn.lock index 279f43a8432..830919cf435 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3647,7 +3647,7 @@ __metadata: "@types/react-dom": 18.2.18 "@types/webpack": 5.28.5 autoprefixer: 10.4.16 - classnames: 2.4.0 + classnames: 2.5.0 cm6-graphql: 0.0.12 codemirror: 6.0.1 compression-webpack-plugin: 10.0.0 @@ -10476,10 +10476,10 @@ __metadata: languageName: node linkType: hard -"classnames@npm:2.4.0": - version: 2.4.0 - resolution: "classnames@npm:2.4.0" - checksum: be22a483a5b853895d8b6b44ad78944a3d1aee6181a697dc038e948202023203f0acb6013000b635ce6b491a072d3e76ad16c8586e178c9f5d788f6797a6cdd8 +"classnames@npm:2.5.0": + version: 2.5.0 + resolution: "classnames@npm:2.5.0" + checksum: 7805e0ed49790dd11da5da4d8509dbad2d9ed8ec817bfa01d3b69d40dc752ee4df757b9e845371a42547989863db76c463619c446aa24cdbd253d65ef927455e languageName: node linkType: hard From 9bafa70e8a487b407ad09c3f90b8653d7a185abb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 00:05:33 +0000 Subject: [PATCH 090/136] chore(deps): update rabbitmq docker digest to 529bd70 --- .../workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml index 0e27f58ae52..67bc30eed58 100644 --- a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml +++ b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml @@ -26,7 +26,7 @@ jobs: ports: - 7687:7687 rabbitmq: - image: rabbitmq@sha256:0742852455ad44e67b04e0d6a422a778a9d9ec3e78a6a9ae2c5cca7d0fa55aa9 + image: rabbitmq@sha256:529bd70467c60aca125a854b29248e61a71a5072085b4668d357d339858cc6d1 env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest From 1316beb8168aa3a41d2f92f05fe8d7c417ddc3b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 00:14:37 +0000 Subject: [PATCH 091/136] chore(deps): update rabbitmq:3.12-management docker digest to 6780042 --- examples/neo-place/docker-compose.yml | 2 +- examples/subscriptions/apollo_rabbitmq/docker-compose.yml | 2 +- packages/graphql-amqp-subscriptions-engine/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/neo-place/docker-compose.yml b/examples/neo-place/docker-compose.yml index 5184f0c9c31..ebd321a3f4e 100644 --- a/examples/neo-place/docker-compose.yml +++ b/examples/neo-place/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:6033d0c2f4e9eb49dda9623067a96d317bc7b550513bd18532fbd3cd9a941c1b + image: rabbitmq:3.12-management@sha256:67800420b0fe13b3a39ec14bc11e5d65ebdf9d353dbb02592b092db435950007 ports: - "5672:5672" - "15672:15672" diff --git a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml index 5184f0c9c31..ebd321a3f4e 100644 --- a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml +++ b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:6033d0c2f4e9eb49dda9623067a96d317bc7b550513bd18532fbd3cd9a941c1b + image: rabbitmq:3.12-management@sha256:67800420b0fe13b3a39ec14bc11e5d65ebdf9d353dbb02592b092db435950007 ports: - "5672:5672" - "15672:15672" diff --git a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml index 92fd61b37ca..79276bd9771 100644 --- a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml +++ b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' # This is just for local testing services: rabbitmq: - image: rabbitmq:3.12-management@sha256:6033d0c2f4e9eb49dda9623067a96d317bc7b550513bd18532fbd3cd9a941c1b + image: rabbitmq:3.12-management@sha256:67800420b0fe13b3a39ec14bc11e5d65ebdf9d353dbb02592b092db435950007 ports: - "5672:5672" - "15672:15672" From cb1ce378b3be5e397a3e2d1cf222de4313858fae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 04:54:42 +0000 Subject: [PATCH 092/136] chore(deps): update dependency terser-webpack-plugin to v5.3.10 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 50 +++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 7f790136ffd..f00449be975 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -96,7 +96,7 @@ "randomstring": "1.3.0", "style-loader": "3.3.3", "tailwindcss": "3.4.0", - "terser-webpack-plugin": "5.3.9", + "terser-webpack-plugin": "5.3.10", "ts-jest": "29.1.1", "ts-loader": "9.5.1", "ts-node": "10.9.2", diff --git a/yarn.lock b/yarn.lock index 830919cf435..735745d10e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3203,6 +3203,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.20": + version: 0.3.20 + resolution: "@jridgewell/trace-mapping@npm:0.3.20" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: cd1a7353135f385909468ff0cf20bdd37e59f2ee49a13a966dedf921943e222082c583ade2b579ff6cd0d8faafcb5461f253e1bf2a9f48fec439211fdbe788f5 + languageName: node + linkType: hard + "@leichtgewicht/ip-codec@npm:^2.0.1": version: 2.0.4 resolution: "@leichtgewicht/ip-codec@npm:2.0.4" @@ -3677,7 +3687,7 @@ __metadata: react-dom: 18.2.0 style-loader: 3.3.3 tailwindcss: 3.4.0 - terser-webpack-plugin: 5.3.9 + terser-webpack-plugin: 5.3.10 thememirror: 2.0.1 ts-jest: 29.1.1 ts-loader: 9.5.1 @@ -24878,7 +24888,29 @@ __metadata: languageName: node linkType: hard -"terser-webpack-plugin@npm:5.3.9, terser-webpack-plugin@npm:^5.3.7": +"terser-webpack-plugin@npm:5.3.10": + version: 5.3.10 + resolution: "terser-webpack-plugin@npm:5.3.10" + dependencies: + "@jridgewell/trace-mapping": ^0.3.20 + jest-worker: ^27.4.5 + schema-utils: ^3.1.1 + serialize-javascript: ^6.0.1 + terser: ^5.26.0 + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: bd6e7596cf815f3353e2a53e79cbdec959a1b0276f5e5d4e63e9d7c3c5bb5306df567729da287d1c7b39d79093e56863c569c42c6c24cc34c76aa313bd2cbcea + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:^5.3.7": version: 5.3.9 resolution: "terser-webpack-plugin@npm:5.3.9" dependencies: @@ -24927,6 +24959,20 @@ __metadata: languageName: node linkType: hard +"terser@npm:^5.26.0": + version: 5.26.0 + resolution: "terser@npm:5.26.0" + dependencies: + "@jridgewell/source-map": ^0.3.3 + acorn: ^8.8.2 + commander: ^2.20.0 + source-map-support: ~0.5.20 + bin: + terser: bin/terser + checksum: 02a9bb896f04df828025af8f0eced36c315d25d310b6c2418e7dad2bed19ddeb34a9cea9b34e7c24789830fa51e1b6a9be26679980987a9c817a7e6d9cd4154b + languageName: node + linkType: hard + "test-exclude@npm:^6.0.0": version: 6.0.0 resolution: "test-exclude@npm:6.0.0" From ebfefc51526a963d594704a4842513aee65ee465 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 01:21:51 +0000 Subject: [PATCH 093/136] chore(deps): update babel monorepo to v7.23.7 --- packages/package-tests/babel/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/package-tests/babel/package.json b/packages/package-tests/babel/package.json index ce351b374a5..543c9233dc5 100644 --- a/packages/package-tests/babel/package.json +++ b/packages/package-tests/babel/package.json @@ -13,8 +13,8 @@ "neo4j-driver": "^5.8.0" }, "devDependencies": { - "@babel/core": "7.23.6", + "@babel/core": "7.23.7", "@babel/node": "7.22.19", - "@babel/preset-env": "7.23.6" + "@babel/preset-env": "7.23.7" } } From 9c9f4fe57b9ba40653cca3d8d038160ffe8b0f13 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 01:32:28 +0000 Subject: [PATCH 094/136] chore(deps): update dependency @types/node to v20.10.6 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- packages/introspector/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index 234f7a09877..1c62813972d 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -40,7 +40,7 @@ "@types/cors": "2.8.17", "@types/debug": "4.1.12", "@types/jest": "29.5.11", - "@types/node": "20.10.5", + "@types/node": "20.10.6", "camelcase": "6.3.0", "graphql-ws": "5.14.3", "jest": "29.7.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index f88374ae8ff..34c115e3ae3 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -56,7 +56,7 @@ "@types/is-uuid": "1.0.2", "@types/jest": "29.5.11", "@types/jsonwebtoken": "9.0.5", - "@types/node": "20.10.5", + "@types/node": "20.10.6", "@types/pluralize": "0.0.33", "@types/randomstring": "1.1.11", "@types/semver": "7.5.6", diff --git a/packages/introspector/package.json b/packages/introspector/package.json index 77a6542485f..ae6b85981b6 100644 --- a/packages/introspector/package.json +++ b/packages/introspector/package.json @@ -38,7 +38,7 @@ "devDependencies": { "@neo4j/graphql": "^4.0.0", "@types/jest": "29.5.11", - "@types/node": "20.10.5", + "@types/node": "20.10.6", "@types/pluralize": "0.0.33", "jest": "29.7.0", "ts-jest": "29.1.1", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index 949384c2a82..68b0cfeda85 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@types/jest": "29.5.11", - "@types/node": "20.10.5", + "@types/node": "20.10.6", "camelcase": "6.3.0", "graphql-tag": "2.12.6", "jest": "29.7.0", diff --git a/yarn.lock b/yarn.lock index 735745d10e9..74c6d084d96 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3585,7 +3585,7 @@ __metadata: "@types/cors": 2.8.17 "@types/debug": 4.1.12 "@types/jest": 29.5.11 - "@types/node": 20.10.5 + "@types/node": 20.10.6 amqplib: 0.10.3 body-parser: ^1.20.2 camelcase: 6.3.0 @@ -3614,7 +3614,7 @@ __metadata: "@graphql-tools/merge": ^9.0.0 "@neo4j/graphql": ^4.4.4 "@types/jest": 29.5.11 - "@types/node": 20.10.5 + "@types/node": 20.10.6 camelcase: 6.3.0 graphql-tag: 2.12.6 jest: 29.7.0 @@ -3719,7 +3719,7 @@ __metadata: "@types/is-uuid": 1.0.2 "@types/jest": 29.5.11 "@types/jsonwebtoken": 9.0.5 - "@types/node": 20.10.5 + "@types/node": 20.10.6 "@types/pluralize": 0.0.33 "@types/randomstring": 1.1.11 "@types/semver": 7.5.6 @@ -3776,7 +3776,7 @@ __metadata: dependencies: "@neo4j/graphql": ^4.0.0 "@types/jest": 29.5.11 - "@types/node": 20.10.5 + "@types/node": 20.10.6 "@types/pluralize": 0.0.33 camelcase: ^6.3.0 debug: ^4.3.4 @@ -7650,12 +7650,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.10.5": - version: 20.10.5 - resolution: "@types/node@npm:20.10.5" +"@types/node@npm:20.10.6": + version: 20.10.6 + resolution: "@types/node@npm:20.10.6" dependencies: undici-types: ~5.26.4 - checksum: e216b679f545a8356960ce985a0e53c3a58fff0eacd855e180b9e223b8db2b5bd07b744a002b8c1f0c37f9194648ab4578533b5c12df2ec10cc02f61d20948d2 + checksum: ada40e4ccbda3697dca88f8d13f4c996c493be6fbc15f5f5d3b91096d56bd700786a2c148a92a2b4c5d1f133379e63f754a786b3aebfc6a7d09fc7ea16dc017b languageName: node linkType: hard From 15ffb3395b59852a2c617926a92d89efaca692c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 03:11:21 +0000 Subject: [PATCH 095/136] fix(deps): update codemirror --- packages/graphql-toolbox/package.json | 4 +-- yarn.lock | 42 +++++++++++++++++++-------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index f00449be975..6c25624b09e 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -43,9 +43,9 @@ "author": "Neo4j", "dependencies": { "@codemirror/autocomplete": "6.11.1", - "@codemirror/commands": "6.3.2", + "@codemirror/commands": "6.3.3", "@codemirror/lang-javascript": "6.2.1", - "@codemirror/language": "6.9.3", + "@codemirror/language": "6.10.0", "@dnd-kit/core": "6.1.0", "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", diff --git a/yarn.lock b/yarn.lock index 74c6d084d96..58d547bb780 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1736,15 +1736,15 @@ __metadata: languageName: node linkType: hard -"@codemirror/commands@npm:6.3.2": - version: 6.3.2 - resolution: "@codemirror/commands@npm:6.3.2" +"@codemirror/commands@npm:6.3.3": + version: 6.3.3 + resolution: "@codemirror/commands@npm:6.3.3" dependencies: "@codemirror/language": ^6.0.0 - "@codemirror/state": ^6.2.0 + "@codemirror/state": ^6.4.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 - checksum: 683c444d8e6ad889ab5efd0d742b0fa28b78c8cad63276ec60d298b13d4939c8bd7e1d6fd3535645b8d255147de0d3aef46d89a29c19d0af58a7f2914bdcb3ab + checksum: 7d23aecc973823969434b839aefa9a98bb47212d2ce0e6869ae903adbb5233aad22a760788fb7bb6eb45b00b01a4932fb93ad43bacdcbc0215e7500cf54b17bb languageName: node linkType: hard @@ -1775,17 +1775,17 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:6.9.3": - version: 6.9.3 - resolution: "@codemirror/language@npm:6.9.3" +"@codemirror/language@npm:6.10.0": + version: 6.10.0 + resolution: "@codemirror/language@npm:6.10.0" dependencies: "@codemirror/state": ^6.0.0 - "@codemirror/view": ^6.0.0 + "@codemirror/view": ^6.23.0 "@lezer/common": ^1.1.0 "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 774a40bc91c748d418a9a774161a5b083061124e4439bb753072bc657ec4c4784f595161c10c7c3935154b22291bf6dc74c9abe827033db32e217ac3963478f3 + checksum: 3bfd9968f5a34ce22434489a5b226db5f3bc454a1ae7c4381587ff4270ac6af61b10f93df560cb73e9a77cc13d4843722a7a7b94dbed02a3ab1971dd329b9e81 languageName: node linkType: hard @@ -1832,6 +1832,13 @@ __metadata: languageName: node linkType: hard +"@codemirror/state@npm:^6.4.0": + version: 6.4.0 + resolution: "@codemirror/state@npm:6.4.0" + checksum: c5236fe5786f1b85d17273a5c17fa8aeb063658c1404ab18caeb6e7591663ec96b65d453ab8162f75839c3801b04cd55ba4bc48f44cb61ebfeeee383f89553c7 + languageName: node + linkType: hard + "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.9.0": version: 6.20.2 resolution: "@codemirror/view@npm:6.20.2" @@ -1843,6 +1850,17 @@ __metadata: languageName: node linkType: hard +"@codemirror/view@npm:^6.23.0": + version: 6.23.0 + resolution: "@codemirror/view@npm:6.23.0" + dependencies: + "@codemirror/state": ^6.4.0 + style-mod: ^4.1.0 + w3c-keyname: ^2.2.4 + checksum: 6e5f2314a3da2c724dc6a525654d949d3f2fcf7009f4d85f980d52ddc885c8969717e903ca1d9132afbe7c524af5d19bff8285fd394106282a965ae83aa47db4 + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -3638,9 +3656,9 @@ __metadata: resolution: "@neo4j/graphql-toolbox@workspace:packages/graphql-toolbox" dependencies: "@codemirror/autocomplete": 6.11.1 - "@codemirror/commands": 6.3.2 + "@codemirror/commands": 6.3.3 "@codemirror/lang-javascript": 6.2.1 - "@codemirror/language": 6.9.3 + "@codemirror/language": 6.10.0 "@dnd-kit/core": 6.1.0 "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 From 522b59d9359e5da29af209169cf7ba7b206cc22b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 04:44:13 +0000 Subject: [PATCH 096/136] fix(deps): update dependency classnames to v2.5.1 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 6c25624b09e..64dd7f59658 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -54,7 +54,7 @@ "@neo4j-ndl/react": "2.2.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", - "classnames": "2.5.0", + "classnames": "2.5.1", "cm6-graphql": "0.0.12", "codemirror": "6.0.1", "dotenv-webpack": "8.0.1", diff --git a/yarn.lock b/yarn.lock index 58d547bb780..d29d2e09f5c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3675,7 +3675,7 @@ __metadata: "@types/react-dom": 18.2.18 "@types/webpack": 5.28.5 autoprefixer: 10.4.16 - classnames: 2.5.0 + classnames: 2.5.1 cm6-graphql: 0.0.12 codemirror: 6.0.1 compression-webpack-plugin: 10.0.0 @@ -10504,10 +10504,10 @@ __metadata: languageName: node linkType: hard -"classnames@npm:2.5.0": - version: 2.5.0 - resolution: "classnames@npm:2.5.0" - checksum: 7805e0ed49790dd11da5da4d8509dbad2d9ed8ec817bfa01d3b69d40dc752ee4df757b9e845371a42547989863db76c463619c446aa24cdbd253d65ef927455e +"classnames@npm:2.5.1": + version: 2.5.1 + resolution: "classnames@npm:2.5.1" + checksum: da424a8a6f3a96a2e87d01a432ba19315503294ac7e025f9fece656db6b6a0f7b5003bb1fbb51cbb0d9624d964f1b9bb35a51c73af9b2434c7b292c42231c1e5 languageName: node linkType: hard From 763bb53b8f8d8caf953047847ae1d0e8d5792701 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 06:15:41 +0000 Subject: [PATCH 097/136] chore(deps): update dependency koa to v2.15.0 --- packages/graphql/package.json | 2 +- yarn.lock | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 34c115e3ae3..33ec47faf46 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -70,7 +70,7 @@ "jest": "29.7.0", "jest-extended": "4.0.2", "jwks-rsa": "3.1.0", - "koa": "2.14.2", + "koa": "2.15.0", "koa-jwt": "4.0.4", "koa-router": "12.0.1", "libnpmsearch": "7.0.1", diff --git a/yarn.lock b/yarn.lock index d29d2e09f5c..473c133feda 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3759,7 +3759,7 @@ __metadata: jest-extended: 4.0.2 jose: ^5.0.0 jwks-rsa: 3.1.0 - koa: 2.14.2 + koa: 2.15.0 koa-jwt: 4.0.4 koa-router: 12.0.1 libnpmsearch: 7.0.1 @@ -11214,13 +11214,13 @@ __metadata: languageName: node linkType: hard -"cookies@npm:~0.8.0": - version: 0.8.0 - resolution: "cookies@npm:0.8.0" +"cookies@npm:~0.9.0": + version: 0.9.0 + resolution: "cookies@npm:0.9.0" dependencies: depd: ~2.0.0 keygrip: ~1.1.0 - checksum: 806055a44f128705265b1bc6a853058da18bf80dea3654ad99be20985b1fa1b14f86c1eef73644aab8071241f8a78acd57202b54c4c5c70769fc694fbb9c4edc + checksum: e4db8b65edc85bb9640ddca88abae319cbde21af56d83b9b0a4346d41450166bc072f19d0eca00cc805be1c61979a6e80f7f38f5af517ffe2549a44ff5812953 languageName: node linkType: hard @@ -17881,15 +17881,15 @@ __metadata: languageName: node linkType: hard -"koa@npm:2.14.2": - version: 2.14.2 - resolution: "koa@npm:2.14.2" +"koa@npm:2.15.0": + version: 2.15.0 + resolution: "koa@npm:2.15.0" dependencies: accepts: ^1.3.5 cache-content-type: ^1.0.0 content-disposition: ~0.5.2 content-type: ^1.0.4 - cookies: ~0.8.0 + cookies: ~0.9.0 debug: ^4.3.2 delegates: ^1.0.0 depd: ^2.0.0 @@ -17908,7 +17908,7 @@ __metadata: statuses: ^1.5.0 type-is: ^1.6.16 vary: ^1.1.2 - checksum: 17fe3b8f5e0b4759004a942cc6ba2a9507299943a697dff9766b85f41f45caed4077ca2645ac9ad254d3359fffedfc4c9ebdd7a70493e5df8cdfac159a8ee835 + checksum: a97741f89f328f25ae94d82d0ee608377d89e086c73f2d868023e6050dea682ef93e0a5c80097f3aaad28121853aea50a7fb3c0c12ecc45798da2fd1255f580b languageName: node linkType: hard From f137d92ba762807f3a114335bdbfa9ecdd14abb4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 07:48:49 +0000 Subject: [PATCH 098/136] chore(deps): update srvaroa/labeler action to v1.10.0 --- .github/workflows/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 5ac07b63b5f..b3ad8a5b946 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -13,6 +13,6 @@ jobs: runs-on: ubuntu-latest steps: - - uses: srvaroa/labeler@ff8cb30f062faad05978491eebd6c75fef132272 # v1.9.0 + - uses: srvaroa/labeler@0381dc470140eaebc6fd87fc4aedc4dd2f39f997 # v1.10.0 env: GITHUB_TOKEN: ${{ secrets.NEO4J_TEAM_GRAPHQL_PERSONAL_ACCESS_TOKEN }} From 5250ad35a52b7238f0b4428b6141168dca5d5680 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 22:09:57 +0000 Subject: [PATCH 099/136] chore(deps): update dependency eslint-plugin-jest to v27.6.1 --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c2166caa638..bab01182f1b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.29.1", - "eslint-plugin-jest": "27.6.0", + "eslint-plugin-jest": "27.6.1", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-react": "7.33.2", "eslint-plugin-simple-import-sort": "10.0.0", diff --git a/yarn.lock b/yarn.lock index 473c133feda..af086bfbe8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13291,9 +13291,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jest@npm:27.6.0": - version: 27.6.0 - resolution: "eslint-plugin-jest@npm:27.6.0" +"eslint-plugin-jest@npm:27.6.1": + version: 27.6.1 + resolution: "eslint-plugin-jest@npm:27.6.1" dependencies: "@typescript-eslint/utils": ^5.10.0 peerDependencies: @@ -13305,7 +13305,7 @@ __metadata: optional: true jest: optional: true - checksum: 4c42641f9bf2d597761637028083e20b9f81762308e98baae40eb805d3e81ff8d837f06f4f0c1a2fd249e2be2fb24d33b7aafeaa8942de805c2b8d7c3b6fc4e4 + checksum: 03dc4784119a06504718b3ec1a5944c8d41fe73669d23433fa794e4059be857ec463da6d5982dcd2920da091fe7c5c033fa69a91f4dfbe3f41aac6db99b8c3d0 languageName: node linkType: hard @@ -19890,7 +19890,7 @@ __metadata: eslint-import-resolver-typescript: 3.6.1 eslint-plugin-eslint-comments: 3.2.0 eslint-plugin-import: 2.29.1 - eslint-plugin-jest: 27.6.0 + eslint-plugin-jest: 27.6.1 eslint-plugin-jsx-a11y: 6.8.0 eslint-plugin-react: 7.33.2 eslint-plugin-simple-import-sort: 10.0.0 From 7b160785e63d7fe64be58e80d23d06d19ed7dfbf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 23:41:21 +0000 Subject: [PATCH 100/136] chore(deps): update typescript-eslint monorepo to v6.17.0 --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index bab01182f1b..165ab5f6d9d 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.16.0", - "@typescript-eslint/parser": "6.16.0", + "@typescript-eslint/eslint-plugin": "6.17.0", + "@typescript-eslint/parser": "6.17.0", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.56.0", diff --git a/yarn.lock b/yarn.lock index af086bfbe8b..df0344c04db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7967,15 +7967,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.16.0" +"@typescript-eslint/eslint-plugin@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.17.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.16.0 - "@typescript-eslint/type-utils": 6.16.0 - "@typescript-eslint/utils": 6.16.0 - "@typescript-eslint/visitor-keys": 6.16.0 + "@typescript-eslint/scope-manager": 6.17.0 + "@typescript-eslint/type-utils": 6.17.0 + "@typescript-eslint/utils": 6.17.0 + "@typescript-eslint/visitor-keys": 6.17.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7988,25 +7988,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: d426a77970dab8e1c3d8320fa50da4dd31c9c36fc91fc0870049d5da96a165290f0c1337b742e6150ad076b5a0ac8ea3eaa6919a2d6d672395b9c2ef8da23449 + checksum: 169646a705fdd1bc2a0d78678dbf3557ff3e534e9d4a11f7b5bba1d9f5cbec821f8c16b260413203efc8d6e0c0a3d7f9332bb1476e3dac80e60aa16eb9a0ad11 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/parser@npm:6.16.0" +"@typescript-eslint/parser@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/parser@npm:6.17.0" dependencies: - "@typescript-eslint/scope-manager": 6.16.0 - "@typescript-eslint/types": 6.16.0 - "@typescript-eslint/typescript-estree": 6.16.0 - "@typescript-eslint/visitor-keys": 6.16.0 + "@typescript-eslint/scope-manager": 6.17.0 + "@typescript-eslint/types": 6.17.0 + "@typescript-eslint/typescript-estree": 6.17.0 + "@typescript-eslint/visitor-keys": 6.17.0 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 5048a4fe63a8edf3b23c4355c7399d39c266a5f92d2c271e0ff3122eff5cd81d6535c871912b9cea991d87c91d264420ad0253b7816206f34356c290b7671188 + checksum: c48864aebf364332540f520d84630a6bb3e2ddc84492d75c14a453964b669a37f1fd43b60469e3683e618e8e8d3d7747baffe92e408599d5df6869cae86ac9e1 languageName: node linkType: hard @@ -8020,22 +8020,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/scope-manager@npm:6.16.0" +"@typescript-eslint/scope-manager@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/scope-manager@npm:6.17.0" dependencies: - "@typescript-eslint/types": 6.16.0 - "@typescript-eslint/visitor-keys": 6.16.0 - checksum: a3380f2cd4dd0928dfcacc45057018cbe11f86cccb53a848d4eb4d15b363e95b11aae453b4a7822701667816fabd4b6393839447a342e55f8cfaa6740c635098 + "@typescript-eslint/types": 6.17.0 + "@typescript-eslint/visitor-keys": 6.17.0 + checksum: 6eabac1e52cd25714ab176c7bbf9919d065febf4580620eb067ab1b41607f5e592857bd831a2ab41daa873af4011217dbcae55ed248855e381127f1cabcd2d2c languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/type-utils@npm:6.16.0" +"@typescript-eslint/type-utils@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/type-utils@npm:6.17.0" dependencies: - "@typescript-eslint/typescript-estree": 6.16.0 - "@typescript-eslint/utils": 6.16.0 + "@typescript-eslint/typescript-estree": 6.17.0 + "@typescript-eslint/utils": 6.17.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8043,7 +8043,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: f322ff7c670f35991982574f9182fd8eb1aee91f52b73249de73805039e5848692713a0bd25e265b2f8a62eadb6d5a08134c94c51690f8bf9a0d1e3efaa8a45a + checksum: bb6f824c1c7f8d25a21b7218a5bcb74e58c38121f85418eb1639f2931c6149285c2ede96dd677a3e7dc64886cc7640d74be6001d970c3ac9c9a4d889315c5d15 languageName: node linkType: hard @@ -8054,10 +8054,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/types@npm:6.16.0" - checksum: 74f8e4412cd52272952bfba8db9c1f7fd991f0f3924d6f63aff4e92614a8a581ea9c0df715190567d176a72b55099f3ef03d5462d4f6a78695d2b659cf5bfe34 +"@typescript-eslint/types@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/types@npm:6.17.0" + checksum: a199516230b505f85de1b99cdf22c526cbae7604fa2dd0dd24e8bba5de45aeaee231263e7e59843af7b226cb91c4ba5447d06517a1a73b511a94c6b483af0d5b languageName: node linkType: hard @@ -8079,12 +8079,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.16.0" +"@typescript-eslint/typescript-estree@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.17.0" dependencies: - "@typescript-eslint/types": 6.16.0 - "@typescript-eslint/visitor-keys": 6.16.0 + "@typescript-eslint/types": 6.17.0 + "@typescript-eslint/visitor-keys": 6.17.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8094,24 +8094,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 20ed8b8f7bf8173d5b68e9b0b86178607a5054adeb9daba87b7c1aa245b2f42ad04b93ee669d74920229eaf430cff146d67c6366a01cc338593a81bf812e6132 + checksum: 4bf7811ddae66361cad55f7a6fcf9975eb77456ceb2eca5d7a6228387737845bdfe1b9eef4c76d5d6b7c7d6029a8f62bc67b509c0724cd37395ae16eb07dd7ab languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/utils@npm:6.16.0" +"@typescript-eslint/utils@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/utils@npm:6.17.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.16.0 - "@typescript-eslint/types": 6.16.0 - "@typescript-eslint/typescript-estree": 6.16.0 + "@typescript-eslint/scope-manager": 6.17.0 + "@typescript-eslint/types": 6.17.0 + "@typescript-eslint/typescript-estree": 6.17.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: d7efa112a1356024cde5306d032c6028d41671ece7ecda5c726cbfed26a9f3f8d317388a3c743cfaeeee1766db303c4a489b6825ad8275ee148d060afa57af4d + checksum: 2eea8fd3763b2ab9d86503c68b4d61df81071fd38851b8ba920d53b055c352d13e192a3d15ca853f11aee818c61e8af65946e963aa0e9b18d19e3254881bded0 languageName: node linkType: hard @@ -8143,13 +8143,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.16.0": - version: 6.16.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.16.0" +"@typescript-eslint/visitor-keys@npm:6.17.0": + version: 6.17.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.17.0" dependencies: - "@typescript-eslint/types": 6.16.0 + "@typescript-eslint/types": 6.17.0 eslint-visitor-keys: ^3.4.1 - checksum: 2863e6d145a79bb12485b39417e30710996d8576894d67a484fde7cef417e3c67fd9fd99cb57736f0667e4425ddb2ab1f0954340ec5f4e08b8cb2ce7378a1977 + checksum: e98755087bd067388d9a9182375e53f590183ca656d02b3d05d9718bab2ac571832fd16691060c7c979fd941e9d4b7923d8975632923697de0691f50fc97c8ac languageName: node linkType: hard @@ -19880,8 +19880,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.16.0 - "@typescript-eslint/parser": 6.16.0 + "@typescript-eslint/eslint-plugin": 6.17.0 + "@typescript-eslint/parser": 6.17.0 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.56.0 From b3054883eb7abc16d5f6b0e00f8bc13631e52046 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 00:24:05 +0000 Subject: [PATCH 101/136] chore(deps): update dependency @apollo/server to v4.10.0 --- .../graphql-amqp-subscriptions-engine/package.json | 2 +- packages/graphql/package.json | 2 +- yarn.lock | 13 ++++++------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index 1c62813972d..2b6ad938352 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -33,7 +33,7 @@ }, "author": "Neo4j Inc.", "devDependencies": { - "@apollo/server": "4.9.5", + "@apollo/server": "4.10.0", "@neo4j/graphql": "^4.0.0", "@types/amqplib": "0.10.4", "@types/body-parser": "1.19.5", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 33ec47faf46..e375d2c8262 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -50,7 +50,7 @@ "author": "Neo4j Inc.", "devDependencies": { "@apollo/gateway": "2.6.2", - "@apollo/server": "4.9.5", + "@apollo/server": "4.10.0", "@faker-js/faker": "8.3.1", "@types/deep-equal": "1.0.4", "@types/is-uuid": "1.0.2", diff --git a/yarn.lock b/yarn.lock index df0344c04db..c6aeb2c3dca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -278,9 +278,9 @@ __metadata: languageName: node linkType: hard -"@apollo/server@npm:4.9.5": - version: 4.9.5 - resolution: "@apollo/server@npm:4.9.5" +"@apollo/server@npm:4.10.0": + version: 4.10.0 + resolution: "@apollo/server@npm:4.10.0" dependencies: "@apollo/cache-control-types": ^1.0.3 "@apollo/server-gateway-interface": ^1.1.1 @@ -298,7 +298,6 @@ __metadata: "@types/express-serve-static-core": ^4.17.30 "@types/node-fetch": ^2.6.1 async-retry: ^1.2.1 - body-parser: ^1.20.0 cors: ^2.8.5 express: ^4.17.1 loglevel: ^1.6.8 @@ -310,7 +309,7 @@ __metadata: whatwg-mimetype: ^3.0.0 peerDependencies: graphql: ^16.6.0 - checksum: 52aac2ef0665a776b2da8930b2a6e31b652a9a3c5b2e48e56d323e40b618acae091c69dc04ebed5355a36e22b793ceb31baa04afe516205c67c2db87c0fb01a0 + checksum: 902df9ea634ef52ba96b26e923d86b5093f678bcd9e76e4c4f57c26f5450064603449e095b8c8d2a21316c8a9277444e7d9145af8811ddc481d1992bf4123c39 languageName: node linkType: hard @@ -3596,7 +3595,7 @@ __metadata: version: 0.0.0-use.local resolution: "@neo4j/graphql-amqp-subscriptions-engine@workspace:packages/graphql-amqp-subscriptions-engine" dependencies: - "@apollo/server": 4.9.5 + "@apollo/server": 4.10.0 "@neo4j/graphql": ^4.0.0 "@types/amqplib": 0.10.4 "@types/body-parser": 1.19.5 @@ -3725,7 +3724,7 @@ __metadata: resolution: "@neo4j/graphql@workspace:packages/graphql" dependencies: "@apollo/gateway": 2.6.2 - "@apollo/server": 4.9.5 + "@apollo/server": 4.10.0 "@apollo/subgraph": ^2.2.3 "@faker-js/faker": 8.3.1 "@graphql-tools/merge": ^9.0.0 From 50043f465788aca0eb15fb743a47b7c6d9e9a35c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 01:56:07 +0000 Subject: [PATCH 102/136] fix(deps): update dependency neo4j-driver to v5.16.0 --- package.json | 2 +- .../package.json | 2 +- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 36 +++++++++---------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 165ab5f6d9d..61645fa2594 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "husky": "8.0.3", "jest": "29.7.0", "lint-staged": "15.2.0", - "neo4j-driver": "5.15.0", + "neo4j-driver": "5.16.0", "npm-run-all": "4.1.5", "prettier": "2.8.8", "set-tz": "0.2.0", diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index 2b6ad938352..c230c5183bb 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -44,7 +44,7 @@ "camelcase": "6.3.0", "graphql-ws": "5.14.3", "jest": "29.7.0", - "neo4j-driver": "5.15.0", + "neo4j-driver": "5.16.0", "pluralize": "8.0.0", "randomstring": "1.3.0", "supertest": "6.3.3", diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 64dd7f59658..8f9154d7966 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -61,7 +61,7 @@ "graphiql-explorer": "0.9.0", "graphql": "16.8.1", "graphql-query-complexity": "0.12.0", - "neo4j-driver": "5.15.0", + "neo4j-driver": "5.16.0", "prettier": "3.0.0", "process": "0.11.10", "react": "18.2.0", diff --git a/yarn.lock b/yarn.lock index c6aeb2c3dca..f80376fe2e4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3609,7 +3609,7 @@ __metadata: cors: ^2.8.5 graphql-ws: 5.14.3 jest: 29.7.0 - neo4j-driver: 5.15.0 + neo4j-driver: 5.16.0 pluralize: 8.0.0 randomstring: 1.3.0 supertest: 6.3.3 @@ -3692,7 +3692,7 @@ __metadata: html-webpack-plugin: 5.6.0 jest: 29.7.0 jest-environment-jsdom: 29.7.0 - neo4j-driver: 5.15.0 + neo4j-driver: 5.16.0 node-polyfill-webpack-plugin: 2.0.1 parse5: 7.1.2 postcss: 8.4.32 @@ -19825,14 +19825,14 @@ __metadata: languageName: node linkType: hard -"neo4j-driver-bolt-connection@npm:5.15.0": - version: 5.15.0 - resolution: "neo4j-driver-bolt-connection@npm:5.15.0" +"neo4j-driver-bolt-connection@npm:5.16.0": + version: 5.16.0 + resolution: "neo4j-driver-bolt-connection@npm:5.16.0" dependencies: buffer: ^6.0.3 - neo4j-driver-core: 5.15.0 + neo4j-driver-core: 5.16.0 string_decoder: ^1.3.0 - checksum: 5e36d6eab0130df8d15e71ad85ca36697292e32ea4195ec7f33a547675942f3148a30c5aa99fc93e830d4b3fb771d50d05f98a12f1134bd7f06d2c09a3ca8d36 + checksum: ddf5337fba3bd31b5909c1ab351d57df3b51d971786ba262d53ba38e89c4204d78cf7401527814e0ea6541dea26d21b54627e17fed4b9e78e2ee31f46b3deaf3 languageName: node linkType: hard @@ -19843,21 +19843,21 @@ __metadata: languageName: node linkType: hard -"neo4j-driver-core@npm:5.15.0": - version: 5.15.0 - resolution: "neo4j-driver-core@npm:5.15.0" - checksum: c13ba8cf0a68ee5de7d3855aa1e5b8e724c8f735ab5514e8dd8cfaee71d808faf38b9511666d223005a10340a1929a7d90074c7596e7f25daa47bb77fcbd0a96 +"neo4j-driver-core@npm:5.16.0": + version: 5.16.0 + resolution: "neo4j-driver-core@npm:5.16.0" + checksum: 58c33ea0121bdbd4d541c1967998fae1b07a092a8b83438c78567dd008f79ab3401a97824c9ccb721bb25c9ff65485521bb0a1b33fa75e3464a5b6324e65d593 languageName: node linkType: hard -"neo4j-driver@npm:5.15.0": - version: 5.15.0 - resolution: "neo4j-driver@npm:5.15.0" +"neo4j-driver@npm:5.16.0": + version: 5.16.0 + resolution: "neo4j-driver@npm:5.16.0" dependencies: - neo4j-driver-bolt-connection: 5.15.0 - neo4j-driver-core: 5.15.0 + neo4j-driver-bolt-connection: 5.16.0 + neo4j-driver-core: 5.16.0 rxjs: ^7.8.1 - checksum: 9e80d00719c1ec24bddfd9f221690db992e4102cb511f7809ae6f77f3fbc555b6420f205b24a6132cd91784356323c69eefc3731ee40c919faaaf791b03eafbb + checksum: ac6beea48043a379149132514fbabcd8ce2604c2e8237fdd60729244834a9ce45f5379aa6ca4fb93f008beaed9c3c4414e7087cd5b9d1e9c3397715fb74aa9e3 languageName: node linkType: hard @@ -19897,7 +19897,7 @@ __metadata: husky: 8.0.3 jest: 29.7.0 lint-staged: 15.2.0 - neo4j-driver: 5.15.0 + neo4j-driver: 5.16.0 npm-run-all: 4.1.5 prettier: 2.8.8 set-tz: 0.2.0 From 3fe68de8d567cc3fd07feba304408bd5ffafe3c9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 01:02:49 +0000 Subject: [PATCH 103/136] chore(deps): update alex-page/github-project-automation-plus action to v0.9.0 --- .github/workflows/bug-reopened.yml | 2 +- .github/workflows/issue-labeled.yml | 4 ++-- .github/workflows/pull-request-labeled.yml | 2 +- .github/workflows/pull-request-opened.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/bug-reopened.yml b/.github/workflows/bug-reopened.yml index efa0a9e5e3c..b54a5d3797d 100644 --- a/.github/workflows/bug-reopened.yml +++ b/.github/workflows/bug-reopened.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43 # v0.8.3 + - uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36 # v0.9.0 with: project: Bug Triage column: Bug reports diff --git a/.github/workflows/issue-labeled.yml b/.github/workflows/issue-labeled.yml index 643d5011d32..470f8e95f0d 100644 --- a/.github/workflows/issue-labeled.yml +++ b/.github/workflows/issue-labeled.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43 # v0.8.3 + - uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36 # v0.9.0 with: project: Bug Triage column: Bug reports @@ -46,7 +46,7 @@ jobs: issue-number: ${{ github.event.issue.number }} body: | We've been able to confirm this bug using the steps to reproduce that you provided - many thanks @${{ github.event.issue.user.login }}! :pray: We will now prioritise the bug and address it appropriately. - - uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43 # v0.8.3 + - uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36 # v0.9.0 with: project: Bug Triage column: Confirmed diff --git a/.github/workflows/pull-request-labeled.yml b/.github/workflows/pull-request-labeled.yml index 8939bed42d8..c7bfb7e563c 100644 --- a/.github/workflows/pull-request-labeled.yml +++ b/.github/workflows/pull-request-labeled.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43 # v0.8.3 + - uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36 # v0.9.0 with: project: RFCs column: RFCs diff --git a/.github/workflows/pull-request-opened.yml b/.github/workflows/pull-request-opened.yml index 57f71debfa2..b4a501e7880 100644 --- a/.github/workflows/pull-request-opened.yml +++ b/.github/workflows/pull-request-opened.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: alex-page/github-project-automation-plus@7ffb872c64bd809d23563a130a0a97d01dfa8f43 # v0.8.3 + - uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36 # v0.9.0 with: project: PR Triage column: Pull requests From d57503c12dbbc9f12ed1a53ce5e051d36a3d59a0 Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Thu, 4 Jan 2024 10:01:22 +0100 Subject: [PATCH 104/136] Fix toolbox failing tests (#4472) * fix: update date to 2024 * build: revert to old version of codemirror The newer version meant we had conflicts with out cm6-graphql dependency's peer dependencies on codemirror. * feat: add maxFailures to playwright config --- packages/graphql-toolbox/package.json | 4 +- packages/graphql-toolbox/playwright.config.ts | 8 ++-- .../src/modules/AppSettings/AppSettings.tsx | 2 +- yarn.lock | 42 ++++++------------- 4 files changed, 19 insertions(+), 37 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 8f9154d7966..249fa452363 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -43,9 +43,9 @@ "author": "Neo4j", "dependencies": { "@codemirror/autocomplete": "6.11.1", - "@codemirror/commands": "6.3.3", + "@codemirror/commands": "6.3.2", "@codemirror/lang-javascript": "6.2.1", - "@codemirror/language": "6.10.0", + "@codemirror/language": "6.9.3", "@dnd-kit/core": "6.1.0", "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", diff --git a/packages/graphql-toolbox/playwright.config.ts b/packages/graphql-toolbox/playwright.config.ts index c9ebee0dba4..b933c4d7bd9 100644 --- a/packages/graphql-toolbox/playwright.config.ts +++ b/packages/graphql-toolbox/playwright.config.ts @@ -17,9 +17,9 @@ * limitations under the License. */ -import { PlaywrightTestConfig, devices } from "@playwright/test"; +import { defineConfig, devices } from "@playwright/test"; -const config: PlaywrightTestConfig = { +export default defineConfig({ webServer: { command: "yarn start", url: "http://localhost:4242", @@ -35,6 +35,7 @@ const config: PlaywrightTestConfig = { forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 6 : undefined, + maxFailures: process.env.CI ? 10 : undefined, projects: [ { name: "chromium", @@ -53,5 +54,4 @@ const config: PlaywrightTestConfig = { }, ], outputDir: "tests/artifacts/", -}; -export default config; +}); diff --git a/packages/graphql-toolbox/src/modules/AppSettings/AppSettings.tsx b/packages/graphql-toolbox/src/modules/AppSettings/AppSettings.tsx index a1e3cfedd68..fe27ffe0885 100644 --- a/packages/graphql-toolbox/src/modules/AppSettings/AppSettings.tsx +++ b/packages/graphql-toolbox/src/modules/AppSettings/AppSettings.tsx @@ -118,7 +118,7 @@ export const AppSettings = ({ onClickClose }: Props) => {
Made by Neo4j, Inc {/* explicitly hard coded values for copyright */} - Copyright © 2002-2023 + Copyright © 2002-2024
App version: 
{process.env.VERSION}
diff --git a/yarn.lock b/yarn.lock index f80376fe2e4..7b212382dd7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1735,15 +1735,15 @@ __metadata: languageName: node linkType: hard -"@codemirror/commands@npm:6.3.3": - version: 6.3.3 - resolution: "@codemirror/commands@npm:6.3.3" +"@codemirror/commands@npm:6.3.2": + version: 6.3.2 + resolution: "@codemirror/commands@npm:6.3.2" dependencies: "@codemirror/language": ^6.0.0 - "@codemirror/state": ^6.4.0 + "@codemirror/state": ^6.2.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 - checksum: 7d23aecc973823969434b839aefa9a98bb47212d2ce0e6869ae903adbb5233aad22a760788fb7bb6eb45b00b01a4932fb93ad43bacdcbc0215e7500cf54b17bb + checksum: 683c444d8e6ad889ab5efd0d742b0fa28b78c8cad63276ec60d298b13d4939c8bd7e1d6fd3535645b8d255147de0d3aef46d89a29c19d0af58a7f2914bdcb3ab languageName: node linkType: hard @@ -1774,17 +1774,17 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:6.10.0": - version: 6.10.0 - resolution: "@codemirror/language@npm:6.10.0" +"@codemirror/language@npm:6.9.3": + version: 6.9.3 + resolution: "@codemirror/language@npm:6.9.3" dependencies: "@codemirror/state": ^6.0.0 - "@codemirror/view": ^6.23.0 + "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 3bfd9968f5a34ce22434489a5b226db5f3bc454a1ae7c4381587ff4270ac6af61b10f93df560cb73e9a77cc13d4843722a7a7b94dbed02a3ab1971dd329b9e81 + checksum: 774a40bc91c748d418a9a774161a5b083061124e4439bb753072bc657ec4c4784f595161c10c7c3935154b22291bf6dc74c9abe827033db32e217ac3963478f3 languageName: node linkType: hard @@ -1831,13 +1831,6 @@ __metadata: languageName: node linkType: hard -"@codemirror/state@npm:^6.4.0": - version: 6.4.0 - resolution: "@codemirror/state@npm:6.4.0" - checksum: c5236fe5786f1b85d17273a5c17fa8aeb063658c1404ab18caeb6e7591663ec96b65d453ab8162f75839c3801b04cd55ba4bc48f44cb61ebfeeee383f89553c7 - languageName: node - linkType: hard - "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.9.0": version: 6.20.2 resolution: "@codemirror/view@npm:6.20.2" @@ -1849,17 +1842,6 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:^6.23.0": - version: 6.23.0 - resolution: "@codemirror/view@npm:6.23.0" - dependencies: - "@codemirror/state": ^6.4.0 - style-mod: ^4.1.0 - w3c-keyname: ^2.2.4 - checksum: 6e5f2314a3da2c724dc6a525654d949d3f2fcf7009f4d85f980d52ddc885c8969717e903ca1d9132afbe7c524af5d19bff8285fd394106282a965ae83aa47db4 - languageName: node - linkType: hard - "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -3655,9 +3637,9 @@ __metadata: resolution: "@neo4j/graphql-toolbox@workspace:packages/graphql-toolbox" dependencies: "@codemirror/autocomplete": 6.11.1 - "@codemirror/commands": 6.3.3 + "@codemirror/commands": 6.3.2 "@codemirror/lang-javascript": 6.2.1 - "@codemirror/language": 6.10.0 + "@codemirror/language": 6.9.3 "@dnd-kit/core": 6.1.0 "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 From c02bd7068e5cf05347c97d60ac75946db8df126a Mon Sep 17 00:00:00 2001 From: Darrell Warde Date: Thu, 4 Jan 2024 13:38:33 +0000 Subject: [PATCH 105/136] Fix query printing in query logs --- packages/graphql/src/classes/Executor.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/graphql/src/classes/Executor.ts b/packages/graphql/src/classes/Executor.ts index 0249985fcd2..d805f4d1b82 100644 --- a/packages/graphql/src/classes/Executor.ts +++ b/packages/graphql/src/classes/Executor.ts @@ -206,7 +206,12 @@ export class Executor { if (info) { const source = { // We avoid using print here, when possible, as it is a heavy process - query: info.operation.loc?.source.body || print(info.operation), + query: + info.operation.loc?.source.body || + // Print both fragments and operation, otherwise printed queries are invalid due to missing fragments + [Object.values(info.fragments).map((fragment) => print(fragment)), print(info.operation)].join( + "\n\n" + ), params: info.variableValues, }; From c641a13cf667bb99ee5e7490799bd33e54525dde Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 23:11:29 +0000 Subject: [PATCH 106/136] chore(deps): update dependency postcss to v8.4.33 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 249fa452363..207f10754a2 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -91,7 +91,7 @@ "jest-environment-jsdom": "29.7.0", "node-polyfill-webpack-plugin": "2.0.1", "parse5": "7.1.2", - "postcss": "8.4.32", + "postcss": "8.4.33", "postcss-loader": "7.3.4", "randomstring": "1.3.0", "style-loader": "3.3.3", diff --git a/yarn.lock b/yarn.lock index 7b212382dd7..b4cee9bca74 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3677,7 +3677,7 @@ __metadata: neo4j-driver: 5.16.0 node-polyfill-webpack-plugin: 2.0.1 parse5: 7.1.2 - postcss: 8.4.32 + postcss: 8.4.33 postcss-loader: 7.3.4 prettier: 3.0.0 process: 0.11.10 @@ -21669,14 +21669,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.32": - version: 8.4.32 - resolution: "postcss@npm:8.4.32" +"postcss@npm:8.4.33": + version: 8.4.33 + resolution: "postcss@npm:8.4.33" dependencies: nanoid: ^3.3.7 picocolors: ^1.0.0 source-map-js: ^1.0.2 - checksum: 220d9d0bf5d65be7ed31006c523bfb11619461d296245c1231831f90150aeb4a31eab9983ac9c5c89759a3ca8b60b3e0d098574964e1691673c3ce5c494305ae + checksum: 6f98b2af4b76632a3de20c4f47bf0e984a1ce1a531cf11adcb0b1d63a6cbda0aae4165e578b66c32ca4879038e3eaad386a6be725a8fb4429c78e3c1ab858fe9 languageName: node linkType: hard From fbddd076875f94629df2fa07bc42f4ed9adf6989 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 4 Jan 2024 23:20:58 +0000 Subject: [PATCH 107/136] fix(deps): update codemirror --- packages/graphql-toolbox/package.json | 4 +-- yarn.lock | 42 +++++++++++++++++++-------- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 207f10754a2..8f48b5d032a 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -43,9 +43,9 @@ "author": "Neo4j", "dependencies": { "@codemirror/autocomplete": "6.11.1", - "@codemirror/commands": "6.3.2", + "@codemirror/commands": "6.3.3", "@codemirror/lang-javascript": "6.2.1", - "@codemirror/language": "6.9.3", + "@codemirror/language": "6.10.0", "@dnd-kit/core": "6.1.0", "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", diff --git a/yarn.lock b/yarn.lock index b4cee9bca74..ffe2acd5ad8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1735,15 +1735,15 @@ __metadata: languageName: node linkType: hard -"@codemirror/commands@npm:6.3.2": - version: 6.3.2 - resolution: "@codemirror/commands@npm:6.3.2" +"@codemirror/commands@npm:6.3.3": + version: 6.3.3 + resolution: "@codemirror/commands@npm:6.3.3" dependencies: "@codemirror/language": ^6.0.0 - "@codemirror/state": ^6.2.0 + "@codemirror/state": ^6.4.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 - checksum: 683c444d8e6ad889ab5efd0d742b0fa28b78c8cad63276ec60d298b13d4939c8bd7e1d6fd3535645b8d255147de0d3aef46d89a29c19d0af58a7f2914bdcb3ab + checksum: 7d23aecc973823969434b839aefa9a98bb47212d2ce0e6869ae903adbb5233aad22a760788fb7bb6eb45b00b01a4932fb93ad43bacdcbc0215e7500cf54b17bb languageName: node linkType: hard @@ -1774,17 +1774,17 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:6.9.3": - version: 6.9.3 - resolution: "@codemirror/language@npm:6.9.3" +"@codemirror/language@npm:6.10.0": + version: 6.10.0 + resolution: "@codemirror/language@npm:6.10.0" dependencies: "@codemirror/state": ^6.0.0 - "@codemirror/view": ^6.0.0 + "@codemirror/view": ^6.23.0 "@lezer/common": ^1.1.0 "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 774a40bc91c748d418a9a774161a5b083061124e4439bb753072bc657ec4c4784f595161c10c7c3935154b22291bf6dc74c9abe827033db32e217ac3963478f3 + checksum: 3bfd9968f5a34ce22434489a5b226db5f3bc454a1ae7c4381587ff4270ac6af61b10f93df560cb73e9a77cc13d4843722a7a7b94dbed02a3ab1971dd329b9e81 languageName: node linkType: hard @@ -1831,6 +1831,13 @@ __metadata: languageName: node linkType: hard +"@codemirror/state@npm:^6.4.0": + version: 6.4.0 + resolution: "@codemirror/state@npm:6.4.0" + checksum: c5236fe5786f1b85d17273a5c17fa8aeb063658c1404ab18caeb6e7591663ec96b65d453ab8162f75839c3801b04cd55ba4bc48f44cb61ebfeeee383f89553c7 + languageName: node + linkType: hard + "@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.9.0": version: 6.20.2 resolution: "@codemirror/view@npm:6.20.2" @@ -1842,6 +1849,17 @@ __metadata: languageName: node linkType: hard +"@codemirror/view@npm:^6.23.0": + version: 6.23.0 + resolution: "@codemirror/view@npm:6.23.0" + dependencies: + "@codemirror/state": ^6.4.0 + style-mod: ^4.1.0 + w3c-keyname: ^2.2.4 + checksum: 6e5f2314a3da2c724dc6a525654d949d3f2fcf7009f4d85f980d52ddc885c8969717e903ca1d9132afbe7c524af5d19bff8285fd394106282a965ae83aa47db4 + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -3637,9 +3655,9 @@ __metadata: resolution: "@neo4j/graphql-toolbox@workspace:packages/graphql-toolbox" dependencies: "@codemirror/autocomplete": 6.11.1 - "@codemirror/commands": 6.3.2 + "@codemirror/commands": 6.3.3 "@codemirror/lang-javascript": 6.2.1 - "@codemirror/language": 6.9.3 + "@codemirror/language": 6.10.0 "@dnd-kit/core": 6.1.0 "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 From c73cd963d5295a5e5e737878d5bb0dadd8b81a65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 00:43:06 +0000 Subject: [PATCH 108/136] chore(deps): update dependency parcel to v2.11.0 --- examples/neo-place/package.json | 2 +- yarn.lock | 914 ++++++++++++++++---------------- 2 files changed, 463 insertions(+), 453 deletions(-) diff --git a/examples/neo-place/package.json b/examples/neo-place/package.json index f95b5a19fc3..ff4c44d8056 100644 --- a/examples/neo-place/package.json +++ b/examples/neo-place/package.json @@ -51,6 +51,6 @@ }, "devDependencies": { "concurrently": "8.2.2", - "parcel": "2.10.3" + "parcel": "2.11.0" } } diff --git a/yarn.lock b/yarn.lock index ffe2acd5ad8..877160f92d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3907,112 +3907,112 @@ __metadata: languageName: node linkType: hard -"@parcel/bundler-default@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/bundler-default@npm:2.10.3" - dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/graph": 3.0.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 - "@parcel/utils": 2.10.3 +"@parcel/bundler-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/bundler-default@npm:2.11.0" + dependencies: + "@parcel/diagnostic": 2.11.0 + "@parcel/graph": 3.1.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 - checksum: 2fd80acec4aeb4306b6ad29d381e8c77003576efc9c057a24fac80c363b3a8ba0c4b7bbea1587312fe3f88ab1fbcac085dbb90cfee5759d33fa085bc550d7191 + checksum: 6541cd9b82cd403f25fa3c1ee50d7cf9d27ed8f51256b1e4ead0655335128f9225c87e3118203b1b48e29f157a69dab5797065abb78fb03a409ad2765ea3a1e5 languageName: node linkType: hard -"@parcel/cache@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/cache@npm:2.10.3" +"@parcel/cache@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/cache@npm:2.11.0" dependencies: - "@parcel/fs": 2.10.3 - "@parcel/logger": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/fs": 2.11.0 + "@parcel/logger": 2.11.0 + "@parcel/utils": 2.11.0 lmdb: 2.8.5 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: b7e9a000a78786c1adda97d23f29d5c35695637db5de305d7fb6d4f8e88bed9c98065f4d0b094a131b2deb392451b897635fd2234fa4cf3a8a6667ae0b6af5db + "@parcel/core": ^2.11.0 + checksum: bcb6ce02244e8bbc3c23647b01a6d4907141de3fc28d5ebabc095d8d8328bfb903da02cf3d8faedd337303afe8bf139e514ed7c0228e6e64bdf628cc40e359b6 languageName: node linkType: hard -"@parcel/codeframe@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/codeframe@npm:2.10.3" +"@parcel/codeframe@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/codeframe@npm:2.11.0" dependencies: chalk: ^4.1.0 - checksum: b8808789dc452079ce9a9d93b14e39713e4dc831ddec5a3bc69284632e347d6fb5714e3e4890de081f3cad2c3905643f9f95d88b1262744bb1967e3278b85842 - languageName: node - linkType: hard - -"@parcel/compressor-raw@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/compressor-raw@npm:2.10.3" - dependencies: - "@parcel/plugin": 2.10.3 - checksum: bf92cd0690ff8858bb5fea7b70bb659a77c091aa95a399ce09b67345ab87db74e6974b6ab9faad18c0deb12416da981f59e171e346291cb2a55fc3830dc0153e - languageName: node - linkType: hard - -"@parcel/config-default@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/config-default@npm:2.10.3" - dependencies: - "@parcel/bundler-default": 2.10.3 - "@parcel/compressor-raw": 2.10.3 - "@parcel/namer-default": 2.10.3 - "@parcel/optimizer-css": 2.10.3 - "@parcel/optimizer-htmlnano": 2.10.3 - "@parcel/optimizer-image": 2.10.3 - "@parcel/optimizer-svgo": 2.10.3 - "@parcel/optimizer-swc": 2.10.3 - "@parcel/packager-css": 2.10.3 - "@parcel/packager-html": 2.10.3 - "@parcel/packager-js": 2.10.3 - "@parcel/packager-raw": 2.10.3 - "@parcel/packager-svg": 2.10.3 - "@parcel/packager-wasm": 2.10.3 - "@parcel/reporter-dev-server": 2.10.3 - "@parcel/resolver-default": 2.10.3 - "@parcel/runtime-browser-hmr": 2.10.3 - "@parcel/runtime-js": 2.10.3 - "@parcel/runtime-react-refresh": 2.10.3 - "@parcel/runtime-service-worker": 2.10.3 - "@parcel/transformer-babel": 2.10.3 - "@parcel/transformer-css": 2.10.3 - "@parcel/transformer-html": 2.10.3 - "@parcel/transformer-image": 2.10.3 - "@parcel/transformer-js": 2.10.3 - "@parcel/transformer-json": 2.10.3 - "@parcel/transformer-postcss": 2.10.3 - "@parcel/transformer-posthtml": 2.10.3 - "@parcel/transformer-raw": 2.10.3 - "@parcel/transformer-react-refresh-wrap": 2.10.3 - "@parcel/transformer-svg": 2.10.3 - peerDependencies: - "@parcel/core": ^2.10.3 - checksum: 7dc834abfe81fecfa582ffeb37471328382bae1f7b3d1a45229766cdafd780b349d6b598ef2a550f72e5877726c759866b83c5b4d494a2723e8bd46910bb4b8c - languageName: node - linkType: hard - -"@parcel/core@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/core@npm:2.10.3" + checksum: abd6b7b444dadcf0a986129c782286fe77098dad584ecc91cabf0b64468b2c7150587ce5e1f548ca9943c3a12bf8fa9abddab3f193df057600bdf88b92928897 + languageName: node + linkType: hard + +"@parcel/compressor-raw@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/compressor-raw@npm:2.11.0" + dependencies: + "@parcel/plugin": 2.11.0 + checksum: 90882f3afa36c4a9f66be7379d39f144d55642398ac50b96394e91c72f2c1b1068297e12ab31f5e229645445024ded24471ee4b4ff6d754c60cf75b8f44b8c61 + languageName: node + linkType: hard + +"@parcel/config-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/config-default@npm:2.11.0" + dependencies: + "@parcel/bundler-default": 2.11.0 + "@parcel/compressor-raw": 2.11.0 + "@parcel/namer-default": 2.11.0 + "@parcel/optimizer-css": 2.11.0 + "@parcel/optimizer-htmlnano": 2.11.0 + "@parcel/optimizer-image": 2.11.0 + "@parcel/optimizer-svgo": 2.11.0 + "@parcel/optimizer-swc": 2.11.0 + "@parcel/packager-css": 2.11.0 + "@parcel/packager-html": 2.11.0 + "@parcel/packager-js": 2.11.0 + "@parcel/packager-raw": 2.11.0 + "@parcel/packager-svg": 2.11.0 + "@parcel/packager-wasm": 2.11.0 + "@parcel/reporter-dev-server": 2.11.0 + "@parcel/resolver-default": 2.11.0 + "@parcel/runtime-browser-hmr": 2.11.0 + "@parcel/runtime-js": 2.11.0 + "@parcel/runtime-react-refresh": 2.11.0 + "@parcel/runtime-service-worker": 2.11.0 + "@parcel/transformer-babel": 2.11.0 + "@parcel/transformer-css": 2.11.0 + "@parcel/transformer-html": 2.11.0 + "@parcel/transformer-image": 2.11.0 + "@parcel/transformer-js": 2.11.0 + "@parcel/transformer-json": 2.11.0 + "@parcel/transformer-postcss": 2.11.0 + "@parcel/transformer-posthtml": 2.11.0 + "@parcel/transformer-raw": 2.11.0 + "@parcel/transformer-react-refresh-wrap": 2.11.0 + "@parcel/transformer-svg": 2.11.0 + peerDependencies: + "@parcel/core": ^2.11.0 + checksum: b35be2dcd3e34185d43f168ad95db6c9681b8600d4e5b08768931c845479a0b2b4b360650018073c300767416dc446e5bcf0ce311e5b31c1dfa4c0d7d536a040 + languageName: node + linkType: hard + +"@parcel/core@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/core@npm:2.11.0" dependencies: "@mischnic/json-sourcemap": ^0.1.0 - "@parcel/cache": 2.10.3 - "@parcel/diagnostic": 2.10.3 - "@parcel/events": 2.10.3 - "@parcel/fs": 2.10.3 - "@parcel/graph": 3.0.3 - "@parcel/logger": 2.10.3 - "@parcel/package-manager": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/profiler": 2.10.3 - "@parcel/rust": 2.10.3 + "@parcel/cache": 2.11.0 + "@parcel/diagnostic": 2.11.0 + "@parcel/events": 2.11.0 + "@parcel/fs": 2.11.0 + "@parcel/graph": 3.1.0 + "@parcel/logger": 2.11.0 + "@parcel/package-manager": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/profiler": 2.11.0 + "@parcel/rust": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 - "@parcel/workers": 2.10.3 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 + "@parcel/workers": 2.11.0 abortcontroller-polyfill: ^1.1.9 base-x: ^3.0.8 browserslist: ^4.6.6 @@ -4023,369 +4023,370 @@ __metadata: msgpackr: ^1.9.9 nullthrows: ^1.1.1 semver: ^7.5.2 - checksum: 9d9def613a19b893c56a6fbf09df07a5abd483a545c4643d8584337c828d2da2e32e56b3a1962b81719da7f384160f1383b911383860755951475a59369efa24 + checksum: 22d4e1f3f5bcb7647c520fdc90bca725cc291e8b1aea71dd1eb0ecf4deb191ccc16f07a4df660ebc237e17f5fcfe35c1f8ec1eb47189c9d953ff59eb27fde344 languageName: node linkType: hard -"@parcel/diagnostic@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/diagnostic@npm:2.10.3" +"@parcel/diagnostic@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/diagnostic@npm:2.11.0" dependencies: "@mischnic/json-sourcemap": ^0.1.0 nullthrows: ^1.1.1 - checksum: 4223a534db21a18fb47c79a9a10ca49b84bddb1135bef8772808af9f36b695d789460d103f0566902df849c8e419ef60f66ab538c597fc38e5643e717c3eb042 + checksum: bcfd74db92bb4a05eaf2abec7ade76f68b119cf3f07ab6eebc8a9b37871ef9839a7dad9476d7c114a6ce15d1fc2569de50dccd38ed28251375f0f72ad35b0349 languageName: node linkType: hard -"@parcel/events@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/events@npm:2.10.3" - checksum: f8b6c53a24378f02ccb8e5beb7f47d70a2b1e25f12541cf0e49be6daf998001806f9da862e908be291e9b44d880b387eee8b2790a7abf22bbefaafc07bd1664d +"@parcel/events@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/events@npm:2.11.0" + checksum: e757383143ad2c5b5fed800eb8fd8a0bf2d6c362dbc1f55993d0be575b5f7b7ad0fcead1db695ceb48e49fb13126849b282879097b4a14ccb8fc3fc522e9e10f languageName: node linkType: hard -"@parcel/fs@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/fs@npm:2.10.3" +"@parcel/fs@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/fs@npm:2.11.0" dependencies: - "@parcel/rust": 2.10.3 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/rust": 2.11.0 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 "@parcel/watcher": ^2.0.7 - "@parcel/workers": 2.10.3 + "@parcel/workers": 2.11.0 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: 916a7a0d6b3c98aa089d85445971f4fb6bf90ef94fb5d941e0c27d4cb775309027a537b5c144352299eadc516fe30f681c3843a24a4e518a24074c25830819c0 + "@parcel/core": ^2.11.0 + checksum: 2702d29dd72c73b30268b1dbeba5bd8c74638baa69c96415c9fc5182cf3fa312c575f22e01f021f42043b32a877ca980e61997332301b15fc2fa626e485edd13 languageName: node linkType: hard -"@parcel/graph@npm:3.0.3": - version: 3.0.3 - resolution: "@parcel/graph@npm:3.0.3" +"@parcel/graph@npm:3.1.0": + version: 3.1.0 + resolution: "@parcel/graph@npm:3.1.0" dependencies: nullthrows: ^1.1.1 - checksum: f906c7709b37abb5e8fb47919de2a1b763a0ee2851fe42f924d16a27f98435a92f0520c1c9990d31d9c835cbd25e9eeb57447ee4b9e8b56556857ad1fb28495a + checksum: 6d645e3ab4bb06fbc967e71072ebe796c602aacf5ac79d30e2d40442d6b08785bed49165b28a914ca419a949f4dec4dc3b2557520064c4a53bcc04f4b023daf0 languageName: node linkType: hard -"@parcel/logger@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/logger@npm:2.10.3" +"@parcel/logger@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/logger@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/events": 2.10.3 - checksum: f67f4010122b6b2e65d9789d328e0672cb250d7e0bf66528c317ddd8d95a771c67c87d75d049b5ed6b0b5858c860052301e9418faeee0c7f3d27e79d688874f5 + "@parcel/diagnostic": 2.11.0 + "@parcel/events": 2.11.0 + checksum: 363cacf5969df4d8b28d397f025cb9f318ebd940cd2372ffdcd25bdbeca25844b9ae7777f35dd7cdb2d1029a8c7379f6c0173bdfc201b88f4acfe6fd7f315ec5 languageName: node linkType: hard -"@parcel/markdown-ansi@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/markdown-ansi@npm:2.10.3" +"@parcel/markdown-ansi@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/markdown-ansi@npm:2.11.0" dependencies: chalk: ^4.1.0 - checksum: e683f8ce1dd12f2a414e3f7840de3a46f0477c4dbf603dfa9b49372367bf248d115b2c73fbba85ad0dff27bd156a55761aa22d12afba098197dc3c7a4f9e6730 + checksum: 26bc69d6e227b3d461b3501014bd9c33cdb7c6514447b7eeb0f17c97ff9dc74f3bdddf271f9976e14c918516044128f477e884ce94b765c5a7e23661edfa739f languageName: node linkType: hard -"@parcel/namer-default@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/namer-default@npm:2.10.3" +"@parcel/namer-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/namer-default@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 nullthrows: ^1.1.1 - checksum: ea6adf6c5cb44d97ce929b967b6ebf5d383c907284166ee57554a8d3815b7da42a867202e8f69ee190de35287639e2ed74f8cd540ecf232232dcc8423a3a613a + checksum: 452978cb597729cc21aec11456dd2121860893c9dec20f588cfc087643f127a6553493bcec5916d32285e7af11d5b832c24f07a10424cf264b4dac7ba1dfc101 languageName: node linkType: hard -"@parcel/node-resolver-core@npm:3.1.3": - version: 3.1.3 - resolution: "@parcel/node-resolver-core@npm:3.1.3" +"@parcel/node-resolver-core@npm:3.2.0": + version: 3.2.0 + resolution: "@parcel/node-resolver-core@npm:3.2.0" dependencies: "@mischnic/json-sourcemap": ^0.1.0 - "@parcel/diagnostic": 2.10.3 - "@parcel/fs": 2.10.3 - "@parcel/rust": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/fs": 2.11.0 + "@parcel/rust": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 semver: ^7.5.2 - checksum: 7daa061d8170eee165005686b9ac82823a5fda5465246226bd8ca163b9434ebfa70163bf64b103f56e0fe7d6b72f10ebf24e0bcc2f832e258876484d0707636e + checksum: 9a006b50b1af5d0c4461647d5de5932a39c910ddd8da478dba68d4c814a92cb20cfca59fde98a3def9b899126a637bb7e1445fa97e794cb57487e7c0be678858 languageName: node linkType: hard -"@parcel/optimizer-css@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/optimizer-css@npm:2.10.3" +"@parcel/optimizer-css@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-css@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/utils": 2.10.3 + "@parcel/utils": 2.11.0 browserslist: ^4.6.6 - lightningcss: ^1.16.1 + lightningcss: ^1.22.1 nullthrows: ^1.1.1 - checksum: f157c14136b24bace773d721d29192dd913770dea3b65348993ce0bd6dbdeb186c4a4bfc42b6912a4674814d4ed73761568bd976e09f1d988a66095d8da83920 + checksum: 8407b5e864a96e768a719ff35498353c5604c8b0c469f2a265d133bce05a1e80a0d95adcfc0a758c83ff35da5b3d12bf44b0b0f8598d2e2c16e86e6c527e9208 languageName: node linkType: hard -"@parcel/optimizer-htmlnano@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/optimizer-htmlnano@npm:2.10.3" +"@parcel/optimizer-htmlnano@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-htmlnano@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 + "@parcel/plugin": 2.11.0 htmlnano: ^2.0.0 nullthrows: ^1.1.1 posthtml: ^0.16.5 svgo: ^2.4.0 - checksum: d2d7c4d5596e64b5a1ee81824aabb132853fbd065e2e8816e061702872ec4cec3527d9f63206d20d78176a4d1e075f25d5f90590b6540b8aa57f0295c59c687b + checksum: 4943948a8f345b8f7024d68b7f401befe943f0de00eb826df530e67f8155739dbae386fae350ad6e7a8ec00ba41598333fa48a3e51cc364cd517e17975131f38 languageName: node linkType: hard -"@parcel/optimizer-image@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/optimizer-image@npm:2.10.3" +"@parcel/optimizer-image@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-image@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 - "@parcel/utils": 2.10.3 - "@parcel/workers": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 + "@parcel/utils": 2.11.0 + "@parcel/workers": 2.11.0 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: 40a4132b9edc344fcab6607b69a3b05743ad1478319183b5eb54c3ee21d676eb9ecdd78ada676998a7cd3a1daaf0cb02c65504cbe9343001e10fd7fff7d1b03d + "@parcel/core": ^2.11.0 + checksum: 9c4d9d087fd9bb47c150b80e2f92620ba376ca6462415a17ea0d81a0c674db363fe8364a7fc39aa1bed25c96e95742b73e18fdab1f2767c78b6e6f9c0fbbe08c languageName: node linkType: hard -"@parcel/optimizer-svgo@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/optimizer-svgo@npm:2.10.3" +"@parcel/optimizer-svgo@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-svgo@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 svgo: ^2.4.0 - checksum: f26c8c931f0648b6c908e6d9639be010cb3f0551eaaf46f205bba39fcdb5190a20a094847f91036734a0b9749bf607ae22b0bedbecaebe30fa198965523fc228 + checksum: 4e671856c28435e4f19335fa5ed062878a9d6fe4232ff22befab5a90df360db1904afbd55bfd4ecff193f4bcd7a9081f5d23db54bb644bb7160fcfa1aac4facf languageName: node linkType: hard -"@parcel/optimizer-swc@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/optimizer-swc@npm:2.10.3" +"@parcel/optimizer-swc@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/optimizer-swc@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/utils": 2.10.3 + "@parcel/utils": 2.11.0 "@swc/core": ^1.3.36 nullthrows: ^1.1.1 - checksum: 6eb1e2c923cff94f71a3d5a8218f826440ac7c0162cc45d9b27ae20ad62f1ab0dcd5efea4cbabebb3cbfe0d6d56b26693754e5daca8469ab36914d7ece1be3ba + checksum: be4b8bc94a5a490f6912a6dee24473eced904f2122f684d164cd781e7b216375999c5a15efa91fece4cb50cfc0c4eaabe9a8773df263163b5951e9d4e76a5798 languageName: node linkType: hard -"@parcel/package-manager@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/package-manager@npm:2.10.3" +"@parcel/package-manager@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/package-manager@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/fs": 2.10.3 - "@parcel/logger": 2.10.3 - "@parcel/node-resolver-core": 3.1.3 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 - "@parcel/workers": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/fs": 2.11.0 + "@parcel/logger": 2.11.0 + "@parcel/node-resolver-core": 3.2.0 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 + "@parcel/workers": 2.11.0 semver: ^7.5.2 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: d25958e342cd6886b7d92b12100f8f58dadc80c925a28e25b8a7aa7349955d701c927b42e97ecff8b078452ff92dd4b976782b47fda7268533e9412de86c710f + "@parcel/core": ^2.11.0 + checksum: 3846542eb59ee39ad53c1aea56f59045a26e58d07b0f0f59a91ca1b91e1268e76cd564a914e1041120f870481ae46063a39737e67d2418547cc0ff0dcf08a124 languageName: node linkType: hard -"@parcel/packager-css@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/packager-css@npm:2.10.3" +"@parcel/packager-css@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-css@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/utils": 2.10.3 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 - checksum: 5da9263a0fcf233c0793029518220a8bbcc4f8707196c1a85acfbf96ebfb821fdc4da2ce01af92b16178e6db4e214d627fc61902fecd65910c1dcecb6af60273 + checksum: 2aa8da12ca83353153cb4d70893dfa691bab6f9e884b434812f3d4200fec3d2bd5a89df1a4c6c9a0d0955b5b5ef88bfacb4287f87c066f377fc304ef5a099720 languageName: node linkType: hard -"@parcel/packager-html@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/packager-html@npm:2.10.3" +"@parcel/packager-html@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-html@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 posthtml: ^0.16.5 - checksum: 85bfdba8be5be33f37c520cc6b770151ab7ad263032aff1126a64a1df9676f25478f7d3e67ea76374362287bbed3419939ae0e6d576b2a20f60f51a23f24fa58 + checksum: a651b4f3cf1e398ff111f31519610957863701471a763369fa26fa7398ed96c02a41f76575e60262e091506f7e7b4c7d3c7df9b3a12fb04dc62e7c9fe0604d71 languageName: node linkType: hard -"@parcel/packager-js@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/packager-js@npm:2.10.3" +"@parcel/packager-js@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-js@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 globals: ^13.2.0 nullthrows: ^1.1.1 - checksum: 1e383bdf39c495d23ac52acb4a821ef9d405ae4eee160a9571dee005faa60e1404046c59250c99898691da6fffa18e9dee5e317b6d06ee7503717ebbb4f7e59f + checksum: 63d96fb22be90f54f5562fc93baad13deff63d7e434648f606b455800610679231a8e7b1349bd0f212568e2e4cf519c6368fbda8f1b0ae392870ecfa6bf8265f languageName: node linkType: hard -"@parcel/packager-raw@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/packager-raw@npm:2.10.3" +"@parcel/packager-raw@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-raw@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - checksum: 7f6615fa93c18e14014de07e677587ccfd1e275972d577c3ef4359969f8fca4ec12351be04a0d34e6287b63041259a0b31bc239555b7cdff7cfec734667f6e4f + "@parcel/plugin": 2.11.0 + checksum: c36dbcc82a31643fd83dce8a5dc5bb038a9396ffec46a8f9c8a7ad35f4645d2050c4228ed360f2c70f11073a606b6c89872a70883d07594b91bd8ce9191ed3a2 languageName: node linkType: hard -"@parcel/packager-svg@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/packager-svg@npm:2.10.3" +"@parcel/packager-svg@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-svg@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 posthtml: ^0.16.4 - checksum: fcc64795be57a3c32e7861d424d3aaaa585cda126a0f7e03d28ffb4cd2105218ae4d1ce8ac68cb986a8fe5b77adf80722de18b6af4d094f368c810aff346f58c + checksum: 2d0394dd5e9ce0025f805241975ee26318f176b42ca30d6f020cfb5521f77ca6eb2b13c9c23f580bab69e55ca883f06d6c023faa3b84e15f2e7d6e826ed2f961 languageName: node linkType: hard -"@parcel/packager-wasm@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/packager-wasm@npm:2.10.3" +"@parcel/packager-wasm@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/packager-wasm@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - checksum: 971a8b1ef763fb593d80536b7728545bc471208fecb05344fb5b4af7f38dc9f5f5faad8047388d4bfcff8bba7b96cf1437789e017e40b0fd95a6da99b03db942 + "@parcel/plugin": 2.11.0 + checksum: 4f0617fe512ffdce0157dff47311ef241645482ddd8a90614bab658de7c1b51387eede6e841480c4478557934e2ce1d318d970f45a8048edfbf8992da7c2bc18 languageName: node linkType: hard -"@parcel/plugin@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/plugin@npm:2.10.3" +"@parcel/plugin@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/plugin@npm:2.11.0" dependencies: - "@parcel/types": 2.10.3 - checksum: d5d18e815856bf76d4e5a6b3daaefa21030a67e46b38cebb9ee4d4aa98b352bce3f54d8c3fc4136692c31e85ca23f1366bd86f77c78cd0daeacbad82a59068d0 + "@parcel/types": 2.11.0 + checksum: 45344c3ac0674b77ea29cbac23de5887fac68bfba118adf93c9bab4631c1e341e1212d250d1279581c51ad6124b6f023bbb5c2ca0e7c1afed4442fc0a0398a97 languageName: node linkType: hard -"@parcel/profiler@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/profiler@npm:2.10.3" +"@parcel/profiler@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/profiler@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/events": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/events": 2.11.0 chrome-trace-event: ^1.0.2 - checksum: b6d797c7abddb2e8861a77fc3f8e11d329a41e3257ba6d5eddfb5cb158d3299d380d49114dfccac54ce73c9ba82e779a39fe3f0e62b40aae4eb8ade5ed3e8726 + checksum: f5b5749786de62f1d9d0285adbbe49e170e691fdbf789d9d706c84b72ed6a300978f2144f7c56f4695fff6ee4388df97158554b105631adde6e43d3ee0090784 languageName: node linkType: hard -"@parcel/reporter-cli@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/reporter-cli@npm:2.10.3" +"@parcel/reporter-cli@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/reporter-cli@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 chalk: ^4.1.0 + cli-progress: ^3.12.0 term-size: ^2.2.1 - checksum: 7b6f4c0e964955422a20936ca53bb864fe0e1a9729a68e303ab9daa6ead8fabb48b695614852549357a881734a230980967d7e1c76f2f78b279e14e28725f2ed + checksum: 81e62144ad834791656458eeea286a061f4b8fa4651d8c68e54ab8050f9101ee9cfc9117f18544baebea5d47da9f4b2e3e6eabc19e7c886131bdcd9b2f40dd71 languageName: node linkType: hard -"@parcel/reporter-dev-server@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/reporter-dev-server@npm:2.10.3" +"@parcel/reporter-dev-server@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/reporter-dev-server@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 - checksum: 0dd35076154e705ea0f00ffbb7fd452a7fd98d0c13cf9af2b72a8762509dfe87594c00e0cfd886ee6d2a4134379581eb281f5e1fde4eb4b4360fb547bc1f3db9 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 + checksum: ac8948c7f30a88c8d05d3a168381d906e6b6bfbdf04001ec46a57b0f9901f009d111ca7d200e5079ca34ce23b7754be38902492ffacdd42d544cbe26c7c2dc67 languageName: node linkType: hard -"@parcel/reporter-tracer@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/reporter-tracer@npm:2.10.3" +"@parcel/reporter-tracer@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/reporter-tracer@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 chrome-trace-event: ^1.0.3 nullthrows: ^1.1.1 - checksum: 818ff5a49c836fc965ebd21373c0924453ae9b5fe2f9bde5e4735cb1bdd16db81af65f2f48235a95e34c9bacec6081b29bf612dc0e3e4d1db7811bec91ac1b2d + checksum: 83aedfc97d3b79f5aae205c88267fe6baf59ccee211aca251198c55594760e84145a3e070ce5efcbef648b72c752649283f13b5500fb848f83dbf723dff295df languageName: node linkType: hard -"@parcel/resolver-default@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/resolver-default@npm:2.10.3" +"@parcel/resolver-default@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/resolver-default@npm:2.11.0" dependencies: - "@parcel/node-resolver-core": 3.1.3 - "@parcel/plugin": 2.10.3 - checksum: 4c6025a129fbdb42964c84e58df3dc555bb77dae2d134a6e98de652e14de1c1b600766add5e95ccaffb3c7bfc006111fdb9aabeb96f815c875c9e3846d66e484 + "@parcel/node-resolver-core": 3.2.0 + "@parcel/plugin": 2.11.0 + checksum: bbb5f6dfd67c754680dade42005a6ddc5fc5d40f7277ba1d63df898ac117ad98c2d74b599b2df91c7f2f8503bf6ba3cb10eef9d9b4d9c09ef0e8a7eb98d38d6e languageName: node linkType: hard -"@parcel/runtime-browser-hmr@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/runtime-browser-hmr@npm:2.10.3" +"@parcel/runtime-browser-hmr@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-browser-hmr@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 - checksum: 6977acaf7797e070626667bef7849cfaebad89323c2da718c690f05f44b778bba7045469d704e7995fe06fd4e4f77194a8059218c85bcb186a05c753c0cf4c7c + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 + checksum: ad7eba3210227ebbcb71889cdfb495172ae0173b75e140b41fe772df90c115f1bab5c23fd6209eabe94f143942725f6b3a8d497483e376cf449078c0a984bf1c languageName: node linkType: hard -"@parcel/runtime-js@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/runtime-js@npm:2.10.3" +"@parcel/runtime-js@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-js@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 - checksum: a0c3f95eefbd9e6a9678d838bedac997ef4ebb797c1aef25d2e72217a70fdf54ae44a1ef0ff4c0161e0df004ee6a44b66958edfd5df9f95cd2017f049f0be2f0 + checksum: 3cab5e6b6218b91b9022c9e0990674be46abd763dd4f5deaaa4d1143df22a37f479d2a1f41f9b1be35e1381437c3ed301b03afec62bb8cba613e473ffd22d43c languageName: node linkType: hard -"@parcel/runtime-react-refresh@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/runtime-react-refresh@npm:2.10.3" +"@parcel/runtime-react-refresh@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-react-refresh@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 react-error-overlay: 6.0.9 react-refresh: ^0.9.0 - checksum: 00f69e6a57918c628fdd4ee2dc4b65e81bdc0be15074d32ffdd6db3aa6d00b0ce0a4e005aba028fc0deaccf38f8b319bf0b5900999cbca5530ad29ab7a0a4074 + checksum: 0a29d9e55ad296ae13413e13ecea2e5966edc4e26a542bf817cc72cd15f793930abe7b2e80065e39ee647be13e211951146c8c643184da8fa2af872f09e9ffc5 languageName: node linkType: hard -"@parcel/runtime-service-worker@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/runtime-service-worker@npm:2.10.3" +"@parcel/runtime-service-worker@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/runtime-service-worker@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 - checksum: 01370853dfc535804353169f349b1d7a8291f4daa0b7728c052c1d9759e4b338fced1801490d8dd6aa12816135f475124daa9c747f7ba68c7c899064b3abb88f + checksum: da8d2b5a925f710e14f9dd49d968603946961b4f8d1f4ef8d4b68e350118d2f6ae42115adcc6952ebe01151dd185de827902d3984367c20c5f9381890d8bfeb5 languageName: node linkType: hard -"@parcel/rust@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/rust@npm:2.10.3" - checksum: 5c1a086742b0a53c935bc992a71cadc8fc3f5bd7ce7fce5dcf13a4079a867ef6df09422cd668e44c3cec0be19630441ca11c95081fc922287312893c5c0ebe1a +"@parcel/rust@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/rust@npm:2.11.0" + checksum: 53a95b23562d71597af726647923db08185ede5b83fd25f00467229b62a51fd5b43a0e44172d90d68721e1463fb4c5f06000ddd47d402779177fe7c441fe8b16 languageName: node linkType: hard @@ -4398,194 +4399,194 @@ __metadata: languageName: node linkType: hard -"@parcel/transformer-babel@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-babel@npm:2.10.3" +"@parcel/transformer-babel@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-babel@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/utils": 2.10.3 + "@parcel/utils": 2.11.0 browserslist: ^4.6.6 json5: ^2.2.0 nullthrows: ^1.1.1 semver: ^7.5.2 - checksum: 5dc31a9ff4b4f7a1400a16c2f2d44badcf330dfc98ff935ece813ce9efd926d34bc230a60c146bd3bb43b2da675f1289b3b55b8386f2739abb521e5c34970d59 + checksum: f36c7973c691619b4c35bdd40135cd6daf735b333f34df99b6cad1b0ad332010b195bdb0388a6ff8b6abad201020a77ad797b974774bb0d26894d1c435f30814 languageName: node linkType: hard -"@parcel/transformer-css@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-css@npm:2.10.3" +"@parcel/transformer-css@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-css@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/utils": 2.10.3 + "@parcel/utils": 2.11.0 browserslist: ^4.6.6 - lightningcss: ^1.16.1 + lightningcss: ^1.22.1 nullthrows: ^1.1.1 - checksum: f9cf5f04ceae726cf8a5c95ba326a73125423245fe34317593dde9956bead1e48021254ffffd0b5b41cd8f71a953580e1216d0897557c7d0999f360a7797ad43 + checksum: 59b1893b94388b4e7e94121cd82cbf734499e1565503b91ec0ea837d9967190c953323a4c054d8d80fd5c53f5b75710a5f20f54d129a076257497a269316a280 languageName: node linkType: hard -"@parcel/transformer-html@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-html@npm:2.10.3" +"@parcel/transformer-html@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-html@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 nullthrows: ^1.1.1 posthtml: ^0.16.5 posthtml-parser: ^0.10.1 posthtml-render: ^3.0.0 semver: ^7.5.2 srcset: 4 - checksum: ecf9f0c18791bdb1b2c65abbe8ef1fd0fe6bb33d4831c294efc78cf8094e7444e1746b86ad82e2cb7fec02c7c94fd8c0a6190201a12ff83e22b6d243cd665ece + checksum: fd333e9a4890bb565b0403f065a46c9c38174b379f6fc30b557455fad13d9b13864bf2cb971ff396cea8724c74c652336f727e2df260e2bfb6d2ea7d952371ae languageName: node linkType: hard -"@parcel/transformer-image@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-image@npm:2.10.3" +"@parcel/transformer-image@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-image@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 - "@parcel/workers": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 + "@parcel/workers": 2.11.0 nullthrows: ^1.1.1 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: 5e1fc73ca2e38f0fcb67cc0851e27a2d0f1bcb01c5b6f6e0ba8195987c32a26111cd27ba26d6d9f0374773c04f98dd88e1e4fcec770a596f0618b4a9bae3e46f + "@parcel/core": ^2.11.0 + checksum: 65e7fa4791100b5db6dd6752a0f43c2c377e2f3825c5cfeb8bff5d3ae994e3ac659ebcb656a607834f54eb3cf6cf499ed78fdba64a968428c2bbcdb23b030d19 languageName: node linkType: hard -"@parcel/transformer-js@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-js@npm:2.10.3" +"@parcel/transformer-js@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-js@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/utils": 2.10.3 - "@parcel/workers": 2.10.3 + "@parcel/utils": 2.11.0 + "@parcel/workers": 2.11.0 "@swc/helpers": ^0.5.0 browserslist: ^4.6.6 nullthrows: ^1.1.1 regenerator-runtime: ^0.13.7 semver: ^7.5.2 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: 7d534ea520808a3f12fa0751f88034a6212e0ec876934b570a48bd905ddea20d1fd8d543e23fd6fa4674591ccad476f1495e7b9732209a22d287674b82df6b02 + "@parcel/core": ^2.11.0 + checksum: ae75820a392f9728ecd4fe98a9ec746c380fb2fd927845980d0f95b0e89afe8c9bf557ba66006612811bc362caa07cd4697dfa732df8cf0de711e8666f0c80ee languageName: node linkType: hard -"@parcel/transformer-json@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-json@npm:2.10.3" +"@parcel/transformer-json@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-json@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 + "@parcel/plugin": 2.11.0 json5: ^2.2.0 - checksum: f08d2a13b284484e4d062b6650d65329d0da1da04dadd770da9911a44b40a051e745f80b5b61e82ad74d99816c7cb10e0094144b5b033cb17c85d38a916f4714 + checksum: 6e25561d09ea238e96558a76c0812c423ca44633824b3271fb3bc5b77604aefe8943332f2b7b17ff7a296cc6b770a6ba3d2322eeac4650785c2f091314c71ddf languageName: node linkType: hard -"@parcel/transformer-postcss@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-postcss@npm:2.10.3" +"@parcel/transformer-postcss@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-postcss@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 + "@parcel/utils": 2.11.0 clone: ^2.1.1 nullthrows: ^1.1.1 postcss-value-parser: ^4.2.0 semver: ^7.5.2 - checksum: bcea34678d39231cd91cebdc8790b4b9f6e56b9a8c94cadd54ab90b43d282505fe17c8b5414b0fdf82d7b66620bffc587c21f2613356085cba7e7dfc5badea77 + checksum: 10f0054e5b751275fc1571d32d91f4412b31575d45eb576d1483771c3d3c445bd50da7937a8aa6b0aa134212e2f3b608482a6e617e6472f77694cd52ec413c82 languageName: node linkType: hard -"@parcel/transformer-posthtml@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-posthtml@npm:2.10.3" +"@parcel/transformer-posthtml@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-posthtml@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 posthtml: ^0.16.5 posthtml-parser: ^0.10.1 posthtml-render: ^3.0.0 semver: ^7.5.2 - checksum: afa94afee4b0e1769227bbd6a8928bd5ce8c38711bc8164cb9a76af2134643d28c3b1887a8237b9c2572f0a30f7181aaeb3ed3c1a4882b064a3f30e2f145b77d + checksum: d79e3666cae4ffb648d042b30e974d68193c05ffb6418d0c79fe784e07b323fe65a3006130f63eeafe0700a09300d8c9e6dcf6a56e24ac2a23fdd30d3bd4a9b5 languageName: node linkType: hard -"@parcel/transformer-raw@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-raw@npm:2.10.3" +"@parcel/transformer-raw@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-raw@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - checksum: 26f5b5c1f80f60b6ea404cce9372591f643accc3357b7164b208888d47e7b9731433d3ef4e62034cadbc998ef84cfa0d9e6b63a842e0f09157d3f5d46324342f + "@parcel/plugin": 2.11.0 + checksum: b914665c090316d677fedc1b646b87c31eea277fb26281b737874940fe1c63bdbcf0f31dc4d2a4d5493bf4e61b420e7b4827039bd8409aaed8e8da4a5a03bacc languageName: node linkType: hard -"@parcel/transformer-react-refresh-wrap@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-react-refresh-wrap@npm:2.10.3" +"@parcel/transformer-react-refresh-wrap@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-react-refresh-wrap@npm:2.11.0" dependencies: - "@parcel/plugin": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/plugin": 2.11.0 + "@parcel/utils": 2.11.0 react-refresh: ^0.9.0 - checksum: 5959b5860d1ac342bd3eaf9fcbde2065c84ef4347100f36ae29cc322a87aea5b1175142fe6c181f9fddbc858384755787f5b9398da2078d5881f2b2f94caf19b + checksum: b17b7a151da31f6abe7e33d798205af3926135e5e936025f74883285519a9fff5207c89fd06c21635965e9d8e46d62450915623d1b5bd97d50297a6633703519 languageName: node linkType: hard -"@parcel/transformer-svg@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/transformer-svg@npm:2.10.3" +"@parcel/transformer-svg@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/transformer-svg@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/plugin": 2.10.3 - "@parcel/rust": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/plugin": 2.11.0 + "@parcel/rust": 2.11.0 nullthrows: ^1.1.1 posthtml: ^0.16.5 posthtml-parser: ^0.10.1 posthtml-render: ^3.0.0 semver: ^7.5.2 - checksum: aa1c3378fc4b809cca9dd90804030d204a587e3a4bebf5f0cf3853eaf6eff0cf82b47e304df2b532831eaabe48143a996a789d3d199f156de534ff03c68a3c8e + checksum: 48bf4503ded4328394fcb23ab08856a2b81fda4ec3e7755ec97492511324d66b20ed1f47e0588f011b0319795094e98537683634318eaf53fcd89229f7e9088c languageName: node linkType: hard -"@parcel/types@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/types@npm:2.10.3" +"@parcel/types@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/types@npm:2.11.0" dependencies: - "@parcel/cache": 2.10.3 - "@parcel/diagnostic": 2.10.3 - "@parcel/fs": 2.10.3 - "@parcel/package-manager": 2.10.3 + "@parcel/cache": 2.11.0 + "@parcel/diagnostic": 2.11.0 + "@parcel/fs": 2.11.0 + "@parcel/package-manager": 2.11.0 "@parcel/source-map": ^2.1.1 - "@parcel/workers": 2.10.3 + "@parcel/workers": 2.11.0 utility-types: ^3.10.0 - checksum: ffc6d24df95b5458e02e2a841fac6bee6ba9f78f3f0c3ae9e465a546a3a05e91ab2781850785a6e153ce20f456b9d4427ea0754cdc8efaabf2fee5823ac5f89b + checksum: 8534156cafcd8eeee008f7cdbe91a609c8e3c9d1fe9248c3649e0649379c3c5cd141a038ca06f457e6b46d254f2667fd55d1b89a3cf3f6091ea5102422c8fc41 languageName: node linkType: hard -"@parcel/utils@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/utils@npm:2.10.3" +"@parcel/utils@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/utils@npm:2.11.0" dependencies: - "@parcel/codeframe": 2.10.3 - "@parcel/diagnostic": 2.10.3 - "@parcel/logger": 2.10.3 - "@parcel/markdown-ansi": 2.10.3 - "@parcel/rust": 2.10.3 + "@parcel/codeframe": 2.11.0 + "@parcel/diagnostic": 2.11.0 + "@parcel/logger": 2.11.0 + "@parcel/markdown-ansi": 2.11.0 + "@parcel/rust": 2.11.0 "@parcel/source-map": ^2.1.1 chalk: ^4.1.0 nullthrows: ^1.1.1 - checksum: fb9aa1ee1a9de81a917a58e4f0960440597accdd68d00e775d69b5ddcf6c82ceb348f412301cfaa78560f36786283cab6105d647cd6442c6be2693b2afec61f3 + checksum: e40f4bca049881c9c4b287f0425b197f44e87a958f528e8598304b61bf645ec648ee68b4e7f194de9a3341cdd6857f3fedce71dc8ca7327d8d37017e350f42b7 languageName: node linkType: hard @@ -4723,19 +4724,19 @@ __metadata: languageName: node linkType: hard -"@parcel/workers@npm:2.10.3": - version: 2.10.3 - resolution: "@parcel/workers@npm:2.10.3" +"@parcel/workers@npm:2.11.0": + version: 2.11.0 + resolution: "@parcel/workers@npm:2.11.0" dependencies: - "@parcel/diagnostic": 2.10.3 - "@parcel/logger": 2.10.3 - "@parcel/profiler": 2.10.3 - "@parcel/types": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/diagnostic": 2.11.0 + "@parcel/logger": 2.11.0 + "@parcel/profiler": 2.11.0 + "@parcel/types": 2.11.0 + "@parcel/utils": 2.11.0 nullthrows: ^1.1.1 peerDependencies: - "@parcel/core": ^2.10.3 - checksum: 5418cfa25d22b1d786d754c20030b4aa081b62e96daf247459549df7f4971229635fa5ecb2860ee500af08a172f0eed689654ed867148c18ae0dae9aac1e68f2 + "@parcel/core": ^2.11.0 + checksum: 0771ad5372a4d27e64d6009df1a81a8a302031dcef041ddd11b43089262af3c4e6c62c0beb05485eddb2a61fc6993eb8ed04379de60cb61988d5195b352e88cc languageName: node linkType: hard @@ -10567,6 +10568,15 @@ __metadata: languageName: node linkType: hard +"cli-progress@npm:^3.12.0": + version: 3.12.0 + resolution: "cli-progress@npm:3.12.0" + dependencies: + string-width: ^4.2.3 + checksum: e8390dc3cdf3c72ecfda0a1e8997bfed63a0d837f97366bbce0ca2ff1b452da386caed007b389f0fe972625037b6c8e7ab087c69d6184cc4dfc8595c4c1d3e6e + languageName: node + linkType: hard + "cli-spinners@npm:^2.5.0": version: 2.9.1 resolution: "cli-spinners@npm:2.9.1" @@ -18026,83 +18036,83 @@ __metadata: languageName: node linkType: hard -"lightningcss-darwin-arm64@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-darwin-arm64@npm:1.22.0" +"lightningcss-darwin-arm64@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-darwin-arm64@npm:1.22.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"lightningcss-darwin-x64@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-darwin-x64@npm:1.22.0" +"lightningcss-darwin-x64@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-darwin-x64@npm:1.22.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"lightningcss-freebsd-x64@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-freebsd-x64@npm:1.22.0" +"lightningcss-freebsd-x64@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-freebsd-x64@npm:1.22.1" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"lightningcss-linux-arm-gnueabihf@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-linux-arm-gnueabihf@npm:1.22.0" +"lightningcss-linux-arm-gnueabihf@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-linux-arm-gnueabihf@npm:1.22.1" conditions: os=linux & cpu=arm languageName: node linkType: hard -"lightningcss-linux-arm64-gnu@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-linux-arm64-gnu@npm:1.22.0" +"lightningcss-linux-arm64-gnu@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-linux-arm64-gnu@npm:1.22.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-arm64-musl@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-linux-arm64-musl@npm:1.22.0" +"lightningcss-linux-arm64-musl@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-linux-arm64-musl@npm:1.22.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"lightningcss-linux-x64-gnu@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-linux-x64-gnu@npm:1.22.0" +"lightningcss-linux-x64-gnu@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-linux-x64-gnu@npm:1.22.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"lightningcss-linux-x64-musl@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-linux-x64-musl@npm:1.22.0" +"lightningcss-linux-x64-musl@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-linux-x64-musl@npm:1.22.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"lightningcss-win32-x64-msvc@npm:1.22.0": - version: 1.22.0 - resolution: "lightningcss-win32-x64-msvc@npm:1.22.0" +"lightningcss-win32-x64-msvc@npm:1.22.1": + version: 1.22.1 + resolution: "lightningcss-win32-x64-msvc@npm:1.22.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"lightningcss@npm:^1.16.1": - version: 1.22.0 - resolution: "lightningcss@npm:1.22.0" +"lightningcss@npm:^1.22.1": + version: 1.22.1 + resolution: "lightningcss@npm:1.22.1" dependencies: detect-libc: ^1.0.3 - lightningcss-darwin-arm64: 1.22.0 - lightningcss-darwin-x64: 1.22.0 - lightningcss-freebsd-x64: 1.22.0 - lightningcss-linux-arm-gnueabihf: 1.22.0 - lightningcss-linux-arm64-gnu: 1.22.0 - lightningcss-linux-arm64-musl: 1.22.0 - lightningcss-linux-x64-gnu: 1.22.0 - lightningcss-linux-x64-musl: 1.22.0 - lightningcss-win32-x64-msvc: 1.22.0 + lightningcss-darwin-arm64: 1.22.1 + lightningcss-darwin-x64: 1.22.1 + lightningcss-freebsd-x64: 1.22.1 + lightningcss-linux-arm-gnueabihf: 1.22.1 + lightningcss-linux-arm64-gnu: 1.22.1 + lightningcss-linux-arm64-musl: 1.22.1 + lightningcss-linux-x64-gnu: 1.22.1 + lightningcss-linux-x64-musl: 1.22.1 + lightningcss-win32-x64-msvc: 1.22.1 dependenciesMeta: lightningcss-darwin-arm64: optional: true @@ -18122,7 +18132,7 @@ __metadata: optional: true lightningcss-win32-x64-msvc: optional: true - checksum: 6b9a04846243a2161ac12ee098f9c2143a1a06fb683228ef0433473257751a709b0bafa195efa8d3d8f1556ca60c54f5434caeb172874a8daced552dedcbed93 + checksum: 75319e14cae842f92d2d3fbf3c7616ef427298fc3bd010bc644eb67c21af93debc2dff5dcf67b6dcf0eab0ca6c073bc670805bba1977cf3423d0da766e15caf3 languageName: node linkType: hard @@ -19806,7 +19816,7 @@ __metadata: graphql: ^16.6.0 graphql-ws: ^5.11.2 neo4j-driver: ^5.8.0 - parcel: 2.10.3 + parcel: 2.11.0 rimraf: ^5.0.0 urql: ^4.0.0 wonka: ^6.1.1 @@ -20984,27 +20994,27 @@ __metadata: languageName: node linkType: hard -"parcel@npm:2.10.3": - version: 2.10.3 - resolution: "parcel@npm:2.10.3" +"parcel@npm:2.11.0": + version: 2.11.0 + resolution: "parcel@npm:2.11.0" dependencies: - "@parcel/config-default": 2.10.3 - "@parcel/core": 2.10.3 - "@parcel/diagnostic": 2.10.3 - "@parcel/events": 2.10.3 - "@parcel/fs": 2.10.3 - "@parcel/logger": 2.10.3 - "@parcel/package-manager": 2.10.3 - "@parcel/reporter-cli": 2.10.3 - "@parcel/reporter-dev-server": 2.10.3 - "@parcel/reporter-tracer": 2.10.3 - "@parcel/utils": 2.10.3 + "@parcel/config-default": 2.11.0 + "@parcel/core": 2.11.0 + "@parcel/diagnostic": 2.11.0 + "@parcel/events": 2.11.0 + "@parcel/fs": 2.11.0 + "@parcel/logger": 2.11.0 + "@parcel/package-manager": 2.11.0 + "@parcel/reporter-cli": 2.11.0 + "@parcel/reporter-dev-server": 2.11.0 + "@parcel/reporter-tracer": 2.11.0 + "@parcel/utils": 2.11.0 chalk: ^4.1.0 commander: ^7.0.0 get-port: ^4.2.0 bin: parcel: lib/bin.js - checksum: 3a277e8e85064227b2d3335520b272023b887df6ef4a8b56a145e00bec7c1fab581081bb0d9bdad026dc4fee64e622ae6386da2d34cc716e7a83ad97ac970100 + checksum: 1990c725049161755c3556effc8d940fb6d05edfd2f2a74bb507d0d9bdd17d2e6d73ac45d1ded9ff31d94549a364cd109c2827de6a0a956e672aa0999f283879 languageName: node linkType: hard From b2b750d345e9949f852db5542a9e72264f47fdee Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:28:59 +0100 Subject: [PATCH 109/136] build: pin codemirror resolutions (#4481) --- package.json | 4 ++++ yarn.lock | 22 ++-------------------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 61645fa2594..673822eab3b 100644 --- a/package.json +++ b/package.json @@ -55,5 +55,9 @@ "dependencies": { "@changesets/changelog-github": "0.5.0", "@changesets/cli": "2.27.1" + }, + "resolutions": { + "@codemirror/view": "6.23.0", + "@codemirror/state": "6.4.0" } } diff --git a/yarn.lock b/yarn.lock index 877160f92d0..3b4485d3175 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1824,32 +1824,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.1.4, @codemirror/state@npm:^6.2.0": - version: 6.2.1 - resolution: "@codemirror/state@npm:6.2.1" - checksum: d12a321d0471b264b9d3259042bff913a8b939e8d28d408ff452004538a71ca9d5329df3f8a1d8a9183f5b42a7ef5b200737bcab1065714f5ae8e0a5ba9d59d3 - languageName: node - linkType: hard - -"@codemirror/state@npm:^6.4.0": +"@codemirror/state@npm:6.4.0": version: 6.4.0 resolution: "@codemirror/state@npm:6.4.0" checksum: c5236fe5786f1b85d17273a5c17fa8aeb063658c1404ab18caeb6e7591663ec96b65d453ab8162f75839c3801b04cd55ba4bc48f44cb61ebfeeee383f89553c7 languageName: node linkType: hard -"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.9.0": - version: 6.20.2 - resolution: "@codemirror/view@npm:6.20.2" - dependencies: - "@codemirror/state": ^6.1.4 - style-mod: ^4.1.0 - w3c-keyname: ^2.2.4 - checksum: eaf47726bb94b40f12c6f1d3494b558addaa7cd98a4ff05bfea7439c03cca3967d73380346ea8b06021478c21ec336a74665c9acb44e2b0280d5e0da4714387b - languageName: node - linkType: hard - -"@codemirror/view@npm:^6.23.0": +"@codemirror/view@npm:6.23.0": version: 6.23.0 resolution: "@codemirror/view@npm:6.23.0" dependencies: From 760d5984be729b2745ef50a73c0e079d4a77811b Mon Sep 17 00:00:00 2001 From: MacondoExpress Date: Fri, 5 Jan 2024 14:54:23 +0000 Subject: [PATCH 110/136] Fix 4450 (#4482) * test: add regression tests for 4450 * bug fix 4450 --------- Co-authored-by: Michael Webb --- .../queryAST/ast/filters/ConnectionFilter.ts | 37 +++--- .../tests/integration/issues/4450.int.test.ts | 115 ++++++++++++++++++ .../graphql/tests/tck/issues/4450.test.ts | 83 +++++++++++++ 3 files changed, 218 insertions(+), 17 deletions(-) create mode 100644 packages/graphql/tests/integration/issues/4450.int.test.ts create mode 100644 packages/graphql/tests/tck/issues/4450.test.ts diff --git a/packages/graphql/src/translate/queryAST/ast/filters/ConnectionFilter.ts b/packages/graphql/src/translate/queryAST/ast/filters/ConnectionFilter.ts index 879772cc44f..07b4aca95b5 100644 --- a/packages/graphql/src/translate/queryAST/ast/filters/ConnectionFilter.ts +++ b/packages/graphql/src/translate/queryAST/ast/filters/ConnectionFilter.ts @@ -107,23 +107,25 @@ export class ConnectionFilter extends Filter { public getPredicate(queryASTContext: QueryASTContext): Cypher.Predicate | undefined { if (!hasTarget(queryASTContext)) throw new Error("No parent node found!"); - if (this.subqueryPredicate) return this.subqueryPredicate; - else { - const target = this.getTargetNode(queryASTContext); - const relationship = new Cypher.Relationship({ - type: this.relationship.type, - }); + if (this.subqueryPredicate) { + return this.subqueryPredicate; + } - const pattern = new Cypher.Pattern(queryASTContext.target) - .withoutLabels() - .related(relationship) - .withDirection(this.relationship.getCypherDirection()) - .to(target); + const target = this.getTargetNode(queryASTContext); + const relationship = new Cypher.Relationship({ + type: this.relationship.type, + }); - const nestedContext = queryASTContext.push({ target, relationship }); + const pattern = new Cypher.Pattern(queryASTContext.target) + .withoutLabels() + .related(relationship) + .withDirection(this.relationship.getCypherDirection()) + .to(target); + + const nestedContext = queryASTContext.push({ target, relationship }); - const predicate = this.createRelationshipOperation(pattern, nestedContext); - if (!predicate) return undefined; + const predicate = this.createRelationshipOperation(pattern, nestedContext); + if (predicate) { return this.wrapInNotIfNeeded(predicate); } } @@ -202,14 +204,15 @@ export class ConnectionFilter extends Filter { const nestedSubqueries = f .getSubqueries(queryASTContext) .map((sq) => new Cypher.Call(sq).innerWith(queryASTContext.target)); - + const selection = f.getSelection(queryASTContext); const predicate = f.getPredicate(queryASTContext); + const clauses = [...selection, ...nestedSubqueries]; if (predicate) { innerFiltersPredicates.push(predicate); - return nestedSubqueries; + return clauses; } - return nestedSubqueries; + return clauses; }); if (subqueries.length === 0) return []; // Hack logic to change predicates logic diff --git a/packages/graphql/tests/integration/issues/4450.int.test.ts b/packages/graphql/tests/integration/issues/4450.int.test.ts new file mode 100644 index 00000000000..349f0b73faa --- /dev/null +++ b/packages/graphql/tests/integration/issues/4450.int.test.ts @@ -0,0 +1,115 @@ +/* + * 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 { graphql } from "graphql"; +import type { Driver } from "neo4j-driver"; +import { Neo4jGraphQL } from "../../../src/classes"; +import { cleanNodes } from "../../utils/clean-nodes"; +import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; + +describe("https://github.com/neo4j/graphql/issues/4450", () => { + let driver: Driver; + let neo4j: Neo4j; + let neo4jGraphql: Neo4jGraphQL; + + const Actor = new UniqueType("Actor"); + const Scene = new UniqueType("Scene"); + const Location = new UniqueType("Location"); + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + const typeDefs = /* GraphQL */ ` + type ${Actor} { + name: String + scene: [${Scene}!]! @relationship(type: "IN_SCENE", properties: "ActorScene", direction: OUT) + } + + type ${Scene} { + number: Int + actors: [${Actor}!]! @relationship(type: "IN_SCENE", properties: "ActorScene", direction: IN) + location: ${Location}! @relationship(type: "AT_LOCATION", direction: OUT) + } + + type ${Location} { + city: String + scenes: [${Scene}!]! @relationship(type: "AT_LOCATION", direction: IN) + } + + interface ActorScene @relationshipProperties { + cut: Boolean + } + `; + + neo4jGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + }); + + const session = await neo4j.getSession(); + try { + await session.run( + ` + CREATE (:${Actor} {name: "actor-1"})-[:IN_SCENE {cut: true}]->(:${Scene} {number: 1})-[:AT_LOCATION]->(:${Location} {city: "test"}) + `, + {} + ); + } finally { + await session.close(); + } + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + try { + await cleanNodes(session, [Actor, Scene, Location]); + } finally { + await session.close(); + } + await driver.close(); + }); + + test("filtering through a connection to a many-to-1 relationship should work", async () => { + const schema = await neo4jGraphql.getSchema(); + + const query = /* GraphQL */ ` + query { + ${Actor.plural}(where: { sceneConnection_SOME: { edge: { cut: true }, node: { location: { city: "test" } } } }) { + name + } + } + `; + + const response = await graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues(), + }); + + expect(response.errors).toBeFalsy(); + expect(response.data).toEqual({ + [Actor.plural]: [ + { + name: "actor-1", + }, + ], + }); + }); +}); diff --git a/packages/graphql/tests/tck/issues/4450.test.ts b/packages/graphql/tests/tck/issues/4450.test.ts new file mode 100644 index 00000000000..14d0657c675 --- /dev/null +++ b/packages/graphql/tests/tck/issues/4450.test.ts @@ -0,0 +1,83 @@ +/* + * 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 gql from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; + +describe("https://github.com/neo4j/graphql/issues/4450", () => { + test("filtering through a connection to a many-to-1 relationship should work", async () => { + const typeDefs = /* GraphQL */ ` + type Actor { + name: String + scene: [Scene!]! @relationship(type: "IN_SCENE", properties: "ActorScene", direction: OUT) + } + + type Scene { + number: Int + actors: [Actor!]! @relationship(type: "IN_SCENE", properties: "ActorScene", direction: IN) + location: Location! @relationship(type: "AT_LOCATION", direction: OUT) + } + + type Location { + city: String + scenes: [Scene!]! @relationship(type: "AT_LOCATION", direction: IN) + } + + interface ActorScene @relationshipProperties { + cut: Boolean + } + `; + + const neoSchema = new Neo4jGraphQL({ typeDefs }); + + const query = gql` + query { + actors(where: { sceneConnection_SOME: { edge: { cut: true }, node: { location: { city: "test" } } } }) { + name + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Actor) + CALL { + WITH this + MATCH (this)-[this0:IN_SCENE]->(this1:Scene) + OPTIONAL MATCH (this1)-[:AT_LOCATION]->(this2:Location) + WITH *, count(this2) AS locationCount + WITH * + WHERE ((locationCount <> 0 AND this2.city = $param0) AND this0.cut = $param1) + RETURN count(this1) > 0 AS var3 + } + WITH * + WHERE var3 = true + RETURN this { .name } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": \\"test\\", + \\"param1\\": true + }" + `); + }); +}); From b2ecdf9a31319fb9d8cc7b56d48d0610c0fe034a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jan 2024 22:28:13 +0000 Subject: [PATCH 111/136] chore(deps): update dependency tailwindcss to v3.4.1 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 8f48b5d032a..4fa6961e98b 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -95,7 +95,7 @@ "postcss-loader": "7.3.4", "randomstring": "1.3.0", "style-loader": "3.3.3", - "tailwindcss": "3.4.0", + "tailwindcss": "3.4.1", "terser-webpack-plugin": "5.3.10", "ts-jest": "29.1.1", "ts-loader": "9.5.1", diff --git a/yarn.lock b/yarn.lock index 3b4485d3175..9897c744518 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3685,7 +3685,7 @@ __metadata: react: 18.2.0 react-dom: 18.2.0 style-loader: 3.3.3 - tailwindcss: 3.4.0 + tailwindcss: 3.4.1 terser-webpack-plugin: 5.3.10 thememirror: 2.0.1 ts-jest: 29.1.1 @@ -24826,9 +24826,9 @@ __metadata: languageName: node linkType: hard -"tailwindcss@npm:3.4.0": - version: 3.4.0 - resolution: "tailwindcss@npm:3.4.0" +"tailwindcss@npm:3.4.1": + version: 3.4.1 + resolution: "tailwindcss@npm:3.4.1" dependencies: "@alloc/quick-lru": ^5.2.0 arg: ^5.0.2 @@ -24855,7 +24855,7 @@ __metadata: bin: tailwind: lib/cli.js tailwindcss: lib/cli.js - checksum: d7f05beb1cf98d169b9b65ef674a82dd16c97757194f9bacee4c536cf74f3852e0008a74f7af8578f4a1e9639fac262fd8ef89efe3e6e06667243640422f9462 + checksum: ef5a587dd32bb4e91e1549ead6162f85f0b78d3e6ffd8b4e8eeb15585b7b886cb3af6ae9df5092ed8ccb7e590608d1b3eec79ca08c862b07cd9ff7e72f73104b languageName: node linkType: hard From 90cbad53728f5fda05f65692e40d41b4670ae4d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:18:12 +0000 Subject: [PATCH 112/136] chore(deps): update rabbitmq docker digest to 56fea74 --- .../workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml index 67bc30eed58..d109de47507 100644 --- a/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml +++ b/.github/workflows/reusable-subscriptions-plugin-amqp-e2e-test.yml @@ -26,7 +26,7 @@ jobs: ports: - 7687:7687 rabbitmq: - image: rabbitmq@sha256:529bd70467c60aca125a854b29248e61a71a5072085b4668d357d339858cc6d1 + image: rabbitmq@sha256:56fea741980800b4e4a6db474372bed284c93dad0db2da4c982ad4b163dcb341 env: RABBITMQ_DEFAULT_USER: guest RABBITMQ_DEFAULT_PASS: guest From 3abd947b01d3768468f7bbd9412813811b1f3c82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 13:27:41 +0000 Subject: [PATCH 113/136] chore(deps): update rabbitmq:3.12-management docker digest to a44ba5a --- examples/neo-place/docker-compose.yml | 2 +- examples/subscriptions/apollo_rabbitmq/docker-compose.yml | 2 +- packages/graphql-amqp-subscriptions-engine/docker-compose.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/neo-place/docker-compose.yml b/examples/neo-place/docker-compose.yml index ebd321a3f4e..9cfd8faac57 100644 --- a/examples/neo-place/docker-compose.yml +++ b/examples/neo-place/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:67800420b0fe13b3a39ec14bc11e5d65ebdf9d353dbb02592b092db435950007 + image: rabbitmq:3.12-management@sha256:a44ba5a23397c3d84f8639f1adc037555541877df8fd370ef460133548e21b36 ports: - "5672:5672" - "15672:15672" diff --git a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml index ebd321a3f4e..9cfd8faac57 100644 --- a/examples/subscriptions/apollo_rabbitmq/docker-compose.yml +++ b/examples/subscriptions/apollo_rabbitmq/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.5' services: rabbitmq: - image: rabbitmq:3.12-management@sha256:67800420b0fe13b3a39ec14bc11e5d65ebdf9d353dbb02592b092db435950007 + image: rabbitmq:3.12-management@sha256:a44ba5a23397c3d84f8639f1adc037555541877df8fd370ef460133548e21b36 ports: - "5672:5672" - "15672:15672" diff --git a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml index 79276bd9771..23eb5dfbea2 100644 --- a/packages/graphql-amqp-subscriptions-engine/docker-compose.yml +++ b/packages/graphql-amqp-subscriptions-engine/docker-compose.yml @@ -2,7 +2,7 @@ version: '3.5' # This is just for local testing services: rabbitmq: - image: rabbitmq:3.12-management@sha256:67800420b0fe13b3a39ec14bc11e5d65ebdf9d353dbb02592b092db435950007 + image: rabbitmq:3.12-management@sha256:a44ba5a23397c3d84f8639f1adc037555541877df8fd370ef460133548e21b36 ports: - "5672:5672" - "15672:15672" From c399bd832e5c85c3ea8d98f1f250e653a457af3f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:36:56 +0000 Subject: [PATCH 114/136] chore(deps): update typescript-eslint monorepo to v6.18.0 --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 673822eab3b..8cb6c3582a2 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.17.0", - "@typescript-eslint/parser": "6.17.0", + "@typescript-eslint/eslint-plugin": "6.18.0", + "@typescript-eslint/parser": "6.18.0", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.56.0", diff --git a/yarn.lock b/yarn.lock index 9897c744518..18c96fffadb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7949,15 +7949,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.17.0" +"@typescript-eslint/eslint-plugin@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.18.0" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.17.0 - "@typescript-eslint/type-utils": 6.17.0 - "@typescript-eslint/utils": 6.17.0 - "@typescript-eslint/visitor-keys": 6.17.0 + "@typescript-eslint/scope-manager": 6.18.0 + "@typescript-eslint/type-utils": 6.18.0 + "@typescript-eslint/utils": 6.18.0 + "@typescript-eslint/visitor-keys": 6.18.0 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7970,25 +7970,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 169646a705fdd1bc2a0d78678dbf3557ff3e534e9d4a11f7b5bba1d9f5cbec821f8c16b260413203efc8d6e0c0a3d7f9332bb1476e3dac80e60aa16eb9a0ad11 + checksum: a0e946c03b3d55326fa2f090341c57063670d654ab3681f48e88af940d2ee843bd4d124655e27820ae284b705232ecfc0665ad39ace95d5210c04ee66d57d58d languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/parser@npm:6.17.0" +"@typescript-eslint/parser@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/parser@npm:6.18.0" dependencies: - "@typescript-eslint/scope-manager": 6.17.0 - "@typescript-eslint/types": 6.17.0 - "@typescript-eslint/typescript-estree": 6.17.0 - "@typescript-eslint/visitor-keys": 6.17.0 + "@typescript-eslint/scope-manager": 6.18.0 + "@typescript-eslint/types": 6.18.0 + "@typescript-eslint/typescript-estree": 6.18.0 + "@typescript-eslint/visitor-keys": 6.18.0 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: c48864aebf364332540f520d84630a6bb3e2ddc84492d75c14a453964b669a37f1fd43b60469e3683e618e8e8d3d7747baffe92e408599d5df6869cae86ac9e1 + checksum: 2f9eb1b8f142cb191de6a6f34b913df1c09ea66bb09bd92c201e28fe84b6f3c13cbed3469c94d498e96ea06349b643632bb693dcf27b85908d7221b58c24bcff languageName: node linkType: hard @@ -8002,22 +8002,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/scope-manager@npm:6.17.0" +"@typescript-eslint/scope-manager@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/scope-manager@npm:6.18.0" dependencies: - "@typescript-eslint/types": 6.17.0 - "@typescript-eslint/visitor-keys": 6.17.0 - checksum: 6eabac1e52cd25714ab176c7bbf9919d065febf4580620eb067ab1b41607f5e592857bd831a2ab41daa873af4011217dbcae55ed248855e381127f1cabcd2d2c + "@typescript-eslint/types": 6.18.0 + "@typescript-eslint/visitor-keys": 6.18.0 + checksum: 9958dcd95605b9699e1fe823cc38869d542f2cb90cde443938c1352de4161703ed6619e772bc12b8b7df2a44623ebf1e6b2b8d1222e5df22880185d0652040ee languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/type-utils@npm:6.17.0" +"@typescript-eslint/type-utils@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/type-utils@npm:6.18.0" dependencies: - "@typescript-eslint/typescript-estree": 6.17.0 - "@typescript-eslint/utils": 6.17.0 + "@typescript-eslint/typescript-estree": 6.18.0 + "@typescript-eslint/utils": 6.18.0 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8025,7 +8025,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: bb6f824c1c7f8d25a21b7218a5bcb74e58c38121f85418eb1639f2931c6149285c2ede96dd677a3e7dc64886cc7640d74be6001d970c3ac9c9a4d889315c5d15 + checksum: 537b2f0b85c4225538a14e5030fc25c3f6ea610ea59dd9ac25e59a2aadd01344e2b154fcd5ab2245d055d977e4ff2b7ab30369f28eb78b6059702a2899fbdd3c languageName: node linkType: hard @@ -8036,10 +8036,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/types@npm:6.17.0" - checksum: a199516230b505f85de1b99cdf22c526cbae7604fa2dd0dd24e8bba5de45aeaee231263e7e59843af7b226cb91c4ba5447d06517a1a73b511a94c6b483af0d5b +"@typescript-eslint/types@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/types@npm:6.18.0" + checksum: 516ad2feb7e7c7b5aac805b287be794e6e42371bc6a5bdd7c9fc230d98bbbcc4877c96377ccce68aede68ec58a64ef9d1e4c5b15cfb55e9a050bafe7b36624c1 languageName: node linkType: hard @@ -8061,12 +8061,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.17.0" +"@typescript-eslint/typescript-estree@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.18.0" dependencies: - "@typescript-eslint/types": 6.17.0 - "@typescript-eslint/visitor-keys": 6.17.0 + "@typescript-eslint/types": 6.18.0 + "@typescript-eslint/visitor-keys": 6.18.0 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8076,24 +8076,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 4bf7811ddae66361cad55f7a6fcf9975eb77456ceb2eca5d7a6228387737845bdfe1b9eef4c76d5d6b7c7d6029a8f62bc67b509c0724cd37395ae16eb07dd7ab + checksum: 64afa0a81af66dfcb1d3027872abc07451691dff956c8b3174da675307050404c720465be5322490859d633e76705fd5e0fd5f040aa4cc1078bd837281e52065 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/utils@npm:6.17.0" +"@typescript-eslint/utils@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/utils@npm:6.18.0" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.17.0 - "@typescript-eslint/types": 6.17.0 - "@typescript-eslint/typescript-estree": 6.17.0 + "@typescript-eslint/scope-manager": 6.18.0 + "@typescript-eslint/types": 6.18.0 + "@typescript-eslint/typescript-estree": 6.18.0 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 2eea8fd3763b2ab9d86503c68b4d61df81071fd38851b8ba920d53b055c352d13e192a3d15ca853f11aee818c61e8af65946e963aa0e9b18d19e3254881bded0 + checksum: 5c8ab14838d5dcc857de43781687b105d972941bd4a08e63d14b6485a3944a77c867c162f14eca9ef526170b26423a0d4a828a0b22d88cb34f99835233152dff languageName: node linkType: hard @@ -8125,13 +8125,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.17.0": - version: 6.17.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.17.0" +"@typescript-eslint/visitor-keys@npm:6.18.0": + version: 6.18.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.18.0" dependencies: - "@typescript-eslint/types": 6.17.0 + "@typescript-eslint/types": 6.18.0 eslint-visitor-keys: ^3.4.1 - checksum: e98755087bd067388d9a9182375e53f590183ca656d02b3d05d9718bab2ac571832fd16691060c7c979fd941e9d4b7923d8975632923697de0691f50fc97c8ac + checksum: d6b1958867f3287c4e2c4f80633346a676060181e27ef69a1aad68634c62311738a3aad49e61c1d30d8e31800de146424ca8b33483d033132d90bf0c2f31cac8 languageName: node linkType: hard @@ -19871,8 +19871,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.17.0 - "@typescript-eslint/parser": 6.17.0 + "@typescript-eslint/eslint-plugin": 6.18.0 + "@typescript-eslint/parser": 6.18.0 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.56.0 From b0dbaae07564d58614eb6a84f89f1e4f0b576fab Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 7 Jan 2024 18:39:38 +0000 Subject: [PATCH 115/136] chore(deps): update dependency @types/node to v20.10.7 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- packages/introspector/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index c230c5183bb..b3cc5861ec1 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -40,7 +40,7 @@ "@types/cors": "2.8.17", "@types/debug": "4.1.12", "@types/jest": "29.5.11", - "@types/node": "20.10.6", + "@types/node": "20.10.7", "camelcase": "6.3.0", "graphql-ws": "5.14.3", "jest": "29.7.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index e375d2c8262..15092c0579e 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -56,7 +56,7 @@ "@types/is-uuid": "1.0.2", "@types/jest": "29.5.11", "@types/jsonwebtoken": "9.0.5", - "@types/node": "20.10.6", + "@types/node": "20.10.7", "@types/pluralize": "0.0.33", "@types/randomstring": "1.1.11", "@types/semver": "7.5.6", diff --git a/packages/introspector/package.json b/packages/introspector/package.json index ae6b85981b6..c0feaed102d 100644 --- a/packages/introspector/package.json +++ b/packages/introspector/package.json @@ -38,7 +38,7 @@ "devDependencies": { "@neo4j/graphql": "^4.0.0", "@types/jest": "29.5.11", - "@types/node": "20.10.6", + "@types/node": "20.10.7", "@types/pluralize": "0.0.33", "jest": "29.7.0", "ts-jest": "29.1.1", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index 68b0cfeda85..bed6913b782 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@types/jest": "29.5.11", - "@types/node": "20.10.6", + "@types/node": "20.10.7", "camelcase": "6.3.0", "graphql-tag": "2.12.6", "jest": "29.7.0", diff --git a/yarn.lock b/yarn.lock index 18c96fffadb..805d8326dc2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3584,7 +3584,7 @@ __metadata: "@types/cors": 2.8.17 "@types/debug": 4.1.12 "@types/jest": 29.5.11 - "@types/node": 20.10.6 + "@types/node": 20.10.7 amqplib: 0.10.3 body-parser: ^1.20.2 camelcase: 6.3.0 @@ -3613,7 +3613,7 @@ __metadata: "@graphql-tools/merge": ^9.0.0 "@neo4j/graphql": ^4.4.4 "@types/jest": 29.5.11 - "@types/node": 20.10.6 + "@types/node": 20.10.7 camelcase: 6.3.0 graphql-tag: 2.12.6 jest: 29.7.0 @@ -3718,7 +3718,7 @@ __metadata: "@types/is-uuid": 1.0.2 "@types/jest": 29.5.11 "@types/jsonwebtoken": 9.0.5 - "@types/node": 20.10.6 + "@types/node": 20.10.7 "@types/pluralize": 0.0.33 "@types/randomstring": 1.1.11 "@types/semver": 7.5.6 @@ -3775,7 +3775,7 @@ __metadata: dependencies: "@neo4j/graphql": ^4.0.0 "@types/jest": 29.5.11 - "@types/node": 20.10.6 + "@types/node": 20.10.7 "@types/pluralize": 0.0.33 camelcase: ^6.3.0 debug: ^4.3.4 @@ -7650,12 +7650,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.10.6": - version: 20.10.6 - resolution: "@types/node@npm:20.10.6" +"@types/node@npm:20.10.7": + version: 20.10.7 + resolution: "@types/node@npm:20.10.7" dependencies: undici-types: ~5.26.4 - checksum: ada40e4ccbda3697dca88f8d13f4c996c493be6fbc15f5f5d3b91096d56bd700786a2c148a92a2b4c5d1f133379e63f754a786b3aebfc6a7d09fc7ea16dc017b + checksum: 86f4f96f5169538f47bbd652ab8e3712cd307701481ff3e9ce0c1ea7d8424a38b5ac4a1d33088cdd9ea1bfe68fd27bbae005a21969aa6d9a36295904da6f09f2 languageName: node linkType: hard From d7263edf7aa3bef03172500543c653b976372fe9 Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:43:54 +0100 Subject: [PATCH 116/136] build: quality gate runs even on skipped jobs (#4489) --- .github/workflows/pull-requests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index dd6b460485a..867125873db 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -89,6 +89,7 @@ jobs: uses: ./.github/workflows/reusable-federation-tests.yml quality-gate: + if: ${{ !(failure() || cancelled()) }} needs: - reviewdog-eslint - code-scanning From 4b97531170c399f243ee848c17a8e38a80e14a51 Mon Sep 17 00:00:00 2001 From: Darrell Warde <8117355+darrellwarde@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:13:56 +0000 Subject: [PATCH 117/136] Fix authorization variable naming for create operations (#4483) * add tck and int tests * Implement fix * Add changeset --------- Co-authored-by: a-alle --- .changeset/two-phones-look.md | 5 + .../src/translate/create-create-and-params.ts | 30 +- .../tests/integration/issues/4429.int.test.ts | 227 ++++++++++ .../implementation-bind.test.ts | 6 +- .../arguments/roles-where.test.ts | 36 +- .../arguments/where/where.test.ts | 12 +- .../graphql/tests/tck/issues/3901.test.ts | 24 +- .../graphql/tests/tck/issues/4118.test.ts | 46 +- .../graphql/tests/tck/issues/4170.test.ts | 34 +- .../graphql/tests/tck/issues/4214.test.ts | 56 +-- .../graphql/tests/tck/issues/4223.test.ts | 44 +- .../graphql/tests/tck/issues/4429.test.ts | 399 ++++++++++++++++++ .../batch/batch-create-auth.test.ts | 12 +- 13 files changed, 771 insertions(+), 160 deletions(-) create mode 100644 .changeset/two-phones-look.md create mode 100644 packages/graphql/tests/integration/issues/4429.int.test.ts create mode 100644 packages/graphql/tests/tck/issues/4429.test.ts diff --git a/.changeset/two-phones-look.md b/.changeset/two-phones-look.md new file mode 100644 index 00000000000..d5c76c39f48 --- /dev/null +++ b/.changeset/two-phones-look.md @@ -0,0 +1,5 @@ +--- +"@neo4j/graphql": patch +--- + +Fix authorization variable naming in create operations diff --git a/packages/graphql/src/translate/create-create-and-params.ts b/packages/graphql/src/translate/create-create-and-params.ts index c363e2a108d..76adb7c889c 100644 --- a/packages/graphql/src/translate/create-create-and-params.ts +++ b/packages/graphql/src/translate/create-create-and-params.ts @@ -63,12 +63,7 @@ function createCreateAndParams({ withVars, includeRelationshipValidation, topLevelNodeVariable, - authorizationPrefix = { - inputIndex: 0, - reducerIndex: 0, - createIndex: 0, - refNodeIndex: 0, - }, + authorizationPrefix = [0], }: { input: any; varName: string; @@ -79,12 +74,7 @@ function createCreateAndParams({ includeRelationshipValidation?: boolean; topLevelNodeVariable?: string; //used to build authorization variable in auth subqueries - authorizationPrefix?: { - inputIndex: number; // index of the input - reducerIndex: number; // index of the reducer in the context of the input - createIndex: number; // index of the create in the context of a run of the reducer - refNodeIndex: number; // when a relationship is to an abstract type, this is the index of the refNode in the context of a run of the reducer - }; + authorizationPrefix?: number[]; }): CreateAndParams { const conflictingProperties = findConflictingProperties({ node, input }); if (conflictingProperties.length > 0) { @@ -169,12 +159,7 @@ function createCreateAndParams({ withVars: [...withVars, nodeName], includeRelationshipValidation: false, topLevelNodeVariable, - authorizationPrefix: { - inputIndex: authorizationPrefix.inputIndex + 1, - reducerIndex, - createIndex, - refNodeIndex, - }, + authorizationPrefix: [...authorizationPrefix, reducerIndex, createIndex, refNodeIndex], }); res.creates.push(nestedCreate); res.params = { ...res.params, ...params }; @@ -408,13 +393,8 @@ function createCreateAndParams({ return { create: creates.join("\n"), params, authorizationPredicates, authorizationSubqueries }; } -function makeAuthorizationParamsPrefix(authorizationPrefix: { - inputIndex: number; - reducerIndex: number; - createIndex: number; - refNodeIndex: number; -}): string { - return `${authorizationPrefix.inputIndex}_${authorizationPrefix.reducerIndex}_${authorizationPrefix.refNodeIndex}_${authorizationPrefix.createIndex}_`; +function makeAuthorizationParamsPrefix(authorizationPrefix: number[]): string { + return `${authorizationPrefix.join("_")}_`; } export default createCreateAndParams; diff --git a/packages/graphql/tests/integration/issues/4429.int.test.ts b/packages/graphql/tests/integration/issues/4429.int.test.ts new file mode 100644 index 00000000000..0026ec8040f --- /dev/null +++ b/packages/graphql/tests/integration/issues/4429.int.test.ts @@ -0,0 +1,227 @@ +/* + * 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 { Driver } from "neo4j-driver"; +import Neo4j from "../neo4j"; +import { Neo4jGraphQL } from "../../../src/classes"; +import { graphql } from "graphql"; +import { UniqueType } from "../../utils/graphql-types"; +import gql from "graphql-tag"; + +describe("https://github.com/neo4j/graphql/issues/4429", () => { + let driver: Driver; + let neo4j: Neo4j; + + const User = new UniqueType("User"); + const Tenant = new UniqueType("Tenant"); + const Settings = new UniqueType("Settings"); + const OpeningDay = new UniqueType("OpeningDay"); + const OpeningHoursInterval = new UniqueType("OpeningHoursInterval"); + + const typeDefs = gql` + type JWT @jwt { + id: String + roles: [String] + } + type ${User.name} @authorization(validate: [{ where: { node: { userId: "$jwt.id" } }, operations: [READ] }]) { + userId: String! @unique + adminAccess: [${Tenant.name}!]! @relationship(type: "ADMIN_IN", direction: OUT) + } + + type ${Tenant.name} @authorization(validate: [{ where: { node: { admins: { userId: "$jwt.id" } } } }]) { + id: ID! @id + settings: ${Settings.name}! @relationship(type: "VEHICLECARD_OWNER", direction: IN) + admins: [${User.name}!]! @relationship(type: "ADMIN_IN", direction: IN) + } + + type ${Settings.name} @authorization(validate: [{ where: { node: { tenant: { admins: { userId: "$jwt.id" } } } } }]) { + id: ID! @id + openingDays: [${OpeningDay.name}!]! @relationship(type: "VALID_GARAGES", direction: OUT) + tenant: ${Tenant.name}! @relationship(type: "VEHICLECARD_OWNER", direction: OUT) + } + + type ${OpeningDay.name} + @authorization( + validate: [{ where: { node: { settings: { tenant: { admins: { userId: "$jwt.id" } } } } } }] + ) { + id: ID! @id + settings: ${Settings.name} @relationship(type: "VALID_GARAGES", direction: IN) + open: [${OpeningHoursInterval.name}!]! @relationship(type: "HAS_OPEN_INTERVALS", direction: OUT) + } + + type ${OpeningHoursInterval.name} + @authorization( + validate: [ + { where: { node: { openingDay: { settings: { tenant: { admins: { userId: "$jwt.id" } } } } } } } + ] + ) { + name: String + openingDay: ${OpeningDay.name}! @relationship(type: "HAS_OPEN_INTERVALS", direction: IN) + createdAt: DateTime! @timestamp(operations: [CREATE]) + updatedAt: DateTime! @timestamp(operations: [CREATE, UPDATE]) + updatedBy: String + @populatedBy( + callback: "getUserIDFromContext" + operations: [CREATE, UPDATE] + ) + } + `; + + const ADD_TENANT = ` + mutation addTenant($input: [${Tenant.name}CreateInput!]!) { + ${Tenant.operations.create}(input: $input) { + ${Tenant.plural} { + id + admins { + userId + } + settings { + openingDays { + open { + name + } + } + } + } + } + } + `; + + let tenantVariables: Record; + let myUserId: string; + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + }); + + beforeEach(() => { + myUserId = Math.random().toString(36).slice(2, 7); + tenantVariables = { + input: { + admins: { + create: { + node: { + userId: myUserId, + }, + }, + }, + settings: { + create: { + node: { + openingDays: { + create: [ + { + node: { + open: { + create: [ + { + node: { + name: "hi", + }, + }, + ], + }, + }, + }, + { + node: { + open: { + create: [ + { + node: { + name: "hi", + }, + }, + { + node: { + name: "hi", + }, + }, + ], + }, + }, + }, + ], + }, + }, + }, + }, + }, + }; + }); + + afterEach(async () => { + const session = driver.session(); + await session.run(` match (n) detach delete n`); + await session.close(); + }); + + afterAll(async () => { + await driver.close(); + }); + test("create tenant with nested openingDays and openHoursInterval - subscriptions disabled", async () => { + const neo4jGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + features: { + populatedBy: { + callbacks: { + getUserIDFromContext: () => "hi", + }, + }, + }, + }); + const schema = await neo4jGraphql.getSchema(); + + const addTenantResponse = await graphql({ + schema, + source: ADD_TENANT, + variableValues: tenantVariables, + contextValue: neo4j.getContextValues({ jwt: { id: myUserId } }), + }); + + expect(addTenantResponse.errors).toBeUndefined(); + }); + + test("create tenant with nested openingDays and openHoursInterval - subscriptions enabled", async () => { + const neo4jGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + features: { + subscriptions: true, + populatedBy: { + callbacks: { + getUserIDFromContext: () => "hi", + }, + }, + }, + }); + const schema = await neo4jGraphql.getSchema(); + + const addTenantResponse = await graphql({ + schema, + source: ADD_TENANT, + variableValues: tenantVariables, + contextValue: neo4j.getContextValues({ jwt: { id: myUserId } }), + }); + + expect(addTenantResponse.errors).toBeUndefined(); + }); +}); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/bind/interface-relationships/implementation-bind.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/bind/interface-relationships/implementation-bind.test.ts index 9b1431e2a35..a0c6f8e72da 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/bind/interface-relationships/implementation-bind.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/bind/interface-relationships/implementation-bind.test.ts @@ -139,10 +139,10 @@ describe("Cypher Auth Allow", () => { RETURN c AS this0_contentPost0_node_creator_User_unique_ignored } WITH * - OPTIONAL MATCH (this0_contentPost0_node)<-[:HAS_CONTENT]-(authorization_1_2_1_0_after_this0:User) - WITH *, count(authorization_1_2_1_0_after_this0) AS creatorCount + OPTIONAL MATCH (this0_contentPost0_node)<-[:HAS_CONTENT]-(authorization_0_2_0_1_after_this0:User) + WITH *, count(authorization_0_2_0_1_after_this0) AS creatorCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0_contentPost0_node_creator0_node.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_1_2_1_0_after_this0.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0_contentPost0_node_creator0_node.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_2_0_1_after_this0.id = $jwt.sub))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts index d33b0a7e154..c28bcb379ec 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/roles-where.test.ts @@ -832,7 +832,7 @@ describe("Cypher Auth Where with Roles", () => { CALL { WITH this0 OPTIONAL MATCH (this0_posts_connect0_node:Post) - WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_0_0_0_before_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_0_0_0_before_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_before_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_before_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_before_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_before_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_before_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_before_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) CALL { WITH * WITH collect(this0_posts_connect0_node) as connectedNodes, collect(this0) as parentNodes @@ -845,11 +845,11 @@ describe("Cypher Auth Where with Roles", () => { } WITH this0, this0_posts_connect0_node WITH this0, this0_posts_connect0_node - WHERE (apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_0_0_0_after_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_after_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param4 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param5 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WHERE (apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_after_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_after_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_after_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param4 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param5 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) RETURN count(*) AS connect_this0_posts_connect_Post0 } WITH * - WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { @@ -871,12 +871,12 @@ describe("Cypher Auth Where with Roles", () => { ], \\"sub\\": \\"id-01\\" }, - \\"authorization_0_0_0_0_before_param2\\": \\"user\\", - \\"authorization_0_0_0_0_before_param3\\": \\"admin\\", - \\"authorization_0_0_0_0_after_param2\\": \\"user\\", - \\"authorization_0_0_0_0_after_param3\\": \\"admin\\", - \\"authorization_0_0_0_0_after_param4\\": \\"user\\", - \\"authorization_0_0_0_0_after_param5\\": \\"admin\\", + \\"authorization_0_before_param2\\": \\"user\\", + \\"authorization_0_before_param3\\": \\"admin\\", + \\"authorization_0_after_param2\\": \\"user\\", + \\"authorization_0_after_param3\\": \\"admin\\", + \\"authorization_0_after_param4\\": \\"user\\", + \\"authorization_0_after_param5\\": \\"admin\\", \\"resolvedCallbacks\\": {} }" `); @@ -917,7 +917,7 @@ describe("Cypher Auth Where with Roles", () => { CALL { WITH this0 OPTIONAL MATCH (this0_posts_connect0_node:Post) - WHERE this0_posts_connect0_node.id = $this0_posts_connect0_node_param0 AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_0_0_0_before_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_0_0_0_before_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_before_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE this0_posts_connect0_node.id = $this0_posts_connect0_node_param0 AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_before_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_before_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_before_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_before_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_before_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) CALL { WITH * WITH collect(this0_posts_connect0_node) as connectedNodes, collect(this0) as parentNodes @@ -930,11 +930,11 @@ describe("Cypher Auth Where with Roles", () => { } WITH this0, this0_posts_connect0_node WITH this0, this0_posts_connect0_node - WHERE (apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_0_0_0_after_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_after_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param4 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param5 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WHERE (apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND single(authorization_0_after_this0 IN [(this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_after_this0:User) WHERE ($jwt.sub IS NOT NULL AND authorization_0_after_this0.id = $jwt.sub) | 1] WHERE true) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param4 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param5 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) RETURN count(*) AS connect_this0_posts_connect_Post0 } WITH * - WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT (($isAuthenticated = true AND ($jwt.sub IS NOT NULL AND this0.id = $jwt.sub) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { @@ -957,12 +957,12 @@ describe("Cypher Auth Where with Roles", () => { ], \\"sub\\": \\"id-01\\" }, - \\"authorization_0_0_0_0_before_param2\\": \\"user\\", - \\"authorization_0_0_0_0_before_param3\\": \\"admin\\", - \\"authorization_0_0_0_0_after_param2\\": \\"user\\", - \\"authorization_0_0_0_0_after_param3\\": \\"admin\\", - \\"authorization_0_0_0_0_after_param4\\": \\"user\\", - \\"authorization_0_0_0_0_after_param5\\": \\"admin\\", + \\"authorization_0_before_param2\\": \\"user\\", + \\"authorization_0_before_param3\\": \\"admin\\", + \\"authorization_0_after_param2\\": \\"user\\", + \\"authorization_0_after_param3\\": \\"admin\\", + \\"authorization_0_after_param4\\": \\"user\\", + \\"authorization_0_after_param5\\": \\"admin\\", \\"resolvedCallbacks\\": {} }" `); diff --git a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts index 32307d0c14f..11f5d530161 100644 --- a/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts +++ b/packages/graphql/tests/tck/directives/authorization/arguments/where/where.test.ts @@ -824,10 +824,10 @@ describe("Cypher Auth Where", () => { CALL { WITH this0 OPTIONAL MATCH (this0_posts_connect0_node:Post) - OPTIONAL MATCH (this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_0_0_0_before_this0:User) - WITH *, count(authorization_0_0_0_0_before_this0) AS creatorCount + OPTIONAL MATCH (this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_before_this0:User) + WITH *, count(authorization_0_before_this0) AS creatorCount WITH * - WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_before_this0.id = $jwt.sub))) + WHERE ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_before_this0.id = $jwt.sub))) CALL { WITH * WITH collect(this0_posts_connect0_node) as connectedNodes, collect(this0) as parentNodes @@ -902,10 +902,10 @@ describe("Cypher Auth Where", () => { CALL { WITH this0 OPTIONAL MATCH (this0_posts_connect0_node:Post) - OPTIONAL MATCH (this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_0_0_0_before_this0:User) - WITH *, count(authorization_0_0_0_0_before_this0) AS creatorCount + OPTIONAL MATCH (this0_posts_connect0_node)<-[:HAS_POST]-(authorization_0_before_this0:User) + WITH *, count(authorization_0_before_this0) AS creatorCount WITH * - WHERE this0_posts_connect0_node.id = $this0_posts_connect0_node_param0 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_before_this0.id = $jwt.sub))) + WHERE this0_posts_connect0_node.id = $this0_posts_connect0_node_param0 AND ($isAuthenticated = true AND (creatorCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_before_this0.id = $jwt.sub))) CALL { WITH * WITH collect(this0_posts_connect0_node) as connectedNodes, collect(this0) as parentNodes diff --git a/packages/graphql/tests/tck/issues/3901.test.ts b/packages/graphql/tests/tck/issues/3901.test.ts index 459d5faed65..19d147c6717 100644 --- a/packages/graphql/tests/tck/issues/3901.test.ts +++ b/packages/graphql/tests/tck/issues/3901.test.ts @@ -167,17 +167,17 @@ describe("https://github.com/neo4j/graphql/issues/3901", () => { WITH * CALL { WITH this0_seasons0_node - MATCH (this0_seasons0_node)-[:SEASON_OF]->(authorization_1_1_0_0_after_this1:Serie) - OPTIONAL MATCH (authorization_1_1_0_0_after_this1)<-[:PUBLISHER]-(authorization_1_1_0_0_after_this2:User) - WITH *, count(authorization_1_1_0_0_after_this2) AS publisherCount + MATCH (this0_seasons0_node)-[:SEASON_OF]->(authorization_0_1_0_0_after_this1:Serie) + OPTIONAL MATCH (authorization_0_1_0_0_after_this1)<-[:PUBLISHER]-(authorization_0_1_0_0_after_this2:User) + WITH *, count(authorization_0_1_0_0_after_this2) AS publisherCount WITH * - WHERE (publisherCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_1_1_0_0_after_this2.id = $jwt.sub)) - RETURN count(authorization_1_1_0_0_after_this1) = 1 AS authorization_1_1_0_0_after_var0 + WHERE (publisherCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_1_0_0_after_this2.id = $jwt.sub)) + RETURN count(authorization_0_1_0_0_after_this1) = 1 AS authorization_0_1_0_0_after_var0 } - OPTIONAL MATCH (this0)<-[:PUBLISHER]-(authorization_0_0_0_0_after_this0:User) - WITH *, count(authorization_0_0_0_0_after_this0) AS publisherCount + OPTIONAL MATCH (this0)<-[:PUBLISHER]-(authorization_0_after_this0:User) + WITH *, count(authorization_0_after_this0) AS publisherCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (authorization_1_1_0_0_after_var0 = true AND ($jwt.roles IS NOT NULL AND $authorization_1_1_0_0_after_param2 IN $jwt.roles) AND ($jwt.roles IS NOT NULL AND $authorization_1_1_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ((publisherCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_0_0_0_after_this0.id = $jwt.sub)) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles) AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (authorization_0_1_0_0_after_var0 = true AND ($jwt.roles IS NOT NULL AND $authorization_0_1_0_0_after_param2 IN $jwt.roles) AND ($jwt.roles IS NOT NULL AND $authorization_0_1_0_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ((publisherCount <> 0 AND ($jwt.sub IS NOT NULL AND authorization_0_after_this0.id = $jwt.sub)) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles) AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { @@ -199,11 +199,11 @@ describe("https://github.com/neo4j/graphql/issues/3901", () => { \\"roles\\": [], \\"sub\\": \\"michel\\" }, - \\"authorization_1_1_0_0_after_param2\\": \\"verified\\", - \\"authorization_1_1_0_0_after_param3\\": \\"creator\\", + \\"authorization_0_1_0_0_after_param2\\": \\"verified\\", + \\"authorization_0_1_0_0_after_param3\\": \\"creator\\", \\"this0_publisher_connect0_node_param0\\": \\"ID\\", - \\"authorization_0_0_0_0_after_param2\\": \\"verified\\", - \\"authorization_0_0_0_0_after_param3\\": \\"creator\\", + \\"authorization_0_after_param2\\": \\"verified\\", + \\"authorization_0_after_param3\\": \\"creator\\", \\"resolvedCallbacks\\": {} }" `); diff --git a/packages/graphql/tests/tck/issues/4118.test.ts b/packages/graphql/tests/tck/issues/4118.test.ts index db800738d35..ddf5947ceb3 100644 --- a/packages/graphql/tests/tck/issues/4118.test.ts +++ b/packages/graphql/tests/tck/issues/4118.test.ts @@ -131,7 +131,7 @@ describe("https://github.com/neo4j/graphql/issues/2871", () => { CALL { WITH this0 OPTIONAL MATCH (this0_host_connect0_node:Tenant) - WHERE this0_host_connect0_node.id = $this0_host_connect0_node_param0 AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND size([(this0_host_connect0_node)<-[:ADMIN_IN]-(authorization_0_0_0_0_before_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_before_this0.userId = $jwt.id) | 1]) > 0) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param2 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE this0_host_connect0_node.id = $this0_host_connect0_node_param0 AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND size([(this0_host_connect0_node)<-[:ADMIN_IN]-(authorization_0_before_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_before_this0.userId = $jwt.id) | 1]) > 0) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_before_param2 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0]) CALL { WITH * WITH collect(this0_host_connect0_node) as connectedNodes, collect(this0) as parentNodes @@ -144,10 +144,10 @@ describe("https://github.com/neo4j/graphql/issues/2871", () => { } WITH this0, this0_host_connect0_node WITH * - OPTIONAL MATCH (this0)-[:HOSTED_BY]->(authorization_0_0_0_0_after_this1:Tenant) - WITH *, count(authorization_0_0_0_0_after_this1) AS hostCount + OPTIONAL MATCH (this0)-[:HOSTED_BY]->(authorization_0_after_this1:Tenant) + WITH *, count(authorization_0_after_this1) AS hostCount WITH * - WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (hostCount <> 0 AND size([(authorization_0_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND size([(this0_host_connect0_node)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this2:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this2.userId = $jwt.id) | 1]) > 0) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (hostCount <> 0 AND size([(authorization_0_after_this1)<-[:ADMIN_IN]-(authorization_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT (($isAuthenticated = true AND size([(this0_host_connect0_node)<-[:ADMIN_IN]-(authorization_0_after_this2:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this2.userId = $jwt.id) | 1]) > 0) OR ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) RETURN count(*) AS connect_this0_host_connect_Tenant0 } WITH * @@ -156,15 +156,15 @@ describe("https://github.com/neo4j/graphql/issues/2871", () => { OPTIONAL MATCH (this0_openingDays_connect0_node:OpeningDay) CALL { WITH this0_openingDays_connect0_node - MATCH (this0_openingDays_connect0_node)<-[:VALID_OPENING_DAYS]-(authorization_0_0_0_0_before_this1:Settings) - OPTIONAL MATCH (authorization_0_0_0_0_before_this1)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_before_this2:Tenant) - WITH *, count(authorization_0_0_0_0_before_this2) AS tenantCount + MATCH (this0_openingDays_connect0_node)<-[:VALID_OPENING_DAYS]-(authorization_0_before_this1:Settings) + OPTIONAL MATCH (authorization_0_before_this1)<-[:HAS_SETTINGS]-(authorization_0_before_this2:Tenant) + WITH *, count(authorization_0_before_this2) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_before_this2)<-[:ADMIN_IN]-(authorization_0_0_0_0_before_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_before_this3.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_0_0_0_0_before_this1) = 1 AS authorization_0_0_0_0_before_var0 + WHERE (tenantCount <> 0 AND size([(authorization_0_before_this2)<-[:ADMIN_IN]-(authorization_0_before_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_before_this3.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_before_this1) = 1 AS authorization_0_before_var0 } WITH * - WHERE this0_openingDays_connect0_node.id = $this0_openingDays_connect0_node_param0 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_before_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE this0_openingDays_connect0_node.id = $this0_openingDays_connect0_node_param0 AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_before_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) CALL { WITH * WITH collect(this0_openingDays_connect0_node) as connectedNodes, collect(this0) as parentNodes @@ -177,19 +177,19 @@ describe("https://github.com/neo4j/graphql/issues/2871", () => { } WITH this0, this0_openingDays_connect0_node WITH * - OPTIONAL MATCH (this0)-[:HOSTED_BY]->(authorization_0_0_0_0_after_this1:Tenant) - WITH *, count(authorization_0_0_0_0_after_this1) AS hostCount + OPTIONAL MATCH (this0)-[:HOSTED_BY]->(authorization_0_after_this1:Tenant) + WITH *, count(authorization_0_after_this1) AS hostCount CALL { WITH this0_openingDays_connect0_node - MATCH (this0_openingDays_connect0_node)<-[:VALID_OPENING_DAYS]-(authorization_0_0_0_0_after_this3:Settings) - OPTIONAL MATCH (authorization_0_0_0_0_after_this3)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_after_this4:Tenant) - WITH *, count(authorization_0_0_0_0_after_this4) AS tenantCount + MATCH (this0_openingDays_connect0_node)<-[:VALID_OPENING_DAYS]-(authorization_0_after_this3:Settings) + OPTIONAL MATCH (authorization_0_after_this3)<-[:HAS_SETTINGS]-(authorization_0_after_this4:Tenant) + WITH *, count(authorization_0_after_this4) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_after_this4)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this5:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this5.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_0_0_0_0_after_this3) = 1 AS authorization_0_0_0_0_after_var2 + WHERE (tenantCount <> 0 AND size([(authorization_0_after_this4)<-[:ADMIN_IN]-(authorization_0_after_this5:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this5.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_after_this3) = 1 AS authorization_0_after_var2 } WITH * - WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (hostCount <> 0 AND size([(authorization_0_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_after_var2 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (hostCount <> 0 AND size([(authorization_0_after_this1)<-[:ADMIN_IN]-(authorization_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_after_var2 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0])) RETURN count(*) AS connect_this0_openingDays_connect_OpeningDay0 } WITH * @@ -201,10 +201,10 @@ describe("https://github.com/neo4j/graphql/issues/2871", () => { RETURN c AS this0_host_Tenant_unique_ignored } WITH * - OPTIONAL MATCH (this0)-[:HOSTED_BY]->(authorization_0_0_0_0_after_this1:Tenant) - WITH *, count(authorization_0_0_0_0_after_this1) AS hostCount + OPTIONAL MATCH (this0)-[:HOSTED_BY]->(authorization_0_after_this1:Tenant) + WITH *, count(authorization_0_after_this1) AS hostCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (hostCount <> 0 AND size([(authorization_0_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (hostCount <> 0 AND size([(authorization_0_after_this1)<-[:ADMIN_IN]-(authorization_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { @@ -227,8 +227,8 @@ describe("https://github.com/neo4j/graphql/issues/2871", () => { \\"jwt\\": {}, \\"create_param2\\": \\"overlord\\", \\"this0_host_connect0_node_param0\\": \\"userid\\", - \\"authorization_0_0_0_0_before_param2\\": \\"overlord\\", - \\"authorization_0_0_0_0_after_param2\\": \\"overlord\\", + \\"authorization_0_before_param2\\": \\"overlord\\", + \\"authorization_0_after_param2\\": \\"overlord\\", \\"this0_openingDays_connect0_node_param0\\": \\"openingdayid\\", \\"resolvedCallbacks\\": {} }" diff --git a/packages/graphql/tests/tck/issues/4170.test.ts b/packages/graphql/tests/tck/issues/4170.test.ts index 1351b88f20b..54630bd594c 100644 --- a/packages/graphql/tests/tck/issues/4170.test.ts +++ b/packages/graphql/tests/tck/issues/4170.test.ts @@ -182,33 +182,33 @@ describe("https://github.com/neo4j/graphql/issues/4170", () => { WITH * CALL { WITH this0_settings0_node_openingDays0_node_open0_node - MATCH (this0_settings0_node_openingDays0_node_open0_node)<-[:HAS_OPEN_INTERVALS]-(authorization_3_0_0_0_after_this1:OpeningDay) + MATCH (this0_settings0_node_openingDays0_node_open0_node)<-[:HAS_OPEN_INTERVALS]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this1:OpeningDay) CALL { - WITH authorization_3_0_0_0_after_this1 - MATCH (authorization_3_0_0_0_after_this1)<-[:VALID_GARAGES]-(authorization_3_0_0_0_after_this2:Settings) - OPTIONAL MATCH (authorization_3_0_0_0_after_this2)<-[:HAS_SETTINGS]-(authorization_3_0_0_0_after_this3:Tenant) - WITH *, count(authorization_3_0_0_0_after_this3) AS tenantCount + WITH authorization_0_0_0_0_0_0_0_0_0_0_after_this1 + MATCH (authorization_0_0_0_0_0_0_0_0_0_0_after_this1)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this2:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_0_0_0_0_0_after_this2)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this3:Tenant) + WITH *, count(authorization_0_0_0_0_0_0_0_0_0_0_after_this3) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_3_0_0_0_after_this3)<-[:ADMIN_IN]-(authorization_3_0_0_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_3_0_0_0_after_this4.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_3_0_0_0_after_this2) = 1 AS authorization_3_0_0_0_after_var5 + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_0_0_0_0_0_after_this3)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_0_0_0_0_0_after_this4.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_0_0_0_0_0_after_this2) = 1 AS authorization_0_0_0_0_0_0_0_0_0_0_after_var5 } WITH * - WHERE authorization_3_0_0_0_after_var5 = true - RETURN count(authorization_3_0_0_0_after_this1) = 1 AS authorization_3_0_0_0_after_var0 + WHERE authorization_0_0_0_0_0_0_0_0_0_0_after_var5 = true + RETURN count(authorization_0_0_0_0_0_0_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_0_0_0_0_0_after_var0 } CALL { WITH this0_settings0_node_openingDays0_node - MATCH (this0_settings0_node_openingDays0_node)<-[:VALID_GARAGES]-(authorization_2_0_0_0_after_this1:Settings) - OPTIONAL MATCH (authorization_2_0_0_0_after_this1)<-[:HAS_SETTINGS]-(authorization_2_0_0_0_after_this2:Tenant) - WITH *, count(authorization_2_0_0_0_after_this2) AS tenantCount + MATCH (this0_settings0_node_openingDays0_node)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_0_0_after_this1:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_0_0_after_this1)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_0_0_0_after_this2:Tenant) + WITH *, count(authorization_0_0_0_0_0_0_0_after_this2) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_2_0_0_0_after_this2)<-[:ADMIN_IN]-(authorization_2_0_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_2_0_0_0_after_this3.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_2_0_0_0_after_this1) = 1 AS authorization_2_0_0_0_after_var0 + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_0_0_after_this2)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_0_0_after_this3.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_0_0_after_var0 } - OPTIONAL MATCH (this0_settings0_node)<-[:HAS_SETTINGS]-(authorization_1_0_0_0_after_this1:Tenant) - WITH *, count(authorization_1_0_0_0_after_this1) AS tenantCount + OPTIONAL MATCH (this0_settings0_node)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_after_this1:Tenant) + WITH *, count(authorization_0_0_0_0_after_this1) AS tenantCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_3_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_2_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (tenantCount <> 0 AND size([(authorization_1_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_1_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_1_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this0)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_0_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (tenantCount <> 0 AND size([(authorization_0_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this0)<-[:ADMIN_IN]-(authorization_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this0.userId = $jwt.id) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { diff --git a/packages/graphql/tests/tck/issues/4214.test.ts b/packages/graphql/tests/tck/issues/4214.test.ts index 66f4399f149..7149f8076ad 100644 --- a/packages/graphql/tests/tck/issues/4214.test.ts +++ b/packages/graphql/tests/tck/issues/4214.test.ts @@ -168,12 +168,12 @@ describe("https://github.com/neo4j/graphql/issues/4214", () => { CALL { WITH this0 OPTIONAL MATCH (this0_transaction_connect0_node:Transaction) - OPTIONAL MATCH (this0_transaction_connect0_node)-[:TRANSACTION]->(authorization_0_0_0_0_before_this0:Store) - WITH *, count(authorization_0_0_0_0_before_this0) AS storeCount - OPTIONAL MATCH (this0_transaction_connect0_node)-[:TRANSACTION]->(authorization_0_0_0_0_before_this1:Store) - WITH *, count(authorization_0_0_0_0_before_this1) AS storeCount + OPTIONAL MATCH (this0_transaction_connect0_node)-[:TRANSACTION]->(authorization_0_before_this0:Store) + WITH *, count(authorization_0_before_this0) AS storeCount + OPTIONAL MATCH (this0_transaction_connect0_node)-[:TRANSACTION]->(authorization_0_before_this1:Store) + WITH *, count(authorization_0_before_this1) AS storeCount WITH * - WHERE this0_transaction_connect0_node.id = $this0_transaction_connect0_node_param0 AND ((($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param3 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param4 IN $jwt.roles)) AND (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_0_0_0_before_this0.id = $jwt.store)))) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param5 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_before_param6 IN $jwt.roles)) AND (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_0_0_0_before_this1.id = $jwt.store))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WHERE this0_transaction_connect0_node.id = $this0_transaction_connect0_node_param0 AND ((($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_before_param2 IN $jwt.roles)) OR ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_before_param3 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_before_param4 IN $jwt.roles)) AND (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_before_this0.id = $jwt.store)))) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_before_param5 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_before_param6 IN $jwt.roles)) AND (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_before_this1.id = $jwt.store))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) CALL { WITH * WITH collect(this0_transaction_connect0_node) as connectedNodes, collect(this0) as parentNodes @@ -188,17 +188,17 @@ describe("https://github.com/neo4j/graphql/issues/4214", () => { WITH * CALL { WITH this0 - MATCH (this0)-[:ITEM_TRANSACTED]->(authorization_0_0_0_0_after_this2:Transaction) - OPTIONAL MATCH (authorization_0_0_0_0_after_this2)-[:TRANSACTION]->(authorization_0_0_0_0_after_this3:Store) - WITH *, count(authorization_0_0_0_0_after_this3) AS storeCount + MATCH (this0)-[:ITEM_TRANSACTED]->(authorization_0_after_this2:Transaction) + OPTIONAL MATCH (authorization_0_after_this2)-[:TRANSACTION]->(authorization_0_after_this3:Store) + WITH *, count(authorization_0_after_this3) AS storeCount WITH * - WHERE (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_0_0_0_after_this3.id = $jwt.store)) - RETURN count(authorization_0_0_0_0_after_this2) = 1 AS authorization_0_0_0_0_after_var0 + WHERE (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_after_this3.id = $jwt.store)) + RETURN count(authorization_0_after_this2) = 1 AS authorization_0_after_var0 } - OPTIONAL MATCH (this0_transaction_connect0_node)-[:TRANSACTION]->(authorization_0_0_0_0_after_this1:Store) - WITH *, count(authorization_0_0_0_0_after_this1) AS storeCount + OPTIONAL MATCH (this0_transaction_connect0_node)-[:TRANSACTION]->(authorization_0_after_this1:Store) + WITH *, count(authorization_0_after_this1) AS storeCount WITH * - WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles)) AND authorization_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param4 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param5 IN $jwt.roles)) AND (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_0_0_0_after_this1.id = $jwt.store))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) + WHERE (apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles)) AND authorization_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_after_param4 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_after_param5 IN $jwt.roles)) AND (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_after_this1.id = $jwt.store))), \\"@neo4j/graphql/FORBIDDEN\\", [0])) RETURN count(*) AS connect_this0_transaction_connect_Transaction0 } WITH * @@ -212,15 +212,15 @@ describe("https://github.com/neo4j/graphql/issues/4214", () => { WITH * CALL { WITH this0 - MATCH (this0)-[:ITEM_TRANSACTED]->(authorization_0_0_0_0_after_this1:Transaction) - OPTIONAL MATCH (authorization_0_0_0_0_after_this1)-[:TRANSACTION]->(authorization_0_0_0_0_after_this2:Store) - WITH *, count(authorization_0_0_0_0_after_this2) AS storeCount + MATCH (this0)-[:ITEM_TRANSACTED]->(authorization_0_after_this1:Transaction) + OPTIONAL MATCH (authorization_0_after_this1)-[:TRANSACTION]->(authorization_0_after_this2:Store) + WITH *, count(authorization_0_after_this2) AS storeCount WITH * - WHERE (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_0_0_0_after_this2.id = $jwt.store)) - RETURN count(authorization_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_after_var0 + WHERE (storeCount <> 0 AND ($jwt.store IS NOT NULL AND authorization_0_after_this2.id = $jwt.store)) + RETURN count(authorization_0_after_this1) = 1 AS authorization_0_after_var0 } WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param3 IN $jwt.roles)) AND authorization_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles) OR ($jwt.roles IS NOT NULL AND $authorization_0_after_param3 IN $jwt.roles)) AND authorization_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { @@ -265,15 +265,15 @@ describe("https://github.com/neo4j/graphql/issues/4214", () => { \\"high\\": 0 }, \\"this0_transaction_connect0_node_param0\\": \\"transactionid\\", - \\"authorization_0_0_0_0_before_param2\\": \\"admin\\", - \\"authorization_0_0_0_0_before_param3\\": \\"store-owner\\", - \\"authorization_0_0_0_0_before_param4\\": \\"employee\\", - \\"authorization_0_0_0_0_before_param5\\": \\"store-owner\\", - \\"authorization_0_0_0_0_before_param6\\": \\"employee\\", - \\"authorization_0_0_0_0_after_param2\\": \\"store-owner\\", - \\"authorization_0_0_0_0_after_param3\\": \\"employee\\", - \\"authorization_0_0_0_0_after_param4\\": \\"store-owner\\", - \\"authorization_0_0_0_0_after_param5\\": \\"employee\\", + \\"authorization_0_before_param2\\": \\"admin\\", + \\"authorization_0_before_param3\\": \\"store-owner\\", + \\"authorization_0_before_param4\\": \\"employee\\", + \\"authorization_0_before_param5\\": \\"store-owner\\", + \\"authorization_0_before_param6\\": \\"employee\\", + \\"authorization_0_after_param2\\": \\"store-owner\\", + \\"authorization_0_after_param3\\": \\"employee\\", + \\"authorization_0_after_param4\\": \\"store-owner\\", + \\"authorization_0_after_param5\\": \\"employee\\", \\"resolvedCallbacks\\": {} }" `); diff --git a/packages/graphql/tests/tck/issues/4223.test.ts b/packages/graphql/tests/tck/issues/4223.test.ts index babf4cfc3b2..093ad5a2d78 100644 --- a/packages/graphql/tests/tck/issues/4223.test.ts +++ b/packages/graphql/tests/tck/issues/4223.test.ts @@ -219,42 +219,42 @@ describe("https://github.com/neo4j/graphql/issues/4223", () => { WITH * CALL { WITH this0_settings0_node_openingDays0_node_open0_node - MATCH (this0_settings0_node_openingDays0_node_open0_node)<-[:HAS_OPEN_INTERVALS]-(authorization_3_0_0_0_after_this1:OpeningDay) + MATCH (this0_settings0_node_openingDays0_node_open0_node)<-[:HAS_OPEN_INTERVALS]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this1:OpeningDay) CALL { - WITH authorization_3_0_0_0_after_this1 - MATCH (authorization_3_0_0_0_after_this1)<-[:VALID_GARAGES]-(authorization_3_0_0_0_after_this2:Settings) - OPTIONAL MATCH (authorization_3_0_0_0_after_this2)<-[:HAS_SETTINGS]-(authorization_3_0_0_0_after_this3:Tenant) - WITH *, count(authorization_3_0_0_0_after_this3) AS tenantCount + WITH authorization_0_0_0_0_0_0_0_0_0_0_after_this1 + MATCH (authorization_0_0_0_0_0_0_0_0_0_0_after_this1)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this2:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_0_0_0_0_0_after_this2)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this3:Tenant) + WITH *, count(authorization_0_0_0_0_0_0_0_0_0_0_after_this3) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_3_0_0_0_after_this3)<-[:ADMIN_IN]-(authorization_3_0_0_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_3_0_0_0_after_this4.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_3_0_0_0_after_this2) = 1 AS authorization_3_0_0_0_after_var5 + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_0_0_0_0_0_after_this3)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_0_0_0_0_0_after_this4.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_0_0_0_0_0_after_this2) = 1 AS authorization_0_0_0_0_0_0_0_0_0_0_after_var5 } WITH * - WHERE authorization_3_0_0_0_after_var5 = true - RETURN count(authorization_3_0_0_0_after_this1) = 1 AS authorization_3_0_0_0_after_var0 + WHERE authorization_0_0_0_0_0_0_0_0_0_0_after_var5 = true + RETURN count(authorization_0_0_0_0_0_0_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_0_0_0_0_0_after_var0 } CALL { WITH this0_settings0_node_openingDays0_node - MATCH (this0_settings0_node_openingDays0_node)<-[:VALID_GARAGES]-(authorization_2_0_0_0_after_this1:Settings) - OPTIONAL MATCH (authorization_2_0_0_0_after_this1)<-[:HAS_SETTINGS]-(authorization_2_0_0_0_after_this2:Tenant) - WITH *, count(authorization_2_0_0_0_after_this2) AS tenantCount + MATCH (this0_settings0_node_openingDays0_node)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_0_0_after_this1:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_0_0_after_this1)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_0_0_0_after_this2:Tenant) + WITH *, count(authorization_0_0_0_0_0_0_0_after_this2) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_2_0_0_0_after_this2)<-[:ADMIN_IN]-(authorization_2_0_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_2_0_0_0_after_this3.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_2_0_0_0_after_this1) = 1 AS authorization_2_0_0_0_after_var0 + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_0_0_after_this2)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_0_0_after_this3.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_0_0_after_var0 } CALL { WITH this0_settings0_node_myWorkspace0_node - MATCH (this0_settings0_node_myWorkspace0_node)<-[:HAS_WORKSPACE_SETTINGS]-(authorization_2_1_0_0_after_this1:Settings) - OPTIONAL MATCH (authorization_2_1_0_0_after_this1)<-[:HAS_SETTINGS]-(authorization_2_1_0_0_after_this2:Tenant) - WITH *, count(authorization_2_1_0_0_after_this2) AS tenantCount + MATCH (this0_settings0_node_myWorkspace0_node)<-[:HAS_WORKSPACE_SETTINGS]-(authorization_0_0_0_0_1_0_0_after_this1:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_1_0_0_after_this1)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_1_0_0_after_this2:Tenant) + WITH *, count(authorization_0_0_0_0_1_0_0_after_this2) AS tenantCount WITH * - WHERE (tenantCount <> 0 AND size([(authorization_2_1_0_0_after_this2)<-[:ADMIN_IN]-(authorization_2_1_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_2_1_0_0_after_this3.userId = $jwt.id) | 1]) > 0) - RETURN count(authorization_2_1_0_0_after_this1) = 1 AS authorization_2_1_0_0_after_var0 + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_1_0_0_after_this2)<-[:ADMIN_IN]-(authorization_0_0_0_0_1_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_1_0_0_after_this3.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_1_0_0_after_this1) = 1 AS authorization_0_0_0_0_1_0_0_after_var0 } - OPTIONAL MATCH (this0_settings0_node)<-[:HAS_SETTINGS]-(authorization_1_0_0_0_after_this1:Tenant) - WITH *, count(authorization_1_0_0_0_after_this1) AS tenantCount + OPTIONAL MATCH (this0_settings0_node)<-[:HAS_SETTINGS]-(authorization_0_0_0_0_after_this1:Tenant) + WITH *, count(authorization_0_0_0_0_after_this1) AS tenantCount WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_3_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_2_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_2_1_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (tenantCount <> 0 AND size([(authorization_1_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_1_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_1_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this0)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_0_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_1_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (tenantCount <> 0 AND size([(authorization_0_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this0)<-[:ADMIN_IN]-(authorization_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this0.userId = $jwt.id) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { diff --git a/packages/graphql/tests/tck/issues/4429.test.ts b/packages/graphql/tests/tck/issues/4429.test.ts new file mode 100644 index 00000000000..d1f80c8e450 --- /dev/null +++ b/packages/graphql/tests/tck/issues/4429.test.ts @@ -0,0 +1,399 @@ +/* + * 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 { gql } from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { formatCypher, translateQuery, formatParams } from "../utils/tck-test-utils"; + +describe("https://github.com/neo4j/graphql/issues/4429", () => { + let neoSchema: Neo4jGraphQL; + + const typeDefs = gql` + type JWT @jwt { + id: String + roles: [String] + } + type User @authorization(validate: [{ where: { node: { userId: "$jwt.id" } }, operations: [READ] }]) { + userId: String! @unique + adminAccess: [Tenant!]! @relationship(type: "ADMIN_IN", direction: OUT) + } + + type Tenant @authorization(validate: [{ where: { node: { admins: { userId: "$jwt.id" } } } }]) { + id: ID! @id + admins: [User!]! @relationship(type: "ADMIN_IN", direction: IN) + settings: Settings @relationship(type: "VEHICLECARD_OWNER", direction: IN) + } + + type Settings @authorization(validate: [{ where: { node: { tenant: { admins: { userId: "$jwt.id" } } } } }]) { + id: ID! @id + openingDays: [OpeningDay!]! @relationship(type: "VALID_GARAGES", direction: OUT) + tenant: Tenant! @relationship(type: "VEHICLECARD_OWNER", direction: OUT) # <--- this line + } + + type OpeningDay + @authorization( + validate: [{ where: { node: { settings: { tenant: { admins: { userId: "$jwt.id" } } } } } }] + ) { + id: ID! @id + settings: Settings @relationship(type: "VALID_GARAGES", direction: IN) + open: [OpeningHoursInterval!]! @relationship(type: "HAS_OPEN_INTERVALS", direction: OUT) + } + type OpeningHoursInterval + @authorization( + validate: [ + { where: { node: { openingDay: { settings: { tenant: { admins: { userId: "$jwt.id" } } } } } } } + ] + ) { + name: String + openingDay: OpeningDay! @relationship(type: "HAS_OPEN_INTERVALS", direction: IN) + createdAt: DateTime! @timestamp(operations: [CREATE]) + updatedAt: DateTime! @timestamp(operations: [CREATE, UPDATE]) + updatedBy: String @populatedBy(callback: "getUserIDFromContext", operations: [CREATE, UPDATE]) + } + `; + + beforeAll(() => { + neoSchema = new Neo4jGraphQL({ + typeDefs, + features: { + populatedBy: { + callbacks: { + getUserIDFromContext: () => "hi", + }, + }, + }, + }); + }); + + test("should include checks for auth jwt param is not null", async () => { + const query = gql` + mutation addTenant($input: [TenantCreateInput!]!) { + createTenants(input: $input) { + tenants { + id + admins { + userId + } + settings { + openingDays { + open { + name + } + } + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query, { + variableValues: { + input: { + settings: { + create: { + node: { + openingDays: { + create: [ + { + node: { + open: { + create: [ + { + node: { + name: "hi", + }, + }, + ], + }, + }, + }, + { + node: { + open: { + create: [ + { + node: { + name: "hi", + }, + }, + { + node: { + name: "hi", + }, + }, + ], + }, + }, + }, + ], + }, + }, + }, + }, + }, + }, + }); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "CALL { + CREATE (this0:Tenant) + SET this0.id = randomUUID() + WITH * + CREATE (this0_settings0_node:Settings) + SET this0_settings0_node.id = randomUUID() + WITH * + CREATE (this0_settings0_node_openingDays0_node:OpeningDay) + SET this0_settings0_node_openingDays0_node.id = randomUUID() + WITH * + CREATE (this0_settings0_node_openingDays0_node_open0_node:OpeningHoursInterval) + SET this0_settings0_node_openingDays0_node_open0_node.createdAt = datetime() + SET this0_settings0_node_openingDays0_node_open0_node.updatedAt = datetime() + SET this0_settings0_node_openingDays0_node_open0_node.updatedBy = $resolvedCallbacks.this0_settings0_node_openingDays0_node_open0_node_updatedBy_getUserIDFromContext + SET this0_settings0_node_openingDays0_node_open0_node.name = $this0_settings0_node_openingDays0_node_open0_node_name + MERGE (this0_settings0_node_openingDays0_node)-[:HAS_OPEN_INTERVALS]->(this0_settings0_node_openingDays0_node_open0_node) + WITH * + CALL { + WITH this0_settings0_node_openingDays0_node_open0_node + MATCH (this0_settings0_node_openingDays0_node_open0_node)<-[this0_settings0_node_openingDays0_node_open0_node_openingDay_OpeningDay_unique:HAS_OPEN_INTERVALS]-(:OpeningDay) + WITH count(this0_settings0_node_openingDays0_node_open0_node_openingDay_OpeningDay_unique) as c + WHERE apoc.util.validatePredicate(NOT (c = 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDOpeningHoursInterval.openingDay required exactly once', [0]) + RETURN c AS this0_settings0_node_openingDays0_node_open0_node_openingDay_OpeningDay_unique_ignored + } + MERGE (this0_settings0_node)-[:VALID_GARAGES]->(this0_settings0_node_openingDays0_node) + WITH * + CALL { + WITH this0_settings0_node_openingDays0_node + MATCH (this0_settings0_node_openingDays0_node)<-[this0_settings0_node_openingDays0_node_settings_Settings_unique:VALID_GARAGES]-(:Settings) + WITH count(this0_settings0_node_openingDays0_node_settings_Settings_unique) as c + WHERE apoc.util.validatePredicate(NOT (c <= 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDOpeningDay.settings must be less than or equal to one', [0]) + RETURN c AS this0_settings0_node_openingDays0_node_settings_Settings_unique_ignored + } + WITH * + CREATE (this0_settings0_node_openingDays1_node:OpeningDay) + SET this0_settings0_node_openingDays1_node.id = randomUUID() + WITH * + CREATE (this0_settings0_node_openingDays1_node_open0_node:OpeningHoursInterval) + SET this0_settings0_node_openingDays1_node_open0_node.createdAt = datetime() + SET this0_settings0_node_openingDays1_node_open0_node.updatedAt = datetime() + SET this0_settings0_node_openingDays1_node_open0_node.updatedBy = $resolvedCallbacks.this0_settings0_node_openingDays1_node_open0_node_updatedBy_getUserIDFromContext + SET this0_settings0_node_openingDays1_node_open0_node.name = $this0_settings0_node_openingDays1_node_open0_node_name + MERGE (this0_settings0_node_openingDays1_node)-[:HAS_OPEN_INTERVALS]->(this0_settings0_node_openingDays1_node_open0_node) + WITH * + CALL { + WITH this0_settings0_node_openingDays1_node_open0_node + MATCH (this0_settings0_node_openingDays1_node_open0_node)<-[this0_settings0_node_openingDays1_node_open0_node_openingDay_OpeningDay_unique:HAS_OPEN_INTERVALS]-(:OpeningDay) + WITH count(this0_settings0_node_openingDays1_node_open0_node_openingDay_OpeningDay_unique) as c + WHERE apoc.util.validatePredicate(NOT (c = 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDOpeningHoursInterval.openingDay required exactly once', [0]) + RETURN c AS this0_settings0_node_openingDays1_node_open0_node_openingDay_OpeningDay_unique_ignored + } + WITH * + CREATE (this0_settings0_node_openingDays1_node_open1_node:OpeningHoursInterval) + SET this0_settings0_node_openingDays1_node_open1_node.createdAt = datetime() + SET this0_settings0_node_openingDays1_node_open1_node.updatedAt = datetime() + SET this0_settings0_node_openingDays1_node_open1_node.updatedBy = $resolvedCallbacks.this0_settings0_node_openingDays1_node_open1_node_updatedBy_getUserIDFromContext + SET this0_settings0_node_openingDays1_node_open1_node.name = $this0_settings0_node_openingDays1_node_open1_node_name + MERGE (this0_settings0_node_openingDays1_node)-[:HAS_OPEN_INTERVALS]->(this0_settings0_node_openingDays1_node_open1_node) + WITH * + CALL { + WITH this0_settings0_node_openingDays1_node_open1_node + MATCH (this0_settings0_node_openingDays1_node_open1_node)<-[this0_settings0_node_openingDays1_node_open1_node_openingDay_OpeningDay_unique:HAS_OPEN_INTERVALS]-(:OpeningDay) + WITH count(this0_settings0_node_openingDays1_node_open1_node_openingDay_OpeningDay_unique) as c + WHERE apoc.util.validatePredicate(NOT (c = 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDOpeningHoursInterval.openingDay required exactly once', [0]) + RETURN c AS this0_settings0_node_openingDays1_node_open1_node_openingDay_OpeningDay_unique_ignored + } + MERGE (this0_settings0_node)-[:VALID_GARAGES]->(this0_settings0_node_openingDays1_node) + WITH * + CALL { + WITH this0_settings0_node_openingDays1_node + MATCH (this0_settings0_node_openingDays1_node)<-[this0_settings0_node_openingDays1_node_settings_Settings_unique:VALID_GARAGES]-(:Settings) + WITH count(this0_settings0_node_openingDays1_node_settings_Settings_unique) as c + WHERE apoc.util.validatePredicate(NOT (c <= 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDOpeningDay.settings must be less than or equal to one', [0]) + RETURN c AS this0_settings0_node_openingDays1_node_settings_Settings_unique_ignored + } + MERGE (this0)<-[:VEHICLECARD_OWNER]-(this0_settings0_node) + WITH * + CALL { + WITH this0_settings0_node + MATCH (this0_settings0_node)-[this0_settings0_node_tenant_Tenant_unique:VEHICLECARD_OWNER]->(:Tenant) + WITH count(this0_settings0_node_tenant_Tenant_unique) as c + WHERE apoc.util.validatePredicate(NOT (c = 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDSettings.tenant required exactly once', [0]) + RETURN c AS this0_settings0_node_tenant_Tenant_unique_ignored + } + WITH * + CALL { + WITH this0 + MATCH (this0)<-[this0_settings_Settings_unique:VEHICLECARD_OWNER]-(:Settings) + WITH count(this0_settings_Settings_unique) as c + WHERE apoc.util.validatePredicate(NOT (c <= 1), '@neo4j/graphql/RELATIONSHIP-REQUIREDTenant.settings must be less than or equal to one', [0]) + RETURN c AS this0_settings_Settings_unique_ignored + } + WITH * + CALL { + WITH this0_settings0_node_openingDays0_node_open0_node + MATCH (this0_settings0_node_openingDays0_node_open0_node)<-[:HAS_OPEN_INTERVALS]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this1:OpeningDay) + CALL { + WITH authorization_0_0_0_0_0_0_0_0_0_0_after_this1 + MATCH (authorization_0_0_0_0_0_0_0_0_0_0_after_this1)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this2:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_0_0_0_0_0_after_this2)-[:VEHICLECARD_OWNER]->(authorization_0_0_0_0_0_0_0_0_0_0_after_this3:Tenant) + WITH *, count(authorization_0_0_0_0_0_0_0_0_0_0_after_this3) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_0_0_0_0_0_after_this3)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_0_0_0_0_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_0_0_0_0_0_after_this4.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_0_0_0_0_0_after_this2) = 1 AS authorization_0_0_0_0_0_0_0_0_0_0_after_var5 + } + WITH * + WHERE authorization_0_0_0_0_0_0_0_0_0_0_after_var5 = true + RETURN count(authorization_0_0_0_0_0_0_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_0_0_0_0_0_after_var0 + } + CALL { + WITH this0_settings0_node_openingDays0_node + MATCH (this0_settings0_node_openingDays0_node)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_0_0_after_this1:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_0_0_after_this1)-[:VEHICLECARD_OWNER]->(authorization_0_0_0_0_0_0_0_after_this2:Tenant) + WITH *, count(authorization_0_0_0_0_0_0_0_after_this2) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_0_0_after_this2)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_0_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_0_0_after_this3.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_0_0_after_var0 + } + CALL { + WITH this0_settings0_node_openingDays1_node_open0_node + MATCH (this0_settings0_node_openingDays1_node_open0_node)<-[:HAS_OPEN_INTERVALS]-(authorization_0_0_0_0_0_1_0_0_0_0_after_this1:OpeningDay) + CALL { + WITH authorization_0_0_0_0_0_1_0_0_0_0_after_this1 + MATCH (authorization_0_0_0_0_0_1_0_0_0_0_after_this1)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_1_0_0_0_0_after_this2:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_1_0_0_0_0_after_this2)-[:VEHICLECARD_OWNER]->(authorization_0_0_0_0_0_1_0_0_0_0_after_this3:Tenant) + WITH *, count(authorization_0_0_0_0_0_1_0_0_0_0_after_this3) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_1_0_0_0_0_after_this3)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_1_0_0_0_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_1_0_0_0_0_after_this4.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_1_0_0_0_0_after_this2) = 1 AS authorization_0_0_0_0_0_1_0_0_0_0_after_var5 + } + WITH * + WHERE authorization_0_0_0_0_0_1_0_0_0_0_after_var5 = true + RETURN count(authorization_0_0_0_0_0_1_0_0_0_0_after_this1) = 1 AS authorization_0_0_0_0_0_1_0_0_0_0_after_var0 + } + CALL { + WITH this0_settings0_node_openingDays1_node_open1_node + MATCH (this0_settings0_node_openingDays1_node_open1_node)<-[:HAS_OPEN_INTERVALS]-(authorization_0_0_0_0_0_1_0_0_1_0_after_this1:OpeningDay) + CALL { + WITH authorization_0_0_0_0_0_1_0_0_1_0_after_this1 + MATCH (authorization_0_0_0_0_0_1_0_0_1_0_after_this1)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_1_0_0_1_0_after_this2:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_1_0_0_1_0_after_this2)-[:VEHICLECARD_OWNER]->(authorization_0_0_0_0_0_1_0_0_1_0_after_this3:Tenant) + WITH *, count(authorization_0_0_0_0_0_1_0_0_1_0_after_this3) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_1_0_0_1_0_after_this3)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_1_0_0_1_0_after_this4:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_1_0_0_1_0_after_this4.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_1_0_0_1_0_after_this2) = 1 AS authorization_0_0_0_0_0_1_0_0_1_0_after_var5 + } + WITH * + WHERE authorization_0_0_0_0_0_1_0_0_1_0_after_var5 = true + RETURN count(authorization_0_0_0_0_0_1_0_0_1_0_after_this1) = 1 AS authorization_0_0_0_0_0_1_0_0_1_0_after_var0 + } + CALL { + WITH this0_settings0_node_openingDays1_node + MATCH (this0_settings0_node_openingDays1_node)<-[:VALID_GARAGES]-(authorization_0_0_0_0_0_1_0_after_this1:Settings) + OPTIONAL MATCH (authorization_0_0_0_0_0_1_0_after_this1)-[:VEHICLECARD_OWNER]->(authorization_0_0_0_0_0_1_0_after_this2:Tenant) + WITH *, count(authorization_0_0_0_0_0_1_0_after_this2) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(authorization_0_0_0_0_0_1_0_after_this2)<-[:ADMIN_IN]-(authorization_0_0_0_0_0_1_0_after_this3:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_0_1_0_after_this3.userId = $jwt.id) | 1]) > 0) + RETURN count(authorization_0_0_0_0_0_1_0_after_this1) = 1 AS authorization_0_0_0_0_0_1_0_after_var0 + } + OPTIONAL MATCH (this0_settings0_node)-[:VEHICLECARD_OWNER]->(authorization_0_0_0_0_after_this1:Tenant) + WITH *, count(authorization_0_0_0_0_after_this1) AS tenantCount + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_0_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_1_0_0_0_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_1_0_0_1_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND authorization_0_0_0_0_0_1_0_after_var0 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (tenantCount <> 0 AND size([(authorization_0_0_0_0_after_this1)<-[:ADMIN_IN]-(authorization_0_0_0_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_0_0_0_after_this0.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) AND apoc.util.validatePredicate(NOT ($isAuthenticated = true AND size([(this0)<-[:ADMIN_IN]-(authorization_0_after_this0:User) WHERE ($jwt.id IS NOT NULL AND authorization_0_after_this0.userId = $jwt.id) | 1]) > 0), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + RETURN this0 + } + CALL { + WITH this0 + CALL { + WITH this0 + MATCH (this0)<-[create_this0:ADMIN_IN]-(create_this1:User) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.id IS NOT NULL AND create_this1.userId = $jwt.id)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH create_this1 { .userId } AS create_this1 + RETURN collect(create_this1) AS create_var2 + } + CALL { + WITH this0 + MATCH (this0)<-[create_this3:VEHICLECARD_OWNER]-(create_this4:Settings) + OPTIONAL MATCH (create_this4)-[:VEHICLECARD_OWNER]->(create_this5:Tenant) + WITH *, count(create_this5) AS tenantCount + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND (tenantCount <> 0 AND size([(create_this5)<-[:ADMIN_IN]-(create_this6:User) WHERE ($jwt.id IS NOT NULL AND create_this6.userId = $jwt.id) | 1]) > 0)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + CALL { + WITH create_this4 + MATCH (create_this4)-[create_this7:VALID_GARAGES]->(create_this8:OpeningDay) + CALL { + WITH create_this8 + MATCH (create_this8)<-[:VALID_GARAGES]-(create_this9:Settings) + OPTIONAL MATCH (create_this9)-[:VEHICLECARD_OWNER]->(create_this10:Tenant) + WITH *, count(create_this10) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(create_this10)<-[:ADMIN_IN]-(create_this11:User) WHERE ($jwt.id IS NOT NULL AND create_this11.userId = $jwt.id) | 1]) > 0) + RETURN count(create_this9) = 1 AS create_var12 + } + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND create_var12 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + CALL { + WITH create_this8 + MATCH (create_this8)-[create_this13:HAS_OPEN_INTERVALS]->(create_this14:OpeningHoursInterval) + CALL { + WITH create_this14 + MATCH (create_this14)<-[:HAS_OPEN_INTERVALS]-(create_this15:OpeningDay) + CALL { + WITH create_this15 + MATCH (create_this15)<-[:VALID_GARAGES]-(create_this16:Settings) + OPTIONAL MATCH (create_this16)-[:VEHICLECARD_OWNER]->(create_this17:Tenant) + WITH *, count(create_this17) AS tenantCount + WITH * + WHERE (tenantCount <> 0 AND size([(create_this17)<-[:ADMIN_IN]-(create_this18:User) WHERE ($jwt.id IS NOT NULL AND create_this18.userId = $jwt.id) | 1]) > 0) + RETURN count(create_this16) = 1 AS create_var19 + } + WITH * + WHERE create_var19 = true + RETURN count(create_this15) = 1 AS create_var20 + } + WITH * + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND create_var20 = true), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WITH create_this14 { .name } AS create_this14 + RETURN collect(create_this14) AS create_var21 + } + WITH create_this8 { open: create_var21 } AS create_this8 + RETURN collect(create_this8) AS create_var22 + } + WITH create_this4 { openingDays: create_var22 } AS create_this4 + RETURN head(collect(create_this4)) AS create_var23 + } + RETURN this0 { .id, admins: create_var2, settings: create_var23 } AS create_var24 + } + RETURN [create_var24] AS data" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"isAuthenticated\\": false, + \\"jwt\\": {}, + \\"this0_settings0_node_openingDays0_node_open0_node_name\\": \\"hi\\", + \\"this0_settings0_node_openingDays1_node_open0_node_name\\": \\"hi\\", + \\"this0_settings0_node_openingDays1_node_open1_node_name\\": \\"hi\\", + \\"resolvedCallbacks\\": { + \\"this0_settings0_node_openingDays0_node_open0_node_updatedBy_getUserIDFromContext\\": \\"hi\\", + \\"this0_settings0_node_openingDays1_node_open0_node_updatedBy_getUserIDFromContext\\": \\"hi\\", + \\"this0_settings0_node_openingDays1_node_open1_node_updatedBy_getUserIDFromContext\\": \\"hi\\" + } + }" + `); + }); +}); diff --git a/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts b/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts index 7e1cf80aa9d..8324211c3bc 100644 --- a/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts +++ b/packages/graphql/tests/tck/operations/batch/batch-create-auth.test.ts @@ -310,7 +310,7 @@ describe("Batch Create, Auth", () => { RETURN c AS this0_website_Website_unique_ignored } WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this0 } CALL { @@ -339,7 +339,7 @@ describe("Batch Create, Auth", () => { RETURN c AS this1_website_Website_unique_ignored } WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this1 } CALL { @@ -358,7 +358,7 @@ describe("Batch Create, Auth", () => { RETURN c AS this2_website_Website_unique_ignored } WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this2 } CALL { @@ -391,7 +391,7 @@ describe("Batch Create, Auth", () => { RETURN c AS this3_website_Website_unique_ignored } WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this3 } CALL { @@ -415,7 +415,7 @@ describe("Batch Create, Auth", () => { RETURN c AS this4_website_Website_unique_ignored } WITH * - WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_0_0_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) + WHERE apoc.util.validatePredicate(NOT ($isAuthenticated = true AND ($jwt.roles IS NOT NULL AND $authorization_0_after_param2 IN $jwt.roles)), \\"@neo4j/graphql/FORBIDDEN\\", [0]) RETURN this4 } CALL { @@ -519,7 +519,7 @@ describe("Batch Create, Auth", () => { \\"low\\": 2022, \\"high\\": 0 }, - \\"authorization_0_0_0_0_after_param2\\": \\"admin\\", + \\"authorization_0_after_param2\\": \\"admin\\", \\"this1_id\\": \\"2\\", \\"this1_actors0_node_name\\": \\"actor 2\\", \\"this1_actors0_relationship_year\\": { From 596de201d97ff3eecfe3b6a0998c2a830977deff Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 23:14:19 +0000 Subject: [PATCH 118/136] chore(deps): update github/codeql-action digest to 8b7fcbf --- .github/workflows/reusable-codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-codeql-analysis.yml b/.github/workflows/reusable-codeql-analysis.yml index 340bf2990b7..60a7ae808d0 100644 --- a/.github/workflows/reusable-codeql-analysis.yml +++ b/.github/workflows/reusable-codeql-analysis.yml @@ -14,9 +14,9 @@ jobs: with: node-version: lts/* - name: Initialize CodeQL - uses: github/codeql-action/init@1500a131381b66de0c52ac28abb13cd79f4b7ecc # v2 + uses: github/codeql-action/init@8b7fcbfac2aae0e6c24d9f9ebd5830b1290b18e4 # v2 with: config-file: ./.github/codeql/codeql-config.yml languages: javascript - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1500a131381b66de0c52ac28abb13cd79f4b7ecc # v2 + uses: github/codeql-action/analyze@8b7fcbfac2aae0e6c24d9f9ebd5830b1290b18e4 # v2 From 40ffa1c032a4603e0b200995b7f2c3568ce82b3c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 23:23:13 +0000 Subject: [PATCH 119/136] chore(deps): update dependency @babel/preset-env to v7.23.8 --- packages/package-tests/babel/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/package-tests/babel/package.json b/packages/package-tests/babel/package.json index 543c9233dc5..6f55bae3bdf 100644 --- a/packages/package-tests/babel/package.json +++ b/packages/package-tests/babel/package.json @@ -15,6 +15,6 @@ "devDependencies": { "@babel/core": "7.23.7", "@babel/node": "7.22.19", - "@babel/preset-env": "7.23.7" + "@babel/preset-env": "7.23.8" } } From fddd90491235e6f58f163bf84445fe7d9d66fc96 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 01:16:13 +0000 Subject: [PATCH 120/136] chore(deps): update typescript-eslint monorepo to v6.18.1 --- package.json | 4 +- yarn.lock | 104 +++++++++++++++++++++++++-------------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 8cb6c3582a2..6bea2d0b676 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ }, "devDependencies": { "@tsconfig/node16": "1.0.4", - "@typescript-eslint/eslint-plugin": "6.18.0", - "@typescript-eslint/parser": "6.18.0", + "@typescript-eslint/eslint-plugin": "6.18.1", + "@typescript-eslint/parser": "6.18.1", "concurrently": "8.2.2", "dotenv": "16.3.1", "eslint": "8.56.0", diff --git a/yarn.lock b/yarn.lock index 805d8326dc2..846149c5fa5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7949,15 +7949,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.18.0" +"@typescript-eslint/eslint-plugin@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/eslint-plugin@npm:6.18.1" dependencies: "@eslint-community/regexpp": ^4.5.1 - "@typescript-eslint/scope-manager": 6.18.0 - "@typescript-eslint/type-utils": 6.18.0 - "@typescript-eslint/utils": 6.18.0 - "@typescript-eslint/visitor-keys": 6.18.0 + "@typescript-eslint/scope-manager": 6.18.1 + "@typescript-eslint/type-utils": 6.18.1 + "@typescript-eslint/utils": 6.18.1 + "@typescript-eslint/visitor-keys": 6.18.1 debug: ^4.3.4 graphemer: ^1.4.0 ignore: ^5.2.4 @@ -7970,25 +7970,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: a0e946c03b3d55326fa2f090341c57063670d654ab3681f48e88af940d2ee843bd4d124655e27820ae284b705232ecfc0665ad39ace95d5210c04ee66d57d58d + checksum: 933ede339bfac8377f94b211253bce40ace272a01466c290b38e681ec4752128ce63f827bbe6cc70cc0383d01655c8a22b25c640841fe90dfa4e57f73baaf2a9 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/parser@npm:6.18.0" +"@typescript-eslint/parser@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/parser@npm:6.18.1" dependencies: - "@typescript-eslint/scope-manager": 6.18.0 - "@typescript-eslint/types": 6.18.0 - "@typescript-eslint/typescript-estree": 6.18.0 - "@typescript-eslint/visitor-keys": 6.18.0 + "@typescript-eslint/scope-manager": 6.18.1 + "@typescript-eslint/types": 6.18.1 + "@typescript-eslint/typescript-estree": 6.18.1 + "@typescript-eslint/visitor-keys": 6.18.1 debug: ^4.3.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 2f9eb1b8f142cb191de6a6f34b913df1c09ea66bb09bd92c201e28fe84b6f3c13cbed3469c94d498e96ea06349b643632bb693dcf27b85908d7221b58c24bcff + checksum: f123310976a73d9f08470dbad917c9e7b038e9e1362924a225a29d35fac1a2726d447952ca77b914d47f50791d235bb66f5171c7a4a0536e9c170fb20e73a2e4 languageName: node linkType: hard @@ -8002,22 +8002,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/scope-manager@npm:6.18.0" +"@typescript-eslint/scope-manager@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/scope-manager@npm:6.18.1" dependencies: - "@typescript-eslint/types": 6.18.0 - "@typescript-eslint/visitor-keys": 6.18.0 - checksum: 9958dcd95605b9699e1fe823cc38869d542f2cb90cde443938c1352de4161703ed6619e772bc12b8b7df2a44623ebf1e6b2b8d1222e5df22880185d0652040ee + "@typescript-eslint/types": 6.18.1 + "@typescript-eslint/visitor-keys": 6.18.1 + checksum: d6708f9f2658ab68f9f4628b93c4131fb82c362383b4d5d671491082ff610258f2fc9e293739618dc76ed6d2c5909f000a54b9b905e58a5172e6e2f731666245 languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/type-utils@npm:6.18.0" +"@typescript-eslint/type-utils@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/type-utils@npm:6.18.1" dependencies: - "@typescript-eslint/typescript-estree": 6.18.0 - "@typescript-eslint/utils": 6.18.0 + "@typescript-eslint/typescript-estree": 6.18.1 + "@typescript-eslint/utils": 6.18.1 debug: ^4.3.4 ts-api-utils: ^1.0.1 peerDependencies: @@ -8025,7 +8025,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 537b2f0b85c4225538a14e5030fc25c3f6ea610ea59dd9ac25e59a2aadd01344e2b154fcd5ab2245d055d977e4ff2b7ab30369f28eb78b6059702a2899fbdd3c + checksum: 44d7e14460f8a22a0c5c58ff7004cb40061e722dfcec3ac4ee15d40dafe68c61e555a79e81af8ffa0ca845fb3caf3ed5376853b9a94e2f3c823ac5e8267230c8 languageName: node linkType: hard @@ -8036,10 +8036,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/types@npm:6.18.0" - checksum: 516ad2feb7e7c7b5aac805b287be794e6e42371bc6a5bdd7c9fc230d98bbbcc4877c96377ccce68aede68ec58a64ef9d1e4c5b15cfb55e9a050bafe7b36624c1 +"@typescript-eslint/types@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/types@npm:6.18.1" + checksum: f1713785c4dd49e6aae4186042679d205312a1c6cbfcdad133abf5c61f71c115e04c6643aa6a8aacd732e6b64030d71bbc92762164b7f231d98fc2e31c3f8ed8 languageName: node linkType: hard @@ -8061,12 +8061,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.18.0" +"@typescript-eslint/typescript-estree@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/typescript-estree@npm:6.18.1" dependencies: - "@typescript-eslint/types": 6.18.0 - "@typescript-eslint/visitor-keys": 6.18.0 + "@typescript-eslint/types": 6.18.1 + "@typescript-eslint/visitor-keys": 6.18.1 debug: ^4.3.4 globby: ^11.1.0 is-glob: ^4.0.3 @@ -8076,24 +8076,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 64afa0a81af66dfcb1d3027872abc07451691dff956c8b3174da675307050404c720465be5322490859d633e76705fd5e0fd5f040aa4cc1078bd837281e52065 + checksum: fc5fb8abea9a6c3b774f62989b9a463569d141c32f6f2febef11d4161acaff946b204226234077b1126294fcf86a83c5fc9227f34ea3ba4cc9d39ca843dfae97 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/utils@npm:6.18.0" +"@typescript-eslint/utils@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/utils@npm:6.18.1" dependencies: "@eslint-community/eslint-utils": ^4.4.0 "@types/json-schema": ^7.0.12 "@types/semver": ^7.5.0 - "@typescript-eslint/scope-manager": 6.18.0 - "@typescript-eslint/types": 6.18.0 - "@typescript-eslint/typescript-estree": 6.18.0 + "@typescript-eslint/scope-manager": 6.18.1 + "@typescript-eslint/types": 6.18.1 + "@typescript-eslint/typescript-estree": 6.18.1 semver: ^7.5.4 peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: 5c8ab14838d5dcc857de43781687b105d972941bd4a08e63d14b6485a3944a77c867c162f14eca9ef526170b26423a0d4a828a0b22d88cb34f99835233152dff + checksum: b7265b0cae099feb98e233dd518b54408fde01b9703535c9e9b84c24e9af6fff0fd9a61f0f7d7b24fb738151ad25a7f57210e83a5a2700cac38ee627f5b856d4 languageName: node linkType: hard @@ -8125,13 +8125,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.18.0": - version: 6.18.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.18.0" +"@typescript-eslint/visitor-keys@npm:6.18.1": + version: 6.18.1 + resolution: "@typescript-eslint/visitor-keys@npm:6.18.1" dependencies: - "@typescript-eslint/types": 6.18.0 + "@typescript-eslint/types": 6.18.1 eslint-visitor-keys: ^3.4.1 - checksum: d6b1958867f3287c4e2c4f80633346a676060181e27ef69a1aad68634c62311738a3aad49e61c1d30d8e31800de146424ca8b33483d033132d90bf0c2f31cac8 + checksum: 4befc450fd459e9dc368c3da7066a4948946e8b24383bf0fbaacd059cbe69ff0f71cac4f6d5d1f99a523c1fb20d39bef907e522d2c8e8315a8ce4ce678a58540 languageName: node linkType: hard @@ -19871,8 +19871,8 @@ __metadata: "@changesets/changelog-github": 0.5.0 "@changesets/cli": 2.27.1 "@tsconfig/node16": 1.0.4 - "@typescript-eslint/eslint-plugin": 6.18.0 - "@typescript-eslint/parser": 6.18.0 + "@typescript-eslint/eslint-plugin": 6.18.1 + "@typescript-eslint/parser": 6.18.1 concurrently: 8.2.2 dotenv: 16.3.1 eslint: 8.56.0 From 8eb2d737dd7335a2eb3bce2dbd493fca0467f53c Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Tue, 9 Jan 2024 11:30:08 +0100 Subject: [PATCH 121/136] Revert codemirror resolutions (#4493) * build: remove codemirror resolutions * build: revert codemirror dependencies to pre-failing dependencies --- package.json | 4 ---- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 28 +++++++++++++-------------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 6bea2d0b676..0f5cb61abb9 100644 --- a/package.json +++ b/package.json @@ -55,9 +55,5 @@ "dependencies": { "@changesets/changelog-github": "0.5.0", "@changesets/cli": "2.27.1" - }, - "resolutions": { - "@codemirror/view": "6.23.0", - "@codemirror/state": "6.4.0" } } diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 4fa6961e98b..ce8d610a38e 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -43,9 +43,9 @@ "author": "Neo4j", "dependencies": { "@codemirror/autocomplete": "6.11.1", - "@codemirror/commands": "6.3.3", + "@codemirror/commands": "6.3.2", "@codemirror/lang-javascript": "6.2.1", - "@codemirror/language": "6.10.0", + "@codemirror/language": "6.9.3", "@dnd-kit/core": "6.1.0", "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", diff --git a/yarn.lock b/yarn.lock index 846149c5fa5..83b8e5f20b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1735,15 +1735,15 @@ __metadata: languageName: node linkType: hard -"@codemirror/commands@npm:6.3.3": - version: 6.3.3 - resolution: "@codemirror/commands@npm:6.3.3" +"@codemirror/commands@npm:6.3.2": + version: 6.3.2 + resolution: "@codemirror/commands@npm:6.3.2" dependencies: "@codemirror/language": ^6.0.0 - "@codemirror/state": ^6.4.0 + "@codemirror/state": ^6.2.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 - checksum: 7d23aecc973823969434b839aefa9a98bb47212d2ce0e6869ae903adbb5233aad22a760788fb7bb6eb45b00b01a4932fb93ad43bacdcbc0215e7500cf54b17bb + checksum: 683c444d8e6ad889ab5efd0d742b0fa28b78c8cad63276ec60d298b13d4939c8bd7e1d6fd3535645b8d255147de0d3aef46d89a29c19d0af58a7f2914bdcb3ab languageName: node linkType: hard @@ -1774,17 +1774,17 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:6.10.0": - version: 6.10.0 - resolution: "@codemirror/language@npm:6.10.0" +"@codemirror/language@npm:6.9.3": + version: 6.9.3 + resolution: "@codemirror/language@npm:6.9.3" dependencies: "@codemirror/state": ^6.0.0 - "@codemirror/view": ^6.23.0 + "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 3bfd9968f5a34ce22434489a5b226db5f3bc454a1ae7c4381587ff4270ac6af61b10f93df560cb73e9a77cc13d4843722a7a7b94dbed02a3ab1971dd329b9e81 + checksum: 774a40bc91c748d418a9a774161a5b083061124e4439bb753072bc657ec4c4784f595161c10c7c3935154b22291bf6dc74c9abe827033db32e217ac3963478f3 languageName: node linkType: hard @@ -1824,14 +1824,14 @@ __metadata: languageName: node linkType: hard -"@codemirror/state@npm:6.4.0": +"@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.2.0, @codemirror/state@npm:^6.4.0": version: 6.4.0 resolution: "@codemirror/state@npm:6.4.0" checksum: c5236fe5786f1b85d17273a5c17fa8aeb063658c1404ab18caeb6e7591663ec96b65d453ab8162f75839c3801b04cd55ba4bc48f44cb61ebfeeee383f89553c7 languageName: node linkType: hard -"@codemirror/view@npm:6.23.0": +"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.9.0": version: 6.23.0 resolution: "@codemirror/view@npm:6.23.0" dependencies: @@ -3637,9 +3637,9 @@ __metadata: resolution: "@neo4j/graphql-toolbox@workspace:packages/graphql-toolbox" dependencies: "@codemirror/autocomplete": 6.11.1 - "@codemirror/commands": 6.3.3 + "@codemirror/commands": 6.3.2 "@codemirror/lang-javascript": 6.2.1 - "@codemirror/language": 6.10.0 + "@codemirror/language": 6.9.3 "@dnd-kit/core": 6.1.0 "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 From c8b6e62d3226ab0cefc2d3d765114bb3fd4f7847 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 22:31:16 +0000 Subject: [PATCH 122/136] chore(deps): update dependency @types/node to v20.10.8 --- .../package.json | 2 +- packages/graphql/package.json | 2 +- packages/introspector/package.json | 2 +- packages/ogm/package.json | 2 +- yarn.lock | 16 ++++++++-------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/graphql-amqp-subscriptions-engine/package.json b/packages/graphql-amqp-subscriptions-engine/package.json index b3cc5861ec1..657023e01ab 100644 --- a/packages/graphql-amqp-subscriptions-engine/package.json +++ b/packages/graphql-amqp-subscriptions-engine/package.json @@ -40,7 +40,7 @@ "@types/cors": "2.8.17", "@types/debug": "4.1.12", "@types/jest": "29.5.11", - "@types/node": "20.10.7", + "@types/node": "20.10.8", "camelcase": "6.3.0", "graphql-ws": "5.14.3", "jest": "29.7.0", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 15092c0579e..1b524b0aa07 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -56,7 +56,7 @@ "@types/is-uuid": "1.0.2", "@types/jest": "29.5.11", "@types/jsonwebtoken": "9.0.5", - "@types/node": "20.10.7", + "@types/node": "20.10.8", "@types/pluralize": "0.0.33", "@types/randomstring": "1.1.11", "@types/semver": "7.5.6", diff --git a/packages/introspector/package.json b/packages/introspector/package.json index c0feaed102d..f402fb0ff98 100644 --- a/packages/introspector/package.json +++ b/packages/introspector/package.json @@ -38,7 +38,7 @@ "devDependencies": { "@neo4j/graphql": "^4.0.0", "@types/jest": "29.5.11", - "@types/node": "20.10.7", + "@types/node": "20.10.8", "@types/pluralize": "0.0.33", "jest": "29.7.0", "ts-jest": "29.1.1", diff --git a/packages/ogm/package.json b/packages/ogm/package.json index bed6913b782..9317452fd62 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -47,7 +47,7 @@ }, "devDependencies": { "@types/jest": "29.5.11", - "@types/node": "20.10.7", + "@types/node": "20.10.8", "camelcase": "6.3.0", "graphql-tag": "2.12.6", "jest": "29.7.0", diff --git a/yarn.lock b/yarn.lock index 83b8e5f20b7..e1491d86e3a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3584,7 +3584,7 @@ __metadata: "@types/cors": 2.8.17 "@types/debug": 4.1.12 "@types/jest": 29.5.11 - "@types/node": 20.10.7 + "@types/node": 20.10.8 amqplib: 0.10.3 body-parser: ^1.20.2 camelcase: 6.3.0 @@ -3613,7 +3613,7 @@ __metadata: "@graphql-tools/merge": ^9.0.0 "@neo4j/graphql": ^4.4.4 "@types/jest": 29.5.11 - "@types/node": 20.10.7 + "@types/node": 20.10.8 camelcase: 6.3.0 graphql-tag: 2.12.6 jest: 29.7.0 @@ -3718,7 +3718,7 @@ __metadata: "@types/is-uuid": 1.0.2 "@types/jest": 29.5.11 "@types/jsonwebtoken": 9.0.5 - "@types/node": 20.10.7 + "@types/node": 20.10.8 "@types/pluralize": 0.0.33 "@types/randomstring": 1.1.11 "@types/semver": 7.5.6 @@ -3775,7 +3775,7 @@ __metadata: dependencies: "@neo4j/graphql": ^4.0.0 "@types/jest": 29.5.11 - "@types/node": 20.10.7 + "@types/node": 20.10.8 "@types/pluralize": 0.0.33 camelcase: ^6.3.0 debug: ^4.3.4 @@ -7650,12 +7650,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.10.7": - version: 20.10.7 - resolution: "@types/node@npm:20.10.7" +"@types/node@npm:20.10.8": + version: 20.10.8 + resolution: "@types/node@npm:20.10.8" dependencies: undici-types: ~5.26.4 - checksum: 86f4f96f5169538f47bbd652ab8e3712cd307701481ff3e9ce0c1ea7d8424a38b5ac4a1d33088cdd9ea1bfe68fd27bbae005a21969aa6d9a36295904da6f09f2 + checksum: ce9b7ee545b3605f667be2ea900e38ab58d7b561192a7342443e5d7f61c44fd9d016eac48e95d3011f090ceea65a727e83a31d51fabdd9fc20ff9992edcbc682 languageName: node linkType: hard From 46ef3738d2ee1e099aaa5394d3cb3a543465ed50 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 22:41:56 +0000 Subject: [PATCH 123/136] chore(deps): update dependency style-loader to v3.3.4 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index ce8d610a38e..95929e3cf74 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -94,7 +94,7 @@ "postcss": "8.4.33", "postcss-loader": "7.3.4", "randomstring": "1.3.0", - "style-loader": "3.3.3", + "style-loader": "3.3.4", "tailwindcss": "3.4.1", "terser-webpack-plugin": "5.3.10", "ts-jest": "29.1.1", diff --git a/yarn.lock b/yarn.lock index e1491d86e3a..82a5674fe05 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3684,7 +3684,7 @@ __metadata: randomstring: 1.3.0 react: 18.2.0 react-dom: 18.2.0 - style-loader: 3.3.3 + style-loader: 3.3.4 tailwindcss: 3.4.1 terser-webpack-plugin: 5.3.10 thememirror: 2.0.1 @@ -24594,12 +24594,12 @@ __metadata: languageName: node linkType: hard -"style-loader@npm:3.3.3": - version: 3.3.3 - resolution: "style-loader@npm:3.3.3" +"style-loader@npm:3.3.4": + version: 3.3.4 + resolution: "style-loader@npm:3.3.4" peerDependencies: webpack: ^5.0.0 - checksum: f59c953f56f6a935bd6a1dfa409f1128fed2b66b48ce4a7a75b85862a7156e5e90ab163878962762f528ec4d510903d828da645e143fbffd26f055dc1c094078 + checksum: caac3f2fe2c3c89e49b7a2a9329e1cfa515ecf5f36b9c4885f9b218019fda207a9029939b2c35821dec177a264a007e7c391ccdd3ff7401881ce6287b9c8f38b languageName: node linkType: hard From 4b6ef577053e2d3521a225db856ad751171ddeb1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 01:47:14 +0000 Subject: [PATCH 124/136] fix(deps): update codemirror --- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 95929e3cf74..1f213da94bb 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -43,9 +43,9 @@ "author": "Neo4j", "dependencies": { "@codemirror/autocomplete": "6.11.1", - "@codemirror/commands": "6.3.2", + "@codemirror/commands": "6.3.3", "@codemirror/lang-javascript": "6.2.1", - "@codemirror/language": "6.9.3", + "@codemirror/language": "6.10.0", "@dnd-kit/core": "6.1.0", "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", diff --git a/yarn.lock b/yarn.lock index 82a5674fe05..7a60c1f4640 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1735,15 +1735,15 @@ __metadata: languageName: node linkType: hard -"@codemirror/commands@npm:6.3.2": - version: 6.3.2 - resolution: "@codemirror/commands@npm:6.3.2" +"@codemirror/commands@npm:6.3.3": + version: 6.3.3 + resolution: "@codemirror/commands@npm:6.3.3" dependencies: "@codemirror/language": ^6.0.0 - "@codemirror/state": ^6.2.0 + "@codemirror/state": ^6.4.0 "@codemirror/view": ^6.0.0 "@lezer/common": ^1.1.0 - checksum: 683c444d8e6ad889ab5efd0d742b0fa28b78c8cad63276ec60d298b13d4939c8bd7e1d6fd3535645b8d255147de0d3aef46d89a29c19d0af58a7f2914bdcb3ab + checksum: 7d23aecc973823969434b839aefa9a98bb47212d2ce0e6869ae903adbb5233aad22a760788fb7bb6eb45b00b01a4932fb93ad43bacdcbc0215e7500cf54b17bb languageName: node linkType: hard @@ -1774,17 +1774,17 @@ __metadata: languageName: node linkType: hard -"@codemirror/language@npm:6.9.3": - version: 6.9.3 - resolution: "@codemirror/language@npm:6.9.3" +"@codemirror/language@npm:6.10.0": + version: 6.10.0 + resolution: "@codemirror/language@npm:6.10.0" dependencies: "@codemirror/state": ^6.0.0 - "@codemirror/view": ^6.0.0 + "@codemirror/view": ^6.23.0 "@lezer/common": ^1.1.0 "@lezer/highlight": ^1.0.0 "@lezer/lr": ^1.0.0 style-mod: ^4.0.0 - checksum: 774a40bc91c748d418a9a774161a5b083061124e4439bb753072bc657ec4c4784f595161c10c7c3935154b22291bf6dc74c9abe827033db32e217ac3963478f3 + checksum: 3bfd9968f5a34ce22434489a5b226db5f3bc454a1ae7c4381587ff4270ac6af61b10f93df560cb73e9a77cc13d4843722a7a7b94dbed02a3ab1971dd329b9e81 languageName: node linkType: hard @@ -1831,7 +1831,7 @@ __metadata: languageName: node linkType: hard -"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.9.0": +"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.9.0": version: 6.23.0 resolution: "@codemirror/view@npm:6.23.0" dependencies: @@ -3637,9 +3637,9 @@ __metadata: resolution: "@neo4j/graphql-toolbox@workspace:packages/graphql-toolbox" dependencies: "@codemirror/autocomplete": 6.11.1 - "@codemirror/commands": 6.3.2 + "@codemirror/commands": 6.3.3 "@codemirror/lang-javascript": 6.2.1 - "@codemirror/language": 6.9.3 + "@codemirror/language": 6.10.0 "@dnd-kit/core": 6.1.0 "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 From ad11dfee3849aca385457cb814d41e4f86955f4c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 01:57:08 +0000 Subject: [PATCH 125/136] chore(deps): update dependency css-loader to v6.9.0 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 28 +++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 1f213da94bb..988c7620842 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -81,7 +81,7 @@ "compression-webpack-plugin": "10.0.0", "copy-webpack-plugin": "11.0.0", "cross-env": "7.0.3", - "css-loader": "6.8.1", + "css-loader": "6.9.0", "dotenv": "16.3.1", "fork-ts-checker-webpack-plugin": "9.0.2", "html-inline-script-webpack-plugin": "3.2.1", diff --git a/yarn.lock b/yarn.lock index 7a60c1f4640..6dfc1f2b02f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3662,7 +3662,7 @@ __metadata: compression-webpack-plugin: 10.0.0 copy-webpack-plugin: 11.0.0 cross-env: 7.0.3 - css-loader: 6.8.1 + css-loader: 6.9.0 dotenv: 16.3.1 dotenv-webpack: 8.0.1 fork-ts-checker-webpack-plugin: 9.0.2 @@ -11490,21 +11490,21 @@ __metadata: languageName: node linkType: hard -"css-loader@npm:6.8.1": - version: 6.8.1 - resolution: "css-loader@npm:6.8.1" +"css-loader@npm:6.9.0": + version: 6.9.0 + resolution: "css-loader@npm:6.9.0" dependencies: icss-utils: ^5.1.0 - postcss: ^8.4.21 + postcss: ^8.4.31 postcss-modules-extract-imports: ^3.0.0 postcss-modules-local-by-default: ^4.0.3 - postcss-modules-scope: ^3.0.0 + postcss-modules-scope: ^3.1.0 postcss-modules-values: ^4.0.0 postcss-value-parser: ^4.2.0 - semver: ^7.3.8 + semver: ^7.5.4 peerDependencies: webpack: ^5.0.0 - checksum: 7c1784247bdbe76dc5c55fb1ac84f1d4177a74c47259942c9cfdb7a8e6baef11967a0bc85ac285f26bd26d5059decb848af8154a03fdb4f4894f41212f45eef3 + checksum: 71f20ee5eb5a4a9373ab41a5c17df411cb4f6f2de037297a2b0c2150681578f4979f319f4307a61e23c231dd6546e657ae95cba5a0698ad13ca43f91d4d2a0bc languageName: node linkType: hard @@ -21629,14 +21629,14 @@ __metadata: languageName: node linkType: hard -"postcss-modules-scope@npm:^3.0.0": - version: 3.0.0 - resolution: "postcss-modules-scope@npm:3.0.0" +"postcss-modules-scope@npm:^3.1.0": + version: 3.1.0 + resolution: "postcss-modules-scope@npm:3.1.0" dependencies: postcss-selector-parser: ^6.0.4 peerDependencies: postcss: ^8.1.0 - checksum: 330b9398dbd44c992c92b0dc612c0626135e2cc840fee41841eb61247a6cfed95af2bd6f67ead9dd9d0bb41f5b0367129d93c6e434fa3e9c58ade391d9a5a138 + checksum: 919d02e2e31956fa3dae2036d4f3259c9b8c5361bd58ee55867edededbee03507df88e98f418b5e553e47f3888daba9ea9ef0b18a82c41cf96cdb74df15322c7 languageName: node linkType: hard @@ -21679,7 +21679,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:8.4.33": +"postcss@npm:8.4.33, postcss@npm:^8.4.31": version: 8.4.33 resolution: "postcss@npm:8.4.33" dependencies: @@ -21690,7 +21690,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^8.1.10, postcss@npm:^8.4.21, postcss@npm:^8.4.23": +"postcss@npm:^8.1.10, postcss@npm:^8.4.23": version: 8.4.30 resolution: "postcss@npm:8.4.30" dependencies: From 83e1272b4c92a8ab7d43d953dee4fdbcabb5ddf4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 02:08:13 +0000 Subject: [PATCH 126/136] fix(deps): update neo4j-ndl to v2.3.0 --- packages/graphql-toolbox/package.json | 4 ++-- yarn.lock | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index 988c7620842..bb4a6f536b7 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -50,8 +50,8 @@ "@dnd-kit/modifiers": "7.0.0", "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", - "@neo4j-ndl/base": "2.2.0", - "@neo4j-ndl/react": "2.2.0", + "@neo4j-ndl/base": "2.3.0", + "@neo4j-ndl/react": "2.3.0", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.5.1", diff --git a/yarn.lock b/yarn.lock index 6dfc1f2b02f..2aee3ce496a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3527,21 +3527,21 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/base@npm:2.2.0, @neo4j-ndl/base@npm:^2.2.0": - version: 2.2.0 - resolution: "@neo4j-ndl/base@npm:2.2.0" - checksum: 22078b0c26bc33e8ca1458b190e735cfbadf6421d2378e0b96a73b7abd1660fb549a5cda16fb5b13a89e121911a7f87f8d5865635343d1c774be05da7494a509 +"@neo4j-ndl/base@npm:2.3.0, @neo4j-ndl/base@npm:^2.3.0": + version: 2.3.0 + resolution: "@neo4j-ndl/base@npm:2.3.0" + checksum: c8d7da4516a3c2216db3a44471ed16b4d46cf4c2641eadddcc04faf24f11156a602f0fb4b13379ccd6f4d74ce7df0e7e080591c8746334d5be20ed515106d7a5 languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.2.0": - version: 2.2.0 - resolution: "@neo4j-ndl/react@npm:2.2.0" +"@neo4j-ndl/react@npm:2.3.0": + version: 2.3.0 + resolution: "@neo4j-ndl/react@npm:2.3.0" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 "@neo4j-cypher/react-codemirror": ^1.0.1 - "@neo4j-ndl/base": ^2.2.0 + "@neo4j-ndl/base": ^2.3.0 "@table-nav/core": 0.0.7 "@table-nav/react": 0.0.7 "@tanstack/react-table": ^8.9.3 @@ -3562,7 +3562,7 @@ __metadata: peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: 88b079fedf3ac571d44daf6f495a420a813e89893cbadf5b053268f7c73f985f08b4523c767f6febab4bc3ed9a01c60d613fa5ddbcc83fdf4a504eb2c696f9f4 + checksum: d1801b0812eb64e7b89f25a71ba998d5fc4b0fbbbbb6cc3f275f99b626ff0b363553a5ceb27837d3abd69c4c40e519296ebfe598ca65e3e53f9461d4dd7b6cbf languageName: node linkType: hard @@ -3644,8 +3644,8 @@ __metadata: "@dnd-kit/modifiers": 7.0.0 "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 - "@neo4j-ndl/base": 2.2.0 - "@neo4j-ndl/react": 2.2.0 + "@neo4j-ndl/base": 2.3.0 + "@neo4j-ndl/react": 2.3.0 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 From a9e8bef7bdeabb235f94518458acff74d19c2b19 Mon Sep 17 00:00:00 2001 From: Andreas Berger Date: Wed, 10 Jan 2024 11:53:43 +0100 Subject: [PATCH 127/136] chore: clean up leftovers of @exclude-directive (#4494) Co-authored-by: Darrell Warde <8117355+darrellwarde@users.noreply.github.com> --- packages/graphql/src/classes/Exclude.ts | 32 --- packages/graphql/src/classes/Node.ts | 8 - packages/graphql/src/classes/index.ts | 1 - .../arguments/enums/CallbackOperation.ts | 30 --- .../arguments/enums/ExcludeOperation.ts | 32 --- packages/graphql/src/schema/get-nodes.ts | 36 +--- .../schema/parse-exclude-directive.test.ts | 67 ------- .../src/schema/parse-exclude-directive.ts | 44 ---- .../src/schema/schema-configuration.test.ts | 145 -------------- .../src/schema/schema-configuration.ts | 189 ------------------ 10 files changed, 1 insertion(+), 583 deletions(-) delete mode 100644 packages/graphql/src/classes/Exclude.ts delete mode 100644 packages/graphql/src/graphql/directives/arguments/enums/CallbackOperation.ts delete mode 100644 packages/graphql/src/graphql/directives/arguments/enums/ExcludeOperation.ts delete mode 100644 packages/graphql/src/schema/parse-exclude-directive.test.ts delete mode 100644 packages/graphql/src/schema/parse-exclude-directive.ts delete mode 100644 packages/graphql/src/schema/schema-configuration.test.ts delete mode 100644 packages/graphql/src/schema/schema-configuration.ts diff --git a/packages/graphql/src/classes/Exclude.ts b/packages/graphql/src/classes/Exclude.ts deleted file mode 100644 index 7922d5c7050..00000000000 --- a/packages/graphql/src/classes/Exclude.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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. - */ - -export interface ExcludeConstructor { - operations: string[]; -} - -class Exclude { - public operations: string[]; - - constructor(input: ExcludeConstructor) { - this.operations = input.operations; - } -} - -export default Exclude; diff --git a/packages/graphql/src/classes/Node.ts b/packages/graphql/src/classes/Node.ts index edc2262594c..bc8f25ce884 100644 --- a/packages/graphql/src/classes/Node.ts +++ b/packages/graphql/src/classes/Node.ts @@ -37,12 +37,10 @@ import type { import type { DecodedGlobalId } from "../utils/global-ids"; import { fromGlobalId, toGlobalId } from "../utils/global-ids"; import { upperFirst } from "../utils/upper-first"; -import type Exclude from "./Exclude"; import type { GraphElementConstructor } from "./GraphElement"; import { GraphElement } from "./GraphElement"; import type { NodeDirective } from "./NodeDirective"; import type { LimitDirective } from "./LimitDirective"; -import type { SchemaConfiguration } from "../schema/schema-configuration"; import { leadingUnderscores } from "../utils/leading-underscore"; import type { Neo4jGraphQLContext } from "../types/neo4j-graphql-context"; @@ -64,8 +62,6 @@ export interface NodeConstructor extends GraphElementConstructor { pointFields: PointField[]; plural?: string; fulltextDirective?: FullText; - exclude?: Exclude; - schemaConfiguration?: SchemaConfiguration; nodeDirective?: NodeDirective; description?: string; limitDirective?: LimitDirective; @@ -129,8 +125,6 @@ class Node extends GraphElement { public interfaceFields: InterfaceField[]; public interfaces: NamedTypeNode[]; public objectFields: ObjectField[]; - public exclude?: Exclude; - public schemaConfiguration?: SchemaConfiguration; public nodeDirective?: NodeDirective; public fulltextDirective?: FullText; public description?: string; @@ -152,8 +146,6 @@ class Node extends GraphElement { this.interfaceFields = input.interfaceFields; this.interfaces = input.interfaces; this.objectFields = input.objectFields; - this.exclude = input.exclude; - this.schemaConfiguration = input.schemaConfiguration; this.nodeDirective = input.nodeDirective; this.fulltextDirective = input.fulltextDirective; this.limit = input.limitDirective; diff --git a/packages/graphql/src/classes/index.ts b/packages/graphql/src/classes/index.ts index 75f7b0ec171..64da04bf09d 100644 --- a/packages/graphql/src/classes/index.ts +++ b/packages/graphql/src/classes/index.ts @@ -18,7 +18,6 @@ */ export * from "./Error"; -export { default as Exclude, ExcludeConstructor } from "./Exclude"; export { GraphElement } from "./GraphElement"; export { Neo4jDatabaseInfo } from "./Neo4jDatabaseInfo"; export { default as Neo4jGraphQL, Neo4jGraphQLConstructor } from "./Neo4jGraphQL"; diff --git a/packages/graphql/src/graphql/directives/arguments/enums/CallbackOperation.ts b/packages/graphql/src/graphql/directives/arguments/enums/CallbackOperation.ts deleted file mode 100644 index 2a532381262..00000000000 --- a/packages/graphql/src/graphql/directives/arguments/enums/CallbackOperation.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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 { GraphQLEnumType } from "graphql"; - -/** Deprecated in favour of @populatedBy */ -export const CallbackOperationEnum = new GraphQLEnumType({ - name: "CallbackOperation", - description: "*For use in the @callback directive only*", - values: { - CREATE: {}, - UPDATE: {}, - }, -}); diff --git a/packages/graphql/src/graphql/directives/arguments/enums/ExcludeOperation.ts b/packages/graphql/src/graphql/directives/arguments/enums/ExcludeOperation.ts deleted file mode 100644 index b8f953ebffd..00000000000 --- a/packages/graphql/src/graphql/directives/arguments/enums/ExcludeOperation.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 { GraphQLEnumType } from "graphql"; - -export const ExcludeOperationEnum = new GraphQLEnumType({ - name: "ExcludeOperation", - description: "*For use in the @exclude directive only*", - values: { - CREATE: {}, - READ: {}, - UPDATE: {}, - DELETE: {}, - SUBSCRIBE: {}, - }, -}); diff --git a/packages/graphql/src/schema/get-nodes.ts b/packages/graphql/src/schema/get-nodes.ts index 735c3800170..fe6d95482e6 100644 --- a/packages/graphql/src/schema/get-nodes.ts +++ b/packages/graphql/src/schema/get-nodes.ts @@ -18,8 +18,7 @@ */ import type { IResolvers } from "@graphql-tools/utils"; -import type { DirectiveNode, NamedTypeNode } from "graphql"; -import type { Exclude } from "../classes"; +import type { NamedTypeNode } from "graphql"; import { Node } from "../classes"; import type { NodeDirective } from "../classes/NodeDirective"; import type { LimitDirective } from "../classes/LimitDirective"; @@ -27,12 +26,10 @@ import type { FullText, Neo4jGraphQLCallbacks } from "../types"; import { asArray } from "../utils/utils"; import type { DefinitionNodes } from "./get-definition-nodes"; import getObjFieldMeta from "./get-obj-field-meta"; -import parseExcludeDirective from "./parse-exclude-directive"; import parseNodeDirective from "./parse-node-directive"; import parseFulltextDirective from "./parse/parse-fulltext-directive"; import parsePluralDirective from "./parse/parse-plural-directive"; import { parseLimitDirective } from "./parse/parse-limit-directive"; -import { schemaConfigurationFromObjectTypeDefinition } from "./schema-configuration"; type Nodes = { nodes: Node[]; @@ -81,40 +78,12 @@ function getNodes( ["deprecated", "shareable"].includes(x.name.value) ); - const excludeDirective = (definition.directives || []).find((x) => x.name.value === "exclude"); const nodeDirectiveDefinition = (definition.directives || []).find((x) => x.name.value === "node"); const pluralDirectiveDefinition = (definition.directives || []).find((x) => x.name.value === "plural"); const fulltextDirectiveDefinition = (definition.directives || []).find((x) => x.name.value === "fulltext"); const limitDirectiveDefinition = (definition.directives || []).find((x) => x.name.value === "limit"); const nodeInterfaces = [...(definition.interfaces || [])] as NamedTypeNode[]; - const { interfaceExcludeDirectives } = nodeInterfaces.reduce<{ - interfaceAuthDirectives: DirectiveNode[]; - interfaceExcludeDirectives: DirectiveNode[]; - }>( - (res, interfaceName) => { - const iface = definitionNodes.interfaceTypes.find((i) => i.name.value === interfaceName.name.value); - - if (iface) { - const interfaceExcludeDirective = (iface.directives || []).find((x) => x.name.value === "exclude"); - - if (interfaceExcludeDirective) { - res.interfaceExcludeDirectives.push(interfaceExcludeDirective); - } - } - - return res; - }, - { interfaceAuthDirectives: [], interfaceExcludeDirectives: [] } - ); - - let exclude: Exclude; - if (excludeDirective || interfaceExcludeDirectives.length) { - exclude = parseExcludeDirective(excludeDirective || interfaceExcludeDirectives[0]); - } - - const schemaConfiguration = schemaConfigurationFromObjectTypeDefinition(definition); - let nodeDirective: NodeDirective; if (nodeDirectiveDefinition) { nodeDirective = parseNodeDirective(nodeDirectiveDefinition); @@ -181,9 +150,6 @@ function getNodes( propagatedDirectives, ...nodeFields, // @ts-ignore we can be sure it's defined - exclude, - schemaConfiguration, - // @ts-ignore we can be sure it's defined nodeDirective, // @ts-ignore we can be sure it's defined fulltextDirective, diff --git a/packages/graphql/src/schema/parse-exclude-directive.test.ts b/packages/graphql/src/schema/parse-exclude-directive.test.ts deleted file mode 100644 index 3a8103bb9a4..00000000000 --- a/packages/graphql/src/schema/parse-exclude-directive.test.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 { DirectiveNode } from "graphql"; -import { parse } from "graphql"; -import parseExcludeDirective from "./parse-exclude-directive"; -import { Exclude } from "../classes"; - -describe("parseExcludeDirective", () => { - test("should throw an error if incorrect directive is passed in", () => { - const typeDefs = ` - type TestType @wrongdirective { - name: String - } - `; - - const directive = (parse(typeDefs) as any).definitions[0].directives[0] as DirectiveNode | undefined; - - expect(() => parseExcludeDirective(directive)).toThrow( - "Undefined or incorrect directive passed into parseExcludeDirective function" - ); - }); - - test("should return array of operations to ignore given valid array input", () => { - const typeDefs = ` - type TestType @exclude(operations: [CREATE, DELETE]) { - name: String - } - `; - - const directive = (parse(typeDefs) as any).definitions[0].directives[0] as DirectiveNode | undefined; - - const expected = new Exclude({ operations: ["create", "delete"] }); - - expect(parseExcludeDirective(directive)).toMatchObject(expected); - }); - - test("should return array of all operations to ignore given valid input of '*'", () => { - const typeDefs = ` - type TestType @exclude { - name: String - } - `; - - const directive = (parse(typeDefs) as any).definitions[0].directives[0] as DirectiveNode | undefined; - - const expected = new Exclude({ operations: ["create", "read", "update", "delete", "subscribe"] }); - - expect(parseExcludeDirective(directive)).toMatchObject(expected); - }); -}); diff --git a/packages/graphql/src/schema/parse-exclude-directive.ts b/packages/graphql/src/schema/parse-exclude-directive.ts deleted file mode 100644 index a5e6ed3df44..00000000000 --- a/packages/graphql/src/schema/parse-exclude-directive.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 { DirectiveNode, ArgumentNode } from "graphql"; -import { valueFromASTUntyped } from "graphql"; -import { Exclude } from "../classes"; - -function parseExcludeDirective(excludeDirective: DirectiveNode | undefined | null) { - if (!excludeDirective || excludeDirective.name.value !== "exclude") { - throw new Error("Undefined or incorrect directive passed into parseExcludeDirective function"); - } - - const allResolvers = ["create", "read", "update", "delete", "subscribe"]; - - if (!excludeDirective.arguments?.length) { - return new Exclude({ operations: allResolvers }); - } - - const operations = excludeDirective.arguments?.find((a) => a.name.value === "operations") as ArgumentNode; - - const argumentValue = valueFromASTUntyped(operations.value) as string[]; - - const result = argumentValue.map((val: string) => val.toLowerCase()); - - return new Exclude({ operations: result }); -} - -export default parseExcludeDirective; diff --git a/packages/graphql/src/schema/schema-configuration.test.ts b/packages/graphql/src/schema/schema-configuration.test.ts deleted file mode 100644 index c3be009048b..00000000000 --- a/packages/graphql/src/schema/schema-configuration.test.ts +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 { ObjectTypeDefinitionNode, SchemaExtensionNode } from "graphql"; -import { Kind, parse } from "graphql"; -import { QueryDirective } from "../classes/QueryDirective"; -import { SubscriptionDirective } from "../classes/SubscriptionDirective"; -import { - getSchemaConfigurationFlags, - schemaConfigurationFromObjectTypeDefinition, - schemaConfigurationFromSchemaExtensions, -} from "./schema-configuration"; -import parseExcludeDirective from "./parse-exclude-directive"; -import { SubscriptionEvent } from "../graphql/directives/subscription"; - -describe("schemaConfiguration", () => { - test("schemaConfigurationFromObjectTypeDefinition should return a Schema Configuration object", () => { - const typeDefs = ` - type TestType @query(read:false) @subscription { - name: String - } - `; - - const definition = parse(typeDefs).definitions[0] as ObjectTypeDefinitionNode; - const schemaConfiguration = schemaConfigurationFromObjectTypeDefinition(definition); - - expect(schemaConfiguration).toMatchObject({ - queryDirective: new QueryDirective({ read: false, aggregate: false }), - subscriptionDirective: new SubscriptionDirective([ - SubscriptionEvent.CREATED, - SubscriptionEvent.DELETED, - SubscriptionEvent.UPDATED, - SubscriptionEvent.RELATIONSHIP_CREATED, - SubscriptionEvent.RELATIONSHIP_DELETED, - ]), - }); - }); - - test("schemaConfigurationFromSchemaExtensions should return a SchemaConfiguration object", () => { - const typeDefs = ` - type TestType @query(read:false) { - name: String - } - extend schema @subscription - `; - - const schemaExtensions = parse(typeDefs).definitions.filter( - (definition) => definition.kind === Kind.SCHEMA_EXTENSION - ) as SchemaExtensionNode[]; - const schemaConfiguration = schemaConfigurationFromSchemaExtensions(schemaExtensions); - - expect(schemaConfiguration).toMatchObject({ - subscriptionDirective: new SubscriptionDirective([ - SubscriptionEvent.CREATED, - SubscriptionEvent.DELETED, - SubscriptionEvent.UPDATED, - SubscriptionEvent.RELATIONSHIP_CREATED, - SubscriptionEvent.RELATIONSHIP_DELETED, - ]), - }); - }); - - test("getSchemaConfigurationFlags should return the correct flags", () => { - const typeDefs = ` - type TestType @query(read:false) @mutation(operations: [CREATE, DELETE]) { - name: String - } - extend schema @subscription(events: [CREATED]) - `; - - const documentNode = parse(typeDefs); - const schemaExtensions = documentNode.definitions.filter( - (definition) => definition.kind === Kind.SCHEMA_EXTENSION - ) as SchemaExtensionNode[]; - const objectTypeDefinition = documentNode.definitions.find( - (definition) => definition.kind === Kind.OBJECT_TYPE_DEFINITION - ) as ObjectTypeDefinitionNode; - const nodeSchemaConfiguration = schemaConfigurationFromObjectTypeDefinition(objectTypeDefinition); - const globalSchemaConfiguration = schemaConfigurationFromSchemaExtensions(schemaExtensions); - const schemaConfigurationFlags = getSchemaConfigurationFlags({ - nodeSchemaConfiguration, - globalSchemaConfiguration, - }); - - expect(schemaConfigurationFlags).toEqual({ - read: false, - aggregate: false, - create: true, - delete: true, - update: false, - subscribeCreate: true, - subscribeCreateRelationship: false, - subscribeDelete: false, - subscribeDeleteRelationship: false, - subscribeUpdate: false, - }); - }); - - test("getSchemaConfigurationFlags should return the correct flags when used with the deprecated exclude directive", () => { - const typeDefs = ` - type TestType @exclude(operations: [CREATE, DELETE]) { - name: String - } - `; - - const documentNode = parse(typeDefs); - const objectTypeDefinition = documentNode.definitions.find( - (definition) => definition.kind === Kind.OBJECT_TYPE_DEFINITION - ) as ObjectTypeDefinitionNode; - const exclude = (objectTypeDefinition.directives as any[])[0]; - const excludeDirective = parseExcludeDirective(exclude); - const schemaConfigurationFlags = getSchemaConfigurationFlags({ - excludeDirective, - }); - - expect(schemaConfigurationFlags).toEqual({ - read: true, - aggregate: true, - create: false, - delete: false, - update: true, - subscribeCreate: true, - subscribeCreateRelationship: true, - subscribeDelete: true, - subscribeDeleteRelationship: true, - subscribeUpdate: true, - }); - }); -}); diff --git a/packages/graphql/src/schema/schema-configuration.ts b/packages/graphql/src/schema/schema-configuration.ts deleted file mode 100644 index 9406ba9d082..00000000000 --- a/packages/graphql/src/schema/schema-configuration.ts +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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 { ObjectTypeDefinitionNode, SchemaExtensionNode } from "graphql"; -import type { Exclude } from "../classes"; -import type { MutationDirective } from "../classes/MutationDirective"; -import type { QueryDirective } from "../classes/QueryDirective"; -import type { SubscriptionDirective } from "../classes/SubscriptionDirective"; -import { - mutationDirective as mutationDirectiveDefinition, - queryDirective as queryDirectiveDefinition, - subscriptionDirective as subscriptionDirectiveDefinition, -} from "../graphql/directives"; -import parseMutationDirective from "./parse-mutation-directive"; -import parseQueryDirective from "./parse-query-directive"; -import parseSubscriptionDirective from "./parse-subscription-directive"; - -export type SchemaConfiguration = { - queryDirective?: QueryDirective; - mutationDirective?: MutationDirective; - subscriptionDirective?: SubscriptionDirective; -}; - -type SchemaConfigurationFlags = { - read: boolean; - aggregate: boolean; - create: boolean; - delete: boolean; - update: boolean; - subscribeCreate: boolean; - subscribeUpdate: boolean; - subscribeDelete: boolean; - subscribeCreateRelationship: boolean; - subscribeDeleteRelationship: boolean; -}; - -// obtain a schema configuration object from a list of SchemaExtensionNode -export function schemaConfigurationFromSchemaExtensions(schemaExtensions: SchemaExtensionNode[]): SchemaConfiguration { - const schemaConfiguration: SchemaConfiguration = {}; - - for (const schemaExtension of schemaExtensions) { - for (const directive of schemaExtension.directives || []) { - if (directive.name.value === queryDirectiveDefinition.name) { - if (schemaConfiguration.queryDirective) { - throw new Error(`Ambiguous usage with the directive named: ${queryDirectiveDefinition.name}`); - } - schemaConfiguration.queryDirective = parseQueryDirective(directive); - } - - if (directive.name.value === mutationDirectiveDefinition.name) { - if (schemaConfiguration.mutationDirective) { - throw new Error(`Ambiguity usage with the directive named: ${queryDirectiveDefinition.name}`); - } - schemaConfiguration.mutationDirective = parseMutationDirective(directive); - } - - if (directive.name.value === subscriptionDirectiveDefinition.name) { - if (schemaConfiguration.subscriptionDirective) { - throw new Error(`Ambiguous usage with the directive named: ${queryDirectiveDefinition.name}`); - } - schemaConfiguration.subscriptionDirective = parseSubscriptionDirective(directive); - } - } - } - return schemaConfiguration; -} - -// obtain a schema configuration object from a ObjectTypeDefinition -export function schemaConfigurationFromObjectTypeDefinition(definition: ObjectTypeDefinitionNode): SchemaConfiguration { - const schemaConfiguration: SchemaConfiguration = {}; - - for (const directive of definition.directives || []) { - if (directive.name.value === queryDirectiveDefinition.name) { - schemaConfiguration.queryDirective = parseQueryDirective(directive); - } - - if (directive.name.value === mutationDirectiveDefinition.name) { - schemaConfiguration.mutationDirective = parseMutationDirective(directive); - } - - if (directive.name.value === subscriptionDirectiveDefinition.name) { - schemaConfiguration.subscriptionDirective = parseSubscriptionDirective(directive); - } - } - - return schemaConfiguration; -} - -// takes the directives that may mutate the output schema and returns a SchemaConfigurationFlags object -export function getSchemaConfigurationFlags(options: { - nodeSchemaConfiguration?: SchemaConfiguration; - globalSchemaConfiguration?: SchemaConfiguration; - excludeDirective?: Exclude; -}) { - // avoid mixing between the exclude directive and the new schema configurations one - if ( - options.excludeDirective && - (options.globalSchemaConfiguration?.queryDirective || - options.nodeSchemaConfiguration?.queryDirective || - options.globalSchemaConfiguration?.mutationDirective || - options.nodeSchemaConfiguration?.mutationDirective) - ) { - throw new Error( - "@exclude directive is a deprecated directive and cannot be used in conjunction with @query, @mutation, @subscription" - ); - } - - // avoid mixing configurations on both schema and object - if (options.globalSchemaConfiguration?.queryDirective && options.nodeSchemaConfiguration?.queryDirective) { - throw new Error("@query directive already defined at the schema location"); - } - - if (options.globalSchemaConfiguration?.mutationDirective && options.nodeSchemaConfiguration?.mutationDirective) { - throw new Error("@mutation directive already defined at the schema location"); - } - - if ( - options.globalSchemaConfiguration?.subscriptionDirective && - options.nodeSchemaConfiguration?.subscriptionDirective - ) { - throw new Error("@subscription directive already defined at the schema location"); - } - - const schemaConfigurationFlags: SchemaConfigurationFlags = { - read: true, - aggregate: true, - create: true, - delete: true, - update: true, - subscribeCreate: true, - subscribeUpdate: true, - subscribeDelete: true, - subscribeCreateRelationship: true, - subscribeDeleteRelationship: true, - }; - - if (options.excludeDirective) { - const excludeOperationsSet = new Set(options.excludeDirective.operations); - schemaConfigurationFlags.read = schemaConfigurationFlags.aggregate = !excludeOperationsSet.has("read"); - schemaConfigurationFlags.create = !excludeOperationsSet.has("create"); - schemaConfigurationFlags.delete = !excludeOperationsSet.has("delete"); - schemaConfigurationFlags.update = !excludeOperationsSet.has("update"); - } - - const queryDirective = - options.nodeSchemaConfiguration?.queryDirective || options.globalSchemaConfiguration?.queryDirective; - const mutationDirective = - options.nodeSchemaConfiguration?.mutationDirective || options.globalSchemaConfiguration?.mutationDirective; - const subscriptionDirective = - options.globalSchemaConfiguration?.subscriptionDirective || - options.nodeSchemaConfiguration?.subscriptionDirective; - - if (queryDirective) { - schemaConfigurationFlags.read = queryDirective.read; - schemaConfigurationFlags.aggregate = queryDirective.aggregate; - } - - if (mutationDirective) { - schemaConfigurationFlags.create = mutationDirective.create; - schemaConfigurationFlags.update = mutationDirective.update; - schemaConfigurationFlags.delete = mutationDirective.delete; - } - - if (subscriptionDirective) { - schemaConfigurationFlags.subscribeCreate = subscriptionDirective.created; - schemaConfigurationFlags.subscribeUpdate = subscriptionDirective.updated; - schemaConfigurationFlags.subscribeDelete = subscriptionDirective.deleted; - schemaConfigurationFlags.subscribeCreateRelationship = subscriptionDirective.relationshipCreated; - schemaConfigurationFlags.subscribeDeleteRelationship = subscriptionDirective.relationshipDeleted; - } - - return schemaConfigurationFlags; -} From 4ba8b36147ce9c88dfaa1aa74f2fbc7fbb19b50b Mon Sep 17 00:00:00 2001 From: Andreas Berger Date: Wed, 10 Jan 2024 17:25:55 +0100 Subject: [PATCH 128/136] chore: clean up leftovers of @readonly and @writeonly directives (#4500) --- packages/graphql/src/index.ts | 1 - .../graphql/src/schema/get-obj-field-meta.ts | 8 --- packages/graphql/src/schema/to-compose.ts | 55 +------------------ ...create-relationship-property-value.test.ts | 6 -- packages/graphql/src/types/index.ts | 2 - .../ogm/src/utils/filter-document.test.ts | 16 +++--- packages/ogm/src/utils/filter-document.ts | 8 +-- .../ogm/tests/integration/ogm.int.test.ts | 4 +- 8 files changed, 15 insertions(+), 85 deletions(-) diff --git a/packages/graphql/src/index.ts b/packages/graphql/src/index.ts index 465ec689cac..9d41079c396 100644 --- a/packages/graphql/src/index.ts +++ b/packages/graphql/src/index.ts @@ -19,7 +19,6 @@ import { Neo4jGraphQL, Neo4jGraphQLConstructor } from "./classes"; import { Neo4jGraphQLContext } from "./types/neo4j-graphql-context"; - import * as directives from "./graphql/directives"; import { CartesianPoint } from "./graphql/objects/CartesianPoint"; import { Point } from "./graphql/objects/Point"; diff --git a/packages/graphql/src/schema/get-obj-field-meta.ts b/packages/graphql/src/schema/get-obj-field-meta.ts index 43167fc9816..3e11e35606b 100644 --- a/packages/graphql/src/schema/get-obj-field-meta.ts +++ b/packages/graphql/src/schema/get-obj-field-meta.ts @@ -170,8 +170,6 @@ function getObjFieldMeta({ "id", "authorization", "authentication", - "readonly", - "writeonly", "customResolver", "default", "coalesce", @@ -190,12 +188,6 @@ function getObjFieldMeta({ ), arguments: [...(field.arguments || [])], description: field.description?.value, - readonly: - directives.some((d) => d.name.value === "readonly") || - interfaceField?.directives?.some((x) => x.name.value === "readonly"), - writeonly: - directives.some((d) => d.name.value === "writeonly") || - interfaceField?.directives?.some((x) => x.name.value === "writeonly"), ...(unique ? { unique } : {}), }; diff --git a/packages/graphql/src/schema/to-compose.ts b/packages/graphql/src/schema/to-compose.ts index 3fc49586334..8b6ad6b456d 100644 --- a/packages/graphql/src/schema/to-compose.ts +++ b/packages/graphql/src/schema/to-compose.ts @@ -17,7 +17,7 @@ * limitations under the License. */ -import type { DirectiveNode, InputValueDefinitionNode } from "graphql"; +import type { DirectiveNode } from "graphql"; import { GraphQLInt } from "graphql"; import type { Directive, @@ -33,27 +33,11 @@ import type { ConcreteEntityAdapter } from "../schema-model/entity/model-adapter import type { InterfaceEntityAdapter } from "../schema-model/entity/model-adapters/InterfaceEntityAdapter"; import { parseValueNode } from "../schema-model/parser/parse-value-node"; import { RelationshipAdapter } from "../schema-model/relationship/model-adapters/RelationshipAdapter"; -import type { BaseField, InputField, PrimitiveField, TemporalField } from "../types"; +import type { InputField } from "../types"; import { DEPRECATE_NOT } from "./constants"; -import getFieldTypeMeta from "./get-field-type-meta"; import { idResolver } from "./resolvers/field/id"; import { numericalResolver } from "./resolvers/field/numerical"; -export function graphqlInputValueToCompose(args: InputValueDefinitionNode[]) { - return args.reduce((res, arg) => { - const meta = getFieldTypeMeta(arg.type); - - return { - ...res, - [arg.name.value]: { - type: meta.pretty, - description: arg.description, - ...(arg.defaultValue ? { defaultValue: parseValueNode(arg.defaultValue) } : {}), - }, - }; - }, {}); -} - export function graphqlArgsToCompose(args: Argument[]) { return args.reduce((res, arg) => { const inputValueAdapter = new ArgumentAdapter(arg); @@ -81,40 +65,6 @@ export function graphqlDirectivesToCompose(directives: DirectiveNode[]): Directi })); } -export function objectFieldsToComposeFields(fields: BaseField[]): { - [k: string]: ObjectTypeComposerFieldConfigAsObjectDefinition; -} { - return fields.reduce((res, field) => { - if (field.writeonly || field.selectableOptions.onRead === false) { - return res; - } - - const newField: ObjectTypeComposerFieldConfigAsObjectDefinition = { - type: field.typeMeta.pretty, - args: {}, - description: field.description, - }; - - if (field.otherDirectives.length) { - newField.directives = graphqlDirectivesToCompose(field.otherDirectives); - } - - if (["Int", "Float"].includes(field.typeMeta.name)) { - newField.resolve = numericalResolver; - } - - if (field.typeMeta.name === "ID") { - newField.resolve = idResolver; - } - - if (field.arguments) { - newField.args = graphqlInputValueToCompose(field.arguments); - } - - return { ...res, [field.fieldName]: newField }; - }, {}); -} - export function relationshipAdapterToComposeFields( objectFields: RelationshipAdapter[], userDefinedFieldDirectives: Map @@ -334,6 +284,7 @@ export function withMathOperators(): AdditionalFieldsCallback { return fields; }; } + export function withArrayOperators(): AdditionalFieldsCallback { return (attribute: AttributeAdapter): InputTypeComposerFieldConfigMapDefinition => { const fields: InputTypeComposerFieldConfigMapDefinition = {}; diff --git a/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts b/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts index 2f8cbb36f9f..b12c40de964 100644 --- a/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts +++ b/packages/graphql/src/translate/projection/elements/create-relationship-property-value.test.ts @@ -72,8 +72,6 @@ describe("createRelationshipPropertyElement", () => { otherDirectives: [], arguments: [], description: undefined, - readonly: false, - writeonly: false, } as PrimitiveField, ], pointFields: [ @@ -115,8 +113,6 @@ describe("createRelationshipPropertyElement", () => { otherDirectives: [], arguments: [], description: undefined, - readonly: false, - writeonly: false, } as PointField, ], temporalFields: [ @@ -158,8 +154,6 @@ describe("createRelationshipPropertyElement", () => { otherDirectives: [], arguments: [], description: undefined, - readonly: false, - writeonly: false, } as TemporalField, ], }); diff --git a/packages/graphql/src/types/index.ts b/packages/graphql/src/types/index.ts index 07eec2daf0e..352731284c7 100644 --- a/packages/graphql/src/types/index.ts +++ b/packages/graphql/src/types/index.ts @@ -113,8 +113,6 @@ export interface BaseField { arguments: InputValueDefinitionNode[]; private?: boolean; description?: string; - readonly?: boolean; - writeonly?: boolean; dbPropertyName?: string; dbPropertyNameUnescaped?: string; unique?: Unique; diff --git a/packages/ogm/src/utils/filter-document.test.ts b/packages/ogm/src/utils/filter-document.test.ts index ad66d007e90..786175db2f2 100644 --- a/packages/ogm/src/utils/filter-document.test.ts +++ b/packages/ogm/src/utils/filter-document.test.ts @@ -23,13 +23,13 @@ import { filterDocument } from "./filter-document"; describe("filterDocument", () => { test("should remove all directives", () => { const initial = ` - type User @auth @exclude { - id: ID @auth @private @readonly @writeonly - name: String @auth @private @readonly @writeonly - email: String @auth @private @readonly @writeonly - password: String @auth @private @readonly @writeonly + type User @authentication @authorization { + id: ID @id @private @unique + name: String @authentication @authorization @private + email: String @cypher @private + password: String @private cars: [Car!]! @relationship(type: "HAS_CAR", direction: OUT, aggregate: false) - bikes: [Car!]! @relationship(type: "HAS_CAR", direction: OUT) + bikes: [Car!]! @relationship(type: "HAS_CAR", direction: OUT) } type Car @query(read: false, aggregate: false) @mutation(operations: []), @subscription(events: []) { @@ -50,9 +50,9 @@ describe("filterDocument", () => { expect(print(filtered)).toMatchInlineSnapshot(` "type User { - id: ID + id: ID @id @unique name: String - email: String + email: String @cypher password: String cars: [Car!]! @relationship(type: \\"HAS_CAR\\", direction: OUT, aggregate: true) bikes: [Car!]! @relationship(type: \\"HAS_CAR\\", direction: OUT, aggregate: true) diff --git a/packages/ogm/src/utils/filter-document.ts b/packages/ogm/src/utils/filter-document.ts index e09ac2cab46..5da26ac76dd 100644 --- a/packages/ogm/src/utils/filter-document.ts +++ b/packages/ogm/src/utils/filter-document.ts @@ -22,14 +22,10 @@ import type { Neo4jGraphQLConstructor } from "@neo4j/graphql"; import { mergeTypeDefs } from "@graphql-tools/merge"; const excludedDirectives = [ - "auth", "authentication", "authorization", "subscriptionsAuthorization", - "exclude", "private", - "readonly", - "writeonly", "query", "mutation", "subscription", @@ -41,8 +37,8 @@ const excludedDirectives = [ export function filterDocument(typeDefs: Neo4jGraphQLConstructor["typeDefs"]): DocumentNode { // hack to keep aggregation enabled for OGM const schemaExtension = ` - extend schema @query(read: true, aggregate: true) - @mutation(operations: [CREATE, UPDATE, DELETE]) + extend schema @query(read: true, aggregate: true) + @mutation(operations: [CREATE, UPDATE, DELETE]) @subscription(events: [CREATED, UPDATED, DELETED, RELATIONSHIP_CREATED, RELATIONSHIP_DELETED])`; const merged = mergeTypeDefs( Array.isArray(typeDefs) ? (typeDefs as string[]).concat(schemaExtension) : [typeDefs as string, schemaExtension] diff --git a/packages/ogm/tests/integration/ogm.int.test.ts b/packages/ogm/tests/integration/ogm.int.test.ts index 391167307b5..b36004ef7b7 100644 --- a/packages/ogm/tests/integration/ogm.int.test.ts +++ b/packages/ogm/tests/integration/ogm.int.test.ts @@ -78,11 +78,11 @@ describe("OGM", () => { await session.close(); }); - test("should filter the document and remove directives such as auth", async () => { + test("should filter the document and remove directives such as authentication", async () => { const session = driver.session(); const typeDefs = ` - type ${typeMovie} @auth(rules: [{ isAuthenticated: true }]){ + type ${typeMovie} @authentication { id: ID } `; From 1817014b3719711211807288d7377f4042a175f9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:07:08 +0000 Subject: [PATCH 129/136] chore(deps): update node.js to f6723db --- packages/apollo-federation-subgraph-compatibility/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/apollo-federation-subgraph-compatibility/Dockerfile b/packages/apollo-federation-subgraph-compatibility/Dockerfile index 238a02b55db..98468a951ef 100644 --- a/packages/apollo-federation-subgraph-compatibility/Dockerfile +++ b/packages/apollo-federation-subgraph-compatibility/Dockerfile @@ -1,4 +1,4 @@ -FROM node:lts@sha256:8d0f16fe841577f9317ab49011c6d819e1fa81f8d4af7ece7ae0ac815e07ac84 +FROM node:lts@sha256:f6723dbbf1e45514d53944acff25086259d9ad0d04d20ca16979109dcd807012 WORKDIR /app From dd5caefc55ffb4cbe0863d8d92e8ee0b7b971a0a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 10 Jan 2024 23:16:37 +0000 Subject: [PATCH 130/136] chore(deps): update dependency eslint-plugin-jest to v27.6.2 --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0f5cb61abb9..5339623e870 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "eslint-import-resolver-typescript": "3.6.1", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.29.1", - "eslint-plugin-jest": "27.6.1", + "eslint-plugin-jest": "27.6.2", "eslint-plugin-jsx-a11y": "6.8.0", "eslint-plugin-react": "7.33.2", "eslint-plugin-simple-import-sort": "10.0.0", diff --git a/yarn.lock b/yarn.lock index 2aee3ce496a..afec7c35790 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13282,9 +13282,9 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-jest@npm:27.6.1": - version: 27.6.1 - resolution: "eslint-plugin-jest@npm:27.6.1" +"eslint-plugin-jest@npm:27.6.2": + version: 27.6.2 + resolution: "eslint-plugin-jest@npm:27.6.2" dependencies: "@typescript-eslint/utils": ^5.10.0 peerDependencies: @@ -13296,7 +13296,7 @@ __metadata: optional: true jest: optional: true - checksum: 03dc4784119a06504718b3ec1a5944c8d41fe73669d23433fa794e4059be857ec463da6d5982dcd2920da091fe7c5c033fa69a91f4dfbe3f41aac6db99b8c3d0 + checksum: 9c2a950d0e7e76dd1b55016800088ab86ce590df24d0abf8573b09c547969daa395157de55408307824deae1cfde136cbaffb85932f28eceec0689f68cbdd3bf languageName: node linkType: hard @@ -19881,7 +19881,7 @@ __metadata: eslint-import-resolver-typescript: 3.6.1 eslint-plugin-eslint-comments: 3.2.0 eslint-plugin-import: 2.29.1 - eslint-plugin-jest: 27.6.1 + eslint-plugin-jest: 27.6.2 eslint-plugin-jsx-a11y: 6.8.0 eslint-plugin-react: 7.33.2 eslint-plugin-simple-import-sort: 10.0.0 From 0492cb0c456b9835aa560e8832bca5fdf1fee62b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 00:48:05 +0000 Subject: [PATCH 131/136] chore(deps): update node.js to 7ba59ab --- packages/apollo-federation-subgraph-compatibility/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/apollo-federation-subgraph-compatibility/Dockerfile b/packages/apollo-federation-subgraph-compatibility/Dockerfile index 98468a951ef..b84972e8f4a 100644 --- a/packages/apollo-federation-subgraph-compatibility/Dockerfile +++ b/packages/apollo-federation-subgraph-compatibility/Dockerfile @@ -1,4 +1,4 @@ -FROM node:lts@sha256:f6723dbbf1e45514d53944acff25086259d9ad0d04d20ca16979109dcd807012 +FROM node:lts@sha256:7ba59ab8fe65c91b7d1945e456457c242d2cadaae912ba43ac8e179af6d43183 WORKDIR /app From 3502b1b4f69922b64492a60197fc71e822addd9d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 00:57:26 +0000 Subject: [PATCH 132/136] fix(deps): update dependency @neo4j-ndl/react to v2.3.1 --- packages/graphql-toolbox/package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index bb4a6f536b7..aee13ab236d 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -51,7 +51,7 @@ "@dnd-kit/sortable": "8.0.0", "@graphiql/react": "0.20.2", "@neo4j-ndl/base": "2.3.0", - "@neo4j-ndl/react": "2.3.0", + "@neo4j-ndl/react": "2.3.1", "@neo4j/graphql": "4.4.4", "@neo4j/introspector": "2.0.0", "classnames": "2.5.1", diff --git a/yarn.lock b/yarn.lock index afec7c35790..b644cd0d99f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3534,9 +3534,9 @@ __metadata: languageName: node linkType: hard -"@neo4j-ndl/react@npm:2.3.0": - version: 2.3.0 - resolution: "@neo4j-ndl/react@npm:2.3.0" +"@neo4j-ndl/react@npm:2.3.1": + version: 2.3.1 + resolution: "@neo4j-ndl/react@npm:2.3.1" dependencies: "@floating-ui/react": 0.25.1 "@heroicons/react": 2.0.13 @@ -3562,7 +3562,7 @@ __metadata: peerDependencies: "@heroicons/react": 2.0.13 react: ">=16.8.0" - checksum: d1801b0812eb64e7b89f25a71ba998d5fc4b0fbbbbb6cc3f275f99b626ff0b363553a5ceb27837d3abd69c4c40e519296ebfe598ca65e3e53f9461d4dd7b6cbf + checksum: 69d160bf5fb4af372d580c35faaffffb7b3638a5e0f4195257b7d876c56a70c6fb8b4876b3b175af65ba6adf933105877596357f32b1b144d00bb21e34a3efd2 languageName: node linkType: hard @@ -3645,7 +3645,7 @@ __metadata: "@dnd-kit/sortable": 8.0.0 "@graphiql/react": 0.20.2 "@neo4j-ndl/base": 2.3.0 - "@neo4j-ndl/react": 2.3.0 + "@neo4j-ndl/react": 2.3.1 "@neo4j/graphql": 4.4.4 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 From 0431e6606ff95b53eb1e18addb7f70a288e084d4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jan 2024 01:07:00 +0000 Subject: [PATCH 133/136] chore(deps): update node.js to v20.11.0 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d2d3df4d5de..03d16673b0d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20.10.0-buster-slim@sha256:d0acb10d0062944abd19d56d79f4953de6bba167b04c961c6eba6054fbc4990c +FROM node:20.11.0-buster-slim@sha256:045eb1471de28085f2388f7307b87f1b66329ed6335c86dc79e15b4f8705d187 WORKDIR /app From 66a19c56f00be90a8c0c6be294c98d402b0f4c5e Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:24:13 +0100 Subject: [PATCH 134/136] Fix: 4477 filtering by count on an aggregate (#4507) * test: add tck and integration tests * fix: add filterSubqueries to transpileNestedRelationship * docs: add changeset --- .changeset/unlucky-forks-pretend.md | 5 + .../queryAST/ast/operations/ReadOperation.ts | 44 ++--- .../tests/integration/issues/4477.int.test.ts | 150 ++++++++++++++++++ .../graphql/tests/tck/issues/4477.test.ts | 90 +++++++++++ 4 files changed, 268 insertions(+), 21 deletions(-) create mode 100644 .changeset/unlucky-forks-pretend.md create mode 100644 packages/graphql/tests/integration/issues/4477.int.test.ts create mode 100644 packages/graphql/tests/tck/issues/4477.test.ts diff --git a/.changeset/unlucky-forks-pretend.md b/.changeset/unlucky-forks-pretend.md new file mode 100644 index 00000000000..40fc1518e4e --- /dev/null +++ b/.changeset/unlucky-forks-pretend.md @@ -0,0 +1,5 @@ +--- +"@neo4j/graphql": patch +--- + +Fixes filtering on nested read operations diff --git a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts index 91d7060ed6e..c0365cea9ce 100644 --- a/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts +++ b/packages/graphql/src/translate/queryAST/ast/operations/ReadOperation.ts @@ -106,41 +106,48 @@ export class ReadOperation extends Operation { ): OperationTranspileResult { const isCreateSelection = context.env.topLevelOperationName === "CREATE"; //TODO: dupe from transpile - if (!hasTarget(context)) throw new Error("No parent node found!"); + if (!hasTarget(context)) { + throw new Error("No parent node found!"); + } // eslint-disable-next-line prefer-const let { selection: matchClause, nestedContext } = this.selection.apply(context); + const filterSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.filters, [nestedContext.target]); const filterPredicates = this.getPredicates(nestedContext); + const fieldSubqueries = this.getFieldsSubqueries(nestedContext); + const cypherFieldSubqueries = this.getCypherFieldsSubqueries(nestedContext); + const subqueries = Cypher.concat(...fieldSubqueries, ...cypherFieldSubqueries); + const sortSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.sortFields, [nestedContext.target]); const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => new Cypher.Call(sq).innerWith(nestedContext.target) ); + const authFiltersPredicate = this.getAuthFilterPredicate(nestedContext); + const ret = this.getProjectionClause(nestedContext, context.returnVariable, entity.isList); let extraMatches: SelectionClause[] = this.getChildren().flatMap((f) => { return f.getSelection(nestedContext); }); - if (extraMatches.length > 0) { extraMatches = [matchClause, ...extraMatches]; matchClause = new Cypher.With("*"); } - const wherePredicate = Cypher.and(filterPredicates, ...authFiltersPredicate); - let withWhere: Cypher.With | undefined; - let filterSubqueryWith: Cypher.With | undefined; - + let filterSubqueriesClause: Cypher.Clause | undefined = undefined; // This weird condition is just for cypher compatibility - const shouldAddWithForAuth = authFiltersPredicate.length > 0; - if (authFilterSubqueries.length > 0 || shouldAddWithForAuth) { + const shouldAddWithForAuth = authFilterSubqueries.length > 0 || authFiltersPredicate.length > 0; + if (filterSubqueries.length > 0 || shouldAddWithForAuth) { if (!isCreateSelection || authFilterSubqueries.length) { + filterSubqueriesClause = Cypher.concat(...filterSubqueries); // for creates auth filters sometimes use variables from the subquery filterSubqueryWith = new Cypher.With("*"); } } + const wherePredicate = Cypher.and(filterPredicates, ...authFiltersPredicate); if (wherePredicate) { if (filterSubqueryWith) { filterSubqueryWith.where(wherePredicate); // TODO: should this only be for aggregation filters? @@ -149,17 +156,12 @@ export class ReadOperation extends Operation { } } - const cypherFieldSubqueries = this.getCypherFieldsSubqueries(nestedContext); - const subqueries = Cypher.concat(...this.getFieldsSubqueries(nestedContext), ...cypherFieldSubqueries); - const sortSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.sortFields, [nestedContext.target]); - const ret = this.getProjectionClause(nestedContext, context.returnVariable, entity.isList); - const clause = Cypher.concat( ...extraMatches, matchClause, ...authFilterSubqueries, + filterSubqueriesClause, filterSubqueryWith, - withWhere, subqueries, ...sortSubqueries, ret @@ -202,6 +204,7 @@ export class ReadOperation extends Operation { } let { selection: matchClause, nestedContext } = this.selection.apply(context); + const isCreateSelection = nestedContext.env.topLevelOperationName === "CREATE"; if (isCreateSelection) { if (!context.hasTarget()) { @@ -216,14 +219,14 @@ export class ReadOperation extends Operation { const filterSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.filters, [nestedContext.target]); const filterPredicates = this.getPredicates(nestedContext); + const fieldSubqueries = this.getFieldsSubqueries(nestedContext); + const cypherFieldSubqueries = this.getCypherFieldsSubqueries(nestedContext); + const subqueries = Cypher.concat(...fieldSubqueries); + const sortSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.sortFields, [nestedContext.target]); const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => new Cypher.Call(sq).innerWith(nestedContext.target) ); - const fieldSubqueries = this.getFieldsSubqueries(nestedContext); - const cypherFieldSubqueries = this.getCypherFieldsSubqueries(nestedContext); - const sortSubqueries = wrapSubqueriesInCypherCalls(nestedContext, this.sortFields, [nestedContext.target]); - const subqueries = Cypher.concat(...fieldSubqueries); const authFiltersPredicate = this.getAuthFilterPredicate(nestedContext); const ret: Cypher.Return = this.getReturnStatement( @@ -234,14 +237,13 @@ export class ReadOperation extends Operation { let extraMatches: SelectionClause[] = this.getChildren().flatMap((f) => { return f.getSelection(nestedContext); }); - if (extraMatches.length > 0) { extraMatches = [matchClause, ...extraMatches]; matchClause = new Cypher.With("*"); } + let filterSubqueryWith: Cypher.With | undefined; let filterSubqueriesClause: Cypher.Clause | undefined = undefined; - // This weird condition is just for cypher compatibility const shouldAddWithForAuth = authFiltersPredicate.length > 0; if (filterSubqueries.length > 0 || shouldAddWithForAuth) { @@ -275,7 +277,7 @@ export class ReadOperation extends Operation { : Cypher.concat(sortBlock, ...cypherFieldSubqueries); let clause: Cypher.Clause; - // Top-level read part of a mutation does not contains the MATCH clause as is implicit in the mutation. + // Top-level read part of a mutation does not contain the MATCH clause as it is implicit in the mutation. if (isCreateSelection) { clause = Cypher.concat(filterSubqueriesClause, filterSubqueryWith, sortAndLimitBlock, subqueries, ret); } else { diff --git a/packages/graphql/tests/integration/issues/4477.int.test.ts b/packages/graphql/tests/integration/issues/4477.int.test.ts new file mode 100644 index 00000000000..a7d1bb1fa7c --- /dev/null +++ b/packages/graphql/tests/integration/issues/4477.int.test.ts @@ -0,0 +1,150 @@ +/* + * 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 { graphql } from "graphql"; +import type { Driver } from "neo4j-driver"; +import { Neo4jGraphQL } from "../../../src/classes"; +import { cleanNodes } from "../../utils/clean-nodes"; +import { UniqueType } from "../../utils/graphql-types"; +import Neo4j from "../neo4j"; + +describe("https://github.com/neo4j/graphql/issues/4477", () => { + let driver: Driver; + let neo4j: Neo4j; + let neo4jGraphql: Neo4jGraphQL; + + const Brand = new UniqueType("Brand"); + const Service = new UniqueType("Service"); + const Collection = new UniqueType("Collection"); + + beforeAll(async () => { + neo4j = new Neo4j(); + driver = await neo4j.getDriver(); + const typeDefs = /* GraphQL */ ` + type ${Brand} { + services: [${Service}!]! @relationship(type: "HAS_SERVICE", direction: OUT) + name: String! + } + + type ${Collection} { + services: [${Service}!]! @relationship(type: "HAS_SERVICE", direction: OUT) + } + + type ${Service} { + collection: ${Collection} @relationship(type: "HAS_SERVICE", direction: IN) + } + `; + + neo4jGraphql = new Neo4jGraphQL({ + typeDefs, + driver, + }); + + const session = await neo4j.getSession(); + try { + await session.run( + ` + CREATE + (brand1:${Brand} {name: 'brand1'}), + (brand2:${Brand} {name: 'brand2'}), + (collection1:${Collection}), + (collection2:${Collection}), + (service1:${Service}), + (service2:${Service}), + (service3:${Service}), + (service4:${Service}), + (brand1)-[:HAS_SERVICE]->(service1), + (brand1)-[:HAS_SERVICE]->(service2), + (brand2)-[:HAS_SERVICE]->(service3), + (brand2)-[:HAS_SERVICE]->(service4), + (collection1)-[:HAS_SERVICE]->(service1), + (collection1)-[:HAS_SERVICE]->(service2), + (collection2)-[:HAS_SERVICE]->(service3) + `, + {} + ); + } finally { + await session.close(); + } + }); + + afterAll(async () => { + const session = await neo4j.getSession(); + try { + await cleanNodes(session, [Brand, Service, Collection]); + } finally { + await session.close(); + } + await driver.close(); + }); + + test("filtering by count on an aggregate should work", async () => { + const schema = await neo4jGraphql.getSchema(); + + const query = /* GraphQL */ ` + query { + ${Brand.plural} { + name + services(where: { collectionAggregate: { count: 1 } }) { + collectionAggregate { + count + } + } + } + } + `; + + const response = await graphql({ + schema, + source: query, + contextValue: neo4j.getContextValues(), + }); + + expect(response.errors).toBeFalsy(); + expect(response.data).toEqual({ + [Brand.plural]: [ + { + name: "brand1", + services: [ + { + collectionAggregate: { + count: 1, + }, + }, + { + collectionAggregate: { + count: 1, + }, + }, + ], + }, + { + name: "brand2", + services: [ + { + collectionAggregate: { + count: 1, + }, + }, + ], + }, + ], + }); + }); +}); diff --git a/packages/graphql/tests/tck/issues/4477.test.ts b/packages/graphql/tests/tck/issues/4477.test.ts new file mode 100644 index 00000000000..898ed642478 --- /dev/null +++ b/packages/graphql/tests/tck/issues/4477.test.ts @@ -0,0 +1,90 @@ +/* + * 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 gql from "graphql-tag"; +import { Neo4jGraphQL } from "../../../src"; +import { formatCypher, formatParams, translateQuery } from "../utils/tck-test-utils"; + +describe("https://github.com/neo4j/graphql/issues/4477", () => { + test("filtering by count on an aggregate should work", async () => { + const typeDefs = /* GraphQL */ ` + type Brand { + services: [Service!]! @relationship(type: "HAS_SERVICE", direction: OUT) + name: String! + } + + type Collection { + services: [Service!]! @relationship(type: "HAS_SERVICE", direction: OUT) + } + + type Service { + collection: Collection @relationship(type: "HAS_SERVICE", direction: IN) + } + `; + + const neoSchema = new Neo4jGraphQL({ typeDefs }); + + const query = gql` + query { + brands { + name + services(where: { collectionAggregate: { count: 0 } }) { + collectionAggregate { + count + } + } + } + } + `; + + const result = await translateQuery(neoSchema, query); + + expect(formatCypher(result.cypher)).toMatchInlineSnapshot(` + "MATCH (this:Brand) + CALL { + WITH this + MATCH (this)-[this0:HAS_SERVICE]->(this1:Service) + CALL { + WITH this1 + MATCH (this1)<-[this2:HAS_SERVICE]-(this3:Collection) + RETURN count(this3) = $param0 AS var4 + } + WITH * + WHERE var4 = true + CALL { + WITH this1 + MATCH (this1)<-[this5:HAS_SERVICE]-(this6:Collection) + RETURN count(this6) AS var7 + } + WITH this1 { collectionAggregate: { count: var7 } } AS this1 + RETURN collect(this1) AS var8 + } + RETURN this { .name, services: var8 } AS this" + `); + + expect(formatParams(result.params)).toMatchInlineSnapshot(` + "{ + \\"param0\\": { + \\"low\\": 0, + \\"high\\": 0 + } + }" + `); + }); +}); From 45279af91ea3b5a138bf88fad8f5a4206f62f2a2 Mon Sep 17 00:00:00 2001 From: Darrell Warde <8117355+darrellwarde@users.noreply.github.com> Date: Mon, 15 Jan 2024 11:50:20 +0000 Subject: [PATCH 135/136] Modified behaviour for test DBs (#4510) * Modified behaviour for test DBs * Also drop indexes and constraints --- packages/graphql/jest.config.js | 1 - packages/graphql/jest.global-setup.js | 16 ++++++++-- packages/graphql/jest.global-teardown.js | 38 ------------------------ 3 files changed, 13 insertions(+), 42 deletions(-) delete mode 100644 packages/graphql/jest.global-teardown.js diff --git a/packages/graphql/jest.config.js b/packages/graphql/jest.config.js index c19d69936ee..4c531e5654a 100644 --- a/packages/graphql/jest.config.js +++ b/packages/graphql/jest.config.js @@ -6,7 +6,6 @@ module.exports = { displayName: "@neo4j/graphql", globalSetup: path.join(__dirname, "jest.global-setup.js"), setupFilesAfterEnv: ["jest-extended/all"], - globalTeardown: path.join(__dirname, "jest.global-teardown.js"), roots: ["/packages/graphql/src/", "/packages/graphql/tests/"], coverageDirectory: "/packages/graphql/coverage/", transform: { diff --git a/packages/graphql/jest.global-setup.js b/packages/graphql/jest.global-setup.js index eac6fe2d261..5024dfeece5 100644 --- a/packages/graphql/jest.global-setup.js +++ b/packages/graphql/jest.global-setup.js @@ -4,6 +4,9 @@ const neo4j = require("neo4j-driver"); const TZ = "Etc/UTC"; const INT_TEST_DB_NAME = "neo4jgraphqlinttestdatabase"; +const cypherDropData = `MATCH (n) DETACH DELETE n`; +const cypherDropIndexes = `CALL apoc.schema.assert({},{},true) YIELD label, key RETURN *`; + module.exports = async function globalSetup() { process.env.NODE_ENV = "test"; @@ -19,12 +22,13 @@ module.exports = async function globalSetup() { let session = null; try { + session = driver.session(); const hasMultiDbSupport = await driver.supportsMultiDb(); if (process.env.USE_DEFAULT_DB || !hasMultiDbSupport) { - // INFO: We do nothing in case the dbms has no multi-db support. + // If we know at this stage that we need to drop data only, then do so + await dropDataAndIndexes(session); return; } - session = driver.session(); await session.run(cypherCreateDb); } catch (error) { if ( @@ -39,11 +43,17 @@ module.exports = async function globalSetup() { ); } else { console.log( - `\nJest /packages/graphql setup: Setup failure on neo4j @ ${NEO_URL}, cypher: "${cypherCreateDb}", Error: ${error.message}` + `\nJest /packages/graphql setup: Failure to create test DB on neo4j @ ${NEO_URL}, cypher: "${cypherCreateDb}", Error: ${error.message}. Falling back to drop data.` ); + await dropDataAndIndexes(session); } } finally { if (session) await session.close(); if (driver) await driver.close(); } }; + +async function dropDataAndIndexes(session) { + await session.run(cypherDropData); + await session.run(cypherDropIndexes); +} diff --git a/packages/graphql/jest.global-teardown.js b/packages/graphql/jest.global-teardown.js deleted file mode 100644 index 0ae368b3a75..00000000000 --- a/packages/graphql/jest.global-teardown.js +++ /dev/null @@ -1,38 +0,0 @@ -const neo4j = require("neo4j-driver"); - -module.exports = async function globalTeardown() { - const { NEO_USER = "neo4j", NEO_PASSWORD = "password", NEO_URL = "neo4j://localhost:7687/neo4j" } = process.env; - const auth = neo4j.auth.basic(NEO_USER, NEO_PASSWORD); - const driver = neo4j.driver(NEO_URL, auth); - const cypherDropDb = `DROP DATABASE ${global.INT_TEST_DB_NAME} IF EXISTS`; - let session = null; - - try { - const hasMultiDbSupport = await driver.supportsMultiDb(); - if (process.env.USE_DEFAULT_DB || !hasMultiDbSupport) { - // INFO: We do nothing in case the dbms has no multi-db support. - return; - } - session = driver.session(); - await session.run(cypherDropDb); - } catch (error) { - if ( - error.message.includes( - "This is an administration command and it should be executed against the system database" - ) || - error.message.includes("Unsupported administration command") || - error.message.includes("Unable to route write operation to leader for database 'system'") - ) { - console.log( - `\nJest /packages/graphql teardown: Expected action - NO drop of database as not supported in the current environment.` - ); - } else { - console.log( - `\nJest /packages/graphql teardown: Teardown failure on neo4j @ ${NEO_URL}, cypher: "${cypherDropDb}", Error: ${error.message}` - ); - } - } finally { - if (session) await session.close(); - if (driver) await driver.close(); - } -}; From ffdc2cbf023bbe9f8a57bada6072fecf4ad0168c Mon Sep 17 00:00:00 2001 From: Neo4j Team GraphQL <88824828+neo4j-team-graphql@users.noreply.github.com> Date: Tue, 16 Jan 2024 08:13:50 +0000 Subject: [PATCH 136/136] Version Packages (#4376) --- .changeset/early-foxes-tickle.md | 7 --- .changeset/friendly-rockets-drive.md | 28 --------- .changeset/khaki-spiders-heal.md | 5 -- .changeset/mighty-windows-knock.md | 25 -------- .changeset/two-phones-look.md | 5 -- .changeset/unlucky-forks-pretend.md | 5 -- .../package.json | 2 +- packages/graphql-toolbox/CHANGELOG.md | 7 +++ packages/graphql-toolbox/package.json | 4 +- packages/graphql/CHANGELOG.md | 61 +++++++++++++++++++ packages/graphql/package.json | 2 +- packages/ogm/CHANGELOG.md | 7 +++ packages/ogm/package.json | 4 +- yarn.lock | 8 +-- 14 files changed, 85 insertions(+), 85 deletions(-) delete mode 100644 .changeset/early-foxes-tickle.md delete mode 100644 .changeset/friendly-rockets-drive.md delete mode 100644 .changeset/khaki-spiders-heal.md delete mode 100644 .changeset/mighty-windows-knock.md delete mode 100644 .changeset/two-phones-look.md delete mode 100644 .changeset/unlucky-forks-pretend.md diff --git a/.changeset/early-foxes-tickle.md b/.changeset/early-foxes-tickle.md deleted file mode 100644 index 42b030b52b6..00000000000 --- a/.changeset/early-foxes-tickle.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@neo4j/graphql": patch ---- - -Fix: allow non-generated mutations on timestamp fields - -Before this patch, it wasn't possible to update a field with a timestamp directive even when the directive specified that only the UPDATE or CREATE operation field should be generated by the database. diff --git a/.changeset/friendly-rockets-drive.md b/.changeset/friendly-rockets-drive.md deleted file mode 100644 index 130aff57d85..00000000000 --- a/.changeset/friendly-rockets-drive.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@neo4j/graphql": patch ---- - -Add support for logical operators on filters for interfaces under the experimental flag: - -``` -interface Show { - title: String! -} - -type Movie implements Show { - title: String! -} - -type Series implements Show { - title: String! -} - -``` - -``` -query actedInWhere { - shows(where: { OR: [{ title: "Show 1" }, { title: "Show 2" }] }) { - title - } -} -``` diff --git a/.changeset/khaki-spiders-heal.md b/.changeset/khaki-spiders-heal.md deleted file mode 100644 index 96a48d9e168..00000000000 --- a/.changeset/khaki-spiders-heal.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@neo4j/graphql": patch ---- - -Remove \_on filter for interfaces under experimental flag diff --git a/.changeset/mighty-windows-knock.md b/.changeset/mighty-windows-knock.md deleted file mode 100644 index d2f4446951f..00000000000 --- a/.changeset/mighty-windows-knock.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@neo4j/graphql": patch ---- - -Add support for typename_IN filters for interfaces under the experimental flag: - -``` -interface Show { - title: String! -} -type Movie implements Show { - title: String! -} -type Series implements Show { - title: String! -} -``` - -``` -query actedInWhere { - shows(where: { typename_IN: [Series] }) { - title - } -} -``` diff --git a/.changeset/two-phones-look.md b/.changeset/two-phones-look.md deleted file mode 100644 index d5c76c39f48..00000000000 --- a/.changeset/two-phones-look.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@neo4j/graphql": patch ---- - -Fix authorization variable naming in create operations diff --git a/.changeset/unlucky-forks-pretend.md b/.changeset/unlucky-forks-pretend.md deleted file mode 100644 index 40fc1518e4e..00000000000 --- a/.changeset/unlucky-forks-pretend.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@neo4j/graphql": patch ---- - -Fixes filtering on nested read operations diff --git a/packages/apollo-federation-subgraph-compatibility/package.json b/packages/apollo-federation-subgraph-compatibility/package.json index b5eed4f3cd2..4e12e3fb044 100644 --- a/packages/apollo-federation-subgraph-compatibility/package.json +++ b/packages/apollo-federation-subgraph-compatibility/package.json @@ -10,7 +10,7 @@ "dependencies": { "@apollo/server": "^4.7.0", "@graphql-tools/wrap": "^10.0.0", - "@neo4j/graphql": "^4.4.4", + "@neo4j/graphql": "^4.4.5", "graphql": "16.8.1", "graphql-tag": "^2.12.6", "neo4j-driver": "^5.8.0" diff --git a/packages/graphql-toolbox/CHANGELOG.md b/packages/graphql-toolbox/CHANGELOG.md index 6895d7e984e..3fb09f2c391 100644 --- a/packages/graphql-toolbox/CHANGELOG.md +++ b/packages/graphql-toolbox/CHANGELOG.md @@ -1,5 +1,12 @@ # @neo4j/graphql-toolbox +## 2.1.7 + +### Patch Changes + +- Updated dependencies [[`2bb8f8b`](https://github.com/neo4j/graphql/commit/2bb8f8b628c52c102c2db988685fc54f08521488), [`d3c6d0e`](https://github.com/neo4j/graphql/commit/d3c6d0e8897dfc7ca168f1c387c6c33b92f8cb56), [`5c42f8d`](https://github.com/neo4j/graphql/commit/5c42f8d5226dcc87c804bc752d676fdc9f623d30), [`387e455`](https://github.com/neo4j/graphql/commit/387e455bb9aebb94663b05baed6c8694ec304e80), [`4b97531`](https://github.com/neo4j/graphql/commit/4b97531170c399f243ee848c17a8e38a80e14a51), [`66a19c5`](https://github.com/neo4j/graphql/commit/66a19c56f00be90a8c0c6be294c98d402b0f4c5e)]: + - @neo4j/graphql@4.4.5 + ## 2.1.6 ### Patch Changes diff --git a/packages/graphql-toolbox/package.json b/packages/graphql-toolbox/package.json index aee13ab236d..53dfe073cf0 100644 --- a/packages/graphql-toolbox/package.json +++ b/packages/graphql-toolbox/package.json @@ -1,7 +1,7 @@ { "name": "@neo4j/graphql-toolbox", "private": true, - "version": "2.1.6", + "version": "2.1.7", "description": "Developer UI For Neo4j GraphQL", "exports": "./dist/main.js", "main": "./dist/main.js", @@ -52,7 +52,7 @@ "@graphiql/react": "0.20.2", "@neo4j-ndl/base": "2.3.0", "@neo4j-ndl/react": "2.3.1", - "@neo4j/graphql": "4.4.4", + "@neo4j/graphql": "4.4.5", "@neo4j/introspector": "2.0.0", "classnames": "2.5.1", "cm6-graphql": "0.0.12", diff --git a/packages/graphql/CHANGELOG.md b/packages/graphql/CHANGELOG.md index 8c79fbfe432..d00f0c62e0f 100644 --- a/packages/graphql/CHANGELOG.md +++ b/packages/graphql/CHANGELOG.md @@ -1,5 +1,66 @@ # @neo4j/graphql +## 4.4.5 + +### Patch Changes + +- [#4449](https://github.com/neo4j/graphql/pull/4449) [`2bb8f8b`](https://github.com/neo4j/graphql/commit/2bb8f8b628c52c102c2db988685fc54f08521488) Thanks [@mjfwebb](https://github.com/mjfwebb)! - Fix: allow non-generated mutations on timestamp fields + + Before this patch, it wasn't possible to update a field with a timestamp directive even when the directive specified that only the UPDATE or CREATE operation field should be generated by the database. + +- [#4375](https://github.com/neo4j/graphql/pull/4375) [`d3c6d0e`](https://github.com/neo4j/graphql/commit/d3c6d0e8897dfc7ca168f1c387c6c33b92f8cb56) Thanks [@angrykoala](https://github.com/angrykoala)! - Add support for logical operators on filters for interfaces under the experimental flag: + + ``` + interface Show { + title: String! + } + + type Movie implements Show { + title: String! + } + + type Series implements Show { + title: String! + } + + ``` + + ``` + query actedInWhere { + shows(where: { OR: [{ title: "Show 1" }, { title: "Show 2" }] }) { + title + } + } + ``` + +- [#4360](https://github.com/neo4j/graphql/pull/4360) [`5c42f8d`](https://github.com/neo4j/graphql/commit/5c42f8d5226dcc87c804bc752d676fdc9f623d30) Thanks [@angrykoala](https://github.com/angrykoala)! - Remove \_on filter for interfaces under experimental flag + +- [#4409](https://github.com/neo4j/graphql/pull/4409) [`387e455`](https://github.com/neo4j/graphql/commit/387e455bb9aebb94663b05baed6c8694ec304e80) Thanks [@MacondoExpress](https://github.com/MacondoExpress)! - Add support for typename_IN filters for interfaces under the experimental flag: + + ``` + interface Show { + title: String! + } + type Movie implements Show { + title: String! + } + type Series implements Show { + title: String! + } + ``` + + ``` + query actedInWhere { + shows(where: { typename_IN: [Series] }) { + title + } + } + ``` + +- [#4483](https://github.com/neo4j/graphql/pull/4483) [`4b97531`](https://github.com/neo4j/graphql/commit/4b97531170c399f243ee848c17a8e38a80e14a51) Thanks [@darrellwarde](https://github.com/darrellwarde)! - Fix authorization variable naming in create operations + +- [#4507](https://github.com/neo4j/graphql/pull/4507) [`66a19c5`](https://github.com/neo4j/graphql/commit/66a19c56f00be90a8c0c6be294c98d402b0f4c5e) Thanks [@mjfwebb](https://github.com/mjfwebb)! - Fixes filtering on nested read operations + ## 4.4.4 ### Patch Changes diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 1b524b0aa07..4f7800f36bb 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -1,6 +1,6 @@ { "name": "@neo4j/graphql", - "version": "4.4.4", + "version": "4.4.5", "description": "A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations", "keywords": [ "neo4j", diff --git a/packages/ogm/CHANGELOG.md b/packages/ogm/CHANGELOG.md index 3327fdfd8a6..232a829179d 100644 --- a/packages/ogm/CHANGELOG.md +++ b/packages/ogm/CHANGELOG.md @@ -1,5 +1,12 @@ # @neo4j/graphql-ogm +## 4.4.5 + +### Patch Changes + +- Updated dependencies [[`2bb8f8b`](https://github.com/neo4j/graphql/commit/2bb8f8b628c52c102c2db988685fc54f08521488), [`d3c6d0e`](https://github.com/neo4j/graphql/commit/d3c6d0e8897dfc7ca168f1c387c6c33b92f8cb56), [`5c42f8d`](https://github.com/neo4j/graphql/commit/5c42f8d5226dcc87c804bc752d676fdc9f623d30), [`387e455`](https://github.com/neo4j/graphql/commit/387e455bb9aebb94663b05baed6c8694ec304e80), [`4b97531`](https://github.com/neo4j/graphql/commit/4b97531170c399f243ee848c17a8e38a80e14a51), [`66a19c5`](https://github.com/neo4j/graphql/commit/66a19c56f00be90a8c0c6be294c98d402b0f4c5e)]: + - @neo4j/graphql@4.4.5 + ## 4.4.4 ### Patch Changes diff --git a/packages/ogm/package.json b/packages/ogm/package.json index 9317452fd62..9bb02d3af32 100644 --- a/packages/ogm/package.json +++ b/packages/ogm/package.json @@ -1,6 +1,6 @@ { "name": "@neo4j/graphql-ogm", - "version": "4.4.4", + "version": "4.4.5", "description": "GraphQL powered OGM for Neo4j and Javascript applications", "keywords": [ "neo4j", @@ -38,7 +38,7 @@ "@graphql-codegen/plugin-helpers": "^5.0.0", "@graphql-codegen/typescript": "^4.0.0", "@graphql-tools/merge": "^9.0.0", - "@neo4j/graphql": "^4.4.4", + "@neo4j/graphql": "^4.4.5", "prettier": "^2.7.1" }, "peerDependencies": { diff --git a/yarn.lock b/yarn.lock index b644cd0d99f..19d9790f2cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3611,7 +3611,7 @@ __metadata: "@graphql-codegen/plugin-helpers": ^5.0.0 "@graphql-codegen/typescript": ^4.0.0 "@graphql-tools/merge": ^9.0.0 - "@neo4j/graphql": ^4.4.4 + "@neo4j/graphql": ^4.4.5 "@types/jest": 29.5.11 "@types/node": 20.10.8 camelcase: 6.3.0 @@ -3646,7 +3646,7 @@ __metadata: "@graphiql/react": 0.20.2 "@neo4j-ndl/base": 2.3.0 "@neo4j-ndl/react": 2.3.1 - "@neo4j/graphql": 4.4.4 + "@neo4j/graphql": 4.4.5 "@neo4j/introspector": 2.0.0 "@playwright/test": 1.40.1 "@tsconfig/create-react-app": 2.0.1 @@ -3701,7 +3701,7 @@ __metadata: languageName: unknown linkType: soft -"@neo4j/graphql@4.4.4, @neo4j/graphql@^4.0.0, @neo4j/graphql@^4.0.0-beta.0, @neo4j/graphql@^4.4.4, @neo4j/graphql@workspace:packages/graphql": +"@neo4j/graphql@4.4.5, @neo4j/graphql@^4.0.0, @neo4j/graphql@^4.0.0-beta.0, @neo4j/graphql@^4.4.5, @neo4j/graphql@workspace:packages/graphql": version: 0.0.0-use.local resolution: "@neo4j/graphql@workspace:packages/graphql" dependencies: @@ -8848,7 +8848,7 @@ __metadata: "@apollo/federation-subgraph-compatibility": 2.1.0 "@apollo/server": ^4.7.0 "@graphql-tools/wrap": ^10.0.0 - "@neo4j/graphql": ^4.4.4 + "@neo4j/graphql": ^4.4.5 fork-ts-checker-webpack-plugin: 9.0.2 graphql: 16.8.1 graphql-tag: ^2.12.6