Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/dev' into 7.x
Browse files Browse the repository at this point in the history
  • Loading branch information
MacondoExpress committed Jan 13, 2025
2 parents 188a767 + fd3f015 commit b0d8882
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 67 deletions.
13 changes: 13 additions & 0 deletions .changeset/beige-beds-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@neo4j/graphql": patch
---

Aggregations on ID fields are now deprecated.
As part of the change, the flag `idAggregations` has been added to the `excludeDeprecatedFields` setting.

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

Introduced the `typename` filter that superseded the `typename_IN` filter.
As part of the change, the flag `typename_IN` has been added to the `excludeDeprecatedFields` setting.

```js
const neoSchema = new Neo4jGraphQL({
typeDefs,
features: { excludeDeprecatedFields: { typename_IN: true } },
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class AggregationTypesMapper {
resolve: numericalResolver,
args: {},
};

// TODO: REMOVE ID FIELD ON 7.x
const composeId = {
type: "ID",
resolve: idResolver,
Expand All @@ -64,6 +64,7 @@ export class AggregationTypesMapper {
fields?: Record<string, any>;
directives?: string[];
}> = [
// TODO: REMOVE ID FIELD ON 7.x
{
name: "ID",
fields: {
Expand Down Expand Up @@ -140,6 +141,7 @@ export class AggregationTypesMapper {
}): ObjectTypeComposer<any, any> {
return composer.getOrCreateOTC(`${name}AggregateSelection`, (tc) => {
tc.addFields(fields ?? { min: name, max: name });

for (const directive of directives) {
tc.setDirectiveByName(directive);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
*/

import { GraphQLInt, GraphQLNonNull } from "graphql";
import type { ObjectTypeComposer, SchemaComposer } from "graphql-compose";
import type { ObjectTypeComposer, ObjectTypeComposerFieldConfigMapDefinition, SchemaComposer } from "graphql-compose";
import type { Subgraph } from "../../classes/Subgraph";
import type { ConcreteEntityAdapter } from "../../schema-model/entity/model-adapters/ConcreteEntityAdapter";
import type { InterfaceEntityAdapter } from "../../schema-model/entity/model-adapters/InterfaceEntityAdapter";
import { UnionEntityAdapter } from "../../schema-model/entity/model-adapters/UnionEntityAdapter";
import { RelationshipAdapter } from "../../schema-model/relationship/model-adapters/RelationshipAdapter";
import type { RelationshipDeclarationAdapter } from "../../schema-model/relationship/model-adapters/RelationshipDeclarationAdapter";
import type { Neo4jFeaturesSettings } from "../../types";
import { numericalResolver } from "../resolvers/field/numerical";
import { AggregationTypesMapper } from "./aggregation-types-mapper";

Expand All @@ -39,29 +40,28 @@ export class FieldAggregationComposer {

private createAggregationField(
name: string,
fields: Record<string, ObjectTypeComposer>
fields: ObjectTypeComposerFieldConfigMapDefinition<any, any>
): ObjectTypeComposer | undefined {
if (Object.keys(fields).length > 0) {
return this.composer.createObjectTC({
name,
fields: {
...fields,
},
fields,
});
}
return undefined;
}

public createAggregationTypeObject(
relationshipAdapter: RelationshipAdapter | RelationshipDeclarationAdapter
relationshipAdapter: RelationshipAdapter | RelationshipDeclarationAdapter,
features: Neo4jFeaturesSettings | undefined
): ObjectTypeComposer {
let aggregateSelectionEdge: ObjectTypeComposer | undefined;

if (relationshipAdapter.target instanceof UnionEntityAdapter) {
throw new Error("UnionEntityAdapter not implemented");
}

const aggregateSelectionNodeFields = this.getAggregationFields(relationshipAdapter.target);
const aggregateSelectionNodeFields = this.getAggregationFields(relationshipAdapter.target, features);
const aggregateSelectionNodeName = relationshipAdapter.operations.getAggregationFieldTypename("node");

const aggregateSelectionNode = this.createAggregationField(
Expand All @@ -70,7 +70,7 @@ export class FieldAggregationComposer {
);

if (relationshipAdapter instanceof RelationshipAdapter && relationshipAdapter.attributes.size > 0) {
const aggregateSelectionEdgeFields = this.getAggregationFields(relationshipAdapter);
const aggregateSelectionEdgeFields = this.getAggregationFields(relationshipAdapter, features);
const aggregateSelectionEdgeName = relationshipAdapter.operations.getAggregationFieldTypename("edge");

aggregateSelectionEdge = this.createAggregationField(
Expand All @@ -94,13 +94,19 @@ export class FieldAggregationComposer {
}

private getAggregationFields(
entity: RelationshipAdapter | ConcreteEntityAdapter | InterfaceEntityAdapter
): Record<string, ObjectTypeComposer> {
entity: RelationshipAdapter | ConcreteEntityAdapter | InterfaceEntityAdapter,
_features: Neo4jFeaturesSettings | undefined
): ObjectTypeComposerFieldConfigMapDefinition<any, any> {
return entity.aggregableFields.reduce((res, field) => {
const objectTypeComposer = this.aggregationTypesMapper.getAggregationType(field.getTypeName());

if (!objectTypeComposer) return res;
if (!objectTypeComposer) {
return res;
}

if (field.typeHelper.isID()) {
return res;
}
res[field.name] = objectTypeComposer.NonNull;

return res;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,10 @@ export function createRelationshipFields({
// make a new fn augmentObjectTypeWithAggregationField
const fieldAggregationComposer = new FieldAggregationComposer(schemaComposer, subgraph);

const aggregationTypeObject = fieldAggregationComposer.createAggregationTypeObject(relationshipAdapter);
const aggregationTypeObject = fieldAggregationComposer.createAggregationTypeObject(
relationshipAdapter,
features
);

const aggregationFieldsBaseArgs = {
where: relationshipTarget.operations.whereInputTypeName,
Expand Down
10 changes: 7 additions & 3 deletions packages/graphql/src/schema/generation/aggregate-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ export function withAggregateSelectionType({
aggregationTypesMapper,
propagatedDirectives,
composer,
features,
}: {
entityAdapter: ConcreteEntityAdapter | InterfaceEntityAdapter;
aggregationTypesMapper: AggregationTypesMapper;
propagatedDirectives: DirectiveNode[];
composer: SchemaComposer;
features: Neo4jFeaturesSettings | undefined;
}): ObjectTypeComposer {
const aggregateSelection = composer.createObjectTC({
name: entityAdapter.operations.aggregateTypeNames.selection,
Expand All @@ -62,23 +64,25 @@ export function withAggregateSelectionType({
},
directives: graphqlDirectivesToCompose(propagatedDirectives),
});
aggregateSelection.addFields(makeAggregableFields({ entityAdapter, aggregationTypesMapper }));
aggregateSelection.addFields(makeAggregableFields({ entityAdapter, aggregationTypesMapper, features }));
return aggregateSelection;
}

function makeAggregableFields({
entityAdapter,
aggregationTypesMapper,
features,
}: {
entityAdapter: ConcreteEntityAdapter | InterfaceEntityAdapter;
aggregationTypesMapper: AggregationTypesMapper;
features: Neo4jFeaturesSettings | undefined;
}): ObjectTypeComposerFieldConfigMapDefinition<any, any> {
const aggregableFields: ObjectTypeComposerFieldConfigMapDefinition<any, any> = {};
const aggregableAttributes = entityAdapter.aggregableFields;
for (const attribute of aggregableAttributes) {
const objectTypeComposer = aggregationTypesMapper.getAggregationType(attribute.getTypeName());
if (objectTypeComposer) {
aggregableFields[attribute.name] = objectTypeComposer.NonNull;
aggregableFields[attribute.name] = { type: objectTypeComposer.NonNull };
}
}
return aggregableFields;
Expand Down Expand Up @@ -214,7 +218,7 @@ function makeAggregationFields(
function addDeprecatedAggregationFieldsByType(
attribute: AttributeAdapter,
directivesOnField: DirectiveNode[] | undefined,
fields: InputTypeComposerFieldConfigMapDefinition
fields: InputTypeComposerFieldConfigMapDefinition,
): InputTypeComposerFieldConfigMapDefinition {
if (attribute.typeHelper.isString()) {
for (const operator of AGGREGATION_COMPARISON_OPERATORS) {
Expand Down
2 changes: 2 additions & 0 deletions packages/graphql/src/schema/make-augmented-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,7 @@ function generateObjectType({
aggregationTypesMapper,
propagatedDirectives,
composer,
features,
});

composer.Query.addFields({
Expand Down Expand Up @@ -845,6 +846,7 @@ function generateInterfaceObjectType({
aggregationTypesMapper,
propagatedDirectives,
composer,
features,
});

composer.Query.addFields({
Expand Down
Loading

0 comments on commit b0d8882

Please sign in to comment.