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

Fix ra-data-graphql-simple creates incorrect query when schema contains a non-null list #9371

Merged
merged 3 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
52 changes: 1 addition & 51 deletions packages/ra-data-graphql-simple/src/buildGqlQuery.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,13 @@ import {
CREATE,
DELETE,
} from 'ra-core';

import buildGqlQuery, {
buildApolloArgs,
buildArgs,
buildFields,
getArgType,
} from './buildGqlQuery';

describe('getArgType', () => {
it('returns the arg type', () => {
expect(
print(getArgType({ type: { kind: TypeKind.SCALAR, name: 'foo' } }))
).toEqual('foo');
});
it('returns the arg type for NON_NULL types', () => {
expect(
print(
getArgType({
type: {
kind: TypeKind.NON_NULL,
ofType: { name: 'ID', kind: TypeKind.SCALAR },
},
})
)
).toEqual('ID!');
});
it('returns the arg type for LIST types', () => {
expect(
print(
getArgType({
type: {
kind: TypeKind.LIST,
ofType: { name: 'ID', kind: TypeKind.SCALAR },
},
})
)
).toEqual('[ID]');
});
it('returns the arg type for LIST types of NON_NULL type', () => {
expect(
print(
getArgType({
type: {
kind: TypeKind.LIST,
ofType: {
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.SCALAR,
name: 'ID',
},
},
},
})
)
).toEqual('[ID!]');
});
});

describe('buildArgs', () => {
it('returns an empty array when query does not have any arguments', () => {
expect(buildArgs({ args: [] }, {})).toEqual([]);
Expand Down
32 changes: 2 additions & 30 deletions packages/ra-data-graphql-simple/src/buildGqlQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@ import {
import {
ArgumentNode,
IntrospectionField,
IntrospectionInputValue,
IntrospectionNamedTypeRef,
IntrospectionObjectType,
IntrospectionUnionType,
TypeKind,
TypeNode,
VariableDefinitionNode,
} from 'graphql';
import * as gqlTypes from 'graphql-ast-types-browser';

import getFinalType from './getFinalType';
import isList from './isList';
import isRequired from './isRequired';
import { getGqlType } from './getGqlType';

export default (introspectionResults: IntrospectionResult) => (
resource: IntrospectedResource,
Expand Down Expand Up @@ -233,35 +230,10 @@ export const buildApolloArgs = (
...acc,
gqlTypes.variableDefinition(
gqlTypes.variable(gqlTypes.name(arg.name)),
getArgType(arg)
getGqlType(arg.type)
),
];
}, []);

return args;
};

export const getArgType = (arg: IntrospectionInputValue): TypeNode => {
const type = getFinalType(arg.type);
const required = isRequired(arg.type);
const list = isList(arg.type);

if (list) {
if (required) {
return gqlTypes.listType(
gqlTypes.nonNullType(
gqlTypes.namedType(gqlTypes.name(type.name))
)
);
}
return gqlTypes.listType(gqlTypes.namedType(gqlTypes.name(type.name)));
}

if (required) {
return gqlTypes.nonNullType(
gqlTypes.namedType(gqlTypes.name(type.name))
);
}

return gqlTypes.namedType(gqlTypes.name(type.name));
};
109 changes: 109 additions & 0 deletions packages/ra-data-graphql-simple/src/getGqlType.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { TypeKind, print } from 'graphql';
import { getGqlType } from './getGqlType';

describe('getGqlType', () => {
it('returns the arg type', () => {
expect(
print(getGqlType({ kind: TypeKind.SCALAR, name: 'foo' }))
).toEqual('foo');
});

it('returns the arg type for NON_NULL types', () => {
expect(
print(
getGqlType({
kind: TypeKind.NON_NULL,
ofType: { name: 'ID', kind: TypeKind.SCALAR },
})
)
).toEqual('ID!');
});

it('returns the arg type for LIST types', () => {
expect(
print(
getGqlType({
kind: TypeKind.LIST,
ofType: { name: 'ID', kind: TypeKind.SCALAR },
})
)
).toEqual('[ID]');
});

it('returns the arg type for LIST with NON_NULL item types', () => {
expect(
print(
getGqlType({
kind: TypeKind.LIST,
ofType: {
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.SCALAR,
name: 'ID',
},
},
})
)
).toEqual('[ID!]');
});

it('returns the arg type for NON_NULL LIST with nullable item type', () => {
expect(
print(
getGqlType({
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.LIST,
ofType: {
kind: TypeKind.SCALAR,
name: 'ID',
},
},
})
)
).toEqual('[ID]!');
});

it('returns the arg type for NON_NULL LIST with NON_NULL items', () => {
expect(
print(
getGqlType({
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.LIST,
ofType: {
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.SCALAR,
name: 'ID',
},
},
},
})
)
).toEqual('[ID!]!');
});

it('returns the arg type for nested LIST and NON_NULL items', () => {
expect(
print(
getGqlType({
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.LIST,
ofType: {
kind: TypeKind.LIST,
ofType: {
kind: TypeKind.NON_NULL,
ofType: {
kind: TypeKind.SCALAR,
name: 'ID',
},
},
},
},
})
)
).toEqual('[[ID!]]!');
});
});
23 changes: 23 additions & 0 deletions packages/ra-data-graphql-simple/src/getGqlType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {
IntrospectionListTypeRef,
IntrospectionType,
IntrospectionTypeRef,
TypeKind,
TypeNode,
} from 'graphql';
import * as gqlTypes from 'graphql-ast-types-browser';

export const getGqlType = (
type: IntrospectionType | IntrospectionListTypeRef | IntrospectionTypeRef
): TypeNode => {
switch (type.kind) {
case TypeKind.LIST:
return gqlTypes.listType(getGqlType(type.ofType));

case TypeKind.NON_NULL:
return gqlTypes.nonNullType(getGqlType(type.ofType));

default:
return gqlTypes.namedType(gqlTypes.name(type.name));
}
};
37 changes: 0 additions & 37 deletions packages/ra-data-graphql-simple/src/isRequired.test.ts

This file was deleted.

18 changes: 0 additions & 18 deletions packages/ra-data-graphql-simple/src/isRequired.ts

This file was deleted.

Loading