feat(medusa): Split base service to its related TransactionBaseService and utilities methods when required

This commit is contained in:
adrien2p
2022-04-21 13:48:16 +02:00
parent 99146b7403
commit e7e715ac17
7 changed files with 218 additions and 233 deletions
+112
View File
@@ -0,0 +1,112 @@
import { FindConfig, Writable } from "../types/common"
import { FindOperator, In, Raw } from "typeorm"
type Selector<TEntity> = { [key in keyof TEntity]?: unknown }
/**
* Used to build TypeORM queries.
* @param selector The selector
* @param config The config
* @return The QueryBuilderConfig
*/
export function buildQuery<TEntity = unknown>(
selector: Selector<TEntity>,
config: FindConfig<TEntity> = {}
): FindConfig<TEntity> & {
where: Partial<Writable<TEntity>>
withDeleted?: boolean
} {
const build = (
obj: Record<string, unknown>
): Partial<Writable<TEntity>> => {
return Object.entries(obj).reduce((acc, [key, value]: any) => {
// Undefined values indicate that they have no significance to the query.
// If the query is looking for rows where a column is not set it should use null instead of undefined
if (typeof value === "undefined") {
return acc
}
const subquery: {
operator: "<" | ">" | "<=" | ">="
value: unknown
}[] = []
switch (true) {
case value instanceof FindOperator:
acc[key] = value
break
case Array.isArray(value):
acc[key] = In([...(value as unknown[])])
break
case value !== null && typeof value === "object":
Object.entries(value).map(([modifier, val]) => {
switch (modifier) {
case "lt":
subquery.push({ operator: "<", value: val })
break
case "gt":
subquery.push({ operator: ">", value: val })
break
case "lte":
subquery.push({ operator: "<=", value: val })
break
case "gte":
subquery.push({ operator: ">=", value: val })
break
default:
acc[key] = value
break
}
})
if (subquery.length) {
acc[key] = Raw(
(a) =>
subquery
.map((s, index) => `${a} ${s.operator} :${index}`)
.join(" AND "),
subquery.map((s) => s.value)
)
}
break
default:
acc[key] = value
break
}
return acc
}, {} as Partial<Writable<TEntity>>)
}
const query: FindConfig<TEntity> & {
where: Partial<Writable<TEntity>>
withDeleted?: boolean
} = {
where: build(selector),
}
if ("deleted_at" in selector) {
query.withDeleted = true
}
if ("skip" in config) {
query.skip = config.skip
}
if ("take" in config) {
query.take = config.take
}
if ("relations" in config) {
query.relations = config.relations
}
if ("select" in config) {
query.select = config.select
}
if ("order" in config) {
query.order = config.order
}
return query
}