Skip to content

Commit 58e3e1f

Browse files
authored
Merge branch 'master' into bugfix/mongoose-query-service-accept-any-ids
2 parents a556963 + 09e9eea commit 58e3e1f

File tree

6 files changed

+37
-17
lines changed

6 files changed

+37
-17
lines changed

documentation/docs/graphql/dtos.mdx

+12
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,18 @@ export class TodoItemDTO {
649649

650650
```
651651
652+
:::info
653+
When we use the `@Relation` decorator or other [relation decorators](./relations.mdx) you might want to define the default sorting criteria like this:
654+
```ts title="todo-item.dto.ts"
655+
import { SortDirection } from '@ptc-org/nestjs-query-core';
656+
// ...
657+
@Relation('assignee', () => UserDTO, {
658+
defaultSort: [{ field: 'id', direction: SortDirection.ASC }],
659+
})
660+
```
661+
Note that default value for `defaultSort` is `[]`, meaning if you do **not** specify it you will receive the results as determined by your underlying database, which is unreliable and calculated based on how your database engine works.
662+
:::
663+
652664
### Allowed Boolean Expressions
653665
654666
When filtering you can provide `and` and `or` expressions to provide advanced filtering. You can turn off either by

packages/query-graphql/src/types/connection/cursor/pager/pager.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class CursorPager<DTO> implements Pager<DTO, CursorPagerResult<DTO>> {
8787
const pageInfo = {
8888
startCursor: edges[0]?.cursor,
8989
endCursor: edges[edges.length - 1]?.cursor,
90-
// if we have are going forward and have an extra node or there was a before cursor
90+
// if we re paging forward and have an extra node we have more pages to load. Or there we know that we have a before cursor, thus we have next page
9191
hasNextPage: isForward ? hasExtraNode : hasBefore,
9292
// we have a previous page if we are going backwards and have an extra node.
9393
hasPreviousPage: this.hasPreviousPage(results, pagingMeta)
@@ -102,12 +102,16 @@ export class CursorPager<DTO> implements Pager<DTO, CursorPagerResult<DTO>> {
102102
return opts.isBackward ? hasExtraNode : !this.strategy.isEmptyCursor(opts)
103103
}
104104

105+
/**
106+
* @description
107+
* It is an empty page if:
108+
*
109+
* 1. We don't have an extra node.
110+
* 2. There were no nodes returned.
111+
* 3. We're paging forward.
112+
* 4. And we don't have an offset.
113+
*/
105114
private isEmptyPage(results: QueryResults<DTO>, pagingMeta: PagingMeta<DTO, CursorPagingOpts<DTO>>): boolean {
106-
// it is an empty page if
107-
// 1. we dont have an extra node
108-
// 2. there were no nodes returned
109-
// 3. we're paging forward
110-
// 4. and we dont have an offset
111115
const { opts } = pagingMeta
112116
const isEmpty = !results.hasExtraNode && !results.nodes.length && pagingMeta.opts.isForward
113117
return isEmpty && this.strategy.isEmptyCursor(opts)

packages/query-graphql/src/types/connection/cursor/pager/strategies/keyset.pager-strategy.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ export class KeysetPagerStrategy<DTO> implements PagerStrategy<DTO> {
4747
paging.limit += 1
4848
}
4949
const { payload } = opts
50-
// Add 1 to the limit so we will fetch an additional node with the current node
5150
const sorting = this.getSortFields(query, opts)
5251
const filter = mergeFilter(query.filter ?? {}, this.createFieldsFilter(sorting, payload))
5352
const createdQuery = { ...query, filter, sorting, paging }
@@ -120,6 +119,10 @@ export class KeysetPagerStrategy<DTO> implements PagerStrategy<DTO> {
120119
return { or: oredFilter } as Filter<DTO>
121120
}
122121

122+
/**
123+
* @description
124+
* Strip the default sorting criteria if it is set by the client.
125+
*/
123126
private getSortFields(query: Query<DTO>, opts: KeySetPagingOpts<DTO>): SortField<DTO>[] {
124127
const { sorting = [] } = query
125128
const defaultSort = opts.defaultSort.filter((dsf) => !sorting.some((sf) => dsf.field === sf.field))

packages/query-typeorm/src/module.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import type { DataSource } from 'typeorm'
77
import { createTypeOrmQueryServiceProviders } from './providers'
88

99
export class NestjsQueryTypeOrmModule {
10-
static forFeature(entities: Class<unknown>[], connection?: DataSource | string): DynamicModule {
11-
const queryServiceProviders = createTypeOrmQueryServiceProviders(entities, connection)
12-
const typeOrmModule = TypeOrmModule.forFeature(entities, connection)
10+
static forFeature(entities: Class<unknown>[], dataSource?: DataSource | string): DynamicModule {
11+
const queryServiceProviders = createTypeOrmQueryServiceProviders(entities, dataSource)
12+
const typeOrmModule = TypeOrmModule.forFeature(entities, dataSource)
1313

1414
return {
1515
imports: [typeOrmModule],

packages/query-typeorm/src/providers.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ import { TypeOrmQueryService } from './services'
88

99
function createTypeOrmQueryServiceProvider<Entity>(
1010
EntityClass: Class<Entity>,
11-
connection?: DataSource | string
11+
dataSource?: DataSource | string
1212
): FactoryProvider {
1313
return {
1414
provide: getQueryServiceToken(EntityClass),
1515
useFactory(repo: Repository<Entity>) {
1616
return new TypeOrmQueryService(repo)
1717
},
18-
inject: [getRepositoryToken(EntityClass, connection)]
18+
inject: [getRepositoryToken(EntityClass, dataSource)]
1919
}
2020
}
2121

2222
export const createTypeOrmQueryServiceProviders = (
2323
entities: Class<unknown>[],
24-
connection?: DataSource | string
25-
): FactoryProvider[] => entities.map((entity) => createTypeOrmQueryServiceProvider(entity, connection))
24+
dataSource?: DataSource | string
25+
): FactoryProvider[] => entities.map((entity) => createTypeOrmQueryServiceProvider(entity, dataSource))

packages/query-typeorm/src/query/filter-query.builder.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,11 @@ export class FilterQueryBuilder<Entity> {
218218
}
219219

220220
return sorts.reduce((prevQb, { field, direction, nulls }) => {
221-
let col = alias ? `${alias}.${field as string}` : `${field as string}`
221+
const stringifiedField = String(field)
222+
let col = alias ? `${alias}.${stringifiedField}` : `${stringifiedField}`
222223

223-
if (this.virtualColumns.includes(field as string)) {
224-
col = prevQb.escape(alias ? `${alias}_${field as string}` : `${field as string}`)
224+
if (this.virtualColumns.includes(stringifiedField)) {
225+
col = prevQb.escape(alias ? `${alias}_${stringifiedField}` : `${stringifiedField}`)
225226
}
226227

227228
return prevQb.addOrderBy(col, direction, nulls)

0 commit comments

Comments
 (0)