feat: customized links (#331)
This commit is contained in:
parent
98cadc6f7d
commit
c513993908
15
README.md
15
README.md
@ -234,6 +234,21 @@ const paginateConfig: PaginateConfig<CatEntity> {
|
||||
* https://typeorm.io/select-query-builder#querying-deleted-rows
|
||||
*/
|
||||
withDeleted: false,
|
||||
|
||||
/**
|
||||
* Required: false
|
||||
* Type: boolean
|
||||
* Default: false
|
||||
* Description: Generate relative paths in the resource links.
|
||||
*/
|
||||
relativePath: true,
|
||||
|
||||
/**
|
||||
* Required: false
|
||||
* Type: string
|
||||
* Description: Overrides the origin of absolute resource links if set.
|
||||
*/
|
||||
origin: 'http://cats.example',
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -160,6 +160,70 @@ describe('paginate', () => {
|
||||
expect(links.last).toBe('?page=3&limit=2&sortBy=id:ASC')
|
||||
})
|
||||
|
||||
it('should return a relative path', async () => {
|
||||
const config: PaginateConfig<CatEntity> = {
|
||||
sortableColumns: ['id'],
|
||||
relativePath: true,
|
||||
}
|
||||
|
||||
const query: PaginateQuery = {
|
||||
path: 'http://localhost/cats',
|
||||
page: 2,
|
||||
limit: 2,
|
||||
}
|
||||
|
||||
const { links } = await paginate<CatEntity>(query, catRepo, config)
|
||||
|
||||
expect(links.first).toBe('/cats?page=1&limit=2&sortBy=id:ASC')
|
||||
expect(links.previous).toBe('/cats?page=1&limit=2&sortBy=id:ASC')
|
||||
expect(links.current).toBe('/cats?page=2&limit=2&sortBy=id:ASC')
|
||||
expect(links.next).toBe('/cats?page=3&limit=2&sortBy=id:ASC')
|
||||
expect(links.last).toBe('/cats?page=3&limit=2&sortBy=id:ASC')
|
||||
})
|
||||
|
||||
it('should return an absolute path', async () => {
|
||||
const config: PaginateConfig<CatEntity> = {
|
||||
sortableColumns: ['id'],
|
||||
relativePath: false,
|
||||
}
|
||||
|
||||
const query: PaginateQuery = {
|
||||
path: 'http://localhost/cats',
|
||||
page: 2,
|
||||
limit: 2,
|
||||
}
|
||||
|
||||
const { links } = await paginate<CatEntity>(query, catRepo, config)
|
||||
|
||||
expect(links.first).toBe('http://localhost/cats?page=1&limit=2&sortBy=id:ASC')
|
||||
expect(links.previous).toBe('http://localhost/cats?page=1&limit=2&sortBy=id:ASC')
|
||||
expect(links.current).toBe('http://localhost/cats?page=2&limit=2&sortBy=id:ASC')
|
||||
expect(links.next).toBe('http://localhost/cats?page=3&limit=2&sortBy=id:ASC')
|
||||
expect(links.last).toBe('http://localhost/cats?page=3&limit=2&sortBy=id:ASC')
|
||||
})
|
||||
|
||||
it('should return an absolute path with new origin', async () => {
|
||||
const config: PaginateConfig<CatEntity> = {
|
||||
sortableColumns: ['id'],
|
||||
relativePath: false,
|
||||
origin: 'http://cats.example',
|
||||
}
|
||||
|
||||
const query: PaginateQuery = {
|
||||
path: 'http://localhost/cats',
|
||||
page: 2,
|
||||
limit: 2,
|
||||
}
|
||||
|
||||
const { links } = await paginate<CatEntity>(query, catRepo, config)
|
||||
|
||||
expect(links.first).toBe('http://cats.example/cats?page=1&limit=2&sortBy=id:ASC')
|
||||
expect(links.previous).toBe('http://cats.example/cats?page=1&limit=2&sortBy=id:ASC')
|
||||
expect(links.current).toBe('http://cats.example/cats?page=2&limit=2&sortBy=id:ASC')
|
||||
expect(links.next).toBe('http://cats.example/cats?page=3&limit=2&sortBy=id:ASC')
|
||||
expect(links.last).toBe('http://cats.example/cats?page=3&limit=2&sortBy=id:ASC')
|
||||
})
|
||||
|
||||
it('should return only current link if zero results', async () => {
|
||||
const config: PaginateConfig<CatEntity> = {
|
||||
sortableColumns: ['id'],
|
||||
|
@ -55,6 +55,8 @@ export interface PaginateConfig<T> {
|
||||
where?: FindOptionsWhere<T> | FindOptionsWhere<T>[]
|
||||
filterableColumns?: { [key in Column<T>]?: FilterOperator[] }
|
||||
withDeleted?: boolean
|
||||
relativePath?: boolean
|
||||
origin?: string
|
||||
}
|
||||
|
||||
export enum FilterOperator {
|
||||
@ -165,7 +167,26 @@ export async function paginate<T>(
|
||||
const limit = Math.min(query.limit || config.defaultLimit || 20, config.maxLimit || 100)
|
||||
const sortBy = [] as SortBy<T>
|
||||
const searchBy: Column<T>[] = []
|
||||
const path = query.path
|
||||
let path
|
||||
|
||||
const r = new RegExp('^(?:[a-z+]+:)?//', 'i')
|
||||
let queryOrigin = ''
|
||||
let queryPath = ''
|
||||
if (r.test(query.path)) {
|
||||
const url = new URL(query.path)
|
||||
queryOrigin = url.origin
|
||||
queryPath = url.pathname
|
||||
} else {
|
||||
queryPath = query.path
|
||||
}
|
||||
|
||||
if (config.relativePath) {
|
||||
path = queryPath
|
||||
} else if (config.origin) {
|
||||
path = config.origin + queryPath
|
||||
} else {
|
||||
path = queryOrigin + queryPath
|
||||
}
|
||||
|
||||
function isEntityKey(entityColumns: Column<T>[], column: string): column is Column<T> {
|
||||
return !!entityColumns.find((c) => c === column)
|
||||
|
Loading…
Reference in New Issue
Block a user