chore: Abstract module service (#6188)

**What**
- Remove services that do not have any custom business and replace them with a simple interfaces
- Abstract module service provide the following base implementation
  - retrieve
  - list
  - listAndCount
  - delete
  - softDelete
  - restore

The above methods are created for the main model and also for each other models for which a config is provided

all method such as list, listAndCount, delete, softDelete and restore are pluralized with the model it refers to

**Migration**
- [x] product
- [x] pricing
- [x] promotion
- [x] cart
- [x] auth
- [x] customer
- [x] payment
- [x] Sales channel
- [x] Workflow-*


**Usage**

**Module**

The module service can now extend the ` ModulesSdkUtils.abstractModuleServiceFactory` which returns a class with the default implementation for each method and each model following the standard naming convention mentioned above.
This factory have 3 template arguments being the container, the main model DTO and an object representing the other model with a config object that contains at list the DTO and optionally a singular and plural property in case it needs to be set manually. It looks like the following:

```ts
export default class PricingModuleService</* ... */>
  extends ModulesSdkUtils.abstractModuleServiceFactory<
    InjectedDependencies,
    PricingTypes.PriceSetDTO,
    {
      Currency: { dto: PricingTypes.CurrencyDTO }
      MoneyAmount: { dto: PricingTypes.MoneyAmountDTO }
      PriceSetMoneyAmount: { dto: PricingTypes.PriceSetMoneyAmountDTO }
      PriceSetMoneyAmountRules: {
        dto: PricingTypes.PriceSetMoneyAmountRulesDTO
      }
      PriceRule: { dto: PricingTypes.PriceRuleDTO }
      RuleType: { dto: PricingTypes.RuleTypeDTO }
      PriceList: { dto: PricingTypes.PriceListDTO }
      PriceListRule: { dto: PricingTypes.PriceListRuleDTO }
    }
  >(PriceSet, generateMethodForModels, entityNameToLinkableKeysMap)
  implements PricingTypes.IPricingModuleService
{
// ...
}
```

In the above, the singular and plural can be inferred as there is no tricky naming. Also, the default implementation does not remove the fact that you need to provides all the overloads etc in your module service interface. The above will provide a default implementation following the interface `AbstractModuleService` which is also auto generated, hence you will have the following methods available:

**for the main model**
- list
- retrieve
- listAndCount 
- delete
- softDelete
- restore


**for the other models**
- list**MyModels**
- retrieve**MyModel**
- listAndCount**MyModels**
- delete**MyModels**
- softDelete**MyModels**
- restore**MyModels**

**Internal module service**

The internal module service can now extend `ModulesSdkUtils.internalModuleServiceFactory` which takes only one template argument which is the container type. 
All internal services provides a default implementation for all retrieve, list, listAndCount, create, update, delete, softDelete, restore methods which follow the following interface `ModulesSdkTypes.InternalModuleService`:

```ts
export interface InternalModuleService<
  TEntity extends {},
  TContainer extends object = object
> {
  get __container__(): TContainer

  retrieve(
    idOrObject: string,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<TEntity>
  retrieve(
    idOrObject: object,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<TEntity>

  list(
    filters?: FilterQuery<any> | BaseFilterable<FilterQuery<any>>,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<TEntity[]>

  listAndCount(
    filters?: FilterQuery<any> | BaseFilterable<FilterQuery<any>>,
    config?: FindConfig<any>,
    sharedContext?: Context
  ): Promise<[TEntity[], number]>

  create(data: any[], sharedContext?: Context): Promise<TEntity[]>
  create(data: any, sharedContext?: Context): Promise<TEntity>

  update(data: any[], sharedContext?: Context): Promise<TEntity[]>
  update(data: any, sharedContext?: Context): Promise<TEntity>
  update(
    selectorAndData: {
      selector: FilterQuery<any> | BaseFilterable<FilterQuery<any>>
      data: any
    },
    sharedContext?: Context
  ): Promise<TEntity[]>
  update(
    selectorAndData: {
      selector: FilterQuery<any> | BaseFilterable<FilterQuery<any>>
      data: any
    }[],
    sharedContext?: Context
  ): Promise<TEntity[]>

  delete(idOrSelector: string, sharedContext?: Context): Promise<void>
  delete(idOrSelector: string[], sharedContext?: Context): Promise<void>
  delete(idOrSelector: object, sharedContext?: Context): Promise<void>
  delete(idOrSelector: object[], sharedContext?: Context): Promise<void>
  delete(
    idOrSelector: {
      selector: FilterQuery<any> | BaseFilterable<FilterQuery<any>>
    },
    sharedContext?: Context
  ): Promise<void>

  softDelete(
    idsOrFilter: string[] | InternalFilterQuery,
    sharedContext?: Context
  ): Promise<[TEntity[], Record<string, unknown[]>]>

  restore(
    idsOrFilter: string[] | InternalFilterQuery,
    sharedContext?: Context
  ): Promise<[TEntity[], Record<string, unknown[]>]>

  upsert(data: any[], sharedContext?: Context): Promise<TEntity[]>
  upsert(data: any, sharedContext?: Context): Promise<TEntity>
}
```

When a service is auto generated you can use that interface to type your class property representing the expected internal service.

**Repositories**

The repositories can now extend `DALUtils.mikroOrmBaseRepositoryFactory` which takes one template argument being the entity or the template entity and provides all the default implementation. If the repository is auto generated you can type it using the `RepositoryService` interface. Here is the new interface typings.

```ts
export interface RepositoryService<T = any> extends BaseRepositoryService<T> {
  find(options?: FindOptions<T>, context?: Context): Promise<T[]>

  findAndCount(
    options?: FindOptions<T>,
    context?: Context
  ): Promise<[T[], number]>

  create(data: any[], context?: Context): Promise<T[]>

  // Becareful here, if you have a custom internal service, the update data should never be the entity otherwise
 // both entity and update will point to the same ref and create issues with mikro orm
  update(data: { entity; update }[], context?: Context): Promise<T[]>

  delete(
    idsOrPKs: FilterQuery<T> & BaseFilterable<FilterQuery<T>>,
    context?: Context
  ): Promise<void>

  /**
   * Soft delete entities and cascade to related entities if configured.
   *
   * @param idsOrFilter
   * @param context
   *
   * @returns [T[], Record<string, string[]>] the second value being the map of the entity names and ids that were soft deleted
   */
  softDelete(
    idsOrFilter: string[] | InternalFilterQuery,
    context?: Context
  ): Promise<[T[], Record<string, unknown[]>]>

  restore(
    idsOrFilter: string[] | InternalFilterQuery,
    context?: Context
  ): Promise<[T[], Record<string, unknown[]>]>

  upsert(data: any[], context?: Context): Promise<T[]>
}
```
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2024-02-02 14:20:32 +00:00
1 parent abc30517cb
commit a7be5d7b6d
163 files changed
+2867 -5080

No files matched your search

@@ -9,6 +9,8 @@ import { createAuthenticatedCustomer } from "../../../helpers/create-authenticat
const env = { MEDUSA_FF_MEDUSA_V2: true } const env = { MEDUSA_FF_MEDUSA_V2: true }
jest.setTimeout(100000)
describe("GET /store/customers/me/addresses", () => { describe("GET /store/customers/me/addresses", () => {
let dbConnection let dbConnection
let appContainer let appContainer
@@ -16,13 +18,17 @@ describe("GET /store/customers/me/addresses", () => {
let customerModuleService: ICustomerModuleService let customerModuleService: ICustomerModuleService
beforeAll(async () => { beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..", "..")) try {
dbConnection = await initDb({ cwd, env } as any) const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
shutdownServer = await startBootstrapApp({ cwd, env }) dbConnection = await initDb({ cwd, env } as any)
appContainer = getContainer() shutdownServer = await startBootstrapApp({ cwd, env })
customerModuleService = appContainer.resolve( appContainer = getContainer()
ModuleRegistrationName.CUSTOMER customerModuleService = appContainer.resolve(
) ModuleRegistrationName.CUSTOMER
)
} catch (error) {
console.error(error)
}
}) })
afterAll(async () => { afterAll(async () => {
@@ -5,14 +5,13 @@ import {
simpleProductFactory, simpleProductFactory,
simpleRegionFactory, simpleRegionFactory,
} from "../../../../factories" } from "../../../../factories"
import { PricingModuleService } from "@medusajs/pricing"
import { ProductModuleService } from "@medusajs/product"
import { AxiosInstance } from "axios" import { AxiosInstance } from "axios"
import path from "path" import path from "path"
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app" import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
import adminSeeder from "../../../../helpers/admin-seeder" import adminSeeder from "../../../../helpers/admin-seeder"
import { createDefaultRuleTypes } from "../../../helpers/create-default-rule-types" import { createDefaultRuleTypes } from "../../../helpers/create-default-rule-types"
import { ProductModuleService } from "@medusajs/product"
import { PricingModuleService } from "@medusajs/pricing"
jest.setTimeout(50000) jest.setTimeout(50000)
@@ -11,7 +11,7 @@ import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app
import { getContainer } from "../../../../environment-helpers/use-container" import { getContainer } from "../../../../environment-helpers/use-container"
import { initDb, useDb } from "../../../../environment-helpers/use-db" import { initDb, useDb } from "../../../../environment-helpers/use-db"
jest.setTimeout(30000) jest.setTimeout(50000)
describe("CreateProduct workflow", function () { describe("CreateProduct workflow", function () {
let medusaContainer let medusaContainer
@@ -129,7 +129,7 @@ describe("CreateProduct workflow", function () {
expect(product).toEqual( expect(product).toEqual(
expect.objectContaining({ expect.objectContaining({
deleted_at: expect.any(String), deleted_at: expect.any(Date),
}) })
) )
}) })
@@ -1,16 +1,16 @@
import { SqlEntityManager } from "@mikro-orm/postgresql" import { SqlEntityManager } from "@mikro-orm/postgresql"
import { AuthProviderService } from "@services"
import { MikroOrmWrapper } from "../../../utils" import { MikroOrmWrapper } from "../../../utils"
import { createAuthProviders } from "../../../__fixtures__/auth-provider" import { createAuthProviders } from "../../../__fixtures__/auth-provider"
import { createMedusaContainer } from "@medusajs/utils" import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix" import { asValue } from "awilix"
import ContainerLoader from "../../../../src/loaders/container" import ContainerLoader from "../../../../src/loaders/container"
import { ModulesSdkTypes } from "@medusajs/types"
jest.setTimeout(30000) jest.setTimeout(30000)
describe("AuthProvider Service", () => { describe("AuthProvider Service", () => {
let service: AuthProviderService let service: ModulesSdkTypes.InternalModuleService<any>
let testManager: SqlEntityManager let testManager: SqlEntityManager
let repositoryManager: SqlEntityManager let repositoryManager: SqlEntityManager
@@ -180,7 +180,7 @@ describe("AuthProvider Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"authProviderProvider" must be defined') expect(error.message).toEqual("authProvider - provider must be defined")
}) })
it("should return authProvider based on config select param", async () => { it("should return authProvider based on config select param", async () => {
@@ -166,7 +166,7 @@ describe("AuthUser Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"authUserId" must be defined') expect(error.message).toEqual("authUser - id must be defined")
}) })
}) })
@@ -229,7 +229,7 @@ describe("AuthUser Service", () => {
id: "test", id: "test",
provider_id: "manual", provider_id: "manual",
entity_id: "test", entity_id: "test",
scope: "store" scope: "store",
}, },
]) ])
@@ -43,9 +43,8 @@ describe("AuthModuleService - AuthProvider", () => {
describe("listAuthProviders", () => { describe("listAuthProviders", () => {
it("should list AuthProviders", async () => { it("should list AuthProviders", async () => {
const authProviders = await service.listAuthProviders() const authProviders = await service.listAuthProviders()
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(serialized).toEqual( expect(authProviders).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: "manual",
@@ -80,9 +79,7 @@ describe("AuthModuleService - AuthProvider", () => {
is_active: true, is_active: true,
}) })
const serialized = JSON.parse(JSON.stringify(authProviders)) expect(authProviders).toEqual([
expect(serialized).toEqual([
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: "manual",
}), }),
@@ -99,10 +96,9 @@ describe("AuthModuleService - AuthProvider", () => {
describe("listAndCountAuthProviders", () => { describe("listAndCountAuthProviders", () => {
it("should list and count AuthProviders", async () => { it("should list and count AuthProviders", async () => {
const [authProviders, count] = await service.listAndCountAuthProviders() const [authProviders, count] = await service.listAndCountAuthProviders()
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(count).toEqual(4) expect(count).toEqual(4)
expect(serialized).toEqual([ expect(authProviders).toEqual([
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: "manual",
}), }),
@@ -136,10 +132,8 @@ describe("AuthModuleService - AuthProvider", () => {
is_active: true, is_active: true,
}) })
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(count).toEqual(3) expect(count).toEqual(3)
expect(serialized).toEqual([ expect(authProviders).toEqual([
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: "manual",
}), }),
@@ -171,9 +165,7 @@ describe("AuthModuleService - AuthProvider", () => {
select: ["provider"], select: ["provider"],
}) })
const serialized = JSON.parse(JSON.stringify(authProvider)) expect(authProvider).toEqual({
expect(serialized).toEqual({
provider, provider,
}) })
}) })
@@ -201,7 +193,7 @@ describe("AuthModuleService - AuthProvider", () => {
error = e error = e
} }
expect(error.message).toEqual('"authProviderProvider" must be defined') expect(error.message).toEqual("authProvider - provider must be defined")
}) })
}) })
@@ -209,7 +201,7 @@ describe("AuthModuleService - AuthProvider", () => {
const provider = "manual" const provider = "manual"
it("should delete the authProviders given a provider successfully", async () => { it("should delete the authProviders given a provider successfully", async () => {
await service.deleteAuthProvider([provider]) await service.deleteAuthProviders([provider])
const authProviders = await service.listAuthProviders({ const authProviders = await service.listAuthProviders({
provider: [provider], provider: [provider],
@@ -43,17 +43,16 @@ describe("AuthModuleService - AuthUser", () => {
describe("listAuthUsers", () => { describe("listAuthUsers", () => {
it("should list authUsers", async () => { it("should list authUsers", async () => {
const authUsers = await service.listAuthUsers() const authUsers = await service.listAuthUsers()
const serialized = JSON.parse(JSON.stringify(authUsers))
expect(serialized).toEqual([ expect(authUsers).toEqual([
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: { provider: "manual" },
}), }),
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: { provider: "manual" },
}), }),
expect.objectContaining({ expect.objectContaining({
provider: "store", provider: { provider: "store" },
}), }),
]) ])
}) })
@@ -75,9 +74,7 @@ describe("AuthModuleService - AuthUser", () => {
provider_id: "manual", provider_id: "manual",
}) })
const serialized = JSON.parse(JSON.stringify(authUsers)) expect(authUsers).toEqual([
expect(serialized).toEqual([
expect.objectContaining({ expect.objectContaining({
id: "test-id", id: "test-id",
}), }),
@@ -91,18 +88,17 @@ describe("AuthModuleService - AuthUser", () => {
describe("listAndCountAuthUsers", () => { describe("listAndCountAuthUsers", () => {
it("should list and count authUsers", async () => { it("should list and count authUsers", async () => {
const [authUsers, count] = await service.listAndCountAuthUsers() const [authUsers, count] = await service.listAndCountAuthUsers()
const serialized = JSON.parse(JSON.stringify(authUsers))
expect(count).toEqual(3) expect(count).toEqual(3)
expect(serialized).toEqual([ expect(authUsers).toEqual([
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: { provider: "manual" },
}), }),
expect.objectContaining({ expect.objectContaining({
provider: "manual", provider: { provider: "manual" },
}), }),
expect.objectContaining({ expect.objectContaining({
provider: "store", provider: { provider: "store" },
}), }),
]) ])
}) })
@@ -171,7 +167,7 @@ describe("AuthModuleService - AuthUser", () => {
error = e error = e
} }
expect(error.message).toEqual('"authUserId" must be defined') expect(error.message).toEqual("authUser - id must be defined")
}) })
it("should return authUser based on config select param", async () => { it("should return authUser based on config select param", async () => {
@@ -179,9 +175,7 @@ describe("AuthModuleService - AuthUser", () => {
select: ["id"], select: ["id"],
}) })
const serialized = JSON.parse(JSON.stringify(authUser)) expect(authUser).toEqual({
expect(serialized).toEqual({
id, id,
}) })
}) })
@@ -191,7 +185,7 @@ describe("AuthModuleService - AuthUser", () => {
const id = "test-id" const id = "test-id"
it("should delete the authUsers given an id successfully", async () => { it("should delete the authUsers given an id successfully", async () => {
await service.deleteAuthUser([id]) await service.deleteAuthUsers([id])
const authUsers = await service.listAuthUsers({ const authUsers = await service.listAuthUsers({
id: [id], id: [id],
@@ -45,9 +45,8 @@ describe("AuthModuleService - AuthProvider", () => {
describe("listAuthProviders", () => { describe("listAuthProviders", () => {
it("should list default AuthProviders registered by loaders", async () => { it("should list default AuthProviders registered by loaders", async () => {
const authProviders = await service.listAuthProviders() const authProviders = await service.listAuthProviders()
const serialized = JSON.parse(JSON.stringify(authProviders))
expect(serialized).toEqual( expect(authProviders).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
provider: "emailpass", provider: "emailpass",
+9 -8
View File
@@ -1,10 +1,11 @@
import { AbstractAuthModuleProvider, MedusaError } from "@medusajs/utils" import { AbstractAuthModuleProvider, MedusaError } from "@medusajs/utils"
import { import {
AuthProviderScope,
AuthenticationInput, AuthenticationInput,
AuthenticationResponse, AuthenticationResponse,
AuthProviderScope,
ModulesSdkTypes,
} from "@medusajs/types" } from "@medusajs/types"
import { AuthProviderService, AuthUserService } from "@services" import { AuthUserService } from "@services"
import jwt, { JwtPayload } from "jsonwebtoken" import jwt, { JwtPayload } from "jsonwebtoken"
import { AuthorizationCode } from "simple-oauth2" import { AuthorizationCode } from "simple-oauth2"
@@ -12,7 +13,7 @@ import url from "url"
type InjectedDependencies = { type InjectedDependencies = {
authUserService: AuthUserService authUserService: AuthUserService
authProviderService: AuthProviderService authProviderService: ModulesSdkTypes.InternalModuleService<any>
} }
type ProviderConfig = { type ProviderConfig = {
@@ -25,13 +26,13 @@ class GoogleProvider extends AbstractAuthModuleProvider {
public static PROVIDER = "google" public static PROVIDER = "google"
public static DISPLAY_NAME = "Google Authentication" public static DISPLAY_NAME = "Google Authentication"
protected readonly authUserSerivce_: AuthUserService protected readonly authUserService_: AuthUserService
protected readonly authProviderService_: AuthProviderService protected readonly authProviderService_: ModulesSdkTypes.InternalModuleService<any>
constructor({ authUserService, authProviderService }: InjectedDependencies) { constructor({ authUserService, authProviderService }: InjectedDependencies) {
super(arguments[0]) super(arguments[0])
this.authUserSerivce_ = authUserService this.authUserService_ = authUserService
this.authProviderService_ = authProviderService this.authProviderService_ = authProviderService
} }
@@ -89,13 +90,13 @@ class GoogleProvider extends AbstractAuthModuleProvider {
let authUser let authUser
try { try {
authUser = await this.authUserSerivce_.retrieveByProviderAndEntityId( authUser = await this.authUserService_.retrieveByProviderAndEntityId(
entity_id, entity_id,
GoogleProvider.PROVIDER GoogleProvider.PROVIDER
) )
} catch (error) { } catch (error) {
if (error.type === MedusaError.Types.NOT_FOUND) { if (error.type === MedusaError.Types.NOT_FOUND) {
const [createdAuthUser] = await this.authUserSerivce_.create([ const [createdAuthUser] = await this.authUserService_.create([
{ {
entity_id, entity_id,
provider: GoogleProvider.PROVIDER, provider: GoogleProvider.PROVIDER,
+53 -170
View File
@@ -1,35 +1,35 @@
import jwt from "jsonwebtoken" import jwt from "jsonwebtoken"
import { import {
AuthenticationInput,
AuthenticationResponse,
AuthProviderDTO, AuthProviderDTO,
AuthTypes, AuthTypes,
AuthUserDTO, AuthUserDTO,
AuthenticationInput,
AuthenticationResponse,
Context, Context,
CreateAuthProviderDTO, CreateAuthProviderDTO,
CreateAuthUserDTO, CreateAuthUserDTO,
DAL, DAL,
FilterableAuthProviderProps,
FilterableAuthUserProps,
FindConfig,
InternalModuleDeclaration, InternalModuleDeclaration,
JWTGenerationOptions, JWTGenerationOptions,
MedusaContainer,
ModuleJoinerConfig, ModuleJoinerConfig,
ModulesSdkTypes,
UpdateAuthUserDTO, UpdateAuthUserDTO,
} from "@medusajs/types" } from "@medusajs/types"
import { AuthProvider, AuthUser } from "@models"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import { import {
AbstractAuthModuleProvider, AbstractAuthModuleProvider,
InjectManager, InjectManager,
InjectTransactionManager, InjectTransactionManager,
MedusaContext, MedusaContext,
MedusaError, MedusaError,
ModulesSdkUtils,
} from "@medusajs/utils" } from "@medusajs/utils"
import { AuthProvider, AuthUser } from "@models"
import { AuthProviderService, AuthUserService } from "@services"
import { ServiceTypes } from "@types" import { ServiceTypes } from "@types"
import { joinerConfig } from "../joiner-config"
type AuthModuleOptions = { type AuthModuleOptions = {
jwt_secret: string jwt_secret: string
@@ -42,28 +42,32 @@ type AuthJWTPayload = {
type InjectedDependencies = { type InjectedDependencies = {
baseRepository: DAL.RepositoryService baseRepository: DAL.RepositoryService
authUserService: AuthUserService<any> authUserService: ModulesSdkTypes.InternalModuleService<any>
authProviderService: AuthProviderService<any> authProviderService: ModulesSdkTypes.InternalModuleService<any>
} }
export default class AuthModuleService< const generateMethodForModels = [AuthProvider, AuthUser]
TAuthUser extends AuthUser = AuthUser,
TAuthProvider extends AuthProvider = AuthProvider
> implements AuthTypes.IAuthModuleService
{
__joinerConfig(): ModuleJoinerConfig {
return joinerConfig
}
export default class AuthModuleService<
TAuthUser extends AuthUser = AuthUser,
TAuthProvider extends AuthProvider = AuthProvider
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
AuthTypes.AuthProviderDTO,
{
AuthUser: { dto: AuthUserDTO }
AuthProvider: { dto: AuthProviderDTO }
}
>(AuthProvider, generateMethodForModels, entityNameToLinkableKeysMap)
implements AuthTypes.IAuthModuleService
{
__hooks = { __hooks = {
onApplicationStart: async () => await this.createProvidersOnLoad(), onApplicationStart: async () => await this.createProvidersOnLoad(),
} }
protected __container__: MedusaContainer
protected baseRepository_: DAL.RepositoryService protected baseRepository_: DAL.RepositoryService
protected authUserService_: ModulesSdkTypes.InternalModuleService<TAuthUser>
protected authUserService_: AuthUserService<TAuthUser> protected authProviderService_: ModulesSdkTypes.InternalModuleService<TAuthProvider>
protected authProviderService_: AuthProviderService<TAuthProvider>
protected options_: AuthModuleOptions protected options_: AuthModuleOptions
constructor( constructor(
@@ -75,66 +79,17 @@ export default class AuthModuleService<
options: AuthModuleOptions, options: AuthModuleOptions,
protected readonly moduleDeclaration: InternalModuleDeclaration protected readonly moduleDeclaration: InternalModuleDeclaration
) { ) {
this.__container__ = arguments[0] // @ts-ignore
super(...arguments)
this.baseRepository_ = baseRepository this.baseRepository_ = baseRepository
this.authUserService_ = authUserService this.authUserService_ = authUserService
this.authProviderService_ = authProviderService this.authProviderService_ = authProviderService
this.options_ = options this.options_ = options
} }
async retrieveAuthProvider( __joinerConfig(): ModuleJoinerConfig {
provider: string, return joinerConfig
config: FindConfig<AuthProviderDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<AuthProviderDTO> {
const authProvider = await this.authProviderService_.retrieve(
provider,
config,
sharedContext
)
return await this.baseRepository_.serialize<AuthTypes.AuthProviderDTO>(
authProvider,
{ populate: true }
)
}
async listAuthProviders(
filters: FilterableAuthProviderProps = {},
config: FindConfig<AuthProviderDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<AuthProviderDTO[]> {
const authProviders = await this.authProviderService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<AuthTypes.AuthProviderDTO[]>(
authProviders,
{ populate: true }
)
}
@InjectManager("baseRepository_")
async listAndCountAuthProviders(
filters: FilterableAuthProviderProps = {},
config: FindConfig<AuthProviderDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<[AuthTypes.AuthProviderDTO[], number]> {
const [authProviders, count] = await this.authProviderService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<AuthTypes.AuthProviderDTO[]>(
authProviders,
{ populate: true }
),
count,
]
} }
async generateJwtToken( async generateJwtToken(
@@ -205,18 +160,11 @@ export default class AuthModuleService<
return Array.isArray(data) ? serializedProviders : serializedProviders[0] return Array.isArray(data) ? serializedProviders : serializedProviders[0]
} }
@InjectTransactionManager("baseRepository_")
protected async createAuthProviders_(
data: any[],
@MedusaContext() sharedContext: Context
): Promise<TAuthProvider[]> {
return await this.authProviderService_.create(data, sharedContext)
}
updateAuthProvider( updateAuthProvider(
data: AuthTypes.UpdateAuthProviderDTO[], data: AuthTypes.UpdateAuthProviderDTO[],
sharedContext?: Context sharedContext?: Context
): Promise<AuthProviderDTO[]> ): Promise<AuthProviderDTO[]>
updateAuthProvider( updateAuthProvider(
data: AuthTypes.UpdateAuthProviderDTO, data: AuthTypes.UpdateAuthProviderDTO,
sharedContext?: Context sharedContext?: Context
@@ -247,78 +195,11 @@ export default class AuthModuleService<
return await this.authProviderService_.update(data, sharedContext) return await this.authProviderService_.update(data, sharedContext)
} }
@InjectTransactionManager("baseRepository_")
async deleteAuthProvider(
ids: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
await this.authProviderService_.delete(ids, sharedContext)
}
@InjectManager("baseRepository_")
async retrieveAuthUser(
id: string,
config: FindConfig<AuthUserDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<AuthUserDTO> {
const authUser = await this.authUserService_.retrieve(
id,
config,
sharedContext
)
return await this.baseRepository_.serialize<AuthTypes.AuthUserDTO>(
authUser,
{
exclude: ["password_hash"],
}
)
}
@InjectManager("baseRepository_")
async listAuthUsers(
filters: FilterableAuthUserProps = {},
config: FindConfig<AuthUserDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<AuthUserDTO[]> {
const authUsers = await this.authUserService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<AuthTypes.AuthUserDTO[]>(
authUsers,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async listAndCountAuthUsers(
filters: FilterableAuthUserProps = {},
config: FindConfig<AuthUserDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[AuthUserDTO[], number]> {
const [authUsers, count] = await this.authUserService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<AuthTypes.AuthUserDTO[]>(authUsers, {
populate: true,
}),
count,
]
}
createAuthUser( createAuthUser(
data: CreateAuthUserDTO[], data: CreateAuthUserDTO[],
sharedContext?: Context sharedContext?: Context
): Promise<AuthUserDTO[]> ): Promise<AuthUserDTO[]>
createAuthUser( createAuthUser(
data: CreateAuthUserDTO, data: CreateAuthUserDTO,
sharedContext?: Context sharedContext?: Context
@@ -342,23 +223,17 @@ export default class AuthModuleService<
return Array.isArray(data) ? serializedUsers : serializedUsers[0] return Array.isArray(data) ? serializedUsers : serializedUsers[0]
} }
@InjectTransactionManager("baseRepository_")
protected async createAuthUsers_(
data: CreateAuthUserDTO[],
@MedusaContext() sharedContext: Context
): Promise<TAuthUser[]> {
return await this.authUserService_.create(data, sharedContext)
}
updateAuthUser( updateAuthUser(
data: UpdateAuthUserDTO[], data: UpdateAuthUserDTO[],
sharedContext?: Context sharedContext?: Context
): Promise<AuthUserDTO[]> ): Promise<AuthUserDTO[]>
updateAuthUser( updateAuthUser(
data: UpdateAuthUserDTO, data: UpdateAuthUserDTO,
sharedContext?: Context sharedContext?: Context
): Promise<AuthUserDTO> ): Promise<AuthUserDTO>
// TODO: should be pluralized, see convention about the methods naming or the abstract module service interface definition @engineering
@InjectManager("baseRepository_") @InjectManager("baseRepository_")
async updateAuthUser( async updateAuthUser(
data: UpdateAuthUserDTO | UpdateAuthUserDTO[], data: UpdateAuthUserDTO | UpdateAuthUserDTO[],
@@ -385,14 +260,6 @@ export default class AuthModuleService<
return await this.authUserService_.update(data, sharedContext) return await this.authUserService_.update(data, sharedContext)
} }
@InjectTransactionManager("baseRepository_")
async deleteAuthUser(
ids: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
await this.authUserService_.delete(ids, sharedContext)
}
protected getRegisteredAuthenticationProvider( protected getRegisteredAuthenticationProvider(
provider: string, provider: string,
{ authScope }: AuthenticationInput { authScope }: AuthenticationInput
@@ -448,6 +315,22 @@ export default class AuthModuleService<
} }
} }
@InjectTransactionManager("baseRepository_")
protected async createAuthProviders_(
data: any[],
@MedusaContext() sharedContext: Context
): Promise<TAuthProvider[]> {
return await this.authProviderService_.create(data, sharedContext)
}
@InjectTransactionManager("baseRepository_")
protected async createAuthUsers_(
data: CreateAuthUserDTO[],
@MedusaContext() sharedContext: Context
): Promise<TAuthUser[]> {
return await this.authUserService_.create(data, sharedContext)
}
private async createProvidersOnLoad() { private async createProvidersOnLoad() {
const providersToLoad = this.__container__["auth_providers"] const providersToLoad = this.__container__["auth_providers"]
@@ -1,24 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { AuthProvider } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
authProviderRepository: DAL.RepositoryService
}
export default class AuthProviderService<
TEntity extends AuthProvider = AuthProvider
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreateAuthProviderDTO
update: ServiceTypes.UpdateAuthProviderDTO
}
>(AuthProvider)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
+13 -12
View File
@@ -1,4 +1,10 @@
import { AuthTypes, Context, DAL, FindConfig } from "@medusajs/types" import {
AuthTypes,
Context,
DAL,
FindConfig,
RepositoryService,
} from "@medusajs/types"
import { import {
InjectManager, InjectManager,
MedusaContext, MedusaContext,
@@ -6,7 +12,6 @@ import {
ModulesSdkUtils, ModulesSdkUtils,
} from "@medusajs/utils" } from "@medusajs/utils"
import { AuthUser } from "@models" import { AuthUser } from "@models"
import { ServiceTypes, RepositoryTypes } from "@types"
type InjectedDependencies = { type InjectedDependencies = {
authUserRepository: DAL.RepositoryService authUserRepository: DAL.RepositoryService
@@ -14,13 +19,11 @@ type InjectedDependencies = {
export default class AuthUserService< export default class AuthUserService<
TEntity extends AuthUser = AuthUser TEntity extends AuthUser = AuthUser
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, AuthUser
{ )<TEntity> {
create: ServiceTypes.CreateAuthUserDTO protected readonly authUserRepository_: RepositoryService<TEntity>
}
>(AuthUser)<TEntity> {
protected readonly authUserRepository_: RepositoryTypes.IAuthUserRepository<TEntity>
constructor(container: InjectedDependencies) { constructor(container: InjectedDependencies) {
// @ts-ignore // @ts-ignore
super(...arguments) super(...arguments)
@@ -28,9 +31,7 @@ export default class AuthUserService<
} }
@InjectManager("authUserRepository_") @InjectManager("authUserRepository_")
async retrieveByProviderAndEntityId< async retrieveByProviderAndEntityId<TEntityMethod = AuthTypes.AuthUserDTO>(
TEntityMethod = AuthTypes.AuthUserDTO
>(
entityId: string, entityId: string,
provider: string, provider: string,
config: FindConfig<TEntityMethod> = {}, config: FindConfig<TEntityMethod> = {},
-1
View File
@@ -1,3 +1,2 @@
export { default as AuthModuleService } from "./auth-module" export { default as AuthModuleService } from "./auth-module"
export { default as AuthProviderService } from "./auth-provider"
export { default as AuthUserService } from "./auth-user" export { default as AuthUserService } from "./auth-user"
@@ -1,28 +1,2 @@
import { AuthProvider, AuthUser } from "@models"
import { CreateAuthProviderDTO, UpdateAuthProviderDTO } from "./auth-provider"
import { DAL } from "@medusajs/types"
import { CreateAuthUserDTO, UpdateAuthUserDTO } from "./auth-user"
export * from "./auth-user" export * from "./auth-user"
export * from "./auth-provider" export * from "./auth-provider"
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IAuthProviderRepository<
TEntity extends AuthProvider = AuthProvider
> extends DAL.RepositoryService<
TEntity,
{
create: CreateAuthProviderDTO
update: UpdateAuthProviderDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IAuthUserRepository<TEntity extends AuthUser = AuthUser>
extends DAL.RepositoryService<
TEntity,
{
create: CreateAuthUserDTO
update: UpdateAuthUserDTO
}
> {}
-23
View File
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { Address } from "@models"
import { CreateAddressDTO, UpdateAddressDTO } from "@types"
type InjectedDependencies = {
addressRepository: DAL.RepositoryService
}
export default class AddressService<
TEntity extends Address = Address
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateAddressDTO
update: UpdateAddressDTO
}
>(Address)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
+85 -261
View File
@@ -3,20 +3,22 @@ import {
Context, Context,
DAL, DAL,
FilterableLineItemTaxLineProps, FilterableLineItemTaxLineProps,
FindConfig,
ICartModuleService, ICartModuleService,
InternalModuleDeclaration, InternalModuleDeclaration,
ModuleJoinerConfig, ModuleJoinerConfig,
ModulesSdkTypes,
} from "@medusajs/types" } from "@medusajs/types"
import { import {
InjectManager, InjectManager,
InjectTransactionManager, InjectTransactionManager,
MedusaContext,
MedusaError,
isObject, isObject,
isString, isString,
MedusaContext,
MedusaError,
ModulesSdkUtils,
} from "@medusajs/utils" } from "@medusajs/utils"
import { import {
Address,
Cart, Cart,
LineItem, LineItem,
LineItemAdjustment, LineItemAdjustment,
@@ -25,32 +27,73 @@ import {
ShippingMethodAdjustment, ShippingMethodAdjustment,
ShippingMethodTaxLine, ShippingMethodTaxLine,
} from "@models" } from "@models"
import { CreateLineItemDTO, UpdateLineItemDTO } from "@types" import {
import { joinerConfig } from "../joiner-config" CreateLineItemDTO,
import * as services from "../services" CreateLineItemTaxLineDTO,
CreateShippingMethodDTO,
CreateShippingMethodTaxLineDTO,
UpdateLineItemDTO,
UpdateLineItemTaxLineDTO,
UpdateShippingMethodTaxLineDTO,
} from "@types"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
type InjectedDependencies = { type InjectedDependencies = {
baseRepository: DAL.RepositoryService baseRepository: DAL.RepositoryService
cartService: services.CartService cartService: ModulesSdkTypes.InternalModuleService<any>
addressService: services.AddressService addressService: ModulesSdkTypes.InternalModuleService<any>
lineItemService: services.LineItemService lineItemService: ModulesSdkTypes.InternalModuleService<any>
shippingMethodAdjustmentService: services.ShippingMethodAdjustmentService shippingMethodAdjustmentService: ModulesSdkTypes.InternalModuleService<any>
shippingMethodService: services.ShippingMethodService shippingMethodService: ModulesSdkTypes.InternalModuleService<any>
lineItemAdjustmentService: services.LineItemAdjustmentService lineItemAdjustmentService: ModulesSdkTypes.InternalModuleService<any>
lineItemTaxLineService: services.LineItemTaxLineService lineItemTaxLineService: ModulesSdkTypes.InternalModuleService<any>
shippingMethodTaxLineService: services.ShippingMethodTaxLineService shippingMethodTaxLineService: ModulesSdkTypes.InternalModuleService<any>
} }
export default class CartModuleService implements ICartModuleService { const generateMethodForModels = [
Address,
LineItem,
LineItemAdjustment,
LineItemTaxLine,
ShippingMethod,
ShippingMethodAdjustment,
ShippingMethodTaxLine,
]
export default class CartModuleService<
TCart extends Cart = Cart,
TAddress extends Address = Address,
TLineItem extends LineItem = LineItem,
TLineItemAdjustment extends LineItemAdjustment = LineItemAdjustment,
TLineItemTaxLine extends LineItemTaxLine = LineItemTaxLine,
TShippingMethodAdjustment extends ShippingMethodAdjustment = ShippingMethodAdjustment,
TShippingMethodTaxLine extends ShippingMethodTaxLine = ShippingMethodTaxLine,
TShippingMethod extends ShippingMethod = ShippingMethod
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
CartTypes.CartDTO,
{
Address: { dto: CartTypes.CartAddressDTO }
LineItem: { dto: CartTypes.CartLineItemDTO }
LineItemAdjustment: { dto: CartTypes.LineItemAdjustmentDTO }
LineItemTaxLine: { dto: CartTypes.LineItemTaxLineDTO }
ShippingMethod: { dto: CartTypes.CartShippingMethodDTO }
ShippingMethodAdjustment: { dto: CartTypes.ShippingMethodAdjustmentDTO }
ShippingMethodTaxLine: { dto: CartTypes.ShippingMethodTaxLineDTO }
}
>(Cart, generateMethodForModels, entityNameToLinkableKeysMap)
implements ICartModuleService
{
protected baseRepository_: DAL.RepositoryService protected baseRepository_: DAL.RepositoryService
protected cartService_: services.CartService protected cartService_: ModulesSdkTypes.InternalModuleService<TCart>
protected addressService_: services.AddressService protected addressService_: ModulesSdkTypes.InternalModuleService<TAddress>
protected lineItemService_: services.LineItemService protected lineItemService_: ModulesSdkTypes.InternalModuleService<TLineItem>
protected shippingMethodAdjustmentService_: services.ShippingMethodAdjustmentService protected shippingMethodAdjustmentService_: ModulesSdkTypes.InternalModuleService<TShippingMethodAdjustment>
protected shippingMethodService_: services.ShippingMethodService protected shippingMethodService_: ModulesSdkTypes.InternalModuleService<TShippingMethod>
protected lineItemAdjustmentService_: services.LineItemAdjustmentService protected lineItemAdjustmentService_: ModulesSdkTypes.InternalModuleService<TLineItemAdjustment>
protected lineItemTaxLineService_: services.LineItemTaxLineService protected lineItemTaxLineService_: ModulesSdkTypes.InternalModuleService<TLineItemTaxLine>
protected shippingMethodTaxLineService_: services.ShippingMethodTaxLineService protected shippingMethodTaxLineService_: ModulesSdkTypes.InternalModuleService<TShippingMethodTaxLine>
constructor( constructor(
{ {
@@ -66,6 +109,9 @@ export default class CartModuleService implements ICartModuleService {
}: InjectedDependencies, }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration protected readonly moduleDeclaration: InternalModuleDeclaration
) { ) {
// @ts-ignore
super(...arguments)
this.baseRepository_ = baseRepository this.baseRepository_ = baseRepository
this.cartService_ = cartService this.cartService_ = cartService
this.addressService_ = addressService this.addressService_ = addressService
@@ -81,52 +127,6 @@ export default class CartModuleService implements ICartModuleService {
return joinerConfig return joinerConfig
} }
@InjectManager("baseRepository_")
async retrieve(
id: string,
config: FindConfig<CartTypes.CartDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<CartTypes.CartDTO> {
const cart = await this.cartService_.retrieve(id, config, sharedContext)
return await this.baseRepository_.serialize<CartTypes.CartDTO>(cart, {
populate: true,
})
}
@InjectManager("baseRepository_")
async list(
filters: CartTypes.FilterableCartProps = {},
config: FindConfig<CartTypes.CartDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<CartTypes.CartDTO[]> {
const carts = await this.cartService_.list(filters, config, sharedContext)
return this.baseRepository_.serialize<CartTypes.CartDTO[]>(carts, {
populate: true,
})
}
@InjectManager("baseRepository_")
async listAndCount(
filters: CartTypes.FilterableCartProps = {},
config: FindConfig<CartTypes.CartDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[CartTypes.CartDTO[], number]> {
const [carts, count] = await this.cartService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<CartTypes.CartDTO[]>(carts, {
populate: true,
}),
count,
]
}
async create( async create(
data: CartTypes.CreateCartDTO[], data: CartTypes.CreateCartDTO[],
sharedContext?: Context sharedContext?: Context
@@ -229,98 +229,6 @@ export default class CartModuleService implements ICartModuleService {
return await this.cartService_.update(data, sharedContext) return await this.cartService_.update(data, sharedContext)
} }
async delete(ids: string[], sharedContext?: Context): Promise<void>
async delete(ids: string, sharedContext?: Context): Promise<void>
@InjectTransactionManager("baseRepository_")
async delete(
ids: string[] | string,
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
const cartIds = Array.isArray(ids) ? ids : [ids]
await this.cartService_.delete(cartIds, sharedContext)
}
@InjectManager("baseRepository_")
async listAddresses(
filters: CartTypes.FilterableAddressProps = {},
config: FindConfig<CartTypes.CartAddressDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const addresses = await this.addressService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<CartTypes.CartAddressDTO[]>(
addresses,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async retrieveLineItem(
itemId: string,
config: FindConfig<CartTypes.CartLineItemDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<CartTypes.CartLineItemDTO> {
const item = await this.lineItemService_.retrieve(
itemId,
config,
sharedContext
)
return await this.baseRepository_.serialize<CartTypes.CartLineItemDTO>(
item,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async listLineItems(
filters: CartTypes.FilterableLineItemProps = {},
config: FindConfig<CartTypes.CartLineItemDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const items = await this.lineItemService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<CartTypes.CartLineItemDTO[]>(
items,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async listShippingMethods(
filters: CartTypes.FilterableShippingMethodProps = {},
config: FindConfig<CartTypes.CartShippingMethodDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<CartTypes.CartShippingMethodDTO[]> {
const methods = await this.shippingMethodService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CartTypes.CartShippingMethodDTO[]
>(methods, {
populate: true,
})
}
addLineItems( addLineItems(
data: CartTypes.CreateLineItemForCartDTO data: CartTypes.CreateLineItemForCartDTO
): Promise<CartTypes.CartLineItemDTO[]> ): Promise<CartTypes.CartLineItemDTO[]>
@@ -585,18 +493,6 @@ export default class CartModuleService implements ICartModuleService {
return await this.addressService_.update(data, sharedContext) return await this.addressService_.update(data, sharedContext)
} }
async deleteAddresses(ids: string[], sharedContext?: Context): Promise<void>
async deleteAddresses(ids: string, sharedContext?: Context): Promise<void>
@InjectTransactionManager("baseRepository_")
async deleteAddresses(
ids: string[] | string,
@MedusaContext() sharedContext: Context = {}
): Promise<void> {
const addressIds = Array.isArray(ids) ? ids : [ids]
await this.addressService_.delete(addressIds, sharedContext)
}
async addShippingMethods( async addShippingMethods(
data: CartTypes.CreateShippingMethodDTO data: CartTypes.CreateShippingMethodDTO
): Promise<CartTypes.CartShippingMethodDTO> ): Promise<CartTypes.CartShippingMethodDTO>
@@ -665,7 +561,10 @@ export default class CartModuleService implements ICartModuleService {
data: CartTypes.CreateShippingMethodDTO[], data: CartTypes.CreateShippingMethodDTO[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<ShippingMethod[]> { ): Promise<ShippingMethod[]> {
return await this.shippingMethodService_.create(data, sharedContext) return await this.shippingMethodService_.create(
data as unknown as CreateShippingMethodDTO[],
sharedContext
)
} }
async removeShippingMethods( async removeShippingMethods(
@@ -708,25 +607,6 @@ export default class CartModuleService implements ICartModuleService {
await this.shippingMethodService_.delete(toDelete, sharedContext) await this.shippingMethodService_.delete(toDelete, sharedContext)
} }
@InjectManager("baseRepository_")
async listLineItemAdjustments(
filters: CartTypes.FilterableLineItemAdjustmentProps = {},
config: FindConfig<CartTypes.LineItemAdjustmentDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const adjustments = await this.lineItemAdjustmentService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CartTypes.LineItemAdjustmentDTO[]
>(adjustments, {
populate: true,
})
}
async addLineItemAdjustments( async addLineItemAdjustments(
adjustments: CartTypes.CreateLineItemAdjustmentDTO[] adjustments: CartTypes.CreateLineItemAdjustmentDTO[]
): Promise<CartTypes.LineItemAdjustmentDTO[]> ): Promise<CartTypes.LineItemAdjustmentDTO[]>
@@ -882,25 +762,6 @@ export default class CartModuleService implements ICartModuleService {
await this.lineItemAdjustmentService_.delete(ids, sharedContext) await this.lineItemAdjustmentService_.delete(ids, sharedContext)
} }
@InjectManager("baseRepository_")
async listShippingMethodAdjustments(
filters: CartTypes.FilterableShippingMethodAdjustmentProps = {},
config: FindConfig<CartTypes.ShippingMethodAdjustmentDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const adjustments = await this.shippingMethodAdjustmentService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CartTypes.ShippingMethodAdjustmentDTO[]
>(adjustments, {
populate: true,
})
}
@InjectTransactionManager("baseRepository_") @InjectTransactionManager("baseRepository_")
async setShippingMethodAdjustments( async setShippingMethodAdjustments(
cartId: string, cartId: string,
@@ -1070,26 +931,6 @@ export default class CartModuleService implements ICartModuleService {
await this.shippingMethodAdjustmentService_.delete(ids, sharedContext) await this.shippingMethodAdjustmentService_.delete(ids, sharedContext)
} }
@InjectManager("baseRepository_")
async listLineItemTaxLines(
filters: CartTypes.FilterableLineItemTaxLineProps = {},
config: FindConfig<CartTypes.LineItemTaxLineDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const taxLines = await this.lineItemTaxLineService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<CartTypes.LineItemTaxLineDTO[]>(
taxLines,
{
populate: true,
}
)
}
addLineItemTaxLines( addLineItemTaxLines(
taxLines: CartTypes.CreateLineItemTaxLineDTO[] taxLines: CartTypes.CreateLineItemTaxLineDTO[]
): Promise<CartTypes.LineItemTaxLineDTO[]> ): Promise<CartTypes.LineItemTaxLineDTO[]>
@@ -1123,14 +964,14 @@ export default class CartModuleService implements ICartModuleService {
const lines = Array.isArray(taxLines) ? taxLines : [taxLines] const lines = Array.isArray(taxLines) ? taxLines : [taxLines]
addedTaxLines = await this.lineItemTaxLineService_.create( addedTaxLines = await this.lineItemTaxLineService_.create(
lines as CartTypes.CreateLineItemTaxLineDTO[], lines as CreateLineItemTaxLineDTO[],
sharedContext sharedContext
) )
} else { } else {
const data = Array.isArray(cartIdOrData) ? cartIdOrData : [cartIdOrData] const data = Array.isArray(cartIdOrData) ? cartIdOrData : [cartIdOrData]
addedTaxLines = await this.lineItemTaxLineService_.create( addedTaxLines = await this.lineItemTaxLineService_.create(
data as CartTypes.CreateLineItemTaxLineDTO[], data as CreateLineItemTaxLineDTO[],
sharedContext sharedContext
) )
} }
@@ -1184,13 +1025,15 @@ export default class CartModuleService implements ICartModuleService {
} }
}) })
await this.lineItemTaxLineService_.delete( if (toDelete.length) {
toDelete.map((taxLine) => taxLine!.id), await this.lineItemTaxLineService_.delete(
sharedContext toDelete.map((taxLine) => taxLine!.id),
) sharedContext
)
}
const result = await this.lineItemTaxLineService_.upsert( const result = await this.lineItemTaxLineService_.upsert(
taxLines, taxLines as UpdateLineItemTaxLineDTO[],
sharedContext sharedContext
) )
@@ -1242,25 +1085,6 @@ export default class CartModuleService implements ICartModuleService {
await this.lineItemTaxLineService_.delete(ids, sharedContext) await this.lineItemTaxLineService_.delete(ids, sharedContext)
} }
@InjectManager("baseRepository_")
async listShippingMethodTaxLines(
filters: CartTypes.FilterableShippingMethodTaxLineProps = {},
config: FindConfig<CartTypes.ShippingMethodTaxLineDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const taxLines = await this.shippingMethodTaxLineService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CartTypes.ShippingMethodTaxLineDTO[]
>(taxLines, {
populate: true,
})
}
addShippingMethodTaxLines( addShippingMethodTaxLines(
taxLines: CartTypes.CreateShippingMethodTaxLineDTO[] taxLines: CartTypes.CreateShippingMethodTaxLineDTO[]
): Promise<CartTypes.ShippingMethodTaxLineDTO[]> ): Promise<CartTypes.ShippingMethodTaxLineDTO[]>
@@ -1296,12 +1120,12 @@ export default class CartModuleService implements ICartModuleService {
const lines = Array.isArray(taxLines) ? taxLines : [taxLines] const lines = Array.isArray(taxLines) ? taxLines : [taxLines]
addedTaxLines = await this.shippingMethodTaxLineService_.create( addedTaxLines = await this.shippingMethodTaxLineService_.create(
lines as CartTypes.CreateShippingMethodTaxLineDTO[], lines as CreateShippingMethodTaxLineDTO[],
sharedContext sharedContext
) )
} else { } else {
addedTaxLines = await this.shippingMethodTaxLineService_.create( addedTaxLines = await this.shippingMethodTaxLineService_.create(
taxLines as CartTypes.CreateShippingMethodTaxLineDTO[], taxLines as CreateShippingMethodTaxLineDTO[],
sharedContext sharedContext
) )
} }
@@ -1367,7 +1191,7 @@ export default class CartModuleService implements ICartModuleService {
} }
const result = await this.shippingMethodTaxLineService_.upsert( const result = await this.shippingMethodTaxLineService_.upsert(
taxLines, taxLines as UpdateShippingMethodTaxLineDTO[],
sharedContext sharedContext
) )
-23
View File
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { Cart } from "@models"
import { CreateCartDTO, UpdateCartDTO } from "@types"
type InjectedDependencies = {
cartRepository: DAL.RepositoryService
}
export default class CartService<
TEntity extends Cart = Cart
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateCartDTO
update: UpdateCartDTO
}
>(Cart)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
-9
View File
@@ -1,10 +1 @@
export { default as AddressService } from "./address"
export { default as CartService } from "./cart"
export { default as CartModuleService } from "./cart-module" export { default as CartModuleService } from "./cart-module"
export { default as LineItemService } from "./line-item"
export { default as LineItemAdjustmentService } from "./line-item-adjustment"
export { default as LineItemTaxLineService } from "./line-item-tax-line"
export { default as ShippingMethodService } from "./shipping-method"
export { default as ShippingMethodAdjustmentService } from "./shipping-method-adjustment"
export { default as ShippingMethodTaxLineService } from "./shipping-method-tax-line"
@@ -1,26 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { LineItemAdjustment } from "@models"
import {
CreateLineItemAdjustmentDTO,
UpdateLineItemAdjustmentDTO,
} from "@types"
type InjectedDependencies = {
lineItemAdjustmentRepository: DAL.RepositoryService
}
export default class LineItemAdjustmentService<
TEntity extends LineItemAdjustment = LineItemAdjustment
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateLineItemAdjustmentDTO
update: UpdateLineItemAdjustmentDTO
}
>(LineItemAdjustment)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,26 +0,0 @@
import {
CreateLineItemTaxLineDTO,
DAL,
UpdateLineItemTaxLineDTO,
} from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { LineItemTaxLine } from "@models"
type InjectedDependencies = {
lineItemTaxLineRepository: DAL.RepositoryService
}
export default class LineItemTaxLineService<
TEntity extends LineItemTaxLine = LineItemTaxLine
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateLineItemTaxLineDTO
update: UpdateLineItemTaxLineDTO
}
>(LineItemTaxLine)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
-23
View File
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { LineItem } from "@models"
import { CreateLineItemDTO, UpdateLineItemDTO } from "@types"
type InjectedDependencies = {
lineItemRepository: DAL.RepositoryService
}
export default class LineItemService<
TEntity extends LineItem = LineItem
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateLineItemDTO
update: UpdateLineItemDTO
}
>(LineItem)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,26 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { ShippingMethodAdjustment } from "@models"
import {
CreateShippingMethodAdjustmentDTO,
UpdateShippingMethodAdjustmentDTO,
} from "@types"
type InjectedDependencies = {
shippingMethodAdjustmentRepository: DAL.RepositoryService
}
export default class ShippingMethodAdjustmentService<
TEntity extends ShippingMethodAdjustment = ShippingMethodAdjustment
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateShippingMethodAdjustmentDTO
update: UpdateShippingMethodAdjustmentDTO
}
>(ShippingMethodAdjustment)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,22 +0,0 @@
import { CreateShippingMethodTaxLineDTO, DAL, UpdateShippingMethodTaxLineDTO } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { ShippingMethodTaxLine } from "@models"
type InjectedDependencies = {
shippingMethodTaxLineRepository: DAL.RepositoryService
}
export default class ShippingMethodTaxLineService<
TEntity extends ShippingMethodTaxLine = ShippingMethodTaxLine
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateShippingMethodTaxLineDTO
update: UpdateShippingMethodTaxLineDTO
}
>(ShippingMethodTaxLine)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { ShippingMethod } from "@models"
import { CreateShippingMethodDTO, UpdateShippingMethodDTO } from "../types"
type InjectedDependencies = {
shippingMethodRepository: DAL.RepositoryService
}
export default class ShippingMethodService<
TEntity extends ShippingMethod = ShippingMethod
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateShippingMethodDTO
update: UpdateShippingMethodDTO
}
>(ShippingMethod)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
-1
View File
@@ -5,7 +5,6 @@ export * from "./cart"
export * from "./line-item" export * from "./line-item"
export * from "./line-item-adjustment" export * from "./line-item-adjustment"
export * from "./line-item-tax-line" export * from "./line-item-tax-line"
export * from "./repositories"
export * from "./shipping-method" export * from "./shipping-method"
export * from "./shipping-method-adjustment" export * from "./shipping-method-adjustment"
export * from "./shipping-method-tax-line" export * from "./shipping-method-tax-line"
-114
View File
@@ -1,114 +0,0 @@
import { DAL } from "@medusajs/types"
import {
Cart,
LineItem,
LineItemAdjustment,
LineItemTaxLine,
ShippingMethod,
ShippingMethodAdjustment,
ShippingMethodTaxLine,
} from "@models"
import { CreateAddressDTO, UpdateAddressDTO } from "./address"
import { CreateCartDTO, UpdateCartDTO } from "./cart"
import { CreateLineItemDTO, UpdateLineItemDTO } from "./line-item"
import {
CreateLineItemAdjustmentDTO,
UpdateLineItemAdjustmentDTO,
} from "./line-item-adjustment"
import {
CreateLineItemTaxLineDTO,
UpdateLineItemTaxLineDTO,
} from "./line-item-tax-line"
import {
CreateShippingMethodDTO,
UpdateShippingMethodDTO,
} from "./shipping-method"
import {
CreateShippingMethodAdjustmentDTO,
UpdateShippingMethodAdjustmentDTO,
} from "./shipping-method-adjustment"
import {
CreateShippingMethodTaxLineDTO,
UpdateShippingMethodTaxLineDTO,
} from "./shipping-method-tax-line"
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IAddressRepository<TEntity extends Cart = Cart>
extends DAL.RepositoryService<
TEntity,
{
create: CreateAddressDTO
update: UpdateAddressDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ICartRepository<TEntity extends Cart = Cart>
extends DAL.RepositoryService<
TEntity,
{
create: CreateCartDTO
update: UpdateCartDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ILineItemRepository<TEntity extends LineItem = LineItem>
extends DAL.RepositoryService<
TEntity,
{
create: CreateLineItemDTO
update: UpdateLineItemDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IShippingMethodRepository<
TEntity extends ShippingMethod = ShippingMethod
> extends DAL.RepositoryService<
TEntity,
{
create: CreateShippingMethodDTO
update: UpdateShippingMethodDTO
}
> {}
export interface ILineItemAdjustmentRepository<
TEntity extends LineItemAdjustment = LineItemAdjustment
> extends DAL.RepositoryService<
TEntity,
{
create: CreateLineItemAdjustmentDTO
update: UpdateLineItemAdjustmentDTO
}
> {}
export interface IShippingMethodAdjustmentRepository<
TEntity extends ShippingMethodAdjustment = ShippingMethodAdjustment
> extends DAL.RepositoryService<
TEntity,
{
create: CreateShippingMethodAdjustmentDTO
update: UpdateShippingMethodAdjustmentDTO
}
> {}
export interface IShippingMethodTaxLineRepository<
TEntity extends ShippingMethodTaxLine = ShippingMethodTaxLine
> extends DAL.RepositoryService<
TEntity,
{
create: CreateShippingMethodTaxLineDTO
update: UpdateShippingMethodTaxLineDTO
}
> {}
export interface ILineItemTaxLineRepository<
TEntity extends LineItemTaxLine = LineItemTaxLine
> extends DAL.RepositoryService<
TEntity,
{
create: CreateLineItemTaxLineDTO
update: UpdateLineItemTaxLineDTO
}
> {}
+1 -1
View File
@@ -1,6 +1,6 @@
export interface CreateShippingMethodDTO { export interface CreateShippingMethodDTO {
name: string name: string
cart_id: string shippingMethod_id: string
amount: number amount: number
data?: Record<string, unknown> data?: Record<string, unknown>
} }
@@ -12,7 +12,7 @@ export const deleteCustomerGroupStep = createStep(
ModuleRegistrationName.CUSTOMER ModuleRegistrationName.CUSTOMER
) )
await service.softDeleteCustomerGroup(ids) await service.softDeleteCustomerGroups(ids)
return new StepResponse(void 0, ids) return new StepResponse(void 0, ids)
}, },
@@ -25,6 +25,6 @@ export const deleteCustomerGroupStep = createStep(
ModuleRegistrationName.CUSTOMER ModuleRegistrationName.CUSTOMER
) )
await service.restoreCustomerGroup(prevCustomerGroups) await service.restoreCustomerGroups(prevCustomerGroups)
} }
) )
@@ -1,8 +1,8 @@
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { import {
CustomerGroupUpdatableFields,
FilterableCustomerGroupProps, FilterableCustomerGroupProps,
ICustomerModuleService, ICustomerModuleService,
CustomerGroupUpdatableFields,
} from "@medusajs/types" } from "@medusajs/types"
import { import {
getSelectsAndRelationsFromObjectArray, getSelectsAndRelationsFromObjectArray,
@@ -31,7 +31,7 @@ export const updateCustomerGroupsStep = createStep(
relations, relations,
}) })
const customers = await service.updateCustomerGroup( const customers = await service.updateCustomerGroups(
data.selector, data.selector,
data.update data.update
) )
@@ -49,7 +49,7 @@ export const updateCustomerGroupsStep = createStep(
await promiseAll( await promiseAll(
prevCustomerGroups.map((c) => prevCustomerGroups.map((c) =>
service.updateCustomerGroup(c.id, { service.updateCustomerGroups(c.id, {
name: c.name, name: c.name,
}) })
) )
@@ -1,8 +1,8 @@
import { import {
ICustomerModuleService,
CreateCustomerAddressDTO, CreateCustomerAddressDTO,
ICustomerModuleService,
} from "@medusajs/types" } from "@medusajs/types"
import { StepResponse, createStep } from "@medusajs/workflows-sdk" import { createStep, StepResponse } from "@medusajs/workflows-sdk"
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
export const createCustomerAddressesStepId = "create-customer-addresses" export const createCustomerAddressesStepId = "create-customer-addresses"
@@ -29,6 +29,6 @@ export const createCustomerAddressesStep = createStep(
ModuleRegistrationName.CUSTOMER ModuleRegistrationName.CUSTOMER
) )
await service.deleteAddress(ids) await service.deleteAddresses(ids)
} }
) )
@@ -14,7 +14,7 @@ export const deleteCustomerAddressesStep = createStep(
const existing = await service.listAddresses({ const existing = await service.listAddresses({
id: ids, id: ids,
}) })
await service.deleteAddress(ids) await service.deleteAddresses(ids)
return new StepResponse(void 0, existing) return new StepResponse(void 0, existing)
}, },
@@ -1,12 +1,12 @@
import { import {
ICustomerModuleService,
CreateCustomerAddressDTO, CreateCustomerAddressDTO,
FilterableCustomerAddressProps,
CustomerAddressDTO, CustomerAddressDTO,
FilterableCustomerAddressProps,
ICustomerModuleService,
} from "@medusajs/types" } from "@medusajs/types"
import { createStep } from "@medusajs/workflows-sdk" import { createStep } from "@medusajs/workflows-sdk"
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { unsetForUpdate, unsetForCreate } from "./utils" import { unsetForCreate, unsetForUpdate } from "./utils"
import { isDefined } from "@medusajs/utils" import { isDefined } from "@medusajs/utils"
type StepInput = { type StepInput = {
@@ -53,7 +53,7 @@ export const maybeUnsetDefaultBillingAddressesStep = createStep(
ModuleRegistrationName.CUSTOMER ModuleRegistrationName.CUSTOMER
) )
await customerModuleService.updateAddress( await customerModuleService.updateAddresses(
{ id: addressesToSet }, { id: addressesToSet },
{ is_default_billing: true } { is_default_billing: true }
) )
@@ -1,12 +1,12 @@
import { import {
ICustomerModuleService,
CreateCustomerAddressDTO, CreateCustomerAddressDTO,
FilterableCustomerAddressProps,
CustomerAddressDTO, CustomerAddressDTO,
FilterableCustomerAddressProps,
ICustomerModuleService,
} from "@medusajs/types" } from "@medusajs/types"
import { createStep } from "@medusajs/workflows-sdk" import { createStep } from "@medusajs/workflows-sdk"
import { ModuleRegistrationName } from "@medusajs/modules-sdk" import { ModuleRegistrationName } from "@medusajs/modules-sdk"
import { unsetForUpdate, unsetForCreate } from "./utils" import { unsetForCreate, unsetForUpdate } from "./utils"
import { isDefined } from "@medusajs/utils" import { isDefined } from "@medusajs/utils"
type StepInput = { type StepInput = {
@@ -52,7 +52,7 @@ export const maybeUnsetDefaultShippingAddressesStep = createStep(
ModuleRegistrationName.CUSTOMER ModuleRegistrationName.CUSTOMER
) )
await customerModuleService.updateAddress( await customerModuleService.updateAddresses(
{ id: addressesToSet }, { id: addressesToSet },
{ is_default_shipping: true } { is_default_shipping: true }
) )
@@ -31,7 +31,7 @@ export const updateCustomerAddressesStep = createStep(
relations, relations,
}) })
const customerAddresses = await service.updateAddress( const customerAddresses = await service.updateAddresses(
data.selector, data.selector,
data.update data.update
) )
@@ -48,7 +48,7 @@ export const updateCustomerAddressesStep = createStep(
) )
await promiseAll( await promiseAll(
prevCustomerAddresses.map((c) => service.updateAddress(c.id, { ...c })) prevCustomerAddresses.map((c) => service.updateAddresses(c.id, { ...c }))
) )
} }
) )
@@ -21,7 +21,7 @@ export const unsetForCreate = async (
[field]: true, [field]: true,
}) })
await customerService.updateAddress( await customerService.updateAddresses(
{ customer_id: customerIds, [field]: true }, { customer_id: customerIds, [field]: true },
{ [field]: false } { [field]: false }
) )
@@ -28,7 +28,7 @@ export const unsetForUpdate = async (
[field]: true, [field]: true,
}) })
await customerService.updateAddress( await customerService.updateAddresses(
{ customer_id: customerIds, [field]: true }, { customer_id: customerIds, [field]: true },
{ [field]: false } { [field]: false }
) )
@@ -535,7 +535,7 @@ describe("Customer Module Service", () => {
await service.delete(customer.id) await service.delete(customer.id)
const res = await service.listCustomerGroupRelations({ const res = await service.listCustomerGroupCustomers({
customer_id: customer.id, customer_id: customer.id,
customer_group_id: group.id, customer_group_id: group.id,
}) })
@@ -546,7 +546,7 @@ describe("Customer Module Service", () => {
describe("deleteCustomerGroup", () => { describe("deleteCustomerGroup", () => {
it("should delete a single customer group", async () => { it("should delete a single customer group", async () => {
const [group] = await service.createCustomerGroup([{ name: "VIP" }]) const [group] = await service.createCustomerGroup([{ name: "VIP" }])
await service.deleteCustomerGroup(group.id) await service.deleteCustomerGroups(group.id)
await expect( await expect(
service.retrieveCustomerGroup(group.id) service.retrieveCustomerGroup(group.id)
@@ -560,7 +560,7 @@ describe("Customer Module Service", () => {
]) ])
const groupIds = groups.map((group) => group.id) const groupIds = groups.map((group) => group.id)
await service.deleteCustomerGroup(groupIds) await service.deleteCustomerGroups(groupIds)
for (const group of groups) { for (const group of groups) {
await expect( await expect(
@@ -575,7 +575,7 @@ describe("Customer Module Service", () => {
await service.createCustomerGroup([{ name: "VIP" }, { name: "Regular" }]) await service.createCustomerGroup([{ name: "VIP" }, { name: "Regular" }])
const selector = { name: "VIP" } const selector = { name: "VIP" }
await service.deleteCustomerGroup(selector) await service.deleteCustomerGroups(selector)
const remainingGroups = await service.listCustomerGroups({ name: "VIP" }) const remainingGroups = await service.listCustomerGroups({ name: "VIP" })
expect(remainingGroups.length).toBe(0) expect(remainingGroups.length).toBe(0)
@@ -595,9 +595,9 @@ describe("Customer Module Service", () => {
customer_group_id: group.id, customer_group_id: group.id,
}) })
await service.deleteCustomerGroup(group.id) await service.deleteCustomerGroups(group.id)
const res = await service.listCustomerGroupRelations({ const res = await service.listCustomerGroupCustomers({
customer_id: customer.id, customer_id: customer.id,
customer_group_id: group.id, customer_group_id: group.id,
}) })
@@ -743,7 +743,7 @@ describe("Customer Module Service", () => {
address_1: "123 Main St", address_1: "123 Main St",
}) })
await service.updateAddress(address.id, { await service.updateAddresses(address.id, {
address_name: "Work", address_name: "Work",
address_1: "456 Main St", address_1: "456 Main St",
}) })
@@ -778,7 +778,7 @@ describe("Customer Module Service", () => {
address_1: "456 Main St", address_1: "456 Main St",
}) })
await service.updateAddress( await service.updateAddresses(
{ customer_id: customer.id }, { customer_id: customer.id },
{ {
address_name: "Under Construction", address_name: "Under Construction",
@@ -822,7 +822,7 @@ describe("Customer Module Service", () => {
}, },
]) ])
await service.updateAddress([address1.id, address2.id], { await service.updateAddresses([address1.id, address2.id], {
address_name: "Under Construction", address_name: "Under Construction",
}) })
@@ -864,7 +864,7 @@ describe("Customer Module Service", () => {
}) })
await expect( await expect(
service.updateAddress(address.id, { is_default_shipping: true }) service.updateAddresses(address.id, { is_default_shipping: true })
).rejects.toThrow("A default shipping address already exists") ).rejects.toThrow("A default shipping address already exists")
}) })
}) })
@@ -1087,7 +1087,7 @@ describe("Customer Module Service", () => {
describe("softDeleteCustomerGroup", () => { describe("softDeleteCustomerGroup", () => {
it("should soft delete a single customer group", async () => { it("should soft delete a single customer group", async () => {
const [group] = await service.createCustomerGroup([{ name: "VIP" }]) const [group] = await service.createCustomerGroup([{ name: "VIP" }])
await service.softDeleteCustomerGroup([group.id]) await service.softDeleteCustomerGroups([group.id])
const res = await service.listCustomerGroups({ id: group.id }) const res = await service.listCustomerGroups({ id: group.id })
expect(res.length).toBe(0) expect(res.length).toBe(0)
@@ -1105,7 +1105,7 @@ describe("Customer Module Service", () => {
{ name: "Regular" }, { name: "Regular" },
]) ])
const groupIds = groups.map((group) => group.id) const groupIds = groups.map((group) => group.id)
await service.softDeleteCustomerGroup(groupIds) await service.softDeleteCustomerGroups(groupIds)
const res = await service.listCustomerGroups({ id: groupIds }) const res = await service.listCustomerGroups({ id: groupIds })
expect(res.length).toBe(0) expect(res.length).toBe(0)
@@ -1121,12 +1121,12 @@ describe("Customer Module Service", () => {
describe("restoreCustomerGroup", () => { describe("restoreCustomerGroup", () => {
it("should restore a single customer group", async () => { it("should restore a single customer group", async () => {
const [group] = await service.createCustomerGroup([{ name: "VIP" }]) const [group] = await service.createCustomerGroup([{ name: "VIP" }])
await service.softDeleteCustomerGroup([group.id]) await service.softDeleteCustomerGroups([group.id])
const res = await service.listCustomerGroups({ id: group.id }) const res = await service.listCustomerGroups({ id: group.id })
expect(res.length).toBe(0) expect(res.length).toBe(0)
await service.restoreCustomerGroup([group.id]) await service.restoreCustomerGroups([group.id])
const restoredGroup = await service.retrieveCustomerGroup(group.id, { const restoredGroup = await service.retrieveCustomerGroup(group.id, {
withDeleted: true, withDeleted: true,
@@ -1140,12 +1140,12 @@ describe("Customer Module Service", () => {
{ name: "Regular" }, { name: "Regular" },
]) ])
const groupIds = groups.map((group) => group.id) const groupIds = groups.map((group) => group.id)
await service.softDeleteCustomerGroup(groupIds) await service.softDeleteCustomerGroups(groupIds)
const res = await service.listCustomerGroups({ id: groupIds }) const res = await service.listCustomerGroups({ id: groupIds })
expect(res.length).toBe(0) expect(res.length).toBe(0)
await service.restoreCustomerGroup(groupIds) await service.restoreCustomerGroups(groupIds)
const restoredGroups = await service.listCustomerGroups( const restoredGroups = await service.listCustomerGroups(
{ id: groupIds }, { id: groupIds },
+10 -5
View File
@@ -2,27 +2,32 @@ import { DAL } from "@medusajs/types"
import { generateEntityId } from "@medusajs/utils" import { generateEntityId } from "@medusajs/utils"
import { import {
BeforeCreate, BeforeCreate,
Cascade,
Entity, Entity,
Index,
ManyToOne,
OnInit, OnInit,
OptionalProps, OptionalProps,
PrimaryKey, PrimaryKey,
Property, Property,
ManyToOne,
Cascade,
Index,
} from "@mikro-orm/core" } from "@mikro-orm/core"
import Customer from "./customer" import Customer from "./customer"
type OptionalAddressProps = DAL.EntityDateColumns // TODO: To be revisited when more clear type OptionalAddressProps = DAL.EntityDateColumns // TODO: To be revisited when more clear
export const UNIQUE_CUSTOMER_SHIPPING_ADDRESS =
"IDX_customer_address_unique_customer_shipping"
export const UNIQUE_CUSTOMER_BILLING_ADDRESS =
"IDX_customer_address_unique_customer_billing"
@Entity({ tableName: "customer_address" }) @Entity({ tableName: "customer_address" })
@Index({ @Index({
name: "IDX_customer_address_unique_customer_shipping", name: UNIQUE_CUSTOMER_SHIPPING_ADDRESS,
expression: expression:
'create unique index "IDX_customer_address_unique_customer_shipping" on "customer_address" ("customer_id") where "is_default_shipping" = true', 'create unique index "IDX_customer_address_unique_customer_shipping" on "customer_address" ("customer_id") where "is_default_shipping" = true',
}) })
@Index({ @Index({
name: "IDX_customer_address_unique_customer_billing", name: UNIQUE_CUSTOMER_BILLING_ADDRESS,
expression: expression:
'create unique index "IDX_customer_address_unique_customer_billing" on "customer_address" ("customer_id") where "is_default_billing" = true', 'create unique index "IDX_customer_address_unique_customer_billing" on "customer_address" ("customer_id") where "is_default_billing" = true',
}) })
-23
View File
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { Address } from "@models"
import { CreateAddressDTO, UpdateAddressDTO } from "@types"
type InjectedDependencies = {
addressRepository: DAL.RepositoryService
}
export default class AddressService<
TEntity extends Address = Address
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateAddressDTO
update: UpdateAddressDTO
}
>(Address)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,25 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { CustomerGroupCustomer } from "@models"
type CreateCustomerGroupCustomerDTO = {
customer_id: string
customer_group_id: string
created_by?: string
}
type InjectedDependencies = {
customerGroupRepository: DAL.RepositoryService
}
export default class CustomerGroupCustomerService<
TEntity extends CustomerGroupCustomer = CustomerGroupCustomer
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{ create: CreateCustomerGroupCustomerDTO }
>(CustomerGroupCustomer)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { CustomerGroup } from "@models"
import { CreateCustomerGroupDTO, UpdateCustomerGroupDTO } from "@medusajs/types"
type InjectedDependencies = {
customerGroupRepository: DAL.RepositoryService
}
export default class CustomerGroupService<
TEntity extends CustomerGroup = CustomerGroup
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreateCustomerGroupDTO
update: UpdateCustomerGroupDTO
}
>(CustomerGroup)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
+154 -464
View File
@@ -1,48 +1,69 @@
import { import {
Context, Context,
CustomerDTO,
CustomerTypes,
DAL, DAL,
FindConfig,
ICustomerModuleService, ICustomerModuleService,
InternalModuleDeclaration, InternalModuleDeclaration,
ModuleJoinerConfig, ModuleJoinerConfig,
CustomerTypes, ModulesSdkTypes,
SoftDeleteReturn,
RestoreReturn,
} from "@medusajs/types" } from "@medusajs/types"
import { import {
InjectManager, InjectManager,
InjectTransactionManager, InjectTransactionManager,
MedusaContext,
mapObjectTo,
isString,
isObject,
isDuplicateError, isDuplicateError,
isString,
MedusaContext,
MedusaError,
ModulesSdkUtils,
} from "@medusajs/utils" } from "@medusajs/utils"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config" import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import * as services from "../services" import {
import { MedusaError } from "@medusajs/utils" Address,
Customer,
CustomerGroup,
CustomerGroupCustomer,
} from "@models"
import { EntityManager } from "@mikro-orm/core" import { EntityManager } from "@mikro-orm/core"
import {
const UNIQUE_CUSTOMER_SHIPPING_ADDRESS = UNIQUE_CUSTOMER_BILLING_ADDRESS,
"IDX_customer_address_unique_customer_shipping" UNIQUE_CUSTOMER_SHIPPING_ADDRESS,
const UNIQUE_CUSTOMER_BILLING_ADDRESS = } from "../models/address"
"IDX_customer_address_unique_customer_billing"
type InjectedDependencies = { type InjectedDependencies = {
baseRepository: DAL.RepositoryService baseRepository: DAL.RepositoryService
customerService: services.CustomerService customerService: ModulesSdkTypes.InternalModuleService<any>
addressService: services.AddressService addressService: ModulesSdkTypes.InternalModuleService<any>
customerGroupService: services.CustomerGroupService customerGroupService: ModulesSdkTypes.InternalModuleService<any>
customerGroupCustomerService: services.CustomerGroupCustomerService customerGroupCustomerService: ModulesSdkTypes.InternalModuleService<any>
} }
export default class CustomerModuleService implements ICustomerModuleService { const generateMethodForModels = [Address, CustomerGroup, CustomerGroupCustomer]
export default class CustomerModuleService<
TAddress extends Address = Address,
TCustomer extends Customer = Customer,
TCustomerGroup extends CustomerGroup = CustomerGroup,
TCustomerGroupCustomer extends CustomerGroupCustomer = CustomerGroupCustomer
>
// TODO seb I let you manage that when you are moving forward
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
CustomerDTO,
{
Address: { dto: any }
CustomerGroup: { dto: any }
CustomerGroupCustomer: { dto: any }
}
>(Customer, generateMethodForModels, entityNameToLinkableKeysMap)
implements ICustomerModuleService
{
protected baseRepository_: DAL.RepositoryService protected baseRepository_: DAL.RepositoryService
protected customerService_: services.CustomerService protected customerService_: ModulesSdkTypes.InternalModuleService<TCustomer>
protected addressService_: services.AddressService protected addressService_: ModulesSdkTypes.InternalModuleService<TAddress>
protected customerGroupService_: services.CustomerGroupService protected customerGroupService_: ModulesSdkTypes.InternalModuleService<TCustomerGroup>
protected customerGroupCustomerService_: services.CustomerGroupCustomerService protected customerGroupCustomerService_: ModulesSdkTypes.InternalModuleService<TCustomerGroupCustomer>
constructor( constructor(
{ {
@@ -54,6 +75,9 @@ export default class CustomerModuleService implements ICustomerModuleService {
}: InjectedDependencies, }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration protected readonly moduleDeclaration: InternalModuleDeclaration
) { ) {
// @ts-ignore
super(...arguments)
this.baseRepository_ = baseRepository this.baseRepository_ = baseRepository
this.customerService_ = customerService this.customerService_ = customerService
this.addressService_ = addressService this.addressService_ = addressService
@@ -65,26 +89,6 @@ export default class CustomerModuleService implements ICustomerModuleService {
return joinerConfig return joinerConfig
} }
@InjectManager("baseRepository_")
async retrieve(
id: string,
config: FindConfig<CustomerTypes.CustomerDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<CustomerTypes.CustomerDTO> {
const customer = await this.customerService_.retrieve(
id,
config,
sharedContext
)
return await this.baseRepository_.serialize<CustomerTypes.CustomerDTO>(
customer,
{
populate: true,
}
)
}
async create( async create(
data: CustomerTypes.CreateCustomerDTO, data: CustomerTypes.CreateCustomerDTO,
sharedContext?: Context sharedContext?: Context
@@ -95,13 +99,33 @@ export default class CustomerModuleService implements ICustomerModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerDTO[]> ): Promise<CustomerTypes.CustomerDTO[]>
@InjectTransactionManager("baseRepository_") @InjectManager("baseRepository_")
async create( async create(
dataOrArray: dataOrArray:
| CustomerTypes.CreateCustomerDTO | CustomerTypes.CreateCustomerDTO
| CustomerTypes.CreateCustomerDTO[], | CustomerTypes.CreateCustomerDTO[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
) { ): Promise<CustomerTypes.CustomerDTO | CustomerTypes.CustomerDTO[]> {
const customers = await this.create_(dataOrArray, sharedContext).catch(
this.handleDbErrors
)
const serialized = await this.baseRepository_.serialize<
CustomerTypes.CustomerDTO[]
>(customers, {
populate: true,
})
return Array.isArray(dataOrArray) ? serialized : serialized[0]
}
@InjectTransactionManager("baseRepository_")
async create_(
dataOrArray:
| CustomerTypes.CreateCustomerDTO
| CustomerTypes.CreateCustomerDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<CustomerTypes.CustomerDTO[]> {
const data = Array.isArray(dataOrArray) ? dataOrArray : [dataOrArray] const data = Array.isArray(dataOrArray) ? dataOrArray : [dataOrArray]
const customers = await this.customerService_.create(data, sharedContext) const customers = await this.customerService_.create(data, sharedContext)
@@ -121,12 +145,7 @@ export default class CustomerModuleService implements ICustomerModuleService {
await this.addAddresses(addressDataWithCustomerIds, sharedContext) await this.addAddresses(addressDataWithCustomerIds, sharedContext)
const serialized = await this.baseRepository_.serialize< return customers as unknown as CustomerTypes.CustomerDTO[]
CustomerTypes.CustomerDTO[]
>(customers, {
populate: true,
})
return Array.isArray(dataOrArray) ? serialized : serialized[0]
} }
update( update(
@@ -151,37 +170,38 @@ export default class CustomerModuleService implements ICustomerModuleService {
data: CustomerTypes.CustomerUpdatableFields, data: CustomerTypes.CustomerUpdatableFields,
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
) { ) {
let updateData: CustomerTypes.UpdateCustomerDTO[] = [] let updateData:
| CustomerTypes.UpdateCustomerDTO
| CustomerTypes.UpdateCustomerDTO[]
| {
selector: CustomerTypes.FilterableCustomerProps
data: CustomerTypes.CustomerUpdatableFields
} = []
if (isString(idsOrSelector)) { if (isString(idsOrSelector)) {
updateData = [ updateData = {
{ id: idsOrSelector,
id: idsOrSelector, ...data,
...data, }
},
]
} else if (Array.isArray(idsOrSelector)) { } else if (Array.isArray(idsOrSelector)) {
updateData = idsOrSelector.map((id) => ({ updateData = idsOrSelector.map((id) => ({
id, id,
...data, ...data,
})) }))
} else { } else {
const ids = await this.customerService_.list( updateData = {
idsOrSelector, selector: idsOrSelector,
{ select: ["id"] }, data: data,
sharedContext }
)
updateData = ids.map(({ id }) => ({
id,
...data,
}))
} }
const customers = await this.customerService_.update( const customers = await this.customerService_.update(
updateData, updateData,
sharedContext sharedContext
) )
const serialized = await this.baseRepository_.serialize< const serialized = await this.baseRepository_.serialize<
CustomerTypes.CustomerDTO[] CustomerTypes.CustomerDTO | CustomerTypes.CustomerDTO[]
>(customers, { >(customers, {
populate: true, populate: true,
}) })
@@ -189,78 +209,6 @@ export default class CustomerModuleService implements ICustomerModuleService {
return isString(idsOrSelector) ? serialized[0] : serialized return isString(idsOrSelector) ? serialized[0] : serialized
} }
delete(customerId: string, sharedContext?: Context): Promise<void>
delete(customerIds: string[], sharedContext?: Context): Promise<void>
delete(
selector: CustomerTypes.FilterableCustomerProps,
sharedContext?: Context
): Promise<void>
@InjectTransactionManager("baseRepository_")
async delete(
idsOrSelector: string | string[] | CustomerTypes.FilterableCustomerProps,
@MedusaContext() sharedContext: Context = {}
) {
let toDelete = Array.isArray(idsOrSelector)
? idsOrSelector
: [idsOrSelector as string]
if (isObject(idsOrSelector)) {
const ids = await this.customerService_.list(
idsOrSelector,
{
select: ["id"],
},
sharedContext
)
toDelete = ids.map(({ id }) => id)
}
return await this.customerService_.delete(toDelete, sharedContext)
}
@InjectManager("baseRepository_")
async list(
filters: CustomerTypes.FilterableCustomerProps = {},
config: FindConfig<CustomerTypes.CustomerDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const customers = await this.customerService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<CustomerTypes.CustomerDTO[]>(
customers,
{
populate: true,
}
)
}
@InjectManager("baseRepository_")
async listAndCount(
filters: CustomerTypes.FilterableCustomerProps = {},
config: FindConfig<CustomerTypes.CustomerDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[CustomerTypes.CustomerDTO[], number]> {
const [customers, count] = await this.customerService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<CustomerTypes.CustomerDTO[]>(
customers,
{
populate: true,
}
),
count,
]
}
async createCustomerGroup( async createCustomerGroup(
dataOrArrayOfData: CustomerTypes.CreateCustomerGroupDTO, dataOrArrayOfData: CustomerTypes.CreateCustomerGroupDTO,
sharedContext?: Context sharedContext?: Context
@@ -278,55 +226,36 @@ export default class CustomerModuleService implements ICustomerModuleService {
| CustomerTypes.CreateCustomerGroupDTO[], | CustomerTypes.CreateCustomerGroupDTO[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
) { ) {
const data = Array.isArray(dataOrArrayOfData) const groups = await this.customerGroupService_.create(
? dataOrArrayOfData dataOrArrayOfData,
: [dataOrArrayOfData] sharedContext
)
const groups = await this.customerGroupService_.create(data, sharedContext) return await this.baseRepository_.serialize<
const serialized = await this.baseRepository_.serialize< CustomerTypes.CustomerGroupDTO | CustomerTypes.CustomerGroupDTO[]
CustomerTypes.CustomerGroupDTO[]
>(groups, { >(groups, {
populate: true, populate: true,
}) })
return Array.isArray(dataOrArrayOfData) ? serialized : serialized[0]
} }
@InjectManager("baseRepository_") async updateCustomerGroups(
async retrieveCustomerGroup(
groupId: string,
config: FindConfig<CustomerTypes.CustomerGroupDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const group = await this.customerGroupService_.retrieve(
groupId,
config,
sharedContext
)
return await this.baseRepository_.serialize<CustomerTypes.CustomerGroupDTO>(
group,
{ populate: true }
)
}
async updateCustomerGroup(
groupId: string, groupId: string,
data: CustomerTypes.CustomerGroupUpdatableFields, data: CustomerTypes.CustomerGroupUpdatableFields,
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerGroupDTO> ): Promise<CustomerTypes.CustomerGroupDTO>
async updateCustomerGroup( async updateCustomerGroups(
groupIds: string[], groupIds: string[],
data: CustomerTypes.CustomerGroupUpdatableFields, data: CustomerTypes.CustomerGroupUpdatableFields,
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerGroupDTO[]> ): Promise<CustomerTypes.CustomerGroupDTO[]>
async updateCustomerGroup( async updateCustomerGroups(
selector: CustomerTypes.FilterableCustomerGroupProps, selector: CustomerTypes.FilterableCustomerGroupProps,
data: CustomerTypes.CustomerGroupUpdatableFields, data: CustomerTypes.CustomerGroupUpdatableFields,
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerGroupDTO[]> ): Promise<CustomerTypes.CustomerGroupDTO[]>
@InjectTransactionManager("baseRepository_") @InjectTransactionManager("baseRepository_")
async updateCustomerGroup( async updateCustomerGroups(
groupIdOrSelector: groupIdOrSelector:
| string | string
| string[] | string[]
@@ -334,29 +263,27 @@ export default class CustomerModuleService implements ICustomerModuleService {
data: CustomerTypes.CustomerGroupUpdatableFields, data: CustomerTypes.CustomerGroupUpdatableFields,
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
) { ) {
let updateData: CustomerTypes.UpdateCustomerGroupDTO[] = [] let updateData:
if (isString(groupIdOrSelector)) { | CustomerTypes.UpdateCustomerGroupDTO
updateData = [ | CustomerTypes.UpdateCustomerGroupDTO[]
{ | {
id: groupIdOrSelector, selector: CustomerTypes.FilterableCustomerGroupProps
...data, data: CustomerTypes.CustomerGroupUpdatableFields
}, } = []
]
} else if (Array.isArray(groupIdOrSelector)) { if (isString(groupIdOrSelector) || Array.isArray(groupIdOrSelector)) {
updateData = groupIdOrSelector.map((id) => ({ const groupIdOrSelectorArray = Array.isArray(groupIdOrSelector)
? groupIdOrSelector
: [groupIdOrSelector]
updateData = groupIdOrSelectorArray.map((id) => ({
id, id,
...data, ...data,
})) }))
} else { } else {
const ids = await this.customerGroupService_.list( updateData = {
groupIdOrSelector, selector: groupIdOrSelector,
{ select: ["id"] }, data: data,
sharedContext }
)
updateData = ids.map(({ id }) => ({
id,
...data,
}))
} }
const groups = await this.customerGroupService_.update( const groups = await this.customerGroupService_.update(
@@ -376,39 +303,6 @@ export default class CustomerModuleService implements ICustomerModuleService {
>(groups, { populate: true }) >(groups, { populate: true })
} }
deleteCustomerGroup(groupId: string, sharedContext?: Context): Promise<void>
deleteCustomerGroup(
groupIds: string[],
sharedContext?: Context
): Promise<void>
deleteCustomerGroup(
selector: CustomerTypes.FilterableCustomerGroupProps,
sharedContext?: Context
): Promise<void>
@InjectTransactionManager("baseRepository_")
async deleteCustomerGroup(
groupIdOrSelector:
| string
| string[]
| CustomerTypes.FilterableCustomerGroupProps,
@MedusaContext() sharedContext: Context = {}
) {
let toDelete = Array.isArray(groupIdOrSelector)
? groupIdOrSelector
: [groupIdOrSelector as string]
if (isObject(groupIdOrSelector)) {
const ids = await this.customerGroupService_.list(
groupIdOrSelector,
{ select: ["id"] },
sharedContext
)
toDelete = ids.map(({ id }) => id)
}
return await this.customerGroupService_.delete(toDelete, sharedContext)
}
async addCustomerToGroup( async addCustomerToGroup(
groupCustomerPair: CustomerTypes.GroupCustomerPair, groupCustomerPair: CustomerTypes.GroupCustomerPair,
sharedContext?: Context sharedContext?: Context
@@ -425,17 +319,20 @@ export default class CustomerModuleService implements ICustomerModuleService {
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<{ id: string } | { id: string }[]> { ): Promise<{ id: string } | { id: string }[]> {
const groupCustomers = await this.customerGroupCustomerService_.create( const groupCustomers = await this.customerGroupCustomerService_.create(
Array.isArray(data) ? data : [data], data,
sharedContext sharedContext
) )
if (Array.isArray(data)) { if (Array.isArray(data)) {
return groupCustomers.map((gc) => ({ id: gc.id })) return (groupCustomers as unknown as TCustomerGroupCustomer[]).map(
(gc) => ({ id: gc.id })
)
} }
return { id: groupCustomers[0].id } return { id: groupCustomers.id }
} }
// TODO: should be createAddresses to conform to the convention
async addAddresses( async addAddresses(
addresses: CustomerTypes.CreateCustomerAddressDTO[], addresses: CustomerTypes.CreateCustomerAddressDTO[],
sharedContext?: Context sharedContext?: Context
@@ -445,7 +342,7 @@ export default class CustomerModuleService implements ICustomerModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerAddressDTO> ): Promise<CustomerTypes.CustomerAddressDTO>
@InjectTransactionManager("baseRepository_") @InjectManager("baseRepository_")
async addAddresses( async addAddresses(
data: data:
| CustomerTypes.CreateCustomerAddressDTO | CustomerTypes.CreateCustomerAddressDTO
@@ -454,13 +351,10 @@ export default class CustomerModuleService implements ICustomerModuleService {
): Promise< ): Promise<
CustomerTypes.CustomerAddressDTO | CustomerTypes.CustomerAddressDTO[] CustomerTypes.CustomerAddressDTO | CustomerTypes.CustomerAddressDTO[]
> { > {
const addresses = await this.addressService_.create( const addresses = await this.addAddresses_(data, sharedContext).catch(
Array.isArray(data) ? data : [data], this.handleDbErrors
sharedContext
) )
await this.flush(sharedContext).catch(this.handleDbErrors)
const serialized = await this.baseRepository_.serialize< const serialized = await this.baseRepository_.serialize<
CustomerTypes.CustomerAddressDTO[] CustomerTypes.CustomerAddressDTO[]
>(addresses, { populate: true }) >(addresses, { populate: true })
@@ -472,24 +366,39 @@ export default class CustomerModuleService implements ICustomerModuleService {
return serialized[0] return serialized[0]
} }
async updateAddress( @InjectTransactionManager("baseRepository_")
private async addAddresses_(
data:
| CustomerTypes.CreateCustomerAddressDTO
| CustomerTypes.CreateCustomerAddressDTO[],
@MedusaContext() sharedContext: Context = {}
) {
const addresses = await this.addressService_.create(
Array.isArray(data) ? data : [data],
sharedContext
)
return addresses
}
async updateAddresses(
addressId: string, addressId: string,
data: CustomerTypes.UpdateCustomerAddressDTO, data: CustomerTypes.UpdateCustomerAddressDTO,
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerAddressDTO> ): Promise<CustomerTypes.CustomerAddressDTO>
async updateAddress( async updateAddresses(
addressIds: string[], addressIds: string[],
data: CustomerTypes.UpdateCustomerAddressDTO, data: CustomerTypes.UpdateCustomerAddressDTO,
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerAddressDTO[]> ): Promise<CustomerTypes.CustomerAddressDTO[]>
async updateAddress( async updateAddresses(
selector: CustomerTypes.FilterableCustomerAddressProps, selector: CustomerTypes.FilterableCustomerAddressProps,
data: CustomerTypes.UpdateCustomerAddressDTO, data: CustomerTypes.UpdateCustomerAddressDTO,
sharedContext?: Context sharedContext?: Context
): Promise<CustomerTypes.CustomerAddressDTO[]> ): Promise<CustomerTypes.CustomerAddressDTO[]>
@InjectTransactionManager("baseRepository_") @InjectTransactionManager("baseRepository_")
async updateAddress( async updateAddresses(
addressIdOrSelector: addressIdOrSelector:
| string | string
| string[] | string[]
@@ -497,7 +406,12 @@ export default class CustomerModuleService implements ICustomerModuleService {
data: CustomerTypes.UpdateCustomerAddressDTO, data: CustomerTypes.UpdateCustomerAddressDTO,
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
) { ) {
let updateData: CustomerTypes.UpdateCustomerAddressDTO[] = [] let updateData:
| CustomerTypes.UpdateCustomerAddressDTO[]
| {
selector: CustomerTypes.FilterableCustomerAddressProps
data: CustomerTypes.UpdateCustomerAddressDTO
} = []
if (isString(addressIdOrSelector)) { if (isString(addressIdOrSelector)) {
updateData = [ updateData = [
{ {
@@ -511,15 +425,10 @@ export default class CustomerModuleService implements ICustomerModuleService {
...data, ...data,
})) }))
} else { } else {
const ids = await this.addressService_.list( updateData = {
addressIdOrSelector, selector: addressIdOrSelector,
{ select: ["id"] }, data,
sharedContext }
)
updateData = ids.map(({ id }) => ({
id,
...data,
}))
} }
const addresses = await this.addressService_.update( const addresses = await this.addressService_.update(
@@ -540,78 +449,6 @@ export default class CustomerModuleService implements ICustomerModuleService {
return serialized return serialized
} }
async deleteAddress(addressId: string, sharedContext?: Context): Promise<void>
async deleteAddress(
addressIds: string[],
sharedContext?: Context
): Promise<void>
async deleteAddress(
selector: CustomerTypes.FilterableCustomerAddressProps,
sharedContext?: Context
): Promise<void>
@InjectTransactionManager("baseRepository_")
async deleteAddress(
addressIdOrSelector:
| string
| string[]
| CustomerTypes.FilterableCustomerAddressProps,
@MedusaContext() sharedContext: Context = {}
) {
let toDelete = Array.isArray(addressIdOrSelector)
? addressIdOrSelector
: [addressIdOrSelector as string]
if (isObject(addressIdOrSelector)) {
const ids = await this.addressService_.list(
addressIdOrSelector,
{ select: ["id"] },
sharedContext
)
toDelete = ids.map(({ id }) => id)
}
await this.addressService_.delete(toDelete, sharedContext)
}
@InjectManager("baseRepository_")
async listAddresses(
filters?: CustomerTypes.FilterableCustomerAddressProps,
config?: FindConfig<CustomerTypes.CustomerAddressDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<CustomerTypes.CustomerAddressDTO[]> {
const addresses = await this.addressService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CustomerTypes.CustomerAddressDTO[]
>(addresses, { populate: true })
}
@InjectManager("baseRepository_")
async listAndCountAddresses(
filters?: CustomerTypes.FilterableCustomerAddressProps,
config?: FindConfig<CustomerTypes.CustomerAddressDTO>,
@MedusaContext() sharedContext: Context = {}
): Promise<[CustomerTypes.CustomerAddressDTO[], number]> {
const [addresses, count] = await this.addressService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<CustomerTypes.CustomerAddressDTO[]>(
addresses,
{ populate: true }
),
count,
]
}
async removeCustomerFromGroup( async removeCustomerFromGroup(
groupCustomerPair: CustomerTypes.GroupCustomerPair, groupCustomerPair: CustomerTypes.GroupCustomerPair,
sharedContext?: Context sharedContext?: Context
@@ -636,153 +473,6 @@ export default class CustomerModuleService implements ICustomerModuleService {
) )
} }
@InjectManager("baseRepository_")
async listCustomerGroupRelations(
filters?: CustomerTypes.FilterableCustomerGroupCustomerProps,
config?: FindConfig<CustomerTypes.CustomerGroupCustomerDTO>,
@MedusaContext() sharedContext: Context = {}
) {
const groupCustomers = await this.customerGroupCustomerService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CustomerTypes.CustomerGroupCustomerDTO[]
>(groupCustomers, {
populate: true,
})
}
@InjectManager("baseRepository_")
async listCustomerGroups(
filters: CustomerTypes.FilterableCustomerGroupProps = {},
config: FindConfig<CustomerTypes.CustomerGroupDTO> = {},
@MedusaContext() sharedContext: Context = {}
) {
const groups = await this.customerGroupService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<
CustomerTypes.CustomerGroupDTO[]
>(groups, {
populate: true,
})
}
@InjectManager("baseRepository_")
async listAndCountCustomerGroups(
filters: CustomerTypes.FilterableCustomerGroupProps = {},
config: FindConfig<CustomerTypes.CustomerGroupDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<[CustomerTypes.CustomerGroupDTO[], number]> {
const [groups, count] = await this.customerGroupService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<CustomerTypes.CustomerGroupDTO[]>(
groups,
{
populate: true,
}
),
count,
]
}
@InjectTransactionManager("baseRepository_")
async softDeleteCustomerGroup<
TReturnableLinkableKeys extends string = string
>(
groupIds: string[],
config: SoftDeleteReturn<TReturnableLinkableKeys> = {},
@MedusaContext() sharedContext: Context = {}
) {
const [_, cascadedEntitiesMap] =
await this.customerGroupService_.softDelete(groupIds, sharedContext)
return config.returnLinkableKeys
? mapObjectTo<Record<TReturnableLinkableKeys, string[]>>(
cascadedEntitiesMap,
entityNameToLinkableKeysMap,
{
pick: config.returnLinkableKeys,
}
)
: void 0
}
@InjectTransactionManager("baseRepository_")
async restoreCustomerGroup<TReturnableLinkableKeys extends string = string>(
groupIds: string[],
config: RestoreReturn<TReturnableLinkableKeys> = {},
@MedusaContext() sharedContext: Context = {}
) {
const [_, cascadedEntitiesMap] = await this.customerGroupService_.restore(
groupIds,
sharedContext
)
return config.returnLinkableKeys
? mapObjectTo<Record<TReturnableLinkableKeys, string[]>>(
cascadedEntitiesMap,
entityNameToLinkableKeysMap,
{
pick: config.returnLinkableKeys,
}
)
: void 0
}
@InjectTransactionManager("baseRepository_")
async softDelete<TReturnableLinkableKeys extends string = string>(
customerIds: string[],
config: SoftDeleteReturn<TReturnableLinkableKeys> = {},
@MedusaContext() sharedContext: Context = {}
) {
const [_, cascadedEntitiesMap] = await this.customerService_.softDelete(
customerIds,
sharedContext
)
return config.returnLinkableKeys
? mapObjectTo<Record<TReturnableLinkableKeys, string[]>>(
cascadedEntitiesMap,
entityNameToLinkableKeysMap,
{
pick: config.returnLinkableKeys,
}
)
: void 0
}
@InjectTransactionManager("baseRepository_")
async restore<TReturnableLinkableKeys extends string = string>(
customerIds: string[],
config: RestoreReturn<TReturnableLinkableKeys> = {},
@MedusaContext() sharedContext: Context = {}
) {
const [_, cascadedEntitiesMap] = await this.customerService_.restore(
customerIds,
sharedContext
)
return config.returnLinkableKeys
? mapObjectTo<Record<TReturnableLinkableKeys, string[]>>(
cascadedEntitiesMap,
entityNameToLinkableKeysMap,
{
pick: config.returnLinkableKeys,
}
)
: void 0
}
private async flush(context: Context) { private async flush(context: Context) {
const em = (context.manager ?? context.transactionManager) as EntityManager const em = (context.manager ?? context.transactionManager) as EntityManager
await em.flush() await em.flush()
@@ -1,22 +0,0 @@
import { CustomerTypes, DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { Customer } from "@models"
type InjectedDependencies = {
customerRepository: DAL.RepositoryService
}
export default class CustomerService<
TEntity extends Customer = Customer
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CustomerTypes.CreateCustomerDTO
update: CustomerTypes.UpdateCustomerDTO
}
>(Customer)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
-4
View File
@@ -1,5 +1 @@
export { default as AddressService } from "./address"
export { default as CustomerGroupService } from "./customer-group"
export { default as CustomerService } from "./customer"
export { default as CustomerModuleService } from "./customer-module" export { default as CustomerModuleService } from "./customer-module"
export { default as CustomerGroupCustomerService } from "./customer-group-customer"
+4 -1
View File
@@ -1,5 +1,8 @@
import { Logger } from "@medusajs/types" import { Logger } from "@medusajs/types"
export * from "./address"
export * as ServiceTypes from "./services"
export * from "./services"
export type InitializeModuleInjectableDependencies = { export type InitializeModuleInjectableDependencies = {
logger?: Logger logger?: Logger
} }
@@ -0,0 +1,5 @@
export interface CreateCustomerGroupCustomerDTO {
customer_id: string
customer_group_id: string
created_by?: string
}
@@ -0,0 +1,2 @@
export * from "./address"
export * from "./customer-group-customer"
@@ -116,7 +116,7 @@ describe("Payment Module Service", () => {
expect(collection.length).toEqual(1) expect(collection.length).toEqual(1)
await service.deletePaymentCollection(["pay-col-id-1"]) await service.deletePaymentCollections(["pay-col-id-1"])
collection = await service.listPaymentCollections({ collection = await service.listPaymentCollections({
id: ["pay-col-id-1"], id: ["pay-col-id-1"],
-1
View File
@@ -1,2 +1 @@
export { default as PaymentModuleService } from "./payment-module" export { default as PaymentModuleService } from "./payment-module"
export { default as PaymentCollectionService } from "./payment-collection"
@@ -1,26 +0,0 @@
import { PaymentCollection } from "@models"
import {
CreatePaymentCollectionDTO,
DAL,
UpdatePaymentCollectionDTO,
} from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
type InjectedDependencies = {
paymentCollectionRepository: DAL.RepositoryService
}
export default class PaymentCollectionService<
TEntity extends PaymentCollection = PaymentCollection
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: CreatePaymentCollectionDTO
update: UpdatePaymentCollectionDTO
}
>(PaymentCollection)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
+44 -88
View File
@@ -4,11 +4,10 @@ import {
CreatePaymentDTO, CreatePaymentDTO,
CreatePaymentSessionDTO, CreatePaymentSessionDTO,
DAL, DAL,
FilterablePaymentCollectionProps,
FindConfig,
InternalModuleDeclaration, InternalModuleDeclaration,
IPaymentModuleService, IPaymentModuleService,
ModuleJoinerConfig, ModuleJoinerConfig,
ModulesSdkTypes,
PaymentCollectionDTO, PaymentCollectionDTO,
PaymentDTO, PaymentDTO,
SetPaymentSessionsDTO, SetPaymentSessionsDTO,
@@ -16,28 +15,64 @@ import {
UpdatePaymentDTO, UpdatePaymentDTO,
} from "@medusajs/types" } from "@medusajs/types"
import { import {
InjectManager,
InjectTransactionManager, InjectTransactionManager,
MedusaContext, MedusaContext,
ModulesSdkUtils,
} from "@medusajs/utils" } from "@medusajs/utils"
import * as services from "@services" import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import {
import { joinerConfig } from "../joiner-config" Capture,
Payment,
PaymentCollection,
PaymentMethodToken,
PaymentProvider,
PaymentSession,
Refund,
} from "@models"
type InjectedDependencies = { type InjectedDependencies = {
baseRepository: DAL.RepositoryService baseRepository: DAL.RepositoryService
paymentCollectionService: services.PaymentCollectionService paymentCollectionService: ModulesSdkTypes.InternalModuleService<any>
} }
export default class PaymentModuleService implements IPaymentModuleService { const generateMethodForModels = [
Capture,
PaymentCollection,
PaymentMethodToken,
PaymentProvider,
PaymentSession,
Refund,
]
export default class PaymentModuleService<
TPaymentCollection extends PaymentCollection = PaymentCollection
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
// TODO revisit when moving forward frane
InjectedDependencies,
PaymentDTO,
{
Capture: { dto: any }
PaymentCollection: { dto: any }
PaymentMethodToken: { dto: any }
PaymentProvider: { dto: any }
PaymentSession: { dto: any }
Refund: { dto: any }
}
>(Payment, generateMethodForModels, entityNameToLinkableKeysMap)
implements IPaymentModuleService
{
protected baseRepository_: DAL.RepositoryService protected baseRepository_: DAL.RepositoryService
protected paymentCollectionService_: services.PaymentCollectionService protected paymentCollectionService_: ModulesSdkTypes.InternalModuleService<TPaymentCollection>
constructor( constructor(
{ baseRepository, paymentCollectionService }: InjectedDependencies, { baseRepository, paymentCollectionService }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration protected readonly moduleDeclaration: InternalModuleDeclaration
) { ) {
// @ts-ignore
super(...arguments)
this.baseRepository_ = baseRepository this.baseRepository_ = baseRepository
this.paymentCollectionService_ = paymentCollectionService this.paymentCollectionService_ = paymentCollectionService
@@ -105,85 +140,6 @@ export default class PaymentModuleService implements IPaymentModuleService {
) )
} }
deletePaymentCollection(
paymentCollectionId: string[],
sharedContext?: Context
): Promise<void>
deletePaymentCollection(
paymentCollectionId: string,
sharedContext?: Context
): Promise<void>
@InjectTransactionManager("baseRepository_")
async deletePaymentCollection(
ids: string | string[],
@MedusaContext() sharedContext?: Context
): Promise<void> {
const paymentCollectionIds = Array.isArray(ids) ? ids : [ids]
await this.paymentCollectionService_.delete(
paymentCollectionIds,
sharedContext
)
}
@InjectManager("baseRepository_")
async retrievePaymentCollection(
paymentCollectionId: string,
config: FindConfig<PaymentCollectionDTO> = {},
@MedusaContext() sharedContext: Context = {}
): Promise<PaymentCollectionDTO> {
const paymentCollection = await this.paymentCollectionService_.retrieve(
paymentCollectionId,
config,
sharedContext
)
return await this.baseRepository_.serialize<PaymentCollectionDTO>(
paymentCollection,
{ populate: true }
)
}
@InjectManager("baseRepository_")
async listPaymentCollections(
filters: FilterablePaymentCollectionProps = {},
config: FindConfig<PaymentCollectionDTO> = {},
@MedusaContext() sharedContext?: Context
): Promise<PaymentCollectionDTO[]> {
const paymentCollections = await this.paymentCollectionService_.list(
filters,
config,
sharedContext
)
return await this.baseRepository_.serialize<PaymentCollectionDTO[]>(
paymentCollections,
{ populate: true }
)
}
@InjectManager("baseRepository_")
async listAndCountPaymentCollections(
filters: FilterablePaymentCollectionProps = {},
config: FindConfig<PaymentCollectionDTO> = {},
@MedusaContext() sharedContext?: Context
): Promise<[PaymentCollectionDTO[], number]> {
const [paymentCollections, count] =
await this.paymentCollectionService_.listAndCount(
filters,
config,
sharedContext
)
return [
await this.baseRepository_.serialize<PaymentCollectionDTO[]>(
paymentCollections,
{ populate: true }
),
count,
]
}
/** /**
* TODO * TODO
*/ */
@@ -1,18 +0,0 @@
import {
DAL,
CreatePaymentCollectionDTO,
UpdatePaymentCollectionDTO,
} from "@medusajs/types"
import { PaymentCollection } from "@models"
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPaymentCollectionRepository<
TEntity extends PaymentCollection = PaymentCollection
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePaymentCollectionDTO
update: UpdatePaymentCollectionDTO
}
> {}
@@ -183,7 +183,7 @@ describe("Currency Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"currencyCode" must be defined') expect(error.message).toEqual("currency - code must be defined")
}) })
it("should return currency based on config select param", async () => { it("should return currency based on config select param", async () => {
@@ -258,7 +258,7 @@ describe("MoneyAmount Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"moneyAmountId" must be defined') expect(error.message).toEqual("moneyAmount - id must be defined")
}) })
it("should return moneyAmount based on config select param", async () => { it("should return moneyAmount based on config select param", async () => {
@@ -162,7 +162,7 @@ describe("PriceListRule Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceListRuleId" must be defined') expect(error.message).toEqual("priceListRule - id must be defined")
}) })
}) })
@@ -157,7 +157,7 @@ describe("PriceList Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceListId" must be defined') expect(error.message).toEqual("priceList - id must be defined")
}) })
}) })
@@ -219,7 +219,7 @@ describe("PriceRule Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceRuleId" must be defined') expect(error.message).toEqual("priceRule - id must be defined")
}) })
it("should return priceRule based on config select param", async () => { it("should return priceRule based on config select param", async () => {
@@ -168,7 +168,7 @@ describe("PriceSetMoneyAmountRules Service", () => {
} }
expect(error.message).toEqual( expect(error.message).toEqual(
'"priceSetMoneyAmountRulesId" must be defined' "priceSetMoneyAmountRules - id must be defined"
) )
}) })
@@ -305,7 +305,7 @@ describe("PriceSet Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceSetId" must be defined') expect(error.message).toEqual("priceSet - id must be defined")
}) })
it("should return priceSet based on config select param", async () => { it("should return priceSet based on config select param", async () => {
@@ -180,7 +180,7 @@ describe("PricingModule Service - Currency", () => {
error = e error = e
} }
expect(error.message).toEqual('"currencyCode" must be defined') expect(error.message).toEqual("currency - code must be defined")
}) })
it("should return currency based on config select param", async () => { it("should return currency based on config select param", async () => {
@@ -245,7 +245,7 @@ describe("PricingModule Service - MoneyAmount", () => {
error = e error = e
} }
expect(error.message).toEqual('"moneyAmountId" must be defined') expect(error.message).toEqual("moneyAmount - id must be defined")
}) })
it("should return moneyAmount based on config select param", async () => { it("should return moneyAmount based on config select param", async () => {
@@ -320,7 +320,7 @@ describe("PricingModule Service - MoneyAmount", () => {
}) })
}) })
describe("restoreDeletedMoneyAmounts", () => { describe("restoreMoneyAmounts", () => {
const id = "money-amount-USD" const id = "money-amount-USD"
it("should restore softDeleted priceSetMoneyAmount and PriceRule when restoring soft-deleting money amount", async () => { it("should restore softDeleted priceSetMoneyAmount and PriceRule when restoring soft-deleting money amount", async () => {
@@ -330,7 +330,7 @@ describe("PricingModule Service - MoneyAmount", () => {
await createPriceRules(testManager) await createPriceRules(testManager)
await createPriceSetMoneyAmountRules(testManager) await createPriceSetMoneyAmountRules(testManager)
await service.softDeleteMoneyAmounts([id]) await service.softDeleteMoneyAmounts([id])
await service.restoreDeletedMoneyAmounts([id]) await service.restoreMoneyAmounts([id])
const [moneyAmount] = await service.listMoneyAmounts( const [moneyAmount] = await service.listMoneyAmounts(
{ {
@@ -171,7 +171,7 @@ describe("PriceListRule Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceListRuleId" must be defined') expect(error.message).toEqual("priceListRule - id must be defined")
}) })
}) })
@@ -283,7 +283,7 @@ describe("PriceListRule Service", () => {
expect(priceList.price_list_rules).toEqual( expect(priceList.price_list_rules).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
rule_type: "rule-type-3", rule_type: { id: "rule-type-3" },
price_list_rule_values: [ price_list_rule_values: [
expect.objectContaining({ value: "sc-1" }), expect.objectContaining({ value: "sc-1" }),
], ],
@@ -323,7 +323,7 @@ describe("PriceListRule Service", () => {
expect(priceList.price_list_rules).toEqual( expect(priceList.price_list_rules).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
rule_type: "rule-type-3", rule_type: { id: "rule-type-3" },
price_list_rule_values: expect.arrayContaining([ price_list_rule_values: expect.arrayContaining([
expect.objectContaining({ value: "sc-1" }), expect.objectContaining({ value: "sc-1" }),
expect.objectContaining({ value: "sc-2" }), expect.objectContaining({ value: "sc-2" }),
@@ -351,7 +351,7 @@ describe("PriceListRule Service", () => {
) )
expect(priceList.price_list_rules).toEqual([ expect(priceList.price_list_rules).toEqual([
expect.objectContaining({ rule_type: "rule-type-2" }), expect.objectContaining({ rule_type: { id: "rule-type-2" } }),
]) ])
}) })
}) })
@@ -179,7 +179,7 @@ describe("PriceList Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceListId" must be defined') expect(error.message).toEqual("priceList - id must be defined")
}) })
}) })
@@ -224,7 +224,7 @@ describe("PricingModule Service - PriceRule", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceRuleId" must be defined') expect(error.message).toEqual("priceRule - id must be defined")
}) })
it("should return PriceRule based on config select param", async () => { it("should return PriceRule based on config select param", async () => {
@@ -192,7 +192,7 @@ describe("PricingModule Service - PriceSetMoneyAmountRules", () => {
} }
expect(error.message).toEqual( expect(error.message).toEqual(
'"priceSetMoneyAmountRulesId" must be defined' "priceSetMoneyAmountRules - id must be defined"
) )
}) })
@@ -248,7 +248,7 @@ describe("PricingModule Service - PriceSet", () => {
error = e error = e
} }
expect(error.message).toEqual('"priceSetId" must be defined') expect(error.message).toEqual("priceSet - id must be defined")
}) })
it("should return priceSet based on config select param", async () => { it("should return priceSet based on config select param", async () => {
@@ -170,7 +170,7 @@ describe("PricingModuleService ruleType", () => {
error = e error = e
} }
expect(error.message).toEqual('"ruleTypeId" must be defined') expect(error.message).toEqual("ruleType - id must be defined")
}) })
it("should return ruleType based on config select param", async () => { it("should return ruleType based on config select param", async () => {
@@ -164,7 +164,7 @@ describe("RuleType Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"ruleTypeId" must be defined') expect(error.message).toEqual("ruleType - id must be defined")
}) })
it("should return ruleType based on config select param", async () => { it("should return ruleType based on config select param", async () => {
@@ -1,6 +1,5 @@
import { Currency } from "@models" import { Currency } from "@models"
import { CurrencyService } from "@services" import { asValue } from "awilix"
import { asClass, asValue, createContainer } from "awilix"
;(Currency as any).meta = { ;(Currency as any).meta = {
/** /**
@@ -10,10 +9,7 @@ import { asClass, asValue, createContainer } from "awilix"
} }
export const nonExistingCurrencyCode = "non-existing-code" export const nonExistingCurrencyCode = "non-existing-code"
export const mockContainer = createContainer() export const currencyRepositoryMock = {
mockContainer.register({
transaction: asValue(async (task) => await task()),
currencyRepository: asValue({ currencyRepository: asValue({
find: jest.fn().mockImplementation(async ({ where: { code } }) => { find: jest.fn().mockImplementation(async ({ where: { code } }) => {
if (code === nonExistingCurrencyCode) { if (code === nonExistingCurrencyCode) {
@@ -25,5 +21,4 @@ mockContainer.register({
findAndCount: jest.fn().mockResolvedValue([[], 0]), findAndCount: jest.fn().mockResolvedValue([[], 0]),
getFreshManager: jest.fn().mockResolvedValue({}), getFreshManager: jest.fn().mockResolvedValue({}),
}), }),
currencyService: asClass(CurrencyService), }
})
@@ -1,18 +1,31 @@
import { import {
mockContainer, currencyRepositoryMock,
nonExistingCurrencyCode, nonExistingCurrencyCode,
} from "../__fixtures__/currency" } from "../__fixtures__/currency"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import ContainerLoader from "../../loaders/container"
import { MedusaContainer } from "@medusajs/types"
const code = "existing-currency" const code = "existing-currency"
describe("Currency service", function () { describe("Currency service", function () {
beforeEach(function () { let container: MedusaContainer
beforeEach(async function () {
jest.clearAllMocks() jest.clearAllMocks()
container = createMedusaContainer()
container.register("manager", asValue({}))
await ContainerLoader({ container })
container.register(currencyRepositoryMock)
}) })
it("should retrieve a currency", async function () { it("should retrieve a currency", async function () {
const currencyService = mockContainer.resolve("currencyService") const currencyService = container.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository") const currencyRepository = container.resolve("currencyRepository")
await currencyService.retrieve(code) await currencyService.retrieve(code)
@@ -33,8 +46,8 @@ describe("Currency service", function () {
}) })
it("should fail to retrieve a currency", async function () { it("should fail to retrieve a currency", async function () {
const currencyService = mockContainer.resolve("currencyService") const currencyService = container.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository") const currencyRepository = container.resolve("currencyRepository")
const err = await currencyService const err = await currencyService
.retrieve(nonExistingCurrencyCode) .retrieve(nonExistingCurrencyCode)
@@ -62,8 +75,8 @@ describe("Currency service", function () {
}) })
it("should list currencys", async function () { it("should list currencys", async function () {
const currencyService = mockContainer.resolve("currencyService") const currencyService = container.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository") const currencyRepository = container.resolve("currencyRepository")
const filters = {} const filters = {}
const config = { const config = {
@@ -88,8 +101,8 @@ describe("Currency service", function () {
}) })
it("should list currencys with filters", async function () { it("should list currencys with filters", async function () {
const currencyService = mockContainer.resolve("currencyService") const currencyService = container.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository") const currencyRepository = container.resolve("currencyRepository")
const filters = { const filters = {
tags: { tags: {
@@ -126,8 +139,8 @@ describe("Currency service", function () {
}) })
it("should list currencys with filters and relations", async function () { it("should list currencys with filters and relations", async function () {
const currencyService = mockContainer.resolve("currencyService") const currencyService = container.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository") const currencyRepository = container.resolve("currencyRepository")
const filters = { const filters = {
tags: { tags: {
@@ -163,9 +176,9 @@ describe("Currency service", function () {
) )
}) })
it("should list and count the currencys with filters and relations", async function () { it("should list and count the currencies with filters and relations", async function () {
const currencyService = mockContainer.resolve("currencyService") const currencyService = container.resolve("currencyService")
const currencyRepository = mockContainer.resolve("currencyRepository") const currencyRepository = container.resolve("currencyRepository")
const filters = { const filters = {
tags: { tags: {
-23
View File
@@ -1,23 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { Currency } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
currencyRepository: DAL.RepositoryService
}
export default class CurrencyService<
TEntity extends Currency = Currency
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreateCurrencyDTO
update: ServiceTypes.UpdateCurrencyDTO
}
>(Currency)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
-6
View File
@@ -1,12 +1,6 @@
export { default as CurrencyService } from "./currency"
export { default as MoneyAmountService } from "./money-amount"
export { default as PriceListService } from "./price-list" export { default as PriceListService } from "./price-list"
export { default as PriceListRuleService } from "./price-list-rule" export { default as PriceListRuleService } from "./price-list-rule"
export { default as PriceListRuleValueService } from "./price-list-rule-value" export { default as PriceListRuleValueService } from "./price-list-rule-value"
export { default as PriceRuleService } from "./price-rule" export { default as PriceRuleService } from "./price-rule"
export { default as PriceSetService } from "./price-set"
export { default as PriceSetMoneyAmountService } from "./price-set-money-amount"
export { default as PriceSetMoneyAmountRulesService } from "./price-set-money-amount-rules"
export { default as PriceSetRuleTypeService } from "./price-set-rule-type"
export { default as PricingModuleService } from "./pricing-module" export { default as PricingModuleService } from "./pricing-module"
export { default as RuleTypeService } from "./rule-type" export { default as RuleTypeService } from "./rule-type"
@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { MoneyAmount } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
moneyAmountRepository: DAL.RepositoryService
}
export default class MoneyAmountService<
TEntity extends MoneyAmount = MoneyAmount
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreateMoneyAmountDTO
update: ServiceTypes.UpdateMoneyAmountDTO
},
{
list: ServiceTypes.FilterableMoneyAmountProps
listAndCount: ServiceTypes.FilterableMoneyAmountProps
}
>(MoneyAmount)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -9,26 +9,32 @@ type InjectedDependencies = {
export default class PriceListRuleValueService< export default class PriceListRuleValueService<
TEntity extends PriceListRuleValue = PriceListRuleValue TEntity extends PriceListRuleValue = PriceListRuleValue
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, PriceListRuleValue
{ )<TEntity> {
update: ServiceTypes.UpdatePriceListRuleValueDTO
},
{
list: ServiceTypes.FilterablePriceListRuleValueProps
listAndCount: ServiceTypes.FilterablePriceListRuleValueProps
}
>(PriceListRuleValue)<TEntity> {
constructor(container: InjectedDependencies) { constructor(container: InjectedDependencies) {
// @ts-ignore // @ts-ignore
super(...arguments) super(...arguments)
} }
async create( create(
data: ServiceTypes.CreatePriceListRuleValueDTO[], data: ServiceTypes.CreatePriceListRuleValueDTO[],
context: Context
): Promise<TEntity[]>
create(
data: ServiceTypes.CreatePriceListRuleValueDTO,
context: Context
): Promise<TEntity>
async create(
data:
| ServiceTypes.CreatePriceListRuleValueDTO
| ServiceTypes.CreatePriceListRuleValueDTO[],
context: Context = {} context: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
const priceListRuleValues = data.map((priceRuleValueData) => { const data_ = Array.isArray(data) ? data : [data]
const priceListRuleValues = data_.map((priceRuleValueData) => {
const { price_list_rule_id: priceListRuleId, ...priceRuleValue } = const { price_list_rule_id: priceListRuleId, ...priceRuleValue } =
priceRuleValueData priceRuleValueData
@@ -9,27 +9,31 @@ type InjectedDependencies = {
export default class PriceListRuleService< export default class PriceListRuleService<
TEntity extends PriceListRule = PriceListRule TEntity extends PriceListRule = PriceListRule
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, PriceListRule
{ )<TEntity> {
create: ServiceTypes.CreatePriceListRuleDTO
update: ServiceTypes.UpdatePriceListRuleDTO
},
{
list: ServiceTypes.FilterablePriceListRuleProps
listAndCount: ServiceTypes.FilterablePriceListRuleProps
}
>(PriceListRule)<TEntity> {
constructor(container: InjectedDependencies) { constructor(container: InjectedDependencies) {
// @ts-ignore // @ts-ignore
super(...arguments) super(...arguments)
} }
async create( create(
data: ServiceTypes.CreatePriceListRuleDTO[], data: ServiceTypes.CreatePriceListRuleDTO[],
sharedContext?: Context
): Promise<TEntity[]>
create(
data: ServiceTypes.CreatePriceListRuleDTO,
sharedContext?: Context
): Promise<TEntity>
async create(
data:
| ServiceTypes.CreatePriceListRuleDTO
| ServiceTypes.CreatePriceListRuleDTO[],
context: Context = {} context: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
const priceListRule = data.map((priceListRule) => { const data_ = Array.isArray(data) ? data : [data]
const priceListRule = data_.map((priceListRule) => {
const { const {
price_list_id: priceListId, price_list_id: priceListId,
rule_type_id: ruleTypeId, rule_type_id: ruleTypeId,
@@ -50,11 +54,28 @@ export default class PriceListRuleService<
return await super.create(priceListRule, context) return await super.create(priceListRule, context)
} }
async update( // @ts-ignore
update(
data: ServiceTypes.UpdatePriceListRuleDTO[], data: ServiceTypes.UpdatePriceListRuleDTO[],
context: Context
): Promise<TEntity[]>
// @ts-ignore
update(
data: ServiceTypes.UpdatePriceListRuleDTO,
context: Context
): Promise<TEntity>
// TODO add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data:
| ServiceTypes.UpdatePriceListRuleDTO
| ServiceTypes.UpdatePriceListRuleDTO[],
context: Context = {} context: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
const priceListRules = data.map((priceListRule) => { const data_ = Array.isArray(data) ? data : [data]
const priceListRules = data_.map((priceListRule) => {
const { price_list_id, rule_type_id, ...priceListRuleData } = const { price_list_id, rule_type_id, ...priceListRuleData } =
priceListRule priceListRule
+27 -14
View File
@@ -9,32 +9,45 @@ type InjectedDependencies = {
export default class PriceListService< export default class PriceListService<
TEntity extends PriceList = PriceList TEntity extends PriceList = PriceList
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, PriceList
{}, )<TEntity> {
{
list: ServiceTypes.FilterablePriceListProps
listAndCount: ServiceTypes.FilterablePriceListProps
}
>(PriceList)<TEntity> {
constructor(container: InjectedDependencies) { constructor(container: InjectedDependencies) {
// @ts-ignore // @ts-ignore
super(...arguments) super(...arguments)
} }
async create( create(
data: ServiceTypes.CreatePriceListDTO[], data: ServiceTypes.CreatePriceListDTO[],
sharedContext?: Context sharedContext?: Context
): Promise<TEntity[]> { ): Promise<TEntity[]>
const priceLists = this.normalizePriceListDate(data) create(
data: ServiceTypes.CreatePriceListDTO,
sharedContext?: Context
): Promise<TEntity>
async create(
data: ServiceTypes.CreatePriceListDTO | ServiceTypes.CreatePriceListDTO[],
sharedContext?: Context
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const priceLists = this.normalizePriceListDate(data_)
return await super.create(priceLists, sharedContext) return await super.create(priceLists, sharedContext)
} }
// @ts-ignore
update(data: any[], sharedContext?: Context): Promise<TEntity[]>
// @ts-ignore
update(data: any, sharedContext?: Context): Promise<TEntity>
// TODO: Add support for selector? and then rm ts ignore
// @ts-ignore
async update( async update(
data: ServiceTypes.UpdatePriceListDTO[], data: ServiceTypes.UpdatePriceListDTO | ServiceTypes.UpdatePriceListDTO[],
sharedContext?: Context sharedContext?: Context
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
const priceLists = this.normalizePriceListDate(data) const data_ = Array.isArray(data) ? data : [data]
const priceLists = this.normalizePriceListDate(data_)
return await super.update(priceLists, sharedContext) return await super.update(priceLists, sharedContext)
} }
+16 -13
View File
@@ -10,26 +10,29 @@ type InjectedDependencies = {
export default class PriceRuleService< export default class PriceRuleService<
TEntity extends PriceRule = PriceRule TEntity extends PriceRule = PriceRule
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, PriceRule
{ )<TEntity> {
update: ServiceTypes.UpdatePriceRuleDTO
},
{
list: ServiceTypes.FilterablePriceRuleProps
listAndCount: ServiceTypes.FilterablePriceRuleProps
}
>(PriceRule)<TEntity> {
constructor(container: InjectedDependencies) { constructor(container: InjectedDependencies) {
// @ts-ignore // @ts-ignore
super(...arguments) super(...arguments)
} }
async create( create(
data: ServiceTypes.CreatePriceRuleDTO[], data: ServiceTypes.CreatePriceRuleDTO[],
sharedContext?: Context sharedContext?: Context
): Promise<TEntity[]> { ): Promise<TEntity[]>
const toCreate = data.map((ruleData) => { create(
data: ServiceTypes.CreatePriceRuleDTO,
sharedContext?: Context
): Promise<TEntity>
async create(
data: ServiceTypes.CreatePriceRuleDTO | ServiceTypes.CreatePriceRuleDTO[],
sharedContext: Context = {}
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const toCreate = data_.map((ruleData) => {
const ruleDataClone = { ...ruleData } as any const ruleDataClone = { ...ruleData } as any
ruleDataClone.rule_type ??= ruleData.rule_type_id ruleDataClone.rule_type ??= ruleData.rule_type_id
@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSetMoneyAmountRules } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetMoneyAmountRulesRepository: DAL.RepositoryService
}
export default class PriceSetMoneyAmountRulesService<
TEntity extends PriceSetMoneyAmountRules = PriceSetMoneyAmountRules
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceSetMoneyAmountRulesDTO
update: ServiceTypes.UpdatePriceSetMoneyAmountRulesDTO
},
{
list: ServiceTypes.FilterablePriceSetMoneyAmountRulesProps
listAndCount: ServiceTypes.FilterablePriceSetMoneyAmountRulesProps
}
>(PriceSetMoneyAmountRules)<TEntity> {
constructor({ priceSetMoneyAmountRulesRepository }: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSetMoneyAmount } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetMoneyAmountRepository: DAL.RepositoryService
}
export default class PriceSetMoneyAmountService<
TEntity extends PriceSetMoneyAmount = PriceSetMoneyAmount
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceSetMoneyAmountDTO
update: ServiceTypes.UpdatePriceSetMoneyAmountDTO
},
{
list: ServiceTypes.FilterablePriceSetMoneyAmountProps
listAndCount: ServiceTypes.FilterablePriceSetMoneyAmountProps
}
>(PriceSetMoneyAmount)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,27 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSetRuleType } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetRuleTypeRepository: DAL.RepositoryService
}
export default class PriceSetRuleTypeService<
TEntity extends PriceSetRuleType = PriceSetRuleType
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: ServiceTypes.CreatePriceSetRuleTypeDTO
update: ServiceTypes.UpdatePriceSetRuleTypeDTO
},
{
list: ServiceTypes.FilterablePriceSetRuleTypeProps
listAndCount: ServiceTypes.FilterablePriceSetRuleTypeProps
}
>(PriceSetRuleType)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
@@ -1,28 +0,0 @@
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
import { PriceSet } from "@models"
import { ServiceTypes } from "@types"
type InjectedDependencies = {
priceSetRepository: DAL.RepositoryService
}
export default class PriceSetService<
TEntity extends PriceSet = PriceSet
> extends ModulesSdkUtils.abstractServiceFactory<
InjectedDependencies,
{
create: Omit<ServiceTypes.CreatePriceSetDTO, "rules">
update: Omit<ServiceTypes.UpdatePriceSetDTO, "rules">
},
{
list: ServiceTypes.FilterablePriceSetProps
listAndCount: ServiceTypes.FilterablePriceSetProps
}
>(PriceSet)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
File diff suppressed because it is too large. Load diff
+39 -23
View File
@@ -14,17 +14,9 @@ type InjectedDependencies = {
export default class RuleTypeService< export default class RuleTypeService<
TEntity extends RuleType = RuleType TEntity extends RuleType = RuleType
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, RuleType
{ )<TEntity> {
create: ServiceTypes.CreateRuleTypeDTO
update: ServiceTypes.UpdateRuleTypeDTO
},
{
list: ServiceTypes.FilterableRuleTypeProps
listAndCount: ServiceTypes.FilterableRuleTypeProps
}
>(RuleType)<TEntity> {
protected readonly ruleTypeRepository_: DAL.RepositoryService<TEntity> protected readonly ruleTypeRepository_: DAL.RepositoryService<TEntity>
constructor({ ruleTypeRepository }: InjectedDependencies) { constructor({ ruleTypeRepository }: InjectedDependencies) {
@@ -33,21 +25,45 @@ export default class RuleTypeService<
this.ruleTypeRepository_ = ruleTypeRepository this.ruleTypeRepository_ = ruleTypeRepository
} }
@InjectTransactionManager("ruleTypeRepository_") create(
async create( data: ServiceTypes.CreateRuleTypeDTO,
sharedContext: Context
): Promise<TEntity>
create(
data: ServiceTypes.CreateRuleTypeDTO[], data: ServiceTypes.CreateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {} sharedContext: Context
): Promise<TEntity[]> { ): Promise<TEntity[]>
validateRuleAttributes(data.map((d) => d.rule_attribute))
return await this.ruleTypeRepository_.create(data, sharedContext)
}
@InjectTransactionManager("ruleTypeRepository_") @InjectTransactionManager("ruleTypeRepository_")
async update( async create(
data: ServiceTypes.UpdateRuleTypeDTO[], data: ServiceTypes.CreateRuleTypeDTO | ServiceTypes.CreateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
validateRuleAttributes(data.map((d) => d.rule_attribute)) const data_ = Array.isArray(data) ? data : [data]
return await this.ruleTypeRepository_.update(data, sharedContext) validateRuleAttributes(data_.map((d) => d.rule_attribute))
return await super.create(data, sharedContext)
}
// @ts-ignore
update(
data: ServiceTypes.UpdateRuleTypeDTO[],
sharedContext: Context
): Promise<TEntity[]>
// @ts-ignore
update(
data: ServiceTypes.UpdateRuleTypeDTO,
sharedContext: Context
): Promise<TEntity>
@InjectTransactionManager("ruleTypeRepository_")
// TODO: add support for selector? and then rm ts ignore
// @ts-ignore
async update(
data: ServiceTypes.UpdateRuleTypeDTO | ServiceTypes.UpdateRuleTypeDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
validateRuleAttributes(data_.map((d) => d.rule_attribute))
return await super.update(data, sharedContext)
} }
} }
@@ -1,44 +1,3 @@
import {
Currency,
MoneyAmount,
PriceList,
PriceListRule,
PriceListRuleValue,
PriceRule,
PriceSet,
PriceSetMoneyAmount,
PriceSetMoneyAmountRules,
PriceSetRuleType,
RuleType,
} from "@models"
import { DAL } from "@medusajs/types"
import { CreateCurrencyDTO, UpdateCurrencyDTO } from "./currency"
import { CreateMoneyAmountDTO, UpdateMoneyAmountDTO } from "./money-amount"
import {
CreatePriceListRuleValueDTO,
UpdatePriceListRuleValueDTO,
} from "./price-list-rule-value"
import {
CreatePriceListRuleDTO,
UpdatePriceListRuleDTO,
} from "./price-list-rule"
import { CreatePriceListDTO, UpdatePriceListDTO } from "./price-list"
import { CreatePriceRuleDTO, UpdatePriceRuleDTO } from "./price-rule"
import {
CreatePriceSetMoneyAmountRulesDTO,
UpdatePriceSetMoneyAmountRulesDTO,
} from "./price-set-money-amount-rules"
import {
CreatePriceSetMoneyAmountDTO,
UpdatePriceSetMoneyAmountDTO,
} from "./price-set-money-amount"
import {
CreatePriceSetRuleTypeDTO,
UpdatePriceSetRuleTypeDTO,
} from "./price-set-rule-type"
import { CreatePriceSetDTO, UpdatePriceSetDTO } from "./price-set"
import { CreateRuleTypeDTO, UpdateRuleTypeDTO } from "./rule-type"
export * from "./currency" export * from "./currency"
export * from "./money-amount" export * from "./money-amount"
export * from "./price-list-rule-value" export * from "./price-list-rule-value"
@@ -50,119 +9,3 @@ export * from "./price-set-money-amount"
export * from "./price-set-rule-type" export * from "./price-set-rule-type"
export * from "./price-set" export * from "./price-set"
export * from "./rule-type" export * from "./rule-type"
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ICurrencyRepository<TEntity extends Currency = Currency>
extends DAL.RepositoryService<
TEntity,
{
create: CreateCurrencyDTO
update: UpdateCurrencyDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IMoneyAmountRepository<
TEntity extends MoneyAmount = MoneyAmount
> extends DAL.RepositoryService<
TEntity,
{
create: CreateMoneyAmountDTO
update: UpdateMoneyAmountDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceListRuleValueRepository<
TEntity extends PriceListRuleValue = PriceListRuleValue
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceListRuleValueDTO
update: UpdatePriceListRuleValueDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceListRuleRepository<
TEntity extends PriceListRule = PriceListRule
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceListRuleDTO
update: UpdatePriceListRuleDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceListRepository<TEntity extends PriceList = PriceList>
extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceListDTO
update: UpdatePriceListDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceRuleRepository<TEntity extends PriceRule = PriceRule>
extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceRuleDTO
update: UpdatePriceRuleDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetMoneyAmountRulesRepository<
TEntity extends PriceSetMoneyAmountRules = PriceSetMoneyAmountRules
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetMoneyAmountRulesDTO
update: UpdatePriceSetMoneyAmountRulesDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetMoneyAmountRepository<
TEntity extends PriceSetMoneyAmount = PriceSetMoneyAmount
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetMoneyAmountDTO
update: UpdatePriceSetMoneyAmountDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetRuleTypeRepository<
TEntity extends PriceSetRuleType = PriceSetRuleType
> extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetRuleTypeDTO
update: UpdatePriceSetRuleTypeDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IPriceSetRepository<TEntity extends PriceSet = PriceSet>
extends DAL.RepositoryService<
TEntity,
{
create: CreatePriceSetDTO
update: UpdatePriceSetDTO
}
> {}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface IRuleTypeRepository<TEntity extends RuleType = RuleType>
extends DAL.RepositoryService<
TEntity,
{
create: CreateRuleTypeDTO
update: UpdateRuleTypeDTO
}
> {}
@@ -240,7 +240,7 @@ describe("Product collection Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"productCollectionId" must be defined') expect(error.message).toEqual("productCollection - id must be defined")
}) })
it("should return collection based on config select param", async () => { it("should return collection based on config select param", async () => {
@@ -796,7 +796,23 @@ describe("ProductModuleService products", function () {
const products = await module.create([data]) const products = await module.create([data])
let retrievedProducts = await module.list({ id: products[0].id })
expect(retrievedProducts).toHaveLength(1)
expect(retrievedProducts[0].deleted_at).toBeNull()
await module.softDelete([products[0].id]) await module.softDelete([products[0].id])
retrievedProducts = await module.list(
{ id: products[0].id },
{
withDeleted: true,
}
)
expect(retrievedProducts).toHaveLength(1)
expect(retrievedProducts[0].deleted_at).not.toBeNull()
await module.restore([products[0].id]) await module.restore([products[0].id])
const deletedProducts = await module.list( const deletedProducts = await module.list(
@@ -205,7 +205,7 @@ describe("ProductOption Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"productOptionId" must be defined') expect(error.message).toEqual("productOption - id must be defined")
}) })
it("should return option based on config select param", async () => { it("should return option based on config select param", async () => {
@@ -237,7 +237,7 @@ describe("ProductTag Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"productTagId" must be defined') expect(error.message).toEqual("productTag - id must be defined")
}) })
it("should return tag based on config select param", async () => { it("should return tag based on config select param", async () => {
@@ -199,7 +199,7 @@ describe("ProductType Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"productTypeId" must be defined') expect(error.message).toEqual("productType - id must be defined")
}) })
it("should return type based on config select param", async () => { it("should return type based on config select param", async () => {
@@ -320,7 +320,7 @@ describe("ProductVariant Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"productVariantId" must be defined') expect(error.message).toEqual("productVariant - id must be defined")
}) })
}) })
}) })
@@ -78,7 +78,7 @@ describe("Product Service", () => {
error = e error = e
} }
expect(error.message).toEqual('"productId" must be defined') expect(error.message).toEqual("product - id must be defined")
}) })
it("should throw an error when product with id does not exist", async () => { it("should throw an error when product with id does not exist", async () => {
@@ -217,7 +217,7 @@ describe("Product Service", () => {
error = e error = e
} }
expect(error.message).toEqual(`Product with id "undefined" not found`) expect(error.message).toEqual(`Product with id "" not found`)
let result = await service.retrieve(productOne.id) let result = await service.retrieve(productOne.id)
+1 -1
View File
@@ -144,7 +144,7 @@ class Product {
@ManyToMany(() => ProductCategory, "products", { @ManyToMany(() => ProductCategory, "products", {
owner: true, owner: true,
pivotTable: "product_category_product", pivotTable: "product_category_product",
cascade: ["soft-remove"] as any, // TODO: rm cascade: ["soft-remove"] as any,
}) })
categories = new Collection<ProductCategory>(this) categories = new Collection<ProductCategory>(this)
@@ -14,6 +14,6 @@ export class ProductImageRepository extends DALUtils.mikroOrmBaseRepositoryFacto
async upsert(urls: string[], context: Context = {}): Promise<Image[]> { async upsert(urls: string[], context: Context = {}): Promise<Image[]> {
const data = urls.map((url) => ({ url })) const data = urls.map((url) => ({ url }))
return await super.upsert(data, context) return (await super.upsert(data, context)) as Image[]
} }
} }
+8 -15
View File
@@ -17,8 +17,8 @@ import {
DALUtils, DALUtils,
isDefined, isDefined,
MedusaError, MedusaError,
promiseAll,
ProductUtils, ProductUtils,
promiseAll,
} from "@medusajs/utils" } from "@medusajs/utils"
import { ProductServiceTypes } from "../types/services" import { ProductServiceTypes } from "../types/services"
@@ -118,7 +118,10 @@ export class ProductRepository extends DALUtils.mikroOrmBaseRepositoryFactory<Pr
} }
async update( async update(
data: WithRequiredProperty<ProductServiceTypes.UpdateProductDTO, "id">[], data: {
entity: Product
update: WithRequiredProperty<ProductServiceTypes.UpdateProductDTO, "id">
}[],
context: Context = {} context: Context = {}
): Promise<Product[]> { ): Promise<Product[]> {
let categoryIds: string[] = [] let categoryIds: string[] = []
@@ -128,7 +131,7 @@ export class ProductRepository extends DALUtils.mikroOrmBaseRepositoryFactory<Pr
// TODO: use the getter method (getActiveManager) // TODO: use the getter method (getActiveManager)
const manager = this.getActiveManager<SqlEntityManager>(context) const manager = this.getActiveManager<SqlEntityManager>(context)
data.forEach((productData) => { data.forEach(({ update: productData }) => {
categoryIds = categoryIds.concat( categoryIds = categoryIds.concat(
productData?.categories?.map((c) => c.id) || [] productData?.categories?.map((c) => c.id) || []
) )
@@ -144,16 +147,6 @@ export class ProductRepository extends DALUtils.mikroOrmBaseRepositoryFactory<Pr
} }
}) })
const productsToUpdate = await manager.find(
Product,
{
id: data.map((updateData) => updateData.id),
},
{
populate: ["tags", "categories"],
}
)
const collectionsToAssign = collectionIds.length const collectionsToAssign = collectionIds.length
? await manager.find(ProductCollection, { ? await manager.find(ProductCollection, {
id: collectionIds, id: collectionIds,
@@ -195,11 +188,11 @@ export class ProductRepository extends DALUtils.mikroOrmBaseRepositoryFactory<Pr
) )
const productsToUpdateMap = new Map<string, Product>( const productsToUpdateMap = new Map<string, Product>(
productsToUpdate.map((product) => [product.id, product]) data.map(({ entity }) => [entity.id, entity])
) )
const products = await promiseAll( const products = await promiseAll(
data.map(async (updateData) => { data.map(async ({ update: updateData }) => {
const product = productsToUpdateMap.get(updateData.id) const product = productsToUpdateMap.get(updateData.id)
if (!product) { if (!product) {
@@ -1,11 +1,8 @@
import { asClass, asValue, createContainer } from "awilix" import { asValue } from "awilix"
import { ProductService } from "@services"
export const nonExistingProductId = "non-existing-id" export const nonExistingProductId = "non-existing-id"
export const mockContainer = createContainer() export const productRepositoryMock = {
mockContainer.register({
transaction: asValue(async (task) => await task()),
productRepository: asValue({ productRepository: asValue({
find: jest.fn().mockImplementation(async ({ where: { id } }) => { find: jest.fn().mockImplementation(async ({ where: { id } }) => {
if (id === nonExistingProductId) { if (id === nonExistingProductId) {
@@ -17,5 +14,4 @@ mockContainer.register({
findAndCount: jest.fn().mockResolvedValue([[], 0]), findAndCount: jest.fn().mockResolvedValue([[], 0]),
getFreshManager: jest.fn().mockResolvedValue({}), getFreshManager: jest.fn().mockResolvedValue({}),
}), }),
productService: asClass(ProductService), }
})
@@ -1,13 +1,28 @@
import { mockContainer, nonExistingProductId } from "../__fixtures__/product" import {
nonExistingProductId,
productRepositoryMock,
} from "../__fixtures__/product"
import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix"
import ContainerLoader from "../../loaders/container"
describe("Product service", function () { describe("Product service", function () {
beforeEach(function () { let container
beforeEach(async function () {
jest.clearAllMocks() jest.clearAllMocks()
container = createMedusaContainer()
container.register("manager", asValue({}))
await ContainerLoader({ container })
container.register(productRepositoryMock)
}) })
it("should retrieve a product", async function () { it("should retrieve a product", async function () {
const productService = mockContainer.resolve("productService") const productService = container.resolve("productService")
const productRepository = mockContainer.resolve("productRepository") const productRepository = container.resolve("productRepository")
const productId = "existing-product" const productId = "existing-product"
await productService.retrieve(productId) await productService.retrieve(productId)
@@ -30,8 +45,8 @@ describe("Product service", function () {
}) })
it("should fail to retrieve a product", async function () { it("should fail to retrieve a product", async function () {
const productService = mockContainer.resolve("productService") const productService = container.resolve("productService")
const productRepository = mockContainer.resolve("productRepository") const productRepository = container.resolve("productRepository")
const err = await productService const err = await productService
.retrieve(nonExistingProductId) .retrieve(nonExistingProductId)
@@ -59,8 +74,8 @@ describe("Product service", function () {
}) })
it("should list products", async function () { it("should list products", async function () {
const productService = mockContainer.resolve("productService") const productService = container.resolve("productService")
const productRepository = mockContainer.resolve("productRepository") const productRepository = container.resolve("productRepository")
const filters = {} const filters = {}
const config = { const config = {
@@ -85,8 +100,8 @@ describe("Product service", function () {
}) })
it("should list products with filters", async function () { it("should list products with filters", async function () {
const productService = mockContainer.resolve("productService") const productService = container.resolve("productService")
const productRepository = mockContainer.resolve("productRepository") const productRepository = container.resolve("productRepository")
const filters = { const filters = {
tags: { tags: {
@@ -123,8 +138,8 @@ describe("Product service", function () {
}) })
it("should list products with filters and relations", async function () { it("should list products with filters and relations", async function () {
const productService = mockContainer.resolve("productService") const productService = container.resolve("productService")
const productRepository = mockContainer.resolve("productRepository") const productRepository = container.resolve("productRepository")
const filters = { const filters = {
tags: { tags: {
@@ -161,8 +176,8 @@ describe("Product service", function () {
}) })
it("should list and count the products with filters and relations", async function () { it("should list and count the products with filters and relations", async function () {
const productService = mockContainer.resolve("productService") const productService = container.resolve("productService")
const productRepository = mockContainer.resolve("productRepository") const productRepository = container.resolve("productRepository")
const filters = { const filters = {
tags: { tags: {
-2
View File
@@ -6,5 +6,3 @@ export { default as ProductTagService } from "./product-tag"
export { default as ProductVariantService } from "./product-variant" export { default as ProductVariantService } from "./product-variant"
export { default as ProductTypeService } from "./product-type" export { default as ProductTypeService } from "./product-type"
export { default as ProductOptionService } from "./product-option" export { default as ProductOptionService } from "./product-option"
export { default as ProductImageService } from "./product-image"
export { default as ProductOptionValueService } from "./product-option-value"
@@ -7,14 +7,7 @@ import {
} from "@medusajs/utils" } from "@medusajs/utils"
import { ProductCollection } from "@models" import { ProductCollection } from "@models"
import { import { ProductCollectionServiceTypes } from "@types"
IProductCollectionRepository,
ProductCollectionServiceTypes,
} from "@types"
import {
CreateProductCollection,
UpdateProductCollection,
} from "../types/services/product-collection"
type InjectedDependencies = { type InjectedDependencies = {
productCollectionRepository: DAL.RepositoryService productCollectionRepository: DAL.RepositoryService
@@ -22,15 +15,11 @@ type InjectedDependencies = {
export default class ProductCollectionService< export default class ProductCollectionService<
TEntity extends ProductCollection = ProductCollection TEntity extends ProductCollection = ProductCollection
> extends ModulesSdkUtils.abstractServiceFactory< > extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
InjectedDependencies, ProductCollection
{ )<TEntity> {
create: CreateProductCollection
update: UpdateProductCollection
}
>(ProductCollection)<TEntity> {
// eslint-disable-next-line max-len // eslint-disable-next-line max-len
protected readonly productCollectionRepository_: IProductCollectionRepository<TEntity> protected readonly productCollectionRepository_: DAL.RepositoryService<TEntity>
constructor(container: InjectedDependencies) { constructor(container: InjectedDependencies) {
super(container) super(container)
@@ -38,9 +27,9 @@ export default class ProductCollectionService<
} }
@InjectManager("productCollectionRepository_") @InjectManager("productCollectionRepository_")
async list<TEntityMethod = ProductTypes.ProductCollectionDTO>( async list(
filters: ProductTypes.FilterableProductCollectionProps = {}, filters: ProductTypes.FilterableProductCollectionProps = {},
config: FindConfig<TEntityMethod> = {}, config: FindConfig<TEntity> = {},
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity[]> {
return await this.productCollectionRepository_.find( return await this.productCollectionRepository_.find(
@@ -50,9 +39,9 @@ export default class ProductCollectionService<
} }
@InjectManager("productCollectionRepository_") @InjectManager("productCollectionRepository_")
async listAndCount<TEntityMethod = ProductTypes.ProductCollectionDTO>( async listAndCount(
filters: ProductTypes.FilterableProductCollectionProps = {}, filters: ProductTypes.FilterableProductCollectionProps = {},
config: FindConfig<TEntityMethod> = {}, config: FindConfig<TEntity> = {},
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<[TEntity[], number]> { ): Promise<[TEntity[], number]> {
return await this.productCollectionRepository_.findAndCount( return await this.productCollectionRepository_.findAndCount(
@@ -61,11 +50,9 @@ export default class ProductCollectionService<
) )
} }
protected buildListQueryOptions< protected buildListQueryOptions(
TEntityMethod = ProductTypes.ProductCollectionDTO
>(
filters: ProductTypes.FilterableProductCollectionProps = {}, filters: ProductTypes.FilterableProductCollectionProps = {},
config: FindConfig<TEntityMethod> = {} config: FindConfig<TEntity> = {}
): DAL.FindOptions<TEntity> { ): DAL.FindOptions<TEntity> {
const queryOptions = ModulesSdkUtils.buildQuery<TEntity>(filters, config) const queryOptions = ModulesSdkUtils.buildQuery<TEntity>(filters, config)
@@ -80,12 +67,24 @@ export default class ProductCollectionService<
return queryOptions return queryOptions
} }
create(
data: ProductCollectionServiceTypes.CreateProductCollection,
context?: Context
): Promise<TEntity>
create(
data: ProductCollectionServiceTypes.CreateProductCollection[],
context?: Context
): Promise<TEntity[]>
@InjectTransactionManager("productCollectionRepository_") @InjectTransactionManager("productCollectionRepository_")
async create( async create(
data: ProductCollectionServiceTypes.CreateProductCollection[], data:
| ProductCollectionServiceTypes.CreateProductCollection
| ProductCollectionServiceTypes.CreateProductCollection[],
context: Context = {} context: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
const productCollections = data.map((collectionData) => { const data_ = Array.isArray(data) ? data : [data]
const productCollections = data_.map((collectionData) => {
if (collectionData.product_ids) { if (collectionData.product_ids) {
collectionData.products = collectionData.product_ids collectionData.products = collectionData.product_ids
@@ -98,12 +97,27 @@ export default class ProductCollectionService<
return super.create(productCollections, context) return super.create(productCollections, context)
} }
@InjectTransactionManager("productCollectionRepository_") // @ts-ignore
async update( update(
data: ProductCollectionServiceTypes.UpdateProductCollection,
context?: Context
): Promise<TEntity>
// @ts-ignore
update(
data: ProductCollectionServiceTypes.UpdateProductCollection[], data: ProductCollectionServiceTypes.UpdateProductCollection[],
context?: Context
): Promise<TEntity[]>
@InjectTransactionManager("productCollectionRepository_")
// @ts-ignore Do not implement all the expected overloads, see if we must do it
async update(
data:
| ProductCollectionServiceTypes.UpdateProductCollection
| ProductCollectionServiceTypes.UpdateProductCollection[],
context: Context = {} context: Context = {}
): Promise<TEntity[]> { ): Promise<TEntity | TEntity[]> {
const productCollections = data.map((collectionData) => { const data_ = Array.isArray(data) ? data : [data]
const productCollections = data_.map((collectionData) => {
if (collectionData.product_ids) { if (collectionData.product_ids) {
collectionData.products = collectionData.product_ids collectionData.products = collectionData.product_ids
@@ -1,18 +0,0 @@
import { Image } from "@models"
import { DAL } from "@medusajs/types"
import { ModulesSdkUtils } from "@medusajs/utils"
type InjectedDependencies = {
productImageRepository: DAL.RepositoryService
}
export default class ProductImageService<
TEntity extends Image = Image
> extends ModulesSdkUtils.abstractServiceFactory<InjectedDependencies>(
Image
)<TEntity> {
constructor(container: InjectedDependencies) {
// @ts-ignore
super(...arguments)
}
}
Loaded 100 of 163 files, more files were not shown because too many files have changed in this diff. Show more