Skip to content

Commit

Permalink
feat(graphql): Allow specifying fields that are required when querying
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-martin committed Jul 29, 2020
1 parent 7426501 commit a425ba7
Show file tree
Hide file tree
Showing 13 changed files with 406 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
type Query {
test(
"""Limit or page results."""
paging: CursorPaging = {first: 10}

"""Specify to filter the records returned."""
filter: TestFilterRequiredDtoFilter!

"""Specify to sort results."""
sorting: [TestFilterRequiredDtoSort!] = []
): String!
}

input CursorPaging {
"""Paginate before opaque cursor"""
before: ConnectionCursor

"""Paginate after opaque cursor"""
after: ConnectionCursor

"""Paginate first"""
first: Int

"""Paginate last"""
last: Int
}

"""Cursor for paging through collections"""
scalar ConnectionCursor

input TestFilterRequiredDtoFilter {
and: [TestFilterRequiredDtoFilter!]
or: [TestFilterRequiredDtoFilter!]
requiredFilterableField: StringFieldComparison!
}

input StringFieldComparison {
is: Boolean
isNot: Boolean
eq: String
neq: String
gt: String
gte: String
lt: String
lte: String
like: String
notLike: String
iLike: String
notILike: String
in: [String!]
notIn: [String!]
}

input TestFilterRequiredDtoSort {
field: TestFilterRequiredDtoSortFields!
direction: SortDirection!
nulls: SortNulls
}

enum TestFilterRequiredDtoSortFields {
requiredFilterableField
}

"""Sort Directions"""
enum SortDirection {
ASC
DESC
}

"""Sort Nulls Options"""
enum SortNulls {
NULLS_FIRST
NULLS_LAST
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
type Query {
test(input: TestComparisonDtoFilter!): Int!
}

input TestComparisonDtoFilter {
and: [TestFilterRequiredComparisonFilter!]
or: [TestFilterRequiredComparisonFilter!]
id: NumberFieldComparison
requiredField: BooleanFieldComparison!
nonRequiredField: DateFieldComparison
notSpecifiedField: NumberFieldComparison
}

input TestFilterRequiredComparisonFilter {
and: [TestFilterRequiredComparisonFilter!]
or: [TestFilterRequiredComparisonFilter!]
id: NumberFieldComparison
requiredField: BooleanFieldComparison!
nonRequiredField: DateFieldComparison
notSpecifiedField: NumberFieldComparison
}

input NumberFieldComparison {
is: Boolean
isNot: Boolean
eq: Float
neq: Float
gt: Float
gte: Float
lt: Float
lte: Float
in: [Float!]
notIn: [Float!]
between: NumberFieldComparisonBetween
notBetween: NumberFieldComparisonBetween
}

input NumberFieldComparisonBetween {
lower: Float!
upper: Float!
}

input BooleanFieldComparison {
is: Boolean
isNot: Boolean
}

input DateFieldComparison {
is: Boolean
isNot: Boolean
eq: DateTime
neq: DateTime
gt: DateTime
gte: DateTime
lt: DateTime
lte: DateTime
in: [DateTime!]
notIn: [DateTime!]
between: DateFieldComparisonBetween
notBetween: DateFieldComparisonBetween
}

"""
A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date-time format.
"""
scalar DateTime

input DateFieldComparisonBetween {
lower: DateTime!
upper: DateTime!
}
12 changes: 12 additions & 0 deletions packages/query-graphql/__tests__/__fixtures__/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export const filterInputTypeSDL = readGraphql(resolve(__dirname, './filter-input
export const filterAllowedComparisonsInputTypeSDL = readGraphql(
resolve(__dirname, './filter-allowed-comparisons-input-type.graphql'),
);
export const filterRequiredFieldInputTypeSDL = readGraphql(
resolve(__dirname, './filter-required-field-input-type.graphql'),
);
export const updateFilterInputTypeSDL = readGraphql(resolve(__dirname, './update-filter-input-type.graphql'));
export const deleteFilterInputTypeSDL = readGraphql(resolve(__dirname, './delete-filter-input-type.graphql'));
export const subscriptionFilterInputTypeSDL = readGraphql(
Expand All @@ -51,8 +54,17 @@ export const pagingInputTypeSDL = readGraphql(resolve(__dirname, './paging-input
export const pageInfoObjectTypeSDL = readGraphql(resolve(__dirname, './page-info-object-type.graphql'));
export const sortingInputTypeSDL = readGraphql(resolve(__dirname, './sorting-input-type.graphql'));
export const cursorQueryArgsTypeSDL = readGraphql(resolve(__dirname, './cursor-query-args-type.graphql'));
export const cursorQueryArgsFilterRequiredTypeSDL = readGraphql(
resolve(__dirname, './cursor-query-args-required-filter-type.graphql'),
);
export const offsetQueryArgsTypeSDL = readGraphql(resolve(__dirname, './offset-query-args-type.graphql'));
export const offsetQueryArgsFilterRequiredTypeSDL = readGraphql(
resolve(__dirname, './offset-query-args-required-filter-type.graphql'),
);
export const noPagingQueryArgsTypeSDL = readGraphql(resolve(__dirname, './no-paging-query-args-type.graphql'));
export const noPagingQueryArgsFilterRequiredTypeSDL = readGraphql(
resolve(__dirname, './no-paging-query-args-required-filter-type.graphql'),
);
export const connectionObjectTypeSDL = readGraphql(resolve(__dirname, './connection-object-type.graphql'));
export const connectionObjectTypeWithTotalCountSDL = readGraphql(
resolve(__dirname, './connection-object-type-with-total-count.graphql'),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
type Query {
test(
"""Specify to filter the records returned."""
filter: TestFilterRequiredDtoFilter!

"""Specify to sort results."""
sorting: [TestFilterRequiredDtoSort!] = []
): String!
}

input TestFilterRequiredDtoFilter {
and: [TestFilterRequiredDtoFilter!]
or: [TestFilterRequiredDtoFilter!]
requiredFilterableField: StringFieldComparison!
}

input StringFieldComparison {
is: Boolean
isNot: Boolean
eq: String
neq: String
gt: String
gte: String
lt: String
lte: String
like: String
notLike: String
iLike: String
notILike: String
in: [String!]
notIn: [String!]
}

input TestFilterRequiredDtoSort {
field: TestFilterRequiredDtoSortFields!
direction: SortDirection!
nulls: SortNulls
}

enum TestFilterRequiredDtoSortFields {
requiredFilterableField
}

"""Sort Directions"""
enum SortDirection {
ASC
DESC
}

"""Sort Nulls Options"""
enum SortNulls {
NULLS_FIRST
NULLS_LAST
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
type Query {
test(
"""Limit or page results."""
paging: OffsetPaging = {limit: 10}

"""Specify to filter the records returned."""
filter: TestFilterRequiredDtoFilter!

"""Specify to sort results."""
sorting: [TestFilterRequiredDtoSort!] = []
): String!
}

input OffsetPaging {
"""Limit the number of records returned"""
limit: Int

"""Offset to start returning records from"""
offset: Int
}

input TestFilterRequiredDtoFilter {
and: [TestFilterRequiredDtoFilter!]
or: [TestFilterRequiredDtoFilter!]
requiredFilterableField: StringFieldComparison!
}

input StringFieldComparison {
is: Boolean
isNot: Boolean
eq: String
neq: String
gt: String
gte: String
lt: String
lte: String
like: String
notLike: String
iLike: String
notILike: String
in: [String!]
notIn: [String!]
}

input TestFilterRequiredDtoSort {
field: TestFilterRequiredDtoSortFields!
direction: SortDirection!
nulls: SortNulls
}

enum TestFilterRequiredDtoSortFields {
requiredFilterableField
}

"""Sort Directions"""
enum SortDirection {
ASC
DESC
}

"""Sort Nulls Options"""
enum SortNulls {
NULLS_FIRST
NULLS_LAST
}
31 changes: 31 additions & 0 deletions packages/query-graphql/__tests__/types/query/filter.type.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
deleteFilterInputTypeSDL,
subscriptionFilterInputTypeSDL,
filterAllowedComparisonsInputTypeSDL,
filterRequiredFieldInputTypeSDL,
} from '../../__fixtures__';

describe('filter types', (): void => {
Expand Down Expand Up @@ -210,6 +211,36 @@ describe('filter types', (): void => {
return expectSDL([FilterTypeSpec], filterAllowedComparisonsInputTypeSDL);
});
});

describe('filterRequired option', () => {
@ObjectType('TestFilterRequiredComparison')
class TestFilterRequiredDto extends BaseType {
@FilterableField({ filterRequired: true })
requiredField!: boolean;

@FilterableField({ filterRequired: false })
nonRequiredField!: Date;

@FilterableField()
notSpecifiedField!: number;
}

const TestGraphQLComparisonFilter: Class<Filter<TestDto>> = FilterType(TestFilterRequiredDto);
@InputType()
class TestComparisonDtoFilter extends TestGraphQLComparisonFilter {}

it('should only expose allowed comparisons', () => {
@Resolver()
class FilterTypeSpec {
@Query(() => Int)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
test(@Args('input') input: TestComparisonDtoFilter): number {
return 1;
}
}
return expectSDL([FilterTypeSpec], filterRequiredFieldInputTypeSDL);
});
});
});

describe('UpdateFilterType', () => {
Expand Down
Loading

0 comments on commit a425ba7

Please sign in to comment.