Query Helpers
The @nestjs-query/core
package provides a number of helper functions to transform or apply queries to a list of items.
An example use case for these helpers would be to write a QueryService
that wraps a store that does not support the
query options natively (e.g. An in memory collection of objects such as a static array of objects).
All examples will be based on the following DTO definition.
interface TestDTO { first?: string | null;
last?: string | null;
age?: number | null;
isVerified?: boolean | null;
created?: Date | null;}
#
applyFilterThe applyFilter
helper applies a Filter
to a single object or an array of objects.
#
Argumentsdto: DTO|DTO[]
- If a single object a function that will test the dto against the filter, returning
true
when if it matches the filter. - If an array of objects is provided the array will be filtered returning a new array with all elements that match the filter.
- If a single object a function that will test the dto against the filter, returning
filter: Filter<DTO>
- The filter to check the object[s] against. SeeFiltering
#
Exampleimport { applyFilter } from `@nestjs-query/core`;
const dtos: TestDTO[] = [ {first: 'Bob', last: 'Yukon'} {first: 'Alice', last: 'Yukon'} {first: 'Sally', last: 'Yukon'} {first: 'Zane', last: 'Yukon'}]const filtered = applyFilter(dtos, {first: {in: ['Bob', 'Sally']})
const dto: TestDTO = {first: 'Bob', last: 'Yukon'};applyFilter<TestDTO>(dto, {first: {in: ['Bob', 'Sally']}) // trueapplyFilter<TestDTO>(dto, {first: {eq: ['Alice', 'Zane']}) // false
#
applySortThe applySort
will sort an array of dtos.
info
Because applySort
uses the native Array#sort
method it may not exactly match the ordering you would expect from a
database.
warning
It is expected that your data types all match. For example if you have a number field that also has some numbers represented as strings the applySort method may not work as expected.
#
Argumentsdto: DTO[]
- The array of DTOs to sort.sortFields: SortField<DTO>[]
- The sorting criteria. SeeSorting
#
Exampleimport { applySort, SortDirection, SortNulls } from `@nestjs-query/core`;
const dtos: TestDTO[] = [ {first: 'Bob', last: 'Yukon'} {first: 'Alice', last: 'Yukon'} {first: null, last: 'Yukon'} {first: 'Sally', last: 'Yukon'} {last: 'Yukon'} {first: 'Zane', last: 'Yukon'}]const sorted = applySort(dtos, [ { field: 'first', direction: SortDirection.DESC, nulls: SortNulls.NULLS_LAST },])
The resulting sorted array would be.
[ {first: 'Zane', last: 'Yukon'} {first: 'Sally', last: 'Yukon'} {first: 'Bob', last: 'Yukon'} {first: 'Alice', last: 'Yukon'} {first: null, last: 'Yukon'} {last: 'Yukon'}]
#
applyPagingThe applyPaging
method will apply a limit
and/or offset
to an array of dtos.
#
Argumentsdto: DTO[]
- The array of DTOs to page.paging: Paging
- The paging arguments to apply. SeePaging
#
Exampleimport { applyPaging } from `@nestjs-query/core`;const dtos: TestDTO[] = [ {first: 'Bob', last: 'Yukon'} {first: 'Alice', last: 'Yukon'} {first: 'Sally', last: 'Yukon'} {first: 'Zane', last: 'Yukon'}]const paged = applyPaging(dtos, {offset: 1, limit: 2})
The resulting paged dtos would be.
[ {first: 'Alice', last: 'Yukon'} {first: 'Sally', last: 'Yukon'}]
#
applyQueryThe applyQuery
uses the applyFilter
, applySorting
, and applyPaging
methods to apply a Query
to an array of
DTOs.
#
Argumentsdto: DTO[]
- The array of DTOs to page.query: Query<DTO>
- The query to apply to the array of dtos. SeeQueries
#
Exampleimport { applyQuery, SortDirection } from `@nestjs-query/core`;
const dtos: TestDTO[] = [ {first: 'Bob', last: 'Yukon', isVerified: true} {first: 'Alice', last: 'Yukon', isVerified: false} {first: 'Sally', last: 'Yukon', isVerified: true} {first: 'Zane', last: 'Yukon', isVerified: true}]const queryResult = applyQuery(dtos, { filter: { isVerified: { is: true } }, sorting: [{ field: 'first', direction: SortDirection.DESC }], paging: { offset: 1, limit: 2 }})
The resulting array of dtos would be.
[ {first: 'Sally', last: 'Yukon', isVerified: true} {first: 'Bob', last: 'Yukon', isVerified: true}]
#
transformFilterThe transformFilter is used to remap fields in a Filter
. This method is commonly used when defining a custom
Assembler.
#
Argumentsfilter: Filter<From>
- The filter you want to transform.fieldMap: QueryFieldMap<From, To>
- A map of fields where the key is a key in the From type, and the value is a key in the to type.
#
Exampleimport { transformFilter, QueryFieldMap, Filter } from `@nestjs-query/core`;
class TestEntity { firstName!: string;
lastName!: string;}
const fieldMap: QueryFieldMap<TestDTO, TestEntity> = { first: 'firstName', last: 'lastName',};
const dtoFilter: Filter<TestDTO> = { first: { eq: 'foo' }, last: { neq: 'bar' },};
const transformed = transformFilter(dtoFilter, fieldMap);
The new filter would be
{ firstName: { eq: 'foo' }, lastName: { neq: 'bar' },}
#
transformSortThe transformSort
is used to remap fields in an array of SortField<DTO>[]
. This method is commonly used when
defining a custom Assembler.
#
ArgumentssortFields: SortField<From>[]
- The array of sorting criteria to transform.fieldMap: QueryFieldMap<From, To>
- A map of fields where the key is a key in the From type, and the value is a key in the to type.
#
Exampleimport { transformSort, QueryFieldMap, SortField, SortDirection } from `@nestjs-query/core`;
class TestEntity { firstName!: string;
lastName!: string;}
const fieldMap: QueryFieldMap<TestDTO, TestEntity> = { first: 'firstName', last: 'lastName',};const dtoSort: SortField<TestDTO>[] = [ { field: 'first', direction: SortDirection.DESC }, { field: 'last', direction: SortDirection.ASC },];
const transformed = transformSort(dtoSort, fieldMap);
[ { field: 'firstName', direction: SortDirection.DESC }, { field: 'lastName', direction: SortDirection.ASC },];
#
transformQueryThe transformQuery
method uses the transformFilter
and transformSort
methods to remap a Query
. This method is
commonly used when defining a custom Assembler.
#
ArgumentssortFields: Query<From>
- The query to transform.fieldMap: QueryFieldMap<From, To>
- A map of fields where the key is a key in the From type, and the value is a key in the to type.
#
Exampleimport { transformQuery, QueryFieldMap, Query, SortDirection } from `@nestjs-query/core`;
class TestEntity { firstName!: string;
lastName!: string;}
const fieldMap: QueryFieldMap<TestDTO, TestEntity> = { first: 'firstName', last: 'lastName',};const dtoQuery: Query<TestDTO> = { filter: { first: { eq: 'foo' }, last: { neq: 'bar' } } sorting: [ { field: 'first', direction: SortDirection.DESC }, { field: 'last', direction: SortDirection.ASC }, ]};
const transformed = transformQuery(dtoQuery, fieldMap);
The resulting query would be.
{ filter: { firstName: { eq: 'foo' }, lastName: { neq: 'bar' } } sorting: [ { field: 'firstName', direction: SortDirection.DESC }, { field: 'lastName', direction: SortDirection.ASC }, ]}
#
getFilterComparisonsUsed to search a filter get a list of comparison objects for a given key.
#
Argumentsfilter: Filter<DTO>
- The filter to search.key: keyof DTO
- The key in the DTO object to search for in the filter object.
#
Exampleimport { Filter, getFilterComparisons } from `@nestjs-query/core`;
class TestDTO { age!: number;
title!: string;}
const filter: Filter<TestDTO> = { age: { gte: 10 }, or: [{ title: { like: '%bar' } }, { title: { eq: 'foobar' } }],};
const comparisons = getFilterComparisons(filter, 'title');
The resulting array would be
[{ like: '%bar' }, { eq: 'foobar' }];
#
getFilterOmittingUsed to get a filter with a given key removed.
#
Argumentsfilter: Filter<DTO>
- The filter containing the unwanted key.key: keyof DTO
- The key in the DTO object to remove in the filter object.
#
Exampleimport { Filter, getFilterOmitting } from `@nestjs-query/core`;
class TestDTO { age!: number;
title!: string;}
const filter: Filter<TestDTO> = { age: { gte: 10 }, or: [{ title: { like: '%bar' } }, { title: { eq: 'foobar' } }],};
const filterWithoutTitle = getFilterOmitting(filter, 'title');
The resulting filter would be
{ age: { gte: 10 },}