Skip to content

Commit

Permalink
Merge pull request #5836 from neo4j/generic-scalar-filters
Browse files Browse the repository at this point in the history
Generic input filters
  • Loading branch information
MacondoExpress authored Jan 3, 2025
2 parents 07f6369 + 548a529 commit 4a1aa86
Show file tree
Hide file tree
Showing 492 changed files with 74,375 additions and 20,467 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-tomatoes-float.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@neo4j/graphql": major
---

The `typename_IN` filter has been renamed to `typename`.
5 changes: 5 additions & 0 deletions .changeset/fair-elephants-yell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@neo4j/graphql": major
---

Aggregations are no longer generated for `ID` fields.
15 changes: 15 additions & 0 deletions .changeset/four-insects-repeat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@neo4j/graphql": patch
---

Deprecate individual mutations in favor of generic mutations

- `_SET`
- `_POP`
- `_PUSH`
- `_INCREMENT`
- `_ADD`
- `_DECREMENT`
- `_SUBTRACT`
- `_MULTIPLY`
- `_DIVIDE`
16 changes: 16 additions & 0 deletions .changeset/green-jobs-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@neo4j/graphql": minor
---

Add suport for generic update operators:

```graphql
mutation {
updateMovies(update: { name: { set: "The Matrix" } }) {
movies {
id
name
}
}
}
```
31 changes: 31 additions & 0 deletions .changeset/khaki-roses-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@neo4j/graphql": patch
---

Deprecates old aggregation filters for relationships in favor of more generic filters:

Before:

```js
query Movies {
movies(
where: { actorsAggregate: { node: { lastRating_AVERAGE_GT: 6 } } }
) {
title
}
}
```

Now:

```js
query Movies {
movies(
where: {
actorsAggregate: { node: { lastRating: { average: { gt: 6 } } } }
}
) {
title
}
}
```
6 changes: 6 additions & 0 deletions .changeset/nine-games-clap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@neo4j/graphql": patch
---

Deprecate relationship filtering using the non-generic version such as `actors_SOME: { title_EQ: "The Matrix" }` in favor of the generic input `actors: { some: { title: { eq: "The Matrix" } } }`.
The setting `excludeDeprecatedFields` now contains the option `relationshipFilters` to remove these deprecated filters.
6 changes: 6 additions & 0 deletions .changeset/quick-dolphins-accept.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@neo4j/graphql": patch
---

Deprecate attribute filtering using the non-generic version such as `title_EQ: "The Matrix"` in favor of the generic input `title: { eq: "The Matrix" }`.
The setting `excludeDeprecatedFields` now contains the option `attributeFilters` to remove these deprecated filters.
13 changes: 13 additions & 0 deletions .changeset/silly-toys-sing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@neo4j/graphql": patch
---

Add generic filters for aggregations:

```graphql
{
posts(where: { likesAggregate: { node: { rating: { average: { eq: 3.2 } } } } }) {
title
}
}
```
12 changes: 12 additions & 0 deletions .changeset/six-bottles-hear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@neo4j/graphql": patch
---

Introduce the flag "aggregationFilters" to remove deprecated aggregation filters:

```js
const neoSchema = new Neo4jGraphQL({
typeDefs,
features: { excludeDeprecatedFields: { aggregationFilters: true } },
});
```
25 changes: 25 additions & 0 deletions .changeset/unlucky-spoons-trade.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
"@neo4j/graphql": minor
---

Introduce a new style for filtering relationships and connections.
The quantifiers `SOME` | `NONE` | `SINGLE` | `ALL` are now available as a nested input object.

**Relationship**

```graphql
{
movies(where: { genres: { some: { name: { equals: "some genre" } } } }) {
actorCount
}
}
```

**Connection**
```graphql
{
movies(where: { genresConnection: { some: { node: { name: { equals: "some genre" } } } } }) {
actorCount
}
}
```
8 changes: 6 additions & 2 deletions packages/graphql/src/classes/Neo4jGraphQL.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,14 @@ describe("Neo4jGraphQL", () => {
describe("getExecutableSchema", () => {
test("error should contain path", async () => {
let schema: GraphQLSchema | undefined = undefined;
const typeDefs = /* GraphQL */ `
type User @node @authorization(filter: [{ where: { banana: { id: "$jwt.sub" } } }]) {
id: ID
}
`;
const errors: Error[] = await getErrorAsync(async () => {
schema = await new Neo4jGraphQL({
typeDefs:
'type User @node @authorization(filter: [{ where: { banana: { id: "$jwt.sub" } } }]) {id: ID}',
typeDefs,
}).getExecutableSchema();
});
expect(errors).toHaveLength(1);
Expand Down
8 changes: 7 additions & 1 deletion packages/graphql/src/classes/Neo4jGraphQL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,12 @@ class Neo4jGraphQL {
});

if (this.validate) {
validateUserDefinition({ userDocument: document, augmentedDocument: typeDefs, jwt: jwt?.type });
validateUserDefinition({
userDocument: document,
augmentedDocument: typeDefs,
jwt: jwt?.type,
features: this.features,
});
}

this._nodes = nodes;
Expand Down Expand Up @@ -473,6 +478,7 @@ class Neo4jGraphQL {
additionalDirectives: directives,
additionalTypes: types,
jwt: jwt?.type,
features: this.features,
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export function getStaticAuthorizationDefinitions(

const JWTPayloadWhere = createJWTPayloadWhere(userDocument, schema, JWTPayloadDefinition);
const JWTPayloadWhereAST = astFromInputObjectType(JWTPayloadWhere, schema);

ASTs.push(JWTPayloadWhereAST);
return ASTs;
}
Expand All @@ -80,14 +81,16 @@ function createJWTPayloadWhere(
(field) => new AttributeAdapter(parseAttribute(field, definitionCollection))
);

const composer = new SchemaComposer();
const inputFieldsType = getWhereFieldsForAttributes({
attributes: jwtFieldAttributeAdapters,
userDefinedFieldDirectives: undefined,
features: undefined,
ignoreCypherFieldFilters: false,
composer,
});

const composer = new SchemaComposer();

const inputTC = composer.createInputTC({
name: "JWTPayloadWhere",
fields: inputFieldsType,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 { GraphQLInputObjectType } from "graphql";
import { BigIntScalarFilters } from "../generic-operators/BigIntScalarFilters";

export const BigIntScalarAggregationFilters = new GraphQLInputObjectType({
name: "BigIntScalarAggregationFilters",
description: "Filters for an aggregation of an BigInt field",
fields: {
average: { type: BigIntScalarFilters },
max: { type: BigIntScalarFilters },
min: { type: BigIntScalarFilters },
sum: { type: BigIntScalarFilters },
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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 { GraphQLInputObjectType } from "graphql";
import { DateTimeScalarFilters } from "../generic-operators/DateTimeScalarFilters";

export const DateTimeScalarAggregationFilters = new GraphQLInputObjectType({
name: "DateTimeScalarAggregationFilters",
description: "Filters for an aggregation of an DateTime input field",
fields: {
max: { type: DateTimeScalarFilters },
min: { type: DateTimeScalarFilters },
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 { GraphQLInputObjectType } from "graphql";
import { DurationScalarFilters } from "../generic-operators/DurationScalarFilters";

export const DurationScalarAggregationFilters = new GraphQLInputObjectType({
name: "DurationScalarAggregationFilters",
description: "Filters for an aggregation of a Dutation input field",
fields: {
max: { type: DurationScalarFilters },
min: { type: DurationScalarFilters },
average: { type: DurationScalarFilters },
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 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 { GraphQLInputObjectType } from "graphql";
import { FloatScalarFilters } from "../generic-operators/FloatScalarFilters";

export const FloatScalarAggregationFilters = new GraphQLInputObjectType({
name: "FloatScalarAggregationFilters",
description: "Filters for an aggregation of a float field",
fields: {
average: { type: FloatScalarFilters },
max: { type: FloatScalarFilters },
min: { type: FloatScalarFilters },
sum: { type: FloatScalarFilters },
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 { GraphQLInputObjectType } from "graphql";
import { FloatScalarFilters } from "../generic-operators/FloatScalarFilters";
import { IntScalarFilters } from "../generic-operators/IntScalarFilters";

export const IntScalarAggregationFilters = new GraphQLInputObjectType({
name: "IntScalarAggregationFilters",
description: "Filters for an aggregation of an int field",
fields: {
average: { type: FloatScalarFilters },
max: { type: IntScalarFilters },
min: { type: IntScalarFilters },
sum: { type: IntScalarFilters },
},
});
Loading

0 comments on commit 4a1aa86

Please sign in to comment.