chore(medusa, interfaces): Uniformise class checks (#5869)

**What**
One problem with local development can be the dependencies management. To mitigate that, transform checks from an instance of to value check as well as harmonize utils function to be part of the class as a static method instead of separate utilities. By using this approach we are not dependent of the origin of the class and therefore it should ease the user experience.

**NOTE**
As a next step to discuss, we should probably move the interfaces from the interfaces/medusa package to the utils package. Then we can deprecate the interfaces package and remove it at a later time
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2023-12-19 13:26:57 +00:00
1 parent 496dcf10c4
commit 45996d58a2
27 files changed
+186 -177

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
---
"@medusajs/medusa": patch
"medusa-fulfillment-webshipper": patch
"medusa-interfaces": patch
"@medusajs/utils": patch
---
chore(medusa, interfaces, utils, webshiper): Uniformise class checks
@@ -10,7 +10,7 @@ class WebshipperFulfillmentService extends AbstractFulfillmentService {
{ logger, totalsService, claimService, swapService, orderService }, { logger, totalsService, claimService, swapService, orderService },
options options
) { ) {
super() super(...arguments)
this.options_ = options this.options_ = options
@@ -3,8 +3,15 @@ import BaseService from "./base-service"
/** /**
* Interface for file connectors * Interface for file connectors
* @interface * @interface
* @deprecated use AbstractFileService from @medusajs/medusa instead
*/ */
class BaseFileService extends BaseService { class BaseFileService extends BaseService {
static _isFileService = true
static isFileService(obj) {
return obj?.constructor?._isFileService
}
constructor() { constructor() {
super() super()
} }
@@ -5,8 +5,15 @@ import BaseService from "./base-service"
* provides the necessary methods for creating, authorizing and managing * provides the necessary methods for creating, authorizing and managing
* fulfillment orders. * fulfillment orders.
* @interface * @interface
* @deprecated use AbstractFulfillmentService from @medusajs/medusa instead
*/ */
class BaseFulfillmentService extends BaseService { class BaseFulfillmentService extends BaseService {
static _isFulfillmentService = true
static isFulfillmentService(obj) {
return obj?.constructor?._isFulfillmentService
}
constructor() { constructor() {
super() super()
} }
@@ -3,8 +3,15 @@ import BaseService from "./base-service"
/** /**
* Interface for Notification Providers * Interface for Notification Providers
* @interface * @interface
* @deprecated use AbstractNotificationService from @medusajs/medusa instead
*/ */
class BaseNotificationService extends BaseService { class BaseNotificationService extends BaseService {
static _isNotificationService = true
static isNotificationService(obj) {
return obj?.constructor?._isNotificationService
}
constructor() { constructor() {
super() super()
} }
@@ -5,6 +5,12 @@ import BaseService from "./base-service"
* @interface * @interface
*/ */
class BaseOauthService extends BaseService { class BaseOauthService extends BaseService {
static _isOauthService = true
static isOauthService(obj) {
return obj?.constructor?._isOauthService
}
constructor() { constructor() {
super() super()
} }
@@ -5,8 +5,15 @@ import BaseService from "./base-service"
* provides the necessary methods for creating, authorizing and managing * provides the necessary methods for creating, authorizing and managing
* payments. * payments.
* @interface * @interface
* @deprecated use AbstractPaymentProcessor from @medusajs/medusa instead
*/ */
class BasePaymentService extends BaseService { class BasePaymentService extends BaseService {
static _isPaymentService = true
static isPaymentService(obj) {
return obj?.constructor?._isPaymentService
}
constructor() { constructor() {
super() super()
} }
@@ -3,8 +3,15 @@ import BaseService from "./base-service"
/** /**
* The interface that all search services must implement. * The interface that all search services must implement.
* @interface * @interface
* @deprecated use AbstractSearchService from @medusajs/utils instead
*/ */
class SearchService extends BaseService { class SearchService extends BaseService {
static _isSearchService = true
static isSearchService(obj) {
return obj?.constructor?._isSearchService
}
constructor() { constructor() {
super() super()
} }
@@ -33,11 +33,16 @@ export abstract class AbstractBatchJobStrategy
extends TransactionBaseService extends TransactionBaseService
implements IBatchJobStrategy implements IBatchJobStrategy
{ {
static _isBatchJobStrategy = true
static identifier: string static identifier: string
static batchType: string static batchType: string
protected abstract batchJobService_: BatchJobService protected abstract batchJobService_: BatchJobService
static isBatchJobStrategy(object): object is IBatchJobStrategy {
return object?.constructor?._isBatchJobStrategy
}
async prepareBatchJobForProcessing( async prepareBatchJobForProcessing(
batchJob: CreateBatchJobInput, batchJob: CreateBatchJobInput,
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -107,9 +112,3 @@ export abstract class AbstractBatchJobStrategy
}) })
} }
} }
export function isBatchJobStrategy(
object: unknown
): object is IBatchJobStrategy {
return object instanceof AbstractBatchJobStrategy
}
@@ -30,16 +30,15 @@ export abstract class AbstractCartCompletionStrategy
extends TransactionBaseService extends TransactionBaseService
implements ICartCompletionStrategy implements ICartCompletionStrategy
{ {
static _isCartCompletionStrategy = true
static isCartCompletionStrategy(object): object is ICartCompletionStrategy {
return object?.constructor?._isCartCompletionStrategy
}
abstract complete( abstract complete(
cartId: string, cartId: string,
idempotencyKey: IdempotencyKey, idempotencyKey: IdempotencyKey,
context: RequestContext context: RequestContext
): Promise<CartCompletionResponse> ): Promise<CartCompletionResponse>
} }
export function isCartCompletionStrategy(obj: unknown): boolean {
return (
typeof (obj as AbstractCartCompletionStrategy).complete === "function" ||
obj instanceof AbstractCartCompletionStrategy
)
}
@@ -55,6 +55,12 @@ export abstract class AbstractFileService
extends TransactionBaseService extends TransactionBaseService
implements IFileService implements IFileService
{ {
static _isFileService = true
static isFileService(object): object is AbstractFileService {
return object?.constructor?._isFileService
}
abstract upload( abstract upload(
fileData: Express.Multer.File fileData: Express.Multer.File
): Promise<FileServiceUploadResult> ): Promise<FileServiceUploadResult>
@@ -77,7 +83,3 @@ export abstract class AbstractFileService
fileData: GetUploadedFileType fileData: GetUploadedFileType
): Promise<string> ): Promise<string>
} }
export const isFileService = (object: unknown): boolean => {
return object instanceof AbstractFileService
}
@@ -1,6 +1,7 @@
import { MedusaContainer } from "@medusajs/types" import { MedusaContainer } from "@medusajs/types"
import { Cart, Fulfillment, LineItem, Order } from "../models" import { Cart, Fulfillment, LineItem, Order } from "../models"
import { CreateReturnType } from "../types/fulfillment-provider" import { CreateReturnType } from "../types/fulfillment-provider"
import { TransactionBaseService } from "./transaction-base-service"
type FulfillmentProviderData = Record<string, unknown> type FulfillmentProviderData = Record<string, unknown>
type ShippingOptionData = Record<string, unknown> type ShippingOptionData = Record<string, unknown>
@@ -44,7 +45,7 @@ type ShippingMethodData = Record<string, unknown>
* *
* --- * ---
*/ */
export interface FulfillmentService { export interface FulfillmentService extends TransactionBaseService {
/** /**
* @ignore * @ignore
* *
@@ -389,7 +390,16 @@ export interface FulfillmentService {
): Promise<any> ): Promise<any>
} }
export abstract class AbstractFulfillmentService implements FulfillmentService { export abstract class AbstractFulfillmentService
extends TransactionBaseService
implements FulfillmentService
{
static _isFulfillmentService = true
static isFulfillmentService(object): boolean {
return object?.constructor?._isFulfillmentService
}
/** /**
* You can use the `constructor` of your fulfillment provider to access the different services in Medusa through dependency injection. * You can use the `constructor` of your fulfillment provider to access the different services in Medusa through dependency injection.
* You can also use the constructor to initialize your integration with the third-party provider. For example, if you use a client to connect to the third-party provider’s APIs, you can initialize it in the constructor and use it in other methods in the service. * You can also use the constructor to initialize your integration with the third-party provider. For example, if you use a client to connect to the third-party provider’s APIs, you can initialize it in the constructor and use it in other methods in the service.
@@ -415,7 +425,9 @@ export abstract class AbstractFulfillmentService implements FulfillmentService {
protected constructor( protected constructor(
protected readonly container: MedusaContainer, protected readonly container: MedusaContainer,
protected readonly config?: Record<string, unknown> // eslint-disable-next-line @typescript-eslint/no-empty-function protected readonly config?: Record<string, unknown> // eslint-disable-next-line @typescript-eslint/no-empty-function
) {} ) {
super(container, config)
}
/** /**
* The `FulfillmentProvider` entity has 2 properties: `identifier` and `is_installed`. The `identifier` property in the class is used when the fulfillment provider is created in the database. * The `FulfillmentProvider` entity has 2 properties: `identifier` and `is_installed`. The `identifier` property in the class is used when the fulfillment provider is created in the database.
@@ -1,5 +1,4 @@
import { TransactionBaseService } from "./transaction-base-service" import { TransactionBaseService } from "./transaction-base-service"
import BaseNotificationService from "medusa-interfaces/dist/notification-service"
type ReturnedData = { type ReturnedData = {
to: string to: string
@@ -25,8 +24,13 @@ export abstract class AbstractNotificationService
extends TransactionBaseService extends TransactionBaseService
implements INotificationService implements INotificationService
{ {
static _isNotificationService = true
static identifier: string static identifier: string
static isNotificationService(object): boolean {
return object?.constructor?._isNotificationService
}
getIdentifier(): string { getIdentifier(): string {
return (this.constructor as any).identifier return (this.constructor as any).identifier
} }
@@ -43,10 +47,3 @@ export abstract class AbstractNotificationService
attachmentGenerator: unknown attachmentGenerator: unknown
): Promise<ReturnedData> ): Promise<ReturnedData>
} }
export const isNotificationService = (obj: unknown): boolean => {
return (
obj instanceof AbstractNotificationService ||
obj instanceof BaseNotificationService
)
}
@@ -676,6 +676,12 @@ export abstract class AbstractPaymentProcessor implements PaymentProcessor {
protected readonly config?: Record<string, unknown> // eslint-disable-next-line @typescript-eslint/no-empty-function protected readonly config?: Record<string, unknown> // eslint-disable-next-line @typescript-eslint/no-empty-function
) {} ) {}
static _isPaymentProcessor = true
static isPaymentProcessor(object): boolean {
return object?.constructor?._isPaymentProcessor
}
/** /**
* The `PaymentProvider` entity has 2 properties: `id` and `is_installed`. The `identifier` property in the payment processor service is used when the payment processor is added to the database. * The `PaymentProvider` entity has 2 properties: `id` and `is_installed`. The `identifier` property in the payment processor service is used when the payment processor is added to the database.
* *
@@ -768,18 +774,6 @@ export abstract class AbstractPaymentProcessor implements PaymentProcessor {
> >
} }
/**
* Return if the input object is AbstractPaymentProcessor
* @param obj
*/
export function isPaymentProcessor(obj: unknown): boolean {
return obj instanceof AbstractPaymentProcessor
}
/**
* Utility function to determine if an object is a processor error
* @param obj
*/
export function isPaymentProcessorError( export function isPaymentProcessorError(
obj: any obj: any
): obj is PaymentProcessorError { ): obj is PaymentProcessorError {
@@ -146,6 +146,12 @@ export abstract class AbstractPaymentService
extends TransactionBaseService extends TransactionBaseService
implements PaymentService implements PaymentService
{ {
static _isPaymentService = true
static isPaymentService(object): boolean {
return object?.constructor?._isPaymentService
}
protected constructor(container: unknown, config?: Record<string, unknown>) { protected constructor(container: unknown, config?: Record<string, unknown>) {
super(container, config) super(container, config)
} }
@@ -258,11 +264,3 @@ export abstract class AbstractPaymentService
*/ */
public abstract getStatus(data: Data): Promise<PaymentSessionStatus> public abstract getStatus(data: Data): Promise<PaymentSessionStatus>
} }
/**
* Return if the input object is one of AbstractPaymentService or PaymentService or AbstractPaymentPluginService
* @param obj
*/
export function isPaymentService(obj: unknown): boolean {
return obj instanceof AbstractPaymentService || obj instanceof PaymentService
}
@@ -32,6 +32,12 @@ export abstract class AbstractPriceSelectionStrategy
extends TransactionBaseService extends TransactionBaseService
implements IPriceSelectionStrategy implements IPriceSelectionStrategy
{ {
static _isPriceSelectionStrategy = true
static isPriceSelectionStrategy(object): boolean {
return object?.constructor?._isPriceSelectionStrategy
}
public abstract calculateVariantPrice( public abstract calculateVariantPrice(
data: { data: {
variantId: string variantId: string
@@ -46,16 +52,6 @@ export abstract class AbstractPriceSelectionStrategy
} }
} }
export function isPriceSelectionStrategy(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
object: any
): object is IPriceSelectionStrategy {
return (
typeof object.calculateVariantPrice === "function" &&
typeof object.withTransaction === "function"
)
}
export type PriceSelectionContext = { export type PriceSelectionContext = {
cart_id?: string cart_id?: string
customer_id?: string customer_id?: string
@@ -2,6 +2,7 @@ import { LineItem } from "../models/line-item"
import { TaxCalculationContext } from "./tax-service" import { TaxCalculationContext } from "./tax-service"
import { LineItemTaxLine } from "../models/line-item-tax-line" import { LineItemTaxLine } from "../models/line-item-tax-line"
import { ShippingMethodTaxLine } from "../models/shipping-method-tax-line" import { ShippingMethodTaxLine } from "../models/shipping-method-tax-line"
import { TransactionBaseService } from "./transaction-base-service"
export interface ITaxCalculationStrategy { export interface ITaxCalculationStrategy {
/** /**
@@ -19,9 +20,22 @@ export interface ITaxCalculationStrategy {
): Promise<number> ): Promise<number>
} }
export function isTaxCalculationStrategy( export abstract class AbstractTaxCalculationStrategy
// eslint-disable-next-line @typescript-eslint/no-explicit-any extends TransactionBaseService
object: any implements ITaxCalculationStrategy
): object is ITaxCalculationStrategy { {
return typeof object.calculate === "function" static _isTaxCalculationStrategy = true
static isTaxCalculationStrategy(object): boolean {
return (
typeof object.calculate === "function" ||
object?.constructor?._isTaxCalculationStrategy
)
}
abstract calculate(
items: LineItem[],
taxLines: (ShippingMethodTaxLine | LineItemTaxLine)[],
calculationContext: TaxCalculationContext
): Promise<number>
} }
@@ -1,5 +1,3 @@
import { BaseService } from "medusa-interfaces"
import { LineItem } from "../models/line-item" import { LineItem } from "../models/line-item"
import { Region } from "../models/region" import { Region } from "../models/region"
import { Address } from "../models/address" import { Address } from "../models/address"
@@ -7,6 +5,7 @@ import { ShippingMethod } from "../models/shipping-method"
import { Customer } from "../models/customer" import { Customer } from "../models/customer"
import { ProviderTaxLine, TaxServiceRate } from "../types/tax-service" import { ProviderTaxLine, TaxServiceRate } from "../types/tax-service"
import { LineAllocationsMap } from "../types/totals" import { LineAllocationsMap } from "../types/totals"
import { TransactionBaseService } from "./transaction-base-service"
/** /**
* A shipping method and the tax rates that have been configured to apply to the * A shipping method and the tax rates that have been configured to apply to the
@@ -61,11 +60,16 @@ export interface ITaxService {
} }
export abstract class AbstractTaxService export abstract class AbstractTaxService
extends BaseService extends TransactionBaseService
implements ITaxService implements ITaxService
{ {
static _isTaxService = true
protected static identifier: string protected static identifier: string
static isTaxService(object): boolean {
return object?.constructor?._isTaxService
}
public getIdentifier(): string { public getIdentifier(): string {
if (!(this.constructor as typeof AbstractTaxService).identifier) { if (!(this.constructor as typeof AbstractTaxService).identifier) {
throw new Error(`Missing static property "identifier".`) throw new Error(`Missing static property "identifier".`)
@@ -14,7 +14,7 @@ export abstract class TransactionBaseService {
protected readonly __configModule__?: Record<string, unknown>, protected readonly __configModule__?: Record<string, unknown>,
protected readonly __moduleDeclaration__?: Record<string, unknown> protected readonly __moduleDeclaration__?: Record<string, unknown>
) { ) {
this.manager_ = __container__.manager this.manager_ = __container__?.manager
} }
withTransaction(transactionManager?: EntityManager): this { withTransaction(transactionManager?: EntityManager): this {
@@ -9,7 +9,11 @@ import { createMedusaContainer } from "medusa-core-utils"
import { resolve } from "path" import { resolve } from "path"
import { DataSource, EntityManager } from "typeorm" import { DataSource, EntityManager } from "typeorm"
import Logger from "../logger" import Logger from "../logger"
import { MEDUSA_PROJECT_NAME, registerServices, registerStrategies } from "../plugins" import {
MEDUSA_PROJECT_NAME,
registerServices,
registerStrategies,
} from "../plugins"
// ***** TEMPLATES ***** // ***** TEMPLATES *****
const buildServiceTemplate = (name: string): string => { const buildServiceTemplate = (name: string): string => {
@@ -32,7 +36,7 @@ const buildBatchJobStrategyTemplate = (name: string, type: string): string => {
return ` return `
import { AbstractBatchJobStrategy } from "../../../../interfaces/batch-job-strategy" import { AbstractBatchJobStrategy } from "../../../../interfaces/batch-job-strategy"
class ${name}BatchStrategy extends AbstractBatchJobStrategy{ class ${name}BatchStrategy extends AbstractBatchJobStrategy {
static identifier = '${name}-identifier'; static identifier = '${name}-identifier';
static batchType = '${type}'; static batchType = '${type}';
@@ -79,7 +83,8 @@ const buildPriceSelectionStrategyTemplate = (name: string): string => {
const buildTaxCalcStrategyTemplate = (name: string): string => { const buildTaxCalcStrategyTemplate = (name: string): string => {
return ` return `
class ${name}TaxCalculationStrategy { import { AbstractTaxCalculationStrategy } from "../../../../interfaces/tax-calculation-strategy"
class ${name}TaxCalculationStrategy extends AbstractTaxCalculationStrategy {
calculate(items, taxLines, calculationContext) { calculate(items, taxLines, calculationContext) {
throw new Error("Method not implemented.") throw new Error("Method not implemented.")
} }
+7 -69
View File
@@ -1,13 +1,10 @@
import { Lifetime, LifetimeType, aliasTo, asFunction } from "awilix" import { aliasTo, asFunction, Lifetime, LifetimeType } from "awilix"
import { FulfillmentService } from "medusa-interfaces"
import { import {
AbstractFulfillmentService, AbstractFulfillmentService,
AbstractPaymentProcessor, AbstractPaymentProcessor,
AbstractPaymentService,
isPaymentProcessor,
isPaymentService,
} from "../../interfaces" } from "../../interfaces"
import { ClassConstructor, MedusaContainer } from "../../types/global" import { ClassConstructor, MedusaContainer } from "../../types/global"
import { PaymentService } from "medusa-interfaces"
type Context = { type Context = {
container: MedusaContainer container: MedusaContainer
@@ -15,44 +12,16 @@ type Context = {
registrationName: string registrationName: string
} }
export function registerPaymentServiceFromClass(
klass: ClassConstructor<AbstractPaymentService> & {
LIFE_TIME?: LifetimeType
},
context: Context
): void {
if (!isPaymentService(klass.prototype)) {
return
}
const { container, pluginDetails, registrationName } = context
container.registerAdd(
"paymentProviders",
asFunction((cradle) => new klass(cradle, pluginDetails.options), {
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
})
)
container.register({
[registrationName]: asFunction(
(cradle) => new klass(cradle, pluginDetails.options),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
[`pp_${(klass as unknown as typeof AbstractPaymentService).identifier}`]:
aliasTo(registrationName),
})
}
export function registerPaymentProcessorFromClass( export function registerPaymentProcessorFromClass(
klass: ClassConstructor<AbstractPaymentProcessor> & { klass: ClassConstructor<AbstractPaymentProcessor> & {
LIFE_TIME?: LifetimeType LIFE_TIME?: LifetimeType
}, },
context: Context context: Context
): void { ): void {
if (!isPaymentProcessor(klass.prototype)) { if (
!AbstractPaymentProcessor.isPaymentProcessor(klass.prototype) &&
!PaymentService.isPaymentService(klass.prototype)
) {
return return
} }
@@ -83,7 +52,7 @@ export function registerAbstractFulfillmentServiceFromClass(
}, },
context: Context context: Context
): void { ): void {
if (!(klass.prototype instanceof AbstractFulfillmentService)) { if (!AbstractFulfillmentService.isFulfillmentService(klass.prototype)) {
return return
} }
@@ -108,34 +77,3 @@ export function registerAbstractFulfillmentServiceFromClass(
}`]: aliasTo(registrationName), }`]: aliasTo(registrationName),
}) })
} }
export function registerFulfillmentServiceFromClass(
klass: ClassConstructor<typeof FulfillmentService> & {
LIFE_TIME?: LifetimeType
},
context: Context
): void {
if (!(klass.prototype instanceof FulfillmentService)) {
return
}
const { container, pluginDetails, registrationName } = context
container.registerAdd(
"fulfillmentProviders",
asFunction((cradle) => new klass(cradle, pluginDetails.options), {
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
})
)
container.register({
[registrationName]: asFunction(
(cradle) => new klass(cradle, pluginDetails.options),
{
lifetime: klass.LIFE_TIME || Lifetime.SINGLETON,
}
),
[`fp_${(klass as unknown as typeof FulfillmentService).identifier}`]:
aliasTo(registrationName),
})
}
+30 -27
View File
@@ -1,4 +1,8 @@
import { promiseAll, SearchUtils, upperCaseFirst } from "@medusajs/utils" import {
AbstractSearchService,
promiseAll,
upperCaseFirst,
} from "@medusajs/utils"
import { aliasTo, asFunction, asValue, Lifetime } from "awilix" import { aliasTo, asFunction, asValue, Lifetime } from "awilix"
import { Express } from "express" import { Express } from "express"
import fs from "fs" import fs from "fs"
@@ -6,19 +10,19 @@ import { sync as existsSync } from "fs-exists-cached"
import glob from "glob" import glob from "glob"
import _ from "lodash" import _ from "lodash"
import { createRequireFromPath } from "medusa-core-utils" import { createRequireFromPath } from "medusa-core-utils"
import { FileService, OauthService } from "medusa-interfaces" import { OauthService } from "medusa-interfaces"
import { trackInstallation } from "medusa-telemetry" import { trackInstallation } from "medusa-telemetry"
import { EOL } from "os" import { EOL } from "os"
import path from "path" import path from "path"
import { EntitySchema } from "typeorm" import { EntitySchema } from "typeorm"
import { import {
AbstractBatchJobStrategy,
AbstractCartCompletionStrategy,
AbstractFileService,
AbstractNotificationService,
AbstractPriceSelectionStrategy,
AbstractTaxCalculationStrategy,
AbstractTaxService, AbstractTaxService,
isBatchJobStrategy,
isCartCompletionStrategy,
isFileService,
isNotificationService,
isPriceSelectionStrategy,
isTaxCalculationStrategy,
} from "../interfaces" } from "../interfaces"
import { MiddlewareService } from "../services" import { MiddlewareService } from "../services"
import { import {
@@ -35,9 +39,7 @@ import { getModelExtensionsMap } from "./helpers/get-model-extension-map"
import ScheduledJobsLoader from "./helpers/jobs" import ScheduledJobsLoader from "./helpers/jobs"
import { import {
registerAbstractFulfillmentServiceFromClass, registerAbstractFulfillmentServiceFromClass,
registerFulfillmentServiceFromClass,
registerPaymentProcessorFromClass, registerPaymentProcessorFromClass,
registerPaymentServiceFromClass,
} from "./helpers/plugins" } from "./helpers/plugins"
import { RoutesLoader } from "./helpers/routing" import { RoutesLoader } from "./helpers/routing"
import { SubscriberLoader } from "./helpers/subscribers" import { SubscriberLoader } from "./helpers/subscribers"
@@ -230,7 +232,9 @@ export function registerStrategies(
const module = require(file).default const module = require(file).default
switch (true) { switch (true) {
case isTaxCalculationStrategy(module.prototype): { case AbstractTaxCalculationStrategy.isTaxCalculationStrategy(
module.prototype
): {
if (!("taxCalculationStrategy" in registeredServices)) { if (!("taxCalculationStrategy" in registeredServices)) {
container.register({ container.register({
taxCalculationStrategy: asFunction( taxCalculationStrategy: asFunction(
@@ -246,7 +250,9 @@ export function registerStrategies(
break break
} }
case isCartCompletionStrategy(module.prototype): { case AbstractCartCompletionStrategy.isCartCompletionStrategy(
module.prototype
): {
if (!("cartCompletionStrategy" in registeredServices)) { if (!("cartCompletionStrategy" in registeredServices)) {
container.register({ container.register({
cartCompletionStrategy: asFunction( cartCompletionStrategy: asFunction(
@@ -262,7 +268,7 @@ export function registerStrategies(
break break
} }
case isBatchJobStrategy(module.prototype): { case AbstractBatchJobStrategy.isBatchJobStrategy(module.prototype): {
container.registerAdd( container.registerAdd(
"batchJobStrategies", "batchJobStrategies",
asFunction((cradle) => new module(cradle, pluginDetails.options)) asFunction((cradle) => new module(cradle, pluginDetails.options))
@@ -279,7 +285,9 @@ export function registerStrategies(
break break
} }
case isPriceSelectionStrategy(module.prototype): { case AbstractPriceSelectionStrategy.isPriceSelectionStrategy(
module.prototype
): {
if (!("priceSelectionStrategy" in registeredServices)) { if (!("priceSelectionStrategy" in registeredServices)) {
container.register({ container.register({
priceSelectionStrategy: asFunction( priceSelectionStrategy: asFunction(
@@ -441,8 +449,7 @@ async function registerApi(
} }
/** /**
* Registers a service at the right location in our container. If the service is * Registers a service at the right location in our container.
* a BaseService instance it will be available directly from the container.
* PaymentService instances are added to the paymentProviders array in the * PaymentService instances are added to the paymentProviders array in the
* container. Names are camelCase formatted and namespaced by the folder i.e: * container. Names are camelCase formatted and namespaced by the folder i.e:
* services/example-payments -> examplePaymentsService * services/example-payments -> examplePaymentsService
@@ -464,13 +471,10 @@ export async function registerServices(
const context = { container, pluginDetails, registrationName: name } const context = { container, pluginDetails, registrationName: name }
registerPaymentServiceFromClass(loaded, context)
registerPaymentProcessorFromClass(loaded, context) registerPaymentProcessorFromClass(loaded, context)
registerFulfillmentServiceFromClass(loaded, context)
registerAbstractFulfillmentServiceFromClass(loaded, context) registerAbstractFulfillmentServiceFromClass(loaded, context)
if (loaded.prototype instanceof OauthService) { if (OauthService.isOauthService(loaded.prototype)) {
const appDetails = loaded.getAppDetails(pluginDetails.options) const appDetails = loaded.getAppDetails(pluginDetails.options)
const oauthService = const oauthService =
@@ -486,7 +490,9 @@ export async function registerServices(
} }
), ),
}) })
} else if (isNotificationService(loaded.prototype)) { } else if (
AbstractNotificationService.isNotificationService(loaded.prototype)
) {
container.registerAdd( container.registerAdd(
"notificationProviders", "notificationProviders",
asFunction((cradle) => new loaded(cradle, pluginDetails.options), { asFunction((cradle) => new loaded(cradle, pluginDetails.options), {
@@ -505,10 +511,7 @@ export async function registerServices(
), ),
[`noti_${loaded.identifier}`]: aliasTo(name), [`noti_${loaded.identifier}`]: aliasTo(name),
}) })
} else if ( } else if (AbstractFileService.isFileService(loaded.prototype)) {
loaded.prototype instanceof FileService ||
isFileService(loaded.prototype)
) {
// Add the service directly to the container in order to make simple // Add the service directly to the container in order to make simple
// resolution if we already know which file storage provider we need to use // resolution if we already know which file storage provider we need to use
container.register({ container.register({
@@ -520,7 +523,7 @@ export async function registerServices(
), ),
[`fileService`]: aliasTo(name), [`fileService`]: aliasTo(name),
}) })
} else if (SearchUtils.isSearchService(loaded.prototype)) { } else if (AbstractSearchService.isSearchService(loaded.prototype)) {
// Add the service directly to the container in order to make simple // Add the service directly to the container in order to make simple
// resolution if we already know which search provider we need to use // resolution if we already know which search provider we need to use
container.register({ container.register({
@@ -534,7 +537,7 @@ export async function registerServices(
}) })
container.register(isSearchEngineInstalledResolutionKey, asValue(true)) container.register(isSearchEngineInstalledResolutionKey, asValue(true))
} else if (loaded.prototype instanceof AbstractTaxService) { } else if (AbstractTaxService.isTaxService(loaded.prototype)) {
container.registerAdd( container.registerAdd(
"taxProviders", "taxProviders",
asFunction((cradle) => new loaded(cradle, pluginDetails.options), { asFunction((cradle) => new loaded(cradle, pluginDetails.options), {
+2 -2
View File
@@ -3,9 +3,9 @@ import path from "path"
import { aliasTo, asFunction } from "awilix" import { aliasTo, asFunction } from "awilix"
import formatRegistrationName from "../utils/format-registration-name" import formatRegistrationName from "../utils/format-registration-name"
import { isBatchJobStrategy } from "../interfaces"
import { MedusaContainer } from "../types/global" import { MedusaContainer } from "../types/global"
import { isDefined } from "medusa-core-utils" import { isDefined } from "medusa-core-utils"
import { AbstractBatchJobStrategy } from "../interfaces"
type LoaderOptions = { type LoaderOptions = {
container: MedusaContainer container: MedusaContainer
@@ -49,7 +49,7 @@ export default ({ container, configModule, isTest }: LoaderOptions): void => {
const loaded = require(fn).default const loaded = require(fn).default
const name = formatRegistrationName(fn) const name = formatRegistrationName(fn)
if (isBatchJobStrategy(loaded.prototype)) { if (AbstractBatchJobStrategy.isBatchJobStrategy(loaded.prototype)) {
container.registerAdd( container.registerAdd(
"batchJobStrategies", "batchJobStrategies",
asFunction((cradle) => new loaded(cradle, configModule)) asFunction((cradle) => new loaded(cradle, configModule))
+1 -1
View File
@@ -10,7 +10,7 @@ class SystemTaxService extends AbstractTaxService {
static identifier = "system" static identifier = "system"
constructor() { constructor() {
super() super({})
} }
async getTaxLines( async getTaxLines(
@@ -3,6 +3,12 @@ import { SearchTypes } from "@medusajs/types"
export abstract class AbstractSearchService export abstract class AbstractSearchService
implements SearchTypes.ISearchService implements SearchTypes.ISearchService
{ {
static _isSearchService = true
static isSearchService(obj) {
return obj?.constructor?._isSearchService
}
abstract readonly isDefault abstract readonly isDefault
protected readonly options_: Record<string, unknown> protected readonly options_: Record<string, unknown>
-2
View File
@@ -1,6 +1,4 @@
export * from "./abstract-service" export * from "./abstract-service"
export * from "./is-search-service"
export * from "./search-relations" export * from "./search-relations"
export * from "./index-types" export * from "./index-types"
export * from "./variant-keys" export * from "./variant-keys"
@@ -1,5 +0,0 @@
import { AbstractSearchService } from "./abstract-service"
export function isSearchService(obj: unknown): boolean {
return obj instanceof AbstractSearchService
}