Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated options argument #5777

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .changeset/soft-planets-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
"@neo4j/graphql": major
---

The deprecated `options` argument has been removed.

Consider the following type definitions:

```graphql
type Movie {
title: String!
}
```

The migration is as below:

```graphql
# Old syntax
{
movies(options: { first: 10, offset: 10, sort: [{ title: ASC }] }) {
title
}
}

# New syntax
{
movies(first: 10, offset: 10, sort: [{ title: ASC }]) {
title
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,6 @@ export class ImplementingEntityOperations<T extends InterfaceEntityAdapter | Con
return `${this.entityAdapter.name}DeleteInput`;
}

public get optionsInputTypeName(): string {
return `${this.entityAdapter.name}Options`;
}

public get sortInputTypeName(): string {
return `${this.entityAdapter.name}Sort`;
}
Expand Down
7 changes: 0 additions & 7 deletions packages/graphql/src/schema/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@ export const DEPRECATE_IMPLICIT_EQUAL_FILTERS = {
},
};

export const DEPRECATE_OPTIONS_ARGUMENT = {
name: DEPRECATED,
args: {
reason: "Query options argument is deprecated, please use pagination arguments like limit, offset and sort instead.",
},
};

export const DEPRECATE_DIRECTED_ARGUMENT = {
name: DEPRECATED,
args: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ import type { Directive, ObjectTypeComposerArgumentConfigMapDefinition, SchemaCo

import type { Subgraph } from "../../classes/Subgraph";
import { DEPRECATED } from "../../constants";
import { QueryOptions } from "../../graphql/input-objects/QueryOptions";
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 { ConnectionQueryArgs, Neo4jFeaturesSettings } from "../../types";
import { DEPRECATE_OPTIONS_ARGUMENT } from "../constants";
import { addDirectedArgument, getDirectedArgument } from "../directed-argument";
import { connectionFieldResolver } from "../pagination";
import { graphqlDirectivesToCompose } from "../to-compose";
Expand All @@ -36,7 +34,6 @@ import {
withConnectionSortInputType,
} from "./connection-where-input";
import { makeSortInput } from "./sort-and-options-input";
import { shouldAddDeprecatedFields } from "./utils";

export function augmentObjectOrInterfaceTypeWithRelationshipField({
relationshipAdapter,
Expand Down Expand Up @@ -73,10 +70,6 @@ export function augmentObjectOrInterfaceTypeWithRelationshipField({
? relationshipAdapter.originalTarget
: relationshipAdapter.target;

const optionsTypeName =
relationshipTarget instanceof UnionEntityAdapter
? QueryOptions
: relationshipTarget.operations.optionsInputTypeName;
const whereTypeName = relationshipTarget.operations.whereInputTypeName;

const nodeFieldsArgs = {
Expand All @@ -94,13 +87,6 @@ export function augmentObjectOrInterfaceTypeWithRelationshipField({
nodeFieldsArgs["sort"] = sortConfig.NonNull.List;
}
}
// SOFT_DEPRECATION: OPTIONS-ARGUMENT
if (shouldAddDeprecatedFields(features, "deprecatedOptionsArgument")) {
nodeFieldsArgs["options"] = {
type: optionsTypeName,
directives: [DEPRECATE_OPTIONS_ARGUMENT],
};
}

if (relationshipAdapter instanceof RelationshipAdapter) {
const directedArg = getDirectedArgument(relationshipAdapter, features);
Expand Down
42 changes: 1 addition & 41 deletions packages/graphql/src/schema/generation/sort-and-options-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { GraphQLInt, type DirectiveNode } from "graphql";
import { type DirectiveNode } from "graphql";
import type { InputTypeComposer, InputTypeComposerFieldConfigMapDefinition, SchemaComposer } from "graphql-compose";
import { DEPRECATED } from "../../constants";
import { SortDirection } from "../../graphql/enums/SortDirection";
Expand All @@ -25,32 +25,6 @@ import type { InterfaceEntityAdapter } from "../../schema-model/entity/model-ada
import { RelationshipAdapter } from "../../schema-model/relationship/model-adapters/RelationshipAdapter";
import { graphqlDirectivesToCompose } from "../to-compose";

export function withOptionsInputType({
entityAdapter,
userDefinedFieldDirectives,
composer,
}: {
entityAdapter: ConcreteEntityAdapter | InterfaceEntityAdapter;
userDefinedFieldDirectives: Map<string, DirectiveNode[]>;
composer: SchemaComposer;
}): InputTypeComposer {
const optionsInputType = makeOptionsInput({ entityAdapter, composer });
const sortInput = makeSortInput({ entityAdapter, userDefinedFieldDirectives, composer });
if (!sortInput) {
return optionsInputType;
}
// TODO: Concrete vs Abstract discrepancy
// is this intended? For ConcreteEntity is NonNull, for InterfaceEntity is nullable
const sortFieldType = sortInput.NonNull.List;
optionsInputType.addFields({
sort: {
description: `Specify one or more ${entityAdapter.operations.sortInputTypeName} objects to sort ${entityAdapter.upperFirstPlural} by. The sorts will be applied in the order in which they are arranged in the array.`,
type: sortFieldType,
},
});
return optionsInputType;
}

export function withSortInputType({
relationshipAdapter,
userDefinedFieldDirectives,
Expand Down Expand Up @@ -130,17 +104,3 @@ export function makeSortInput({
}
return sortInput;
}

function makeOptionsInput({
entityAdapter,
composer,
}: {
entityAdapter: ConcreteEntityAdapter | InterfaceEntityAdapter;
composer: SchemaComposer;
}): InputTypeComposer {
const optionsInput = composer.createInputTC({
name: entityAdapter.operations.optionsInputTypeName,
fields: { limit: GraphQLInt, offset: GraphQLInt },
});
return optionsInput;
}
6 changes: 0 additions & 6 deletions packages/graphql/src/schema/make-augmented-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,12 +73,6 @@ describe("makeAugmentedSchema", () => {
).type as NamedTypeNode;
expect(nodeFindQueryType.name.value).toEqual(type);

// Options
const options = document.definitions.find(
(x) => x.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && x.name.value === `${type}Options`
);
expect(options).toBeTruthy();

// Where
const where = document.definitions.find(
(x) => x.kind === Kind.INPUT_OBJECT_TYPE_DEFINITION && x.name.value === `${type}Where`
Expand Down
6 changes: 0 additions & 6 deletions packages/graphql/src/schema/make-augmented-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ import { withCreateInputType } from "./generation/create-input";
import { withInterfaceType } from "./generation/interface-type";
import { withObjectType } from "./generation/object-type";
import { withMutationResponseTypes } from "./generation/response-types";
import { withOptionsInputType } from "./generation/sort-and-options-input";
import { withUpdateInputType } from "./generation/update-input";
import { withUniqueWhereInputType, withWhereInputType } from "./generation/where-input";
import getNodes from "./get-nodes";
Expand Down Expand Up @@ -221,7 +220,6 @@ function makeAugmentedSchema({
composer.Query.addFields({
[unionEntityAdapter.operations.rootTypeFieldNames.read]: findResolver({
entityAdapter: unionEntityAdapter,
features,
composer,
}),
});
Expand Down Expand Up @@ -508,7 +506,6 @@ function generateObjectType({
userDefinedDirectivesForNode: Map<string, DirectiveNode[]>;
userDefinedFieldDirectivesForNode: Map<string, Map<string, DirectiveNode[]>>;
}) {
withOptionsInputType({ entityAdapter: concreteEntityAdapter, userDefinedFieldDirectives, composer });
withWhereInputType({
entityAdapter: concreteEntityAdapter,
userDefinedFieldDirectives,
Expand Down Expand Up @@ -546,7 +543,6 @@ function generateObjectType({
composer.Query.addFields({
[concreteEntityAdapter.operations.rootTypeFieldNames.read]: findResolver({
entityAdapter: concreteEntityAdapter,
features,
composer,
}),
});
Expand Down Expand Up @@ -654,7 +650,6 @@ function generateInterfaceObjectType({
string,
DirectiveNode[]
>;
withOptionsInputType({ entityAdapter: interfaceEntityAdapter, userDefinedFieldDirectives, composer });
withWhereInputType({
entityAdapter: interfaceEntityAdapter,
userDefinedFieldDirectives,
Expand Down Expand Up @@ -687,7 +682,6 @@ function generateInterfaceObjectType({
composer.Query.addFields({
[interfaceEntityAdapter.operations.rootTypeFieldNames.read]: findResolver({
entityAdapter: interfaceEntityAdapter,
features,
composer,
}),
});
Expand Down
11 changes: 0 additions & 11 deletions packages/graphql/src/schema/resolvers/query/read.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,6 @@ describe("Read resolver", () => {
expect(result.resolve).toBeInstanceOf(Function);
expect(result.args).toMatchObject({
where: `MovieWhere`,
options: {
directives: [
{
args: {
reason: "Query options argument is deprecated, please use pagination arguments like limit, offset and sort instead.",
},
name: "deprecated",
},
],
type: "MovieOptions",
},
});
});
});
24 changes: 1 addition & 23 deletions packages/graphql/src/schema/resolvers/query/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,17 @@

import type { GraphQLResolveInfo } from "graphql";
import type { SchemaComposer } from "graphql-compose";
import { QueryOptions } from "../../../graphql/input-objects/QueryOptions";
import type { EntityAdapter } from "../../../schema-model/entity/EntityAdapter";
import { UnionEntityAdapter } from "../../../schema-model/entity/model-adapters/UnionEntityAdapter";
import { translateRead } from "../../../translate";
import { isConcreteEntity } from "../../../translate/queryAST/utils/is-concrete-entity";
import type { Neo4jFeaturesSettings } from "../../../types";
import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context";
import { execute } from "../../../utils";
import getNeo4jResolveTree from "../../../utils/get-neo4j-resolve-tree";
import { DEPRECATE_OPTIONS_ARGUMENT } from "../../constants";
import { makeSortInput } from "../../generation/sort-and-options-input";
import { shouldAddDeprecatedFields } from "../../generation/utils";
import type { Neo4jGraphQLComposedContext } from "../composition/wrap-query-and-mutation";

export function findResolver({
entityAdapter,
features,
composer,
}: {
entityAdapter: EntityAdapter;
features?: Neo4jFeaturesSettings;
composer: SchemaComposer;
}) {
export function findResolver({ entityAdapter, composer }: { entityAdapter: EntityAdapter; composer: SchemaComposer }) {
async function resolve(_root: any, args: any, context: Neo4jGraphQLComposedContext, info: GraphQLResolveInfo) {
const resolveTree = getNeo4jResolveTree(info, { args });

Expand Down Expand Up @@ -82,16 +70,6 @@ export function findResolver({
args["sort"] = sortConfig.NonNull.List;
}
}
// SOFT_DEPRECATION: OPTIONS-ARGUMENT
if (shouldAddDeprecatedFields(features, "deprecatedOptionsArgument")) {
args["options"] = {
type:
entityAdapter instanceof UnionEntityAdapter
? QueryOptions
: entityAdapter.operations.optionsInputTypeName,
directives: [DEPRECATE_OPTIONS_ARGUMENT],
};
}

return {
type: `[${entityAdapter.name}!]!`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type { ConcreteEntityAdapter } from "../../../schema-model/entity/model-a
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 { GraphQLOptionsArg } from "../../../types";
import type { GraphQLSortingAndPaginationArgs } from "../../../types";
import type { Neo4jGraphQLTranslationContext } from "../../../types/neo4j-graphql-translation-context";
import { filterTruthy, isRecord } from "../../../utils/utils";
import type { Filter } from "../ast/filters/Filter";
Expand Down Expand Up @@ -367,7 +367,7 @@ export class OperationsFactory {
limitArg: number | Integer;
offsetArg: number;
sortArg: Record<string, any>[];
}): GraphQLOptionsArg | undefined {
}): GraphQLSortingAndPaginationArgs | undefined {
const limitDirective = isUnionEntity(entity) ? undefined : entity.annotations.limit;

let limit: Integer | number | undefined = limitArg ?? limitDirective?.default ?? limitDirective?.max;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,11 @@ export class ConnectionFactory {

private getConnectionOptions(
entity: ConcreteEntityAdapter | InterfaceEntityAdapter,
options: Record<string, any>
args: Record<string, any>
): Pick<ConnectionQueryArgs, "first" | "after" | "sort"> | undefined {
const limitDirective = entity.annotations.limit;

let limit: Integer | number | undefined = options?.first ?? limitDirective?.default ?? limitDirective?.max;
let limit: Integer | number | undefined = args?.first ?? limitDirective?.default ?? limitDirective?.max;
if (limit instanceof Integer) {
limit = limit.toNumber();
}
Expand All @@ -310,12 +310,12 @@ export class ConnectionFactory {
limit = Math.min(limit, maxLimit);
}

if (limit === undefined && options.after === undefined && options.sort === undefined) return undefined;
if (limit === undefined && args.after === undefined && args.sort === undefined) return undefined;

return {
first: limit,
after: options.after,
sort: options.sort,
after: args.after,
sort: args.sort,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import { RelationshipSelection } from "../../ast/selection/RelationshipSelection
import { getConcreteEntities } from "../../utils/get-concrete-entities";
import { getConcreteWhere } from "../../utils/get-concrete-where";
import { isConcreteEntity } from "../../utils/is-concrete-entity";
import { raiseOnMixedPagination } from "../../utils/raise-on-mixed-pagination";
import type { QueryASTFactory } from "../QueryASTFactory";

export class ReadFactory {
Expand Down Expand Up @@ -158,17 +157,9 @@ export class ReadFactory {
whereArgs: Record<string, any> | Filter[];
partialOf?: InterfaceEntityAdapter | UnionEntityAdapter;
}): T {
// SOFT_DEPRECATION: OPTIONS-ARGUMENT
const optionsArg: Record<string, any> = (resolveTree.args.options ?? {}) as Record<string, any>;
const sortArg = resolveTree.args.sort ?? optionsArg.sort;
const limitArg = resolveTree.args.limit ?? optionsArg.limit;
const offsetArg = resolveTree.args.offset ?? optionsArg.offset;
raiseOnMixedPagination({
optionsArg,
sort: resolveTree.args.sort,
limit: resolveTree.args.limit,
offset: resolveTree.args.offset,
});
const sortArg = resolveTree.args.sort;
const limitArg = resolveTree.args.limit;
const offsetArg = resolveTree.args.offset;

const paginationArgs: Record<string, any> = { limit: limitArg, offset: offsetArg, sort: sortArg };

Expand All @@ -189,17 +180,10 @@ export class ReadFactory {
resolveTree: ResolveTree,
context: Neo4jGraphQLTranslationContext
) {
// SOFT_DEPRECATION: OPTIONS-ARGUMENT
const optionsArg: Record<string, any> = (resolveTree.args.options ?? {}) as Record<string, any>;
const sortArg = resolveTree.args.sort ?? optionsArg.sort;
const limitArg = resolveTree.args.limit ?? optionsArg.limit;
const offsetArg = resolveTree.args.offset ?? optionsArg.offset;
raiseOnMixedPagination({
optionsArg,
sort: resolveTree.args.sort,
limit: resolveTree.args.limit,
offset: resolveTree.args.offset,
});
const sortArg = resolveTree.args.sort as Record<string, any>[];
const limitArg = resolveTree.args.limit as number;
const offsetArg = resolveTree.args.offset as number;

const options = this.queryASTFactory.operationsFactory.getOptions({ entity, sortArg, limitArg, offsetArg });
if (options) {
const sort = this.queryASTFactory.sortAndPaginationFactory.createSortFields(options, entity, context);
Expand Down
Loading
Loading