fix: introduce listAndCount for gift cards to enable pagination (#1754)

**What**
Proper `listAndCount` implementation for gift cards.
This commit is contained in:
Sebastian Rindom
2022-07-04 16:52:55 +02:00
committed by GitHub
parent 9b5c2e8c1f
commit 9a14b84e58
3 changed files with 87 additions and 18 deletions

View File

@@ -1,7 +1,6 @@
import { Type } from "class-transformer"
import { IsInt, IsOptional, IsString } from "class-validator"
import { pickBy } from "lodash"
import { defaultAdminGiftCardFields, defaultAdminGiftCardRelations } from "."
import { GiftCardService } from "../../../../services"
import { validator } from "../../../../utils/validator"
@@ -30,14 +29,14 @@ export default async (req, res) => {
const giftCardService: GiftCardService = req.scope.resolve("giftCardService")
const giftCards = await giftCardService.list(
const [giftCards, count] = await giftCardService.listAndCount(
pickBy(req.filterableFields, (val) => typeof val !== "undefined"),
req.listConfig
)
res.status(200).json({
gift_cards: giftCards,
count: giftCards.length,
count,
offset: validated.offset,
limit: validated.limit,
})

View File

@@ -15,12 +15,18 @@ export class GiftCardRepository extends Repository<GiftCard> {
idsOrOptionsWithoutRelations:
| Omit<FindManyOptions<GiftCard>, "relations">
| string[] = {}
): Promise<GiftCard[]> {
let entities
): Promise<[GiftCard[], number]> {
let entities: GiftCard[] = []
let count = 0
if (Array.isArray(idsOrOptionsWithoutRelations)) {
entities = await this.findByIds(idsOrOptionsWithoutRelations)
count = idsOrOptionsWithoutRelations.length
} else {
entities = await this.find(idsOrOptionsWithoutRelations)
const [results, resultCount] = await this.findAndCount(
idsOrOptionsWithoutRelations
)
entities = results
count = resultCount
}
const entitiesIds = entities.map(({ id }) => id)
@@ -45,15 +51,19 @@ export class GiftCardRepository extends Repository<GiftCard> {
const entitiesAndRelations = entitiesIdsWithRelations.concat(entities)
const entitiesAndRelationsById = groupBy(entitiesAndRelations, "id")
return Object.values(entitiesAndRelationsById).map((v) => merge({}, ...v))
return [
Object.values(entitiesAndRelationsById).map((v) => merge({}, ...v)),
count,
]
}
protected async queryGiftCards(
q: string,
where: Partial<Writable<QuerySelector<GiftCard>>>,
rels: (keyof GiftCard | string)[]
): Promise<GiftCard[]> {
const raw = await this.createQueryBuilder("gift_card")
rels: (keyof GiftCard | string)[],
shouldCount = false
): Promise<[GiftCard[], number]> {
const qb = this.createQueryBuilder("gift_card")
.leftJoinAndSelect("gift_card.order", "order")
.select(["gift_card.id"])
.where(where)
@@ -64,12 +74,39 @@ export class GiftCardRepository extends Repository<GiftCard> {
.orWhere(`display_id::varchar(255) ILIKE :dId`, { dId: `${q}` })
})
)
.getMany()
return this.findWithRelations(
let raw: GiftCard[] = []
let count = 0
if (shouldCount) {
const [results, resultCount] = await qb.getManyAndCount()
raw = results
count = resultCount
} else {
raw = await qb.getMany()
}
const [results] = await this.findWithRelations(
rels,
raw.map((i) => i.id)
)
return [results, count]
}
public async listGiftCardsAndCount(
inputQuery: ExtendedFindConfig<GiftCard, QuerySelector<GiftCard>>,
rels: (keyof GiftCard | string)[] = [],
q?: string
): Promise<[GiftCard[], number]> {
const query = { ...inputQuery }
if (q) {
const where = query.where
delete where.id
return await this.queryGiftCards(q, where, rels, true)
}
return await this.findWithRelations(rels, query)
}
public async listGiftCards(
@@ -81,9 +118,12 @@ export class GiftCardRepository extends Repository<GiftCard> {
const where = query.where
delete where.id
return await this.queryGiftCards(q, where, rels)
const [result] = await this.queryGiftCards(q, where, rels)
return result
}
return this.findWithRelations(rels, query)
const [results] = await this.findWithRelations(rels, query)
return results
}
public async findOneWithRelations(
@@ -93,7 +133,7 @@ export class GiftCardRepository extends Repository<GiftCard> {
// Limit 1
optionsWithoutRelations.take = 1
const result = await this.findWithRelations(
const [result] = await this.findWithRelations(
relations,
optionsWithoutRelations
)

View File

@@ -1,6 +1,6 @@
import { MedusaError } from "medusa-core-utils"
import randomize from "randomatic"
import { Brackets, EntityManager, FindOneOptions } from "typeorm"
import { EntityManager } from "typeorm"
import { EventBusService } from "."
import { TransactionBaseService } from "../interfaces"
import { GiftCard } from "../models"
@@ -76,6 +76,36 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
return code
}
/**
* @param selector - the query object for find
* @param config - the configuration used to find the objects. contains relations, skip, and take.
* @return the result of the find operation
*/
async listAndCount(
selector: QuerySelector<GiftCard> = {},
config: FindConfig<GiftCard> = { relations: [], skip: 0, take: 10 }
): Promise<[GiftCard[], number]> {
return await this.atomicPhase_(async (manager) => {
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
let q: string | undefined
if (typeof selector.q !== "undefined") {
q = selector.q
delete selector.q
}
const query: ExtendedFindConfig<
GiftCard,
QuerySelector<GiftCard>
> = buildQuery<QuerySelector<GiftCard>, GiftCard>(selector, config)
const rels = query.relations
delete query.relations
return await giftCardRepo.listGiftCardsAndCount(query, rels, q)
})
}
/**
* @param selector - the query object for find
* @param config - the configuration used to find the objects. contains relations, skip, and take.
@@ -88,8 +118,8 @@ class GiftCardService extends TransactionBaseService<GiftCardService> {
return await this.atomicPhase_(async (manager) => {
const giftCardRepo = manager.getCustomRepository(this.giftCardRepository_)
let q
if ("q" in selector) {
let q: string | undefined
if (typeof selector.q !== "undefined") {
q = selector.q
delete selector.q
}