diff --git a/packages/medusa/src/interfaces/__tests__/base-service.spec.ts b/packages/medusa/src/interfaces/__tests__/base-service.spec.ts index 9166759fac..9fa804e4f1 100644 --- a/packages/medusa/src/interfaces/__tests__/base-service.spec.ts +++ b/packages/medusa/src/interfaces/__tests__/base-service.spec.ts @@ -1,4 +1,4 @@ -import BaseService from "../base-service" +import { BaseService } from "../base-service" import { In, Not } from "typeorm" import { MockManager } from "medusa-test-utils" @@ -6,7 +6,7 @@ describe("BaseService", () => { it("should cloned the child class withTransaction", () => { class Child extends BaseService { constructor(protected readonly container) { - super(container, {}); + super(container); this.container = container } @@ -58,4 +58,4 @@ describe("BaseService", () => { }) }) }) -}) +}) \ No newline at end of file diff --git a/packages/medusa/src/interfaces/base-service.ts b/packages/medusa/src/interfaces/base-service.ts index 18560465f2..d606da89e7 100644 --- a/packages/medusa/src/interfaces/base-service.ts +++ b/packages/medusa/src/interfaces/base-service.ts @@ -1,7 +1,7 @@ import { MedusaError } from "medusa-core-utils" import { EntityManager, FindOperator, In, Raw } from "typeorm" import { IsolationLevel } from "typeorm/driver/types/IsolationLevel" -import { FindConfig } from "../types/common" +import { FindConfig, Writable } from "../types/common" type Selector = { [key in keyof TEntity]?: unknown } @@ -9,7 +9,7 @@ type Selector = { [key in keyof TEntity]?: unknown } * Common functionality for Services * @interface */ -class BaseService< +export class BaseService< TChild extends BaseService, TContainer = unknown > { @@ -19,22 +19,17 @@ class BaseService< constructor( container: TContainer, - protected readonly configModule: Record + protected readonly configModule?: Record ) { this.container_ = container } - withTransaction(): this - withTransaction(transactionManager: EntityManager): TChild withTransaction(transactionManager?: EntityManager): this | TChild { if (!transactionManager) { return this } - const cloned = new (this.constructor)< - TChild, - TContainer - >( + const cloned = new (this.constructor)( { ...this.container_, manager: transactionManager, @@ -57,12 +52,12 @@ class BaseService< selector: Selector, config: FindConfig = {} ): FindConfig & { - where: { [key in keyof TEntity]?: unknown } + where: Partial> withDeleted?: boolean } { const build = ( obj: Record - ): { [key in keyof TEntity]?: unknown } => { + ): Partial> => { 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 @@ -83,27 +78,25 @@ class BaseService< acc[key] = In([...(value as unknown[])]) break case value !== null && typeof value === "object": - Object.entries(value as Record).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 - } + 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( @@ -121,11 +114,11 @@ class BaseService< } return acc - }, {} as { [key in keyof TEntity]?: unknown }) + }, {} as Partial>) } const query: FindConfig & { - where: { [key in keyof TEntity]?: unknown } + where: Partial> withDeleted?: boolean } = { where: build(selector), @@ -217,17 +210,19 @@ class BaseService< * @param maybeErrorHandlerOrDontFail Potential error handler * @return the result of the transactional work */ - async atomicPhase_( - work: (transactionManager: EntityManager) => Promise, + async atomicPhase_( + work: (transactionManager: EntityManager) => Promise, isolationOrErrorHandler?: | IsolationLevel - | ((error: unknown) => Promise), - maybeErrorHandlerOrDontFail?: (error: unknown) => Promise - ): Promise { + | ((error: TError) => Promise), + maybeErrorHandlerOrDontFail?: ( + error: TError + ) => Promise + ): Promise { let errorHandler = maybeErrorHandlerOrDontFail let isolation: | IsolationLevel - | ((error: unknown) => Promise) + | ((error: TError) => Promise) | undefined | null = isolationOrErrorHandler let dontFail = false @@ -238,7 +233,7 @@ class BaseService< } if (this.transactionManager_) { - const doWork = async (m: EntityManager): Promise => { + const doWork = async (m: EntityManager): Promise => { this.manager_ = m this.transactionManager_ = m try { @@ -256,10 +251,10 @@ class BaseService< } } - return doWork(this.transactionManager_) + return await doWork(this.transactionManager_) } else { const temp = this.manager_ - const doWork = async (m: EntityManager): Promise => { + const doWork = async (m: EntityManager): Promise => { this.manager_ = m this.transactionManager_ = m try { @@ -284,8 +279,9 @@ class BaseService< return result } catch (error) { if (this.shouldRetryTransaction(error)) { - return this.manager_.transaction(isolation as IsolationLevel, (m) => - doWork(m) + return this.manager_.transaction( + isolation as IsolationLevel, + (m): Promise => doWork(m) ) } else { if (errorHandler) { @@ -302,7 +298,7 @@ class BaseService< if (errorHandler) { const result = await errorHandler(error) if (dontFail) { - return result + return result as TResult } } @@ -338,5 +334,4 @@ class BaseService< ...newData, } } -} -export default BaseService +} \ No newline at end of file