From 5e655dd59bda4ffface28db38021ba71cae6de10 Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Fri, 19 Jan 2024 15:09:38 +0100 Subject: [PATCH] chore: Hide repository creation if they are not custom + add upsert support by default (#6127) --- .changeset/gold-drinks-smile.md | 8 + .../services/auth-provider/index.spec.ts | 15 +- .../services/auth-user/index.spec.ts | 15 +- packages/authentication/package.json | 2 - packages/authentication/src/index.ts | 17 +- .../authentication/src/loaders/container.ts | 56 +---- .../src/repositories/auth-provider.ts | 17 -- .../src/repositories/auth-user.ts | 17 -- .../authentication/src/repositories/index.ts | 2 - .../src/scripts/bin/run-migration-down.ts | 8 - .../src/scripts/bin/run-migration-up.ts | 8 - packages/authentication/src/scripts/index.ts | 2 - .../src/scripts/migration-down.ts | 50 ----- .../src/scripts/migration-up.ts | 62 ------ .../authentication/src/services/auth-user.ts | 2 +- .../src/types/repositories/index.ts | 26 +++ .../__tests__/services/address/index.spec.ts | 15 +- .../__tests__/services/cart/index.spec.ts | 15 +- packages/cart/package.json | 2 - packages/cart/src/index.ts | 17 +- packages/cart/src/loaders/container.ts | 62 +----- packages/cart/src/repositories/address.ts | 16 -- packages/cart/src/repositories/cart.ts | 16 -- packages/cart/src/repositories/index.ts | 5 - packages/cart/src/repositories/line-item.ts | 16 -- .../cart/src/repositories/shipping-method.ts | 16 -- .../src/scripts/bin/run-migration-down.ts | 8 - .../cart/src/scripts/bin/run-migration-up.ts | 8 - packages/cart/src/scripts/index.ts | 2 - packages/cart/src/scripts/migration-down.ts | 50 ----- packages/cart/src/scripts/migration-up.ts | 62 ------ packages/cart/src/types/index.ts | 2 + packages/cart/src/types/repositories.ts | 50 +++++ packages/payment/src/loaders/container.ts | 47 +---- .../__tests__/services/currency/index.spec.ts | 15 +- .../services/money-amount/index.spec.ts | 15 +- .../services/price-list-rule/index.spec.ts | 16 +- .../services/price-list/index.spec.ts | 15 +- .../services/price-rule/index.spec.ts | 16 +- .../index.spec.ts | 17 +- .../services/price-set/index.spec.ts | 15 +- .../services/rule-type/index.spec.ts | 16 +- packages/pricing/package.json | 2 - packages/pricing/src/index.ts | 17 +- packages/pricing/src/loaders/container.ts | 103 +--------- packages/pricing/src/repositories/currency.ts | 17 -- packages/pricing/src/repositories/index.ts | 11 - .../pricing/src/repositories/money-amount.ts | 17 -- .../src/repositories/price-list-rule-value.ts | 35 ---- .../src/repositories/price-list-rule.ts | 61 ------ .../pricing/src/repositories/price-list.ts | 52 ----- .../pricing/src/repositories/price-rule.ts | 35 ---- .../price-set-money-amount-rules.ts | 17 -- .../repositories/price-set-money-amount.ts | 17 -- .../src/repositories/price-set-rule-type.ts | 17 -- .../pricing/src/repositories/price-set.ts | 17 -- .../pricing/src/repositories/rule-type.ts | 16 -- .../src/scripts/bin/run-migration-down.ts | 8 - .../src/scripts/bin/run-migration-up.ts | 8 - packages/pricing/src/scripts/index.ts | 2 - .../pricing/src/scripts/migration-down.ts | 44 ---- packages/pricing/src/scripts/migration-up.ts | 54 ----- packages/pricing/src/services/currency.ts | 2 +- .../src/services/price-list-rule-value.ts | 21 +- .../pricing/src/services/price-list-rule.ts | 49 ++++- packages/pricing/src/services/price-list.ts | 41 +++- packages/pricing/src/services/price-rule.ts | 21 +- .../services/price-set-money-amount-rules.ts | 4 + .../src/services/price-set-money-amount.ts | 46 +---- .../src/services/price-set-rule-type.ts | 46 +---- .../pricing/src/types/repositories/index.ts | 157 ++++++++++++++ .../services/product-category/index.ts | 191 ++++++++++-------- .../services/product-collection/index.ts | 116 ++++++----- .../services/product-option/index.ts | 15 +- .../__tests__/services/product-tag/index.ts | 145 ++++++------- .../__tests__/services/product-type/index.ts | 108 +++++----- .../services/product-variant/index.ts | 24 +-- .../__tests__/services/product/index.ts | 16 +- packages/product/src/loaders/container.ts | 116 +---------- packages/product/src/repositories/index.ts | 6 - .../src/repositories/product-collection.ts | 55 ----- .../product/src/repositories/product-image.ts | 40 +--- .../src/repositories/product-option-value.ts | 89 -------- .../src/repositories/product-option.ts | 112 ---------- .../product/src/repositories/product-tag.ts | 71 ------- .../product/src/repositories/product-type.ts | 71 ------- .../src/repositories/product-variant.ts | 22 -- .../src/services/product-collection.ts | 57 +++++- .../product/src/services/product-image.ts | 25 +-- .../src/services/product-option-value.ts | 37 +--- .../product/src/services/product-option.ts | 20 +- packages/product/src/services/product-tag.ts | 26 +-- packages/product/src/services/product-type.ts | 26 +-- .../product/src/services/product-variant.ts | 4 +- packages/product/src/services/product.ts | 4 +- packages/product/src/types/index.ts | 3 +- packages/product/src/types/repositories.ts | 100 +++++++++ .../src/types/services/product-collection.ts | 12 ++ .../services/promotion/index.spec.ts | 16 +- packages/promotion/package.json | 2 - packages/promotion/src/index.ts | 17 +- packages/promotion/src/loaders/container.ts | 78 +------ .../src/repositories/application-method.ts | 16 -- .../src/repositories/campaign-budget.ts | 11 - packages/promotion/src/repositories/index.ts | 5 - .../src/repositories/promotion-rule-value.ts | 19 -- .../src/repositories/promotion-rule.ts | 16 -- .../promotion/src/repositories/promotion.ts | 16 -- .../src/scripts/bin/run-migration-down.ts | 8 - .../src/scripts/bin/run-migration-up.ts | 8 - .../promotion/src/scripts/bin/run-seed.ts | 19 -- packages/promotion/src/scripts/index.ts | 2 - .../promotion/src/scripts/migration-down.ts | 43 ---- .../promotion/src/scripts/migration-up.ts | 55 ----- packages/promotion/src/scripts/seed.ts | 58 ------ packages/promotion/src/types/index.ts | 1 + packages/promotion/src/types/repositories.ts | 91 +++++++++ packages/types/src/dal/repository-service.ts | 18 +- .../src/dal/mikro-orm/mikro-orm-repository.ts | 91 ++++++++- packages/utils/src/dal/repository.ts | 3 + .../modules-sdk/abstract-service-factory.ts | 14 +- packages/utils/src/modules-sdk/index.ts | 1 + .../loaders/container-loader-factory.ts | 170 ++++++++++++++++ yarn.lock | 8 - 124 files changed, 1516 insertions(+), 2559 deletions(-) create mode 100644 .changeset/gold-drinks-smile.md delete mode 100644 packages/authentication/src/repositories/auth-provider.ts delete mode 100644 packages/authentication/src/repositories/auth-user.ts delete mode 100644 packages/authentication/src/scripts/bin/run-migration-down.ts delete mode 100644 packages/authentication/src/scripts/bin/run-migration-up.ts delete mode 100644 packages/authentication/src/scripts/index.ts delete mode 100644 packages/authentication/src/scripts/migration-down.ts delete mode 100644 packages/authentication/src/scripts/migration-up.ts delete mode 100644 packages/cart/src/repositories/address.ts delete mode 100644 packages/cart/src/repositories/cart.ts delete mode 100644 packages/cart/src/repositories/line-item.ts delete mode 100644 packages/cart/src/repositories/shipping-method.ts delete mode 100644 packages/cart/src/scripts/bin/run-migration-down.ts delete mode 100644 packages/cart/src/scripts/bin/run-migration-up.ts delete mode 100644 packages/cart/src/scripts/index.ts delete mode 100644 packages/cart/src/scripts/migration-down.ts delete mode 100644 packages/cart/src/scripts/migration-up.ts create mode 100644 packages/cart/src/types/repositories.ts delete mode 100644 packages/pricing/src/repositories/currency.ts delete mode 100644 packages/pricing/src/repositories/money-amount.ts delete mode 100644 packages/pricing/src/repositories/price-list-rule-value.ts delete mode 100644 packages/pricing/src/repositories/price-list-rule.ts delete mode 100644 packages/pricing/src/repositories/price-list.ts delete mode 100644 packages/pricing/src/repositories/price-rule.ts delete mode 100644 packages/pricing/src/repositories/price-set-money-amount-rules.ts delete mode 100644 packages/pricing/src/repositories/price-set-money-amount.ts delete mode 100644 packages/pricing/src/repositories/price-set-rule-type.ts delete mode 100644 packages/pricing/src/repositories/price-set.ts delete mode 100644 packages/pricing/src/repositories/rule-type.ts delete mode 100644 packages/pricing/src/scripts/bin/run-migration-down.ts delete mode 100644 packages/pricing/src/scripts/bin/run-migration-up.ts delete mode 100644 packages/pricing/src/scripts/index.ts delete mode 100644 packages/pricing/src/scripts/migration-down.ts delete mode 100644 packages/pricing/src/scripts/migration-up.ts delete mode 100644 packages/product/src/repositories/product-collection.ts delete mode 100644 packages/product/src/repositories/product-option-value.ts delete mode 100644 packages/product/src/repositories/product-option.ts delete mode 100644 packages/product/src/repositories/product-tag.ts delete mode 100644 packages/product/src/repositories/product-type.ts delete mode 100644 packages/product/src/repositories/product-variant.ts create mode 100644 packages/product/src/types/repositories.ts delete mode 100644 packages/promotion/src/repositories/application-method.ts delete mode 100644 packages/promotion/src/repositories/campaign-budget.ts delete mode 100644 packages/promotion/src/repositories/promotion-rule-value.ts delete mode 100644 packages/promotion/src/repositories/promotion-rule.ts delete mode 100644 packages/promotion/src/repositories/promotion.ts delete mode 100644 packages/promotion/src/scripts/bin/run-migration-down.ts delete mode 100644 packages/promotion/src/scripts/bin/run-migration-up.ts delete mode 100644 packages/promotion/src/scripts/bin/run-seed.ts delete mode 100644 packages/promotion/src/scripts/index.ts delete mode 100644 packages/promotion/src/scripts/migration-down.ts delete mode 100644 packages/promotion/src/scripts/migration-up.ts delete mode 100644 packages/promotion/src/scripts/seed.ts create mode 100644 packages/promotion/src/types/repositories.ts create mode 100644 packages/utils/src/modules-sdk/loaders/container-loader-factory.ts diff --git a/.changeset/gold-drinks-smile.md b/.changeset/gold-drinks-smile.md new file mode 100644 index 0000000000..a7095c4fe1 --- /dev/null +++ b/.changeset/gold-drinks-smile.md @@ -0,0 +1,8 @@ +--- +"@medusajs/utils": patch +"@medusajs/types": patch +"@medusajs/product": patch +"@medusajs/pricing": patch +--- + +chore: Hide repository creation if they are not custom + add upsert support by default diff --git a/packages/authentication/integration-tests/__tests__/services/auth-provider/index.spec.ts b/packages/authentication/integration-tests/__tests__/services/auth-provider/index.spec.ts index 645045ecd2..934bf94ec7 100644 --- a/packages/authentication/integration-tests/__tests__/services/auth-provider/index.spec.ts +++ b/packages/authentication/integration-tests/__tests__/services/auth-provider/index.spec.ts @@ -1,9 +1,11 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" -import { AuthProviderRepository } from "@repositories" import { AuthProviderService } from "@services" import { MikroOrmWrapper } from "../../../utils" import { createAuthProviders } from "../../../__fixtures__/auth-provider" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -17,13 +19,12 @@ describe("AuthProvider Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const authProviderRepository = new AuthProviderRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new AuthProviderService({ - authProviderRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("authProviderService") await createAuthProviders(testManager) }) diff --git a/packages/authentication/integration-tests/__tests__/services/auth-user/index.spec.ts b/packages/authentication/integration-tests/__tests__/services/auth-user/index.spec.ts index 1aaa7d2f99..eaaf4324ef 100644 --- a/packages/authentication/integration-tests/__tests__/services/auth-user/index.spec.ts +++ b/packages/authentication/integration-tests/__tests__/services/auth-user/index.spec.ts @@ -1,10 +1,12 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" -import { AuthUserRepository } from "@repositories" import { AuthUserService } from "@services" import { MikroOrmWrapper } from "../../../utils" import { createAuthProviders } from "../../../__fixtures__/auth-provider" import { createAuthUsers } from "../../../__fixtures__/auth-user" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -18,13 +20,12 @@ describe("AuthUser Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const authUserRepository = new AuthUserRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new AuthUserService({ - authUserRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("authUserService") await createAuthProviders(testManager) await createAuthUsers(testManager) diff --git a/packages/authentication/package.json b/packages/authentication/package.json index 7ae37e790a..05fb16fbbf 100644 --- a/packages/authentication/package.json +++ b/packages/authentication/package.json @@ -11,8 +11,6 @@ "node": ">=16" }, "bin": { - "medusa-authentication-migrations-down": "dist/scripts/bin/run-migration-down.js", - "medusa-authentication-migrations-up": "dist/scripts/bin/run-migration-up.js", "medusa-authentication-seed": "dist/scripts/bin/run-seed.js" }, "repository": { diff --git a/packages/authentication/src/index.ts b/packages/authentication/src/index.ts index 4ea0e7c3e3..46e1b29938 100644 --- a/packages/authentication/src/index.ts +++ b/packages/authentication/src/index.ts @@ -1,7 +1,22 @@ import { moduleDefinition } from "./module-definition" +import { Modules } from "@medusajs/modules-sdk" +import * as Models from "@models" +import { ModulesSdkUtils } from "@medusajs/utils" export default moduleDefinition +const migrationScriptOptions = { + moduleName: Modules.AUTHENTICATION, + models: Models, + pathToMigrations: __dirname + "/migrations", +} + +export const runMigrations = ModulesSdkUtils.buildMigrationScript( + migrationScriptOptions +) +export const revertMigration = ModulesSdkUtils.buildRevertMigrationScript( + migrationScriptOptions +) + export * from "./initialize" export * from "./loaders" -export * from "./scripts" diff --git a/packages/authentication/src/loaders/container.ts b/packages/authentication/src/loaders/container.ts index d9d36e6daf..28ea110f2d 100644 --- a/packages/authentication/src/loaders/container.ts +++ b/packages/authentication/src/loaders/container.ts @@ -1,48 +1,10 @@ -import * as defaultRepositories from "@repositories" -import * as defaultServices from "@services" +import { ModulesSdkUtils } from "@medusajs/utils" +import * as ModuleModels from "@models" +import * as ModuleRepositories from "@repositories" +import * as ModuleServices from "@services" -import { LoaderOptions } from "@medusajs/modules-sdk" -import { ModulesSdkTypes } from "@medusajs/types" -import { loadCustomRepositories } from "@medusajs/utils" -import { asClass } from "awilix" - -export default async ({ - container, - options, -}: LoaderOptions< - | ModulesSdkTypes.ModuleServiceInitializeOptions - | ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions ->): Promise => { - const customRepositories = ( - options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions - )?.repositories - - container.register({ - authUserService: asClass(defaultServices.AuthUserService).singleton(), - authProviderService: asClass( - defaultServices.AuthProviderService - ).singleton(), - }) - - if (customRepositories) { - loadCustomRepositories({ - defaultRepositories, - customRepositories, - container, - }) - } else { - loadDefaultRepositories({ container }) - } -} - -function loadDefaultRepositories({ container }) { - container.register({ - baseRepository: asClass(defaultRepositories.BaseRepository).singleton(), - authUserRepository: asClass( - defaultRepositories.AuthUserRepository - ).singleton(), - authProviderRepository: asClass( - defaultRepositories.AuthProviderRepository - ).singleton(), - }) -} +export default ModulesSdkUtils.moduleContainerLoaderFactory({ + moduleModels: ModuleModels, + moduleRepositories: ModuleRepositories, + moduleServices: ModuleServices, +}) diff --git a/packages/authentication/src/repositories/auth-provider.ts b/packages/authentication/src/repositories/auth-provider.ts deleted file mode 100644 index 6246ead8c6..0000000000 --- a/packages/authentication/src/repositories/auth-provider.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { AuthProvider } from "@models" -import { RepositoryTypes } from "@types" - -export class AuthProviderRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - AuthProvider, - { - create: RepositoryTypes.CreateAuthProviderDTO - update: RepositoryTypes.UpdateAuthProviderDTO - } ->(AuthProvider) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/authentication/src/repositories/auth-user.ts b/packages/authentication/src/repositories/auth-user.ts deleted file mode 100644 index a5b47652f0..0000000000 --- a/packages/authentication/src/repositories/auth-user.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { AuthUser } from "@models" -import { RepositoryTypes } from "@types" - -export class AuthUserRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - AuthUser, - { - create: RepositoryTypes.CreateAuthUserDTO - update: RepositoryTypes.UpdateAuthUserDTO - } ->(AuthUser) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/authentication/src/repositories/index.ts b/packages/authentication/src/repositories/index.ts index 506db731aa..147c9cc259 100644 --- a/packages/authentication/src/repositories/index.ts +++ b/packages/authentication/src/repositories/index.ts @@ -1,3 +1 @@ export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils" -export { AuthProviderRepository } from "./auth-provider" -export { AuthUserRepository } from "./auth-user" diff --git a/packages/authentication/src/scripts/bin/run-migration-down.ts b/packages/authentication/src/scripts/bin/run-migration-down.ts deleted file mode 100644 index e352048fd4..0000000000 --- a/packages/authentication/src/scripts/bin/run-migration-down.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { revertMigration } = await import("../migration-down") - const { config } = await import("dotenv") - config() - await revertMigration() -})() diff --git a/packages/authentication/src/scripts/bin/run-migration-up.ts b/packages/authentication/src/scripts/bin/run-migration-up.ts deleted file mode 100644 index 35f3bee853..0000000000 --- a/packages/authentication/src/scripts/bin/run-migration-up.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { runMigrations } = await import("../migration-up") - const { config } = await import("dotenv") - config() - await runMigrations() -})() diff --git a/packages/authentication/src/scripts/index.ts b/packages/authentication/src/scripts/index.ts deleted file mode 100644 index cfa5c5ddf5..0000000000 --- a/packages/authentication/src/scripts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./migration-up" -export * from "./migration-down" diff --git a/packages/authentication/src/scripts/migration-down.ts b/packages/authentication/src/scripts/migration-down.ts deleted file mode 100644 index 84fcd75e35..0000000000 --- a/packages/authentication/src/scripts/migration-down.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk"; -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types"; -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils"; -import { EntitySchema } from "@mikro-orm/core"; -import * as AuthenticationModels from "@models"; - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of reverting the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function revertMigration({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig( - Modules.AUTHENTICATION, - options - )! - const entities = Object.values( - AuthenticationModels - ) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - await migrator.down() - - logger?.info("Authentication module migration executed") - } catch (error) { - logger?.error( - `Authentication module migration failed to run - Error: ${error}` - ) - } - - await orm.close() -} diff --git a/packages/authentication/src/scripts/migration-up.ts b/packages/authentication/src/scripts/migration-up.ts deleted file mode 100644 index 5f3cda160e..0000000000 --- a/packages/authentication/src/scripts/migration-up.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk"; -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types"; -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils"; -import { EntitySchema } from "@mikro-orm/core"; -import * as AuthenticationModels from "@models"; - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of running the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function runMigrations({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig( - Modules.AUTHENTICATION, - options - )! - const entities = Object.values( - AuthenticationModels - ) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - - const pendingMigrations = await migrator.getPendingMigrations() - logger.info( - `Running pending migrations: ${JSON.stringify( - pendingMigrations, - null, - 2 - )}` - ) - - await migrator.up({ - migrations: pendingMigrations.map((m) => m.name), - }) - - logger.info("Authentication module migration executed") - } catch (error) { - logger.error( - `Authentication module migration failed to run - Error: ${error}` - ) - } - - await orm.close() -} diff --git a/packages/authentication/src/services/auth-user.ts b/packages/authentication/src/services/auth-user.ts index 6cb6336ebe..352d818a2a 100644 --- a/packages/authentication/src/services/auth-user.ts +++ b/packages/authentication/src/services/auth-user.ts @@ -16,7 +16,7 @@ export default class AuthUserService< create: ServiceTypes.CreateAuthUserDTO } >(AuthUser) { - constructor({ authUserRepository }: InjectedDependencies) { + constructor(container: InjectedDependencies) { // @ts-ignore super(...arguments) } diff --git a/packages/authentication/src/types/repositories/index.ts b/packages/authentication/src/types/repositories/index.ts index b4282c985c..86ed738257 100644 --- a/packages/authentication/src/types/repositories/index.ts +++ b/packages/authentication/src/types/repositories/index.ts @@ -1,2 +1,28 @@ +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-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 + extends DAL.RepositoryService< + TEntity, + { + create: CreateAuthUserDTO + update: UpdateAuthUserDTO + } + > {} diff --git a/packages/cart/integration-tests/__tests__/services/address/index.spec.ts b/packages/cart/integration-tests/__tests__/services/address/index.spec.ts index 4ec32c1284..e7008793f3 100644 --- a/packages/cart/integration-tests/__tests__/services/address/index.spec.ts +++ b/packages/cart/integration-tests/__tests__/services/address/index.spec.ts @@ -1,7 +1,9 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" -import { AddressRepository } from "../../../../src/repositories" import { AddressService } from "../../../../src/services" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -15,13 +17,12 @@ describe("Address Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const addressRepository = new AddressRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new AddressService({ - addressRepository: addressRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("addressService") }) afterEach(async () => { diff --git a/packages/cart/integration-tests/__tests__/services/cart/index.spec.ts b/packages/cart/integration-tests/__tests__/services/cart/index.spec.ts index b5eb017f0a..de63177a9d 100644 --- a/packages/cart/integration-tests/__tests__/services/cart/index.spec.ts +++ b/packages/cart/integration-tests/__tests__/services/cart/index.spec.ts @@ -1,8 +1,10 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" -import { CartRepository } from "../../../../src/repositories" import { CartService } from "../../../../src/services" import { createCarts } from "../../../__fixtures__/cart" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -16,13 +18,12 @@ describe("Cart Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const cartRepository = new CartRepository({ - manager: repositoryManager - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new CartService({ - cartRepository: cartRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("cartService") await createCarts(testManager) }) diff --git a/packages/cart/package.json b/packages/cart/package.json index 46e9908a95..2bce6c6f54 100644 --- a/packages/cart/package.json +++ b/packages/cart/package.json @@ -11,8 +11,6 @@ "node": ">=16" }, "bin": { - "medusa-cart-migrations-down": "dist/scripts/bin/run-migration-down.js", - "medusa-cart-migrations-up": "dist/scripts/bin/run-migration-up.js", "medusa-cart-seed": "dist/scripts/bin/run-seed.js" }, "repository": { diff --git a/packages/cart/src/index.ts b/packages/cart/src/index.ts index 4ea0e7c3e3..e025c714a4 100644 --- a/packages/cart/src/index.ts +++ b/packages/cart/src/index.ts @@ -1,7 +1,22 @@ import { moduleDefinition } from "./module-definition" +import { Modules } from "@medusajs/modules-sdk" +import * as Models from "@models" +import { ModulesSdkUtils } from "@medusajs/utils" export default moduleDefinition +const migrationScriptOptions = { + moduleName: Modules.CART, + models: Models, + pathToMigrations: __dirname + "/migrations", +} + +export const runMigrations = ModulesSdkUtils.buildMigrationScript( + migrationScriptOptions +) +export const revertMigration = ModulesSdkUtils.buildRevertMigrationScript( + migrationScriptOptions +) + export * from "./initialize" export * from "./loaders" -export * from "./scripts" diff --git a/packages/cart/src/loaders/container.ts b/packages/cart/src/loaders/container.ts index 1affad8557..28ea110f2d 100644 --- a/packages/cart/src/loaders/container.ts +++ b/packages/cart/src/loaders/container.ts @@ -1,54 +1,10 @@ -import * as defaultRepositories from "@repositories" +import { ModulesSdkUtils } from "@medusajs/utils" +import * as ModuleModels from "@models" +import * as ModuleRepositories from "@repositories" +import * as ModuleServices from "@services" -import { LoaderOptions } from "@medusajs/modules-sdk" -import { ModulesSdkTypes } from "@medusajs/types" -import { loadCustomRepositories } from "@medusajs/utils" -import * as defaultServices from "@services" -import { asClass } from "awilix" - -export default async ({ - container, - options, -}: LoaderOptions< - | ModulesSdkTypes.ModuleServiceInitializeOptions - | ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions ->): Promise => { - const customRepositories = ( - options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions - )?.repositories - - container.register({ - cartService: asClass(defaultServices.CartService).singleton(), - addressService: asClass(defaultServices.AddressService).singleton(), - shippingMethodService: asClass( - defaultServices.ShippingMethodService - ).singleton(), - lineItemService: asClass(defaultServices.LineItemService).singleton(), - }) - - if (customRepositories) { - loadCustomRepositories({ - defaultRepositories, - customRepositories, - container, - }) - } else { - loadDefaultRepositories({ container }) - } -} - -function loadDefaultRepositories({ container }) { - container.register({ - baseRepository: asClass(defaultRepositories.BaseRepository).singleton(), - cartRepository: asClass(defaultRepositories.CartRepository).singleton(), - addressRepository: asClass( - defaultRepositories.AddressRepository - ).singleton(), - lineItemRepository: asClass( - defaultRepositories.LineItemRepository - ).singleton(), - shippingMethodRepository: asClass( - defaultRepositories.ShippingMethodRepository - ).singleton(), - }) -} +export default ModulesSdkUtils.moduleContainerLoaderFactory({ + moduleModels: ModuleModels, + moduleRepositories: ModuleRepositories, + moduleServices: ModuleServices, +}) diff --git a/packages/cart/src/repositories/address.ts b/packages/cart/src/repositories/address.ts deleted file mode 100644 index 2fb052cf7f..0000000000 --- a/packages/cart/src/repositories/address.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { Address } from "@models" -import { CreateAddressDTO, UpdateAddressDTO } from "../types" - -export class AddressRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - Address, - { - create: CreateAddressDTO - update: UpdateAddressDTO - } ->(Address) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/cart/src/repositories/cart.ts b/packages/cart/src/repositories/cart.ts deleted file mode 100644 index 577d826786..0000000000 --- a/packages/cart/src/repositories/cart.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { Cart } from "@models" -import { CreateCartDTO, UpdateCartDTO } from "@types" - -export class CartRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - Cart, - { - create: CreateCartDTO - update: UpdateCartDTO - } ->(Cart) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/cart/src/repositories/index.ts b/packages/cart/src/repositories/index.ts index d1bf0c1118..147c9cc259 100644 --- a/packages/cart/src/repositories/index.ts +++ b/packages/cart/src/repositories/index.ts @@ -1,6 +1 @@ export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils" -export * from "./address" -export * from "./cart" -export * from "./line-item" -export * from "./shipping-method" - diff --git a/packages/cart/src/repositories/line-item.ts b/packages/cart/src/repositories/line-item.ts deleted file mode 100644 index 8ac5e3c863..0000000000 --- a/packages/cart/src/repositories/line-item.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { LineItem } from "@models" -import { CreateLineItemDTO, UpdateLineItemDTO } from "../types" - -export class LineItemRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - LineItem, - { - create: CreateLineItemDTO - update: UpdateLineItemDTO - } ->(LineItem) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/cart/src/repositories/shipping-method.ts b/packages/cart/src/repositories/shipping-method.ts deleted file mode 100644 index 2b228ba5a4..0000000000 --- a/packages/cart/src/repositories/shipping-method.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { ShippingMethod } from "@models" -import { CreateShippingMethodDTO, UpdateShippingMethodDTO } from "@types" - -export class ShippingMethodRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - ShippingMethod, - { - create: CreateShippingMethodDTO - update: UpdateShippingMethodDTO - } ->(ShippingMethod) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/cart/src/scripts/bin/run-migration-down.ts b/packages/cart/src/scripts/bin/run-migration-down.ts deleted file mode 100644 index e352048fd4..0000000000 --- a/packages/cart/src/scripts/bin/run-migration-down.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { revertMigration } = await import("../migration-down") - const { config } = await import("dotenv") - config() - await revertMigration() -})() diff --git a/packages/cart/src/scripts/bin/run-migration-up.ts b/packages/cart/src/scripts/bin/run-migration-up.ts deleted file mode 100644 index 35f3bee853..0000000000 --- a/packages/cart/src/scripts/bin/run-migration-up.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { runMigrations } = await import("../migration-up") - const { config } = await import("dotenv") - config() - await runMigrations() -})() diff --git a/packages/cart/src/scripts/index.ts b/packages/cart/src/scripts/index.ts deleted file mode 100644 index cfa5c5ddf5..0000000000 --- a/packages/cart/src/scripts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./migration-up" -export * from "./migration-down" diff --git a/packages/cart/src/scripts/migration-down.ts b/packages/cart/src/scripts/migration-down.ts deleted file mode 100644 index 7346ce41b6..0000000000 --- a/packages/cart/src/scripts/migration-down.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk"; -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types"; -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils"; -import { EntitySchema } from "@mikro-orm/core"; -import * as CartModels from "@models"; - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of reverting the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function revertMigration({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig( - Modules.CART, - options - )! - const entities = Object.values( - CartModels - ) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - await migrator.down() - - logger?.info("Cart module migration executed") - } catch (error) { - logger?.error( - `Cart module migration failed to run - Error: ${error}` - ) - } - - await orm.close() -} diff --git a/packages/cart/src/scripts/migration-up.ts b/packages/cart/src/scripts/migration-up.ts deleted file mode 100644 index 0db7588a13..0000000000 --- a/packages/cart/src/scripts/migration-up.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk"; -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types"; -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils"; -import { EntitySchema } from "@mikro-orm/core"; -import * as CartModels from "@models"; - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of running the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function runMigrations({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig( - Modules.CART, - options - )! - const entities = Object.values( - CartModels - ) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - - const pendingMigrations = await migrator.getPendingMigrations() - logger.info( - `Running pending migrations: ${JSON.stringify( - pendingMigrations, - null, - 2 - )}` - ) - - await migrator.up({ - migrations: pendingMigrations.map((m) => m.name), - }) - - logger.info("Cart module migration executed") - } catch (error) { - logger.error( - `Cart module migration failed to run - Error: ${error}` - ) - } - - await orm.close() -} diff --git a/packages/cart/src/types/index.ts b/packages/cart/src/types/index.ts index 243d7d3c8d..3ee41da0c0 100644 --- a/packages/cart/src/types/index.ts +++ b/packages/cart/src/types/index.ts @@ -1,8 +1,10 @@ import { Logger } from "@medusajs/types" + export * from "./address" export * from "./cart" export * from "./line-item" export * from "./shipping-method" +export * from "./repositories" export type InitializeModuleInjectableDependencies = { logger?: Logger diff --git a/packages/cart/src/types/repositories.ts b/packages/cart/src/types/repositories.ts new file mode 100644 index 0000000000..6df208fdaa --- /dev/null +++ b/packages/cart/src/types/repositories.ts @@ -0,0 +1,50 @@ +import { DAL } from "@medusajs/types" +import { Cart, LineItem, ShippingMethod } from "@models" +import { CreateAddressDTO, UpdateAddressDTO } from "./address" +import { CreateCartDTO, UpdateCartDTO } from "./cart" +import { CreateLineItemDTO, UpdateLineItemDTO } from "./line-item" +import { + CreateShippingMethodDTO, + UpdateShippingMethodDTO, +} from "./shipping-method" + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IAddressRepository + extends DAL.RepositoryService< + TEntity, + { + create: CreateAddressDTO + update: UpdateAddressDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ICartRepository + extends DAL.RepositoryService< + TEntity, + { + create: CreateCartDTO + update: UpdateCartDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ILineItemRepository + 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 + } + > {} diff --git a/packages/payment/src/loaders/container.ts b/packages/payment/src/loaders/container.ts index ba1b855344..28ea110f2d 100644 --- a/packages/payment/src/loaders/container.ts +++ b/packages/payment/src/loaders/container.ts @@ -1,39 +1,10 @@ -import { LoaderOptions } from "@medusajs/modules-sdk" -import { ModulesSdkTypes } from "@medusajs/types" -import { loadCustomRepositories } from "@medusajs/utils" -import { asClass } from "awilix" +import { ModulesSdkUtils } from "@medusajs/utils" +import * as ModuleModels from "@models" +import * as ModuleRepositories from "@repositories" +import * as ModuleServices from "@services" -import * as defaultRepositories from "@repositories" -import * as defaultServices from "@services" - -export default async ({ - container, - options, -}: LoaderOptions< - | ModulesSdkTypes.ModuleServiceInitializeOptions - | ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions ->): Promise => { - const customRepositories = ( - options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions - )?.repositories - - container.register({ - // paymentService: asClass(defaultServices.PaymentService).singleton(), - }) - - if (customRepositories) { - loadCustomRepositories({ - defaultRepositories, - customRepositories, - container, - }) - } else { - loadDefaultRepositories({ container }) - } -} - -function loadDefaultRepositories({ container }) { - container.register({ - baseRepository: asClass(defaultRepositories.BaseRepository).singleton(), - }) -} +export default ModulesSdkUtils.moduleContainerLoaderFactory({ + moduleModels: ModuleModels, + moduleRepositories: ModuleRepositories, + moduleServices: ModuleServices, +}) diff --git a/packages/pricing/integration-tests/__tests__/services/currency/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/currency/index.spec.ts index 7b8a97c15b..33400946d4 100644 --- a/packages/pricing/integration-tests/__tests__/services/currency/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/currency/index.spec.ts @@ -1,11 +1,13 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" import { Currency } from "@models" -import { CurrencyRepository } from "@repositories" import { CurrencyService } from "@services" import { createCurrencies } from "../../../__fixtures__/currency" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -34,13 +36,12 @@ describe("Currency Service", () => { await MikroOrmWrapper.setupDatabase() repositoryManager = await MikroOrmWrapper.forkManager() - const currencyRepository = new CurrencyRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new CurrencyService({ - currencyRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("currencyService") testManager = await MikroOrmWrapper.forkManager() diff --git a/packages/pricing/integration-tests/__tests__/services/money-amount/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/money-amount/index.spec.ts index 849cba3c08..ae6a8cf2b6 100644 --- a/packages/pricing/integration-tests/__tests__/services/money-amount/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/money-amount/index.spec.ts @@ -1,12 +1,14 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" import { Currency, MoneyAmount } from "@models" -import { MoneyAmountRepository } from "@repositories" import { MoneyAmountService } from "@services" import { createCurrencies } from "../../../__fixtures__/currency" import { createMoneyAmounts } from "../../../__fixtures__/money-amount" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -21,13 +23,12 @@ describe("MoneyAmount Service", () => { await MikroOrmWrapper.setupDatabase() repositoryManager = await MikroOrmWrapper.forkManager() - const moneyAmountRepository = new MoneyAmountRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new MoneyAmountService({ - moneyAmountRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("moneyAmountService") testManager = await MikroOrmWrapper.forkManager() currencyData = await createCurrencies(testManager) diff --git a/packages/pricing/integration-tests/__tests__/services/price-list-rule/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/price-list-rule/index.spec.ts index ac96811798..f677a10fc0 100644 --- a/packages/pricing/integration-tests/__tests__/services/price-list-rule/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/price-list-rule/index.spec.ts @@ -1,12 +1,13 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" - -import { PriceListRuleRepository } from "@repositories" import { PriceListRuleService } from "@services" import { createPriceLists } from "../../../__fixtures__/price-list" import { createPriceListRules } from "../../../__fixtures__/price-list-rules" import { createRuleTypes } from "../../../__fixtures__/rule-type" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -19,13 +20,12 @@ describe("PriceListRule Service", () => { await MikroOrmWrapper.setupDatabase() repositoryManager = await MikroOrmWrapper.forkManager() - const priceListRuleRepository = new PriceListRuleRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new PriceListRuleService({ - priceListRuleRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("priceListRuleService") testManager = await MikroOrmWrapper.forkManager() await createRuleTypes(testManager) diff --git a/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts index eb729bf2ea..79c2985044 100644 --- a/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/price-list/index.spec.ts @@ -1,8 +1,10 @@ import { MikroOrmWrapper } from "../../../utils" -import { PriceListRepository } from "@repositories" import { PriceListService } from "@services" import { SqlEntityManager } from "@mikro-orm/postgresql" import { createPriceLists } from "../../../__fixtures__/price-list" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -15,13 +17,12 @@ describe("PriceList Service", () => { await MikroOrmWrapper.setupDatabase() repositoryManager = await MikroOrmWrapper.forkManager() - const priceListRepository = new PriceListRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new PriceListService({ - priceListRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("priceListService") testManager = await MikroOrmWrapper.forkManager() await createPriceLists(testManager) diff --git a/packages/pricing/integration-tests/__tests__/services/price-rule/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/price-rule/index.spec.ts index b917fbde9f..81c0eb3dff 100644 --- a/packages/pricing/integration-tests/__tests__/services/price-rule/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/price-rule/index.spec.ts @@ -2,7 +2,6 @@ import { PriceSetMoneyAmount } from "@models" import { CreatePriceRuleDTO } from "@medusajs/types" import { SqlEntityManager } from "@mikro-orm/postgresql" -import { PriceRuleRepository } from "@repositories" import { PriceRuleService } from "@services" import { createCurrencies } from "../../../__fixtures__/currency" import { createMoneyAmounts } from "../../../__fixtures__/money-amount" @@ -12,6 +11,9 @@ import { createPriceSetMoneyAmounts } from "../../../__fixtures__/price-set-mone import { createPriceSetMoneyAmountRules } from "../../../__fixtures__/price-set-money-amount-rules" import { createRuleTypes } from "../../../__fixtures__/rule-type" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -25,13 +27,13 @@ describe("PriceRule Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const priceRuleRepository = new PriceRuleRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) + + await ContainerLoader({ container }) + + service = container.resolve("priceRuleService") - service = new PriceRuleService({ - priceRuleRepository: priceRuleRepository, - }) await createCurrencies(testManager) await createMoneyAmounts(testManager) await createPriceSets(testManager) diff --git a/packages/pricing/integration-tests/__tests__/services/price-set-money-amonut-rules/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/price-set-money-amonut-rules/index.spec.ts index 246de82346..4c80f1a47c 100644 --- a/packages/pricing/integration-tests/__tests__/services/price-set-money-amonut-rules/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/price-set-money-amonut-rules/index.spec.ts @@ -1,10 +1,11 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" - -import { PriceSetMoneyAmountRulesRepository } from "@repositories" import { PriceSetMoneyAmountRulesService } from "@services" import { seedPriceData } from "../../../__fixtures__/seed-price-data" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -17,14 +18,12 @@ describe("PriceSetMoneyAmountRules Service", () => { await MikroOrmWrapper.setupDatabase() repositoryManager = await MikroOrmWrapper.forkManager() - const priceSetMoneyAmountRulesRepository = - new PriceSetMoneyAmountRulesRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new PriceSetMoneyAmountRulesService({ - priceSetMoneyAmountRulesRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("priceSetMoneyAmountRulesService") testManager = await MikroOrmWrapper.forkManager() diff --git a/packages/pricing/integration-tests/__tests__/services/price-set/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/price-set/index.spec.ts index 29ed3ffe07..70ef27e8b4 100644 --- a/packages/pricing/integration-tests/__tests__/services/price-set/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/price-set/index.spec.ts @@ -1,13 +1,15 @@ import { CreatePriceSetDTO } from "@medusajs/types" import { SqlEntityManager } from "@mikro-orm/postgresql" import { MoneyAmount, PriceSet } from "@models" -import { PriceSetRepository } from "@repositories" import { PriceSetService } from "@services" import { createCurrencies } from "../../../__fixtures__/currency" import { createMoneyAmounts } from "../../../__fixtures__/money-amount" import { createPriceSets } from "../../../__fixtures__/price-set" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -54,13 +56,12 @@ describe("PriceSet Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const priceSetRepository = new PriceSetRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new PriceSetService({ - priceSetRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("priceSetService") await createCurrencies(testManager) diff --git a/packages/pricing/integration-tests/__tests__/services/rule-type/index.spec.ts b/packages/pricing/integration-tests/__tests__/services/rule-type/index.spec.ts index 5a39254ef0..a2f038ee96 100644 --- a/packages/pricing/integration-tests/__tests__/services/rule-type/index.spec.ts +++ b/packages/pricing/integration-tests/__tests__/services/rule-type/index.spec.ts @@ -1,10 +1,11 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" - -import { RuleTypeRepository } from "@repositories" import { RuleTypeService } from "@services" import { createRuleTypes } from "../../../__fixtures__/rule-type" import { MikroOrmWrapper } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -17,13 +18,12 @@ describe("RuleType Service", () => { await MikroOrmWrapper.setupDatabase() repositoryManager = await MikroOrmWrapper.forkManager() - const ruleTypeRepository = new RuleTypeRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new RuleTypeService({ - ruleTypeRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("ruleTypeService") testManager = await MikroOrmWrapper.forkManager() diff --git a/packages/pricing/package.json b/packages/pricing/package.json index 5b635015d7..385ae1a665 100644 --- a/packages/pricing/package.json +++ b/packages/pricing/package.json @@ -11,8 +11,6 @@ "node": ">=16" }, "bin": { - "medusa-pricing-migrations-down": "dist/scripts/bin/run-migration-down.js", - "medusa-pricing-migrations-up": "dist/scripts/bin/run-migration-up.js", "medusa-pricing-seed": "dist/scripts/bin/run-seed.js" }, "repository": { diff --git a/packages/pricing/src/index.ts b/packages/pricing/src/index.ts index 45da1e739d..f4609139aa 100644 --- a/packages/pricing/src/index.ts +++ b/packages/pricing/src/index.ts @@ -1,8 +1,23 @@ import { moduleDefinition } from "./module-definition" +import { Modules } from "@medusajs/modules-sdk" +import * as Models from "@models" +import { ModulesSdkUtils } from "@medusajs/utils" export default moduleDefinition -export * from "./scripts" +const migrationScriptOptions = { + moduleName: Modules.PRICING, + models: Models, + pathToMigrations: __dirname + "/migrations", +} + +export const runMigrations = ModulesSdkUtils.buildMigrationScript( + migrationScriptOptions +) +export const revertMigration = ModulesSdkUtils.buildRevertMigrationScript( + migrationScriptOptions +) + export * from "./initialize" export * from "./types" export * from "./loaders" diff --git a/packages/pricing/src/loaders/container.ts b/packages/pricing/src/loaders/container.ts index 37ef7d0616..28ea110f2d 100644 --- a/packages/pricing/src/loaders/container.ts +++ b/packages/pricing/src/loaders/container.ts @@ -1,95 +1,10 @@ -import * as defaultRepositories from "@repositories" -import * as defaultServices from "@services" +import { ModulesSdkUtils } from "@medusajs/utils" +import * as ModuleModels from "@models" +import * as ModuleRepositories from "@repositories" +import * as ModuleServices from "@services" -import { LoaderOptions } from "@medusajs/modules-sdk" -import { ModulesSdkTypes } from "@medusajs/types" -import { loadCustomRepositories } from "@medusajs/utils" -import { asClass } from "awilix" - -export default async ({ - container, - options, -}: LoaderOptions< - | ModulesSdkTypes.ModuleServiceInitializeOptions - | ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions ->): Promise => { - const customRepositories = ( - options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions - )?.repositories - - container.register({ - currencyService: asClass(defaultServices.CurrencyService).singleton(), - moneyAmountService: asClass(defaultServices.MoneyAmountService).singleton(), - priceSetService: asClass(defaultServices.PriceSetService).singleton(), - ruleTypeService: asClass(defaultServices.RuleTypeService).singleton(), - priceSetMoneyAmountRulesService: asClass( - defaultServices.PriceSetMoneyAmountRulesService - ).singleton(), - priceRuleService: asClass(defaultServices.PriceRuleService).singleton(), - priceSetRuleTypeService: asClass( - defaultServices.PriceSetRuleTypeService - ).singleton(), - priceSetMoneyAmountService: asClass( - defaultServices.PriceSetMoneyAmountService - ).singleton(), - priceListService: asClass(defaultServices.PriceListService).singleton(), - priceListRuleService: asClass( - defaultServices.PriceListRuleService - ).singleton(), - priceListRuleValueService: asClass( - defaultServices.PriceListRuleValueService - ).singleton(), - }) - - if (customRepositories) { - loadCustomRepositories({ - defaultRepositories, - customRepositories, - container, - }) - } else { - loadDefaultRepositories({ container }) - } -} - -function loadDefaultRepositories({ container }) { - container.register({ - baseRepository: asClass(defaultRepositories.BaseRepository).singleton(), - pricingRepository: asClass( - defaultRepositories.PricingRepository - ).singleton(), - currencyRepository: asClass( - defaultRepositories.CurrencyRepository - ).singleton(), - moneyAmountRepository: asClass( - defaultRepositories.MoneyAmountRepository - ).singleton(), - priceSetRepository: asClass( - defaultRepositories.PriceSetRepository - ).singleton(), - ruleTypeRepository: asClass( - defaultRepositories.RuleTypeRepository - ).singleton(), - priceSetMoneyAmountRulesRepository: asClass( - defaultRepositories.PriceSetMoneyAmountRulesRepository - ).singleton(), - priceRuleRepository: asClass( - defaultRepositories.PriceRuleRepository - ).singleton(), - priceSetRuleTypeRepository: asClass( - defaultRepositories.PriceSetRuleTypeRepository - ).singleton(), - priceSetMoneyAmountRepository: asClass( - defaultRepositories.PriceSetMoneyAmountRepository - ).singleton(), - priceListRepository: asClass( - defaultRepositories.PriceListRepository - ).singleton(), - priceListRuleRepository: asClass( - defaultRepositories.PriceListRuleRepository - ).singleton(), - priceListRuleValueRepository: asClass( - defaultRepositories.PriceListRuleValueRepository - ).singleton(), - }) -} +export default ModulesSdkUtils.moduleContainerLoaderFactory({ + moduleModels: ModuleModels, + moduleRepositories: ModuleRepositories, + moduleServices: ModuleServices, +}) diff --git a/packages/pricing/src/repositories/currency.ts b/packages/pricing/src/repositories/currency.ts deleted file mode 100644 index 7a15ded16b..0000000000 --- a/packages/pricing/src/repositories/currency.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { Currency } from "@models" -import { RepositoryTypes } from "@types" - -export class CurrencyRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - Currency, - { - create: RepositoryTypes.CreateCurrencyDTO - update: RepositoryTypes.UpdateCurrencyDTO - } ->(Currency) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/repositories/index.ts b/packages/pricing/src/repositories/index.ts index 0cf8d09aae..2edee3deb2 100644 --- a/packages/pricing/src/repositories/index.ts +++ b/packages/pricing/src/repositories/index.ts @@ -1,13 +1,2 @@ export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils" -export { CurrencyRepository } from "./currency" -export { MoneyAmountRepository } from "./money-amount" -export { PriceListRepository } from "./price-list" -export { PriceListRuleRepository } from "./price-list-rule" -export { PriceListRuleValueRepository } from "./price-list-rule-value" -export { PriceRuleRepository } from "./price-rule" -export { PriceSetRepository } from "./price-set" -export { PriceSetMoneyAmountRepository } from "./price-set-money-amount" -export { PriceSetMoneyAmountRulesRepository } from "./price-set-money-amount-rules" -export { PriceSetRuleTypeRepository } from "./price-set-rule-type" export { PricingRepository } from "./pricing" -export { RuleTypeRepository } from "./rule-type" diff --git a/packages/pricing/src/repositories/money-amount.ts b/packages/pricing/src/repositories/money-amount.ts deleted file mode 100644 index c23c7fa070..0000000000 --- a/packages/pricing/src/repositories/money-amount.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { MoneyAmount } from "@models" -import { RepositoryTypes } from "@types" - -export class MoneyAmountRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - MoneyAmount, - { - create: RepositoryTypes.CreateMoneyAmountDTO - update: RepositoryTypes.UpdateMoneyAmountDTO - } ->(MoneyAmount) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/repositories/price-list-rule-value.ts b/packages/pricing/src/repositories/price-list-rule-value.ts deleted file mode 100644 index d1512834c0..0000000000 --- a/packages/pricing/src/repositories/price-list-rule-value.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Context } from "@medusajs/types" -import { DALUtils } from "@medusajs/utils" - -import { PriceListRuleValue } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceListRuleValueRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PriceListRuleValue, - { - update: RepositoryTypes.UpdatePriceListRuleValueDTO - } ->(PriceListRuleValue) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async create( - data: RepositoryTypes.CreatePriceListRuleValueDTO[], - context: Context = {} - ): Promise { - const priceListRuleValues = data.map((priceRuleValueData) => { - const { price_list_rule_id: priceListRuleId, ...priceRuleValue } = - priceRuleValueData - - if (priceListRuleId) { - priceRuleValue.price_list_rule = priceListRuleId - } - - return priceRuleValue - }) - - return await super.create(priceListRuleValues, context) - } -} diff --git a/packages/pricing/src/repositories/price-list-rule.ts b/packages/pricing/src/repositories/price-list-rule.ts deleted file mode 100644 index 481549f7ab..0000000000 --- a/packages/pricing/src/repositories/price-list-rule.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Context } from "@medusajs/types" -import { DALUtils } from "@medusajs/utils" - -import { PriceListRule } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceListRuleRepository extends DALUtils.mikroOrmBaseRepositoryFactory( - PriceListRule -) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async create( - data: RepositoryTypes.CreatePriceListRuleDTO[], - context: Context = {} - ): Promise { - const priceListRule = data.map((priceListRule) => { - const { - price_list_id: priceListId, - rule_type_id: ruleTypeId, - ...createData - } = priceListRule - - if (priceListId) { - createData.price_list = priceListId - } - - if (ruleTypeId) { - createData.rule_type = ruleTypeId - } - - return createData - }) - - return await super.create(priceListRule, context) - } - - async update( - data: RepositoryTypes.UpdatePriceListRuleDTO[], - context: Context = {} - ): Promise { - const priceListRules = data.map((priceListRule) => { - const { price_list_id, rule_type_id, ...priceListRuleData } = - priceListRule - - if (price_list_id) { - priceListRuleData.price_list = price_list_id - } - - if (rule_type_id) { - priceListRuleData.rule_type = rule_type_id - } - - return priceListRuleData - }) - - return await super.update(priceListRules, context) - } -} diff --git a/packages/pricing/src/repositories/price-list.ts b/packages/pricing/src/repositories/price-list.ts deleted file mode 100644 index e1db5946df..0000000000 --- a/packages/pricing/src/repositories/price-list.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Context } from "@medusajs/types" -import { DALUtils, GetIsoStringFromDate } from "@medusajs/utils" - -import { PriceList } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceListRepository extends DALUtils.mikroOrmBaseRepositoryFactory( - PriceList -) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async create( - data: RepositoryTypes.CreatePriceListDTO[], - context: Context = {} - ): Promise { - const priceLists = data.map((priceListData: any) => { - if (!!priceListData.starts_at) { - priceListData.starts_at = GetIsoStringFromDate(priceListData.starts_at) - } - - if (!!priceListData.ends_at) { - priceListData.ends_at = GetIsoStringFromDate(priceListData.ends_at) - } - - return priceListData - }) - - return await super.create(priceLists, context) - } - - async update( - data: RepositoryTypes.UpdatePriceListDTO[], - context: Context = {} - ): Promise { - const priceLists = data.map((priceListData: any) => { - if (!!priceListData.starts_at) { - priceListData.starts_at = GetIsoStringFromDate(priceListData.starts_at) - } - - if (!!priceListData.ends_at) { - priceListData.ends_at = GetIsoStringFromDate(priceListData.ends_at) - } - - return priceListData - }) - - return await super.update(priceLists, context) - } -} diff --git a/packages/pricing/src/repositories/price-rule.ts b/packages/pricing/src/repositories/price-rule.ts deleted file mode 100644 index ce6d41ee30..0000000000 --- a/packages/pricing/src/repositories/price-rule.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Context } from "@medusajs/types" -import { DALUtils } from "@medusajs/utils" - -import { PriceRule } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceRuleRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PriceRule, - { - update: RepositoryTypes.UpdatePriceRuleDTO - } ->(PriceRule) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async create( - data: RepositoryTypes.CreatePriceRuleDTO[], - context: Context = {} - ): Promise { - const toCreate = data.map((ruleData) => { - const ruleDataClone = { ...ruleData } as any - - ruleDataClone.rule_type ??= ruleData.rule_type_id - ruleDataClone.price_set ??= ruleData.price_set_id - ruleDataClone.price_set_money_amount ??= - ruleData.price_set_money_amount_id - - return ruleDataClone - }) - - return await super.create(toCreate, context) - } -} diff --git a/packages/pricing/src/repositories/price-set-money-amount-rules.ts b/packages/pricing/src/repositories/price-set-money-amount-rules.ts deleted file mode 100644 index 8577254b9f..0000000000 --- a/packages/pricing/src/repositories/price-set-money-amount-rules.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { PriceSetMoneyAmountRules } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceSetMoneyAmountRulesRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PriceSetMoneyAmountRules, - { - create: RepositoryTypes.CreatePriceSetMoneyAmountRulesDTO - update: RepositoryTypes.UpdatePriceSetMoneyAmountRulesDTO - } ->(PriceSetMoneyAmountRules) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/repositories/price-set-money-amount.ts b/packages/pricing/src/repositories/price-set-money-amount.ts deleted file mode 100644 index dde772edc6..0000000000 --- a/packages/pricing/src/repositories/price-set-money-amount.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { PriceSetMoneyAmount } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceSetMoneyAmountRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PriceSetMoneyAmount, - { - create: RepositoryTypes.CreatePriceSetMoneyAmountDTO - update: RepositoryTypes.UpdatePriceSetMoneyAmountDTO - } ->(PriceSetMoneyAmount) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/repositories/price-set-rule-type.ts b/packages/pricing/src/repositories/price-set-rule-type.ts deleted file mode 100644 index 9cffb54d7e..0000000000 --- a/packages/pricing/src/repositories/price-set-rule-type.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { PriceSetRuleType } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceSetRuleTypeRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PriceSetRuleType, - { - create: RepositoryTypes.CreatePriceSetRuleTypeDTO - update: RepositoryTypes.UpdatePriceSetRuleTypeDTO - } ->(PriceSetRuleType) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/repositories/price-set.ts b/packages/pricing/src/repositories/price-set.ts deleted file mode 100644 index 94cfe23065..0000000000 --- a/packages/pricing/src/repositories/price-set.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DALUtils } from "@medusajs/utils" - -import { PriceSet } from "@models" -import { RepositoryTypes } from "@types" - -export class PriceSetRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PriceSet, - { - create: RepositoryTypes.CreatePriceSetDTO - update: RepositoryTypes.UpdatePriceSetDTO - } ->(PriceSet) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/repositories/rule-type.ts b/packages/pricing/src/repositories/rule-type.ts deleted file mode 100644 index 21d9f3d4f1..0000000000 --- a/packages/pricing/src/repositories/rule-type.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { RuleType } from "@models" -import { RepositoryTypes } from "@types" - -export class RuleTypeRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - RuleType, - { - create: RepositoryTypes.CreateRuleTypeDTO - update: RepositoryTypes.UpdateRuleTypeDTO - } ->(RuleType) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/pricing/src/scripts/bin/run-migration-down.ts b/packages/pricing/src/scripts/bin/run-migration-down.ts deleted file mode 100644 index e352048fd4..0000000000 --- a/packages/pricing/src/scripts/bin/run-migration-down.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { revertMigration } = await import("../migration-down") - const { config } = await import("dotenv") - config() - await revertMigration() -})() diff --git a/packages/pricing/src/scripts/bin/run-migration-up.ts b/packages/pricing/src/scripts/bin/run-migration-up.ts deleted file mode 100644 index 35f3bee853..0000000000 --- a/packages/pricing/src/scripts/bin/run-migration-up.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { runMigrations } = await import("../migration-up") - const { config } = await import("dotenv") - config() - await runMigrations() -})() diff --git a/packages/pricing/src/scripts/index.ts b/packages/pricing/src/scripts/index.ts deleted file mode 100644 index cfa5c5ddf5..0000000000 --- a/packages/pricing/src/scripts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./migration-up" -export * from "./migration-down" diff --git a/packages/pricing/src/scripts/migration-down.ts b/packages/pricing/src/scripts/migration-down.ts deleted file mode 100644 index 5b9eff8f13..0000000000 --- a/packages/pricing/src/scripts/migration-down.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as PricingModels from "@models" - -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types" - -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils" -import { EntitySchema } from "@mikro-orm/core" - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of reverting the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function revertMigration({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig("pricing", options)! - const entities = Object.values(PricingModels) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - await migrator.down() - - logger?.info("Pricing module migration executed") - } catch (error) { - logger?.error(`Pricing module migration failed to run - Error: ${error}`) - } - - await orm.close() -} diff --git a/packages/pricing/src/scripts/migration-up.ts b/packages/pricing/src/scripts/migration-up.ts deleted file mode 100644 index adf128bed5..0000000000 --- a/packages/pricing/src/scripts/migration-up.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types" -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils" -import { EntitySchema } from "@mikro-orm/core" -import * as PricingModels from "@models" - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of running the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function runMigrations({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig("pricing", options)! - const entities = Object.values(PricingModels) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - - const pendingMigrations = await migrator.getPendingMigrations() - logger.info( - `Running pending migrations: ${JSON.stringify( - pendingMigrations, - null, - 2 - )}` - ) - - await migrator.up({ - migrations: pendingMigrations.map((m) => m.name), - }) - - logger.info("Pricing module migration executed") - } catch (error) { - logger.error(`Pricing module migration failed to run - Error: ${error}`) - } - - await orm.close() -} diff --git a/packages/pricing/src/services/currency.ts b/packages/pricing/src/services/currency.ts index 4477da7588..d7df5abda4 100644 --- a/packages/pricing/src/services/currency.ts +++ b/packages/pricing/src/services/currency.ts @@ -16,7 +16,7 @@ export default class CurrencyService< update: ServiceTypes.UpdateCurrencyDTO } >(Currency) { - constructor({ currencyRepository }: InjectedDependencies) { + constructor(container: InjectedDependencies) { // @ts-ignore super(...arguments) } diff --git a/packages/pricing/src/services/price-list-rule-value.ts b/packages/pricing/src/services/price-list-rule-value.ts index d7ee43653a..10b5cc9ed3 100644 --- a/packages/pricing/src/services/price-list-rule-value.ts +++ b/packages/pricing/src/services/price-list-rule-value.ts @@ -1,4 +1,4 @@ -import { DAL } from "@medusajs/types" +import { Context, DAL } from "@medusajs/types" import { ModulesSdkUtils } from "@medusajs/utils" import { PriceListRuleValue } from "@models" import { ServiceTypes } from "@types" @@ -12,7 +12,6 @@ export default class PriceListRuleValueService< > extends ModulesSdkUtils.abstractServiceFactory< InjectedDependencies, { - create: ServiceTypes.CreatePriceListRuleValueDTO update: ServiceTypes.UpdatePriceListRuleValueDTO }, { @@ -24,4 +23,22 @@ export default class PriceListRuleValueService< // @ts-ignore super(...arguments) } + + async create( + data: ServiceTypes.CreatePriceListRuleValueDTO[], + context: Context = {} + ): Promise { + const priceListRuleValues = data.map((priceRuleValueData) => { + const { price_list_rule_id: priceListRuleId, ...priceRuleValue } = + priceRuleValueData + + if (priceListRuleId) { + priceRuleValue.price_list_rule = priceListRuleId + } + + return priceRuleValue + }) + + return await super.create(priceListRuleValues, context) + } } diff --git a/packages/pricing/src/services/price-list-rule.ts b/packages/pricing/src/services/price-list-rule.ts index c1f1fc0366..cb9ddb7487 100644 --- a/packages/pricing/src/services/price-list-rule.ts +++ b/packages/pricing/src/services/price-list-rule.ts @@ -1,4 +1,4 @@ -import { DAL } from "@medusajs/types" +import { Context, DAL } from "@medusajs/types" import { ModulesSdkUtils } from "@medusajs/utils" import { PriceListRule } from "@models" import { ServiceTypes } from "@types" @@ -24,4 +24,51 @@ export default class PriceListRuleService< // @ts-ignore super(...arguments) } + + async create( + data: ServiceTypes.CreatePriceListRuleDTO[], + context: Context = {} + ): Promise { + const priceListRule = data.map((priceListRule) => { + const { + price_list_id: priceListId, + rule_type_id: ruleTypeId, + ...createData + } = priceListRule + + if (priceListId) { + createData.price_list = priceListId + } + + if (ruleTypeId) { + createData.rule_type = ruleTypeId + } + + return createData + }) + + return await super.create(priceListRule, context) + } + + async update( + data: ServiceTypes.UpdatePriceListRuleDTO[], + context: Context = {} + ): Promise { + const priceListRules = data.map((priceListRule) => { + const { price_list_id, rule_type_id, ...priceListRuleData } = + priceListRule + + if (price_list_id) { + priceListRuleData.price_list = price_list_id + } + + if (rule_type_id) { + priceListRuleData.rule_type = rule_type_id + } + + return priceListRuleData + }) + + return await super.update(priceListRules, context) + } } diff --git a/packages/pricing/src/services/price-list.ts b/packages/pricing/src/services/price-list.ts index e4fccad003..c5ddc99398 100644 --- a/packages/pricing/src/services/price-list.ts +++ b/packages/pricing/src/services/price-list.ts @@ -1,5 +1,5 @@ -import { DAL } from "@medusajs/types" -import { ModulesSdkUtils } from "@medusajs/utils" +import { Context, DAL } from "@medusajs/types" +import { GetIsoStringFromDate, ModulesSdkUtils } from "@medusajs/utils" import { PriceList } from "@models" import { ServiceTypes } from "@types" @@ -11,10 +11,7 @@ export default class PriceListService< TEntity extends PriceList = PriceList > extends ModulesSdkUtils.abstractServiceFactory< InjectedDependencies, - { - create: ServiceTypes.CreatePriceListDTO - update: ServiceTypes.UpdatePriceListDTO - }, + {}, { list: ServiceTypes.FilterablePriceListProps listAndCount: ServiceTypes.FilterablePriceListProps @@ -24,4 +21,36 @@ export default class PriceListService< // @ts-ignore super(...arguments) } + + async create( + data: ServiceTypes.CreatePriceListDTO[], + sharedContext?: Context + ): Promise { + const priceLists = this.normalizePriceListDate(data) + return await super.create(priceLists, sharedContext) + } + + async update( + data: ServiceTypes.UpdatePriceListDTO[], + sharedContext?: Context + ): Promise { + const priceLists = this.normalizePriceListDate(data) + return await super.update(priceLists, sharedContext) + } + + protected normalizePriceListDate( + data: (ServiceTypes.UpdatePriceListDTO | ServiceTypes.CreatePriceListDTO)[] + ) { + return data.map((priceListData: any) => { + if (!!priceListData.starts_at) { + priceListData.starts_at = GetIsoStringFromDate(priceListData.starts_at) + } + + if (!!priceListData.ends_at) { + priceListData.ends_at = GetIsoStringFromDate(priceListData.ends_at) + } + + return priceListData + }) + } } diff --git a/packages/pricing/src/services/price-rule.ts b/packages/pricing/src/services/price-rule.ts index eb9ab85730..1c3f365e5c 100644 --- a/packages/pricing/src/services/price-rule.ts +++ b/packages/pricing/src/services/price-rule.ts @@ -1,4 +1,4 @@ -import { DAL } from "@medusajs/types" +import { Context, DAL } from "@medusajs/types" import { ModulesSdkUtils } from "@medusajs/utils" import { PriceRule } from "@models" @@ -13,7 +13,6 @@ export default class PriceRuleService< > extends ModulesSdkUtils.abstractServiceFactory< InjectedDependencies, { - create: ServiceTypes.CreatePriceRuleDTO update: ServiceTypes.UpdatePriceRuleDTO }, { @@ -25,4 +24,22 @@ export default class PriceRuleService< // @ts-ignore super(...arguments) } + + async create( + data: ServiceTypes.CreatePriceRuleDTO[], + sharedContext?: Context + ): Promise { + const toCreate = data.map((ruleData) => { + const ruleDataClone = { ...ruleData } as any + + ruleDataClone.rule_type ??= ruleData.rule_type_id + ruleDataClone.price_set ??= ruleData.price_set_id + ruleDataClone.price_set_money_amount ??= + ruleData.price_set_money_amount_id + + return ruleDataClone + }) + + return await super.create(toCreate, sharedContext) + } } diff --git a/packages/pricing/src/services/price-set-money-amount-rules.ts b/packages/pricing/src/services/price-set-money-amount-rules.ts index ec073c342c..a1915770cf 100644 --- a/packages/pricing/src/services/price-set-money-amount-rules.ts +++ b/packages/pricing/src/services/price-set-money-amount-rules.ts @@ -14,6 +14,10 @@ export default class PriceSetMoneyAmountRulesService< { create: ServiceTypes.CreatePriceSetMoneyAmountRulesDTO update: ServiceTypes.UpdatePriceSetMoneyAmountRulesDTO + }, + { + list: ServiceTypes.FilterablePriceSetMoneyAmountRulesProps + listAndCount: ServiceTypes.FilterablePriceSetMoneyAmountRulesProps } >(PriceSetMoneyAmountRules) { constructor({ priceSetMoneyAmountRulesRepository }: InjectedDependencies) { diff --git a/packages/pricing/src/services/price-set-money-amount.ts b/packages/pricing/src/services/price-set-money-amount.ts index 569cfb5eee..78644213d6 100644 --- a/packages/pricing/src/services/price-set-money-amount.ts +++ b/packages/pricing/src/services/price-set-money-amount.ts @@ -1,5 +1,5 @@ -import { Context, DAL, FindConfig } from "@medusajs/types" -import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" +import { DAL } from "@medusajs/types" +import { ModulesSdkUtils } from "@medusajs/utils" import { PriceSetMoneyAmount } from "@models" import { ServiceTypes } from "@types" @@ -14,46 +14,14 @@ export default class PriceSetMoneyAmountService< { create: ServiceTypes.CreatePriceSetMoneyAmountDTO update: ServiceTypes.UpdatePriceSetMoneyAmountDTO + }, + { + list: ServiceTypes.FilterablePriceSetMoneyAmountProps + listAndCount: ServiceTypes.FilterablePriceSetMoneyAmountProps } >(PriceSetMoneyAmount) { - protected readonly priceSetMoneyAmountRepository_: DAL.RepositoryService - - constructor({ priceSetMoneyAmountRepository }: InjectedDependencies) { + constructor(container: InjectedDependencies) { // @ts-ignore super(...arguments) - this.priceSetMoneyAmountRepository_ = priceSetMoneyAmountRepository - } - - @InjectManager("priceSetMoneyAmountRepository_") - async list( - filters: ServiceTypes.FilterablePriceSetMoneyAmountProps = {}, - config: FindConfig = {}, - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.priceSetMoneyAmountRepository_.find( - this.buildQueryForList(filters, config), - sharedContext - ) - } - - @InjectManager("priceSetMoneyAmountRepository_") - async listAndCount( - filters: ServiceTypes.FilterablePriceSetMoneyAmountProps = {}, - config: FindConfig = {}, - @MedusaContext() sharedContext: Context = {} - ): Promise<[TEntity[], number]> { - return await this.priceSetMoneyAmountRepository_.findAndCount( - this.buildQueryForList(filters, config), - sharedContext - ) - } - - private buildQueryForList< - TEntityMethod = ServiceTypes.PriceSetMoneyAmountDTO - >( - filters: ServiceTypes.FilterablePriceSetMoneyAmountProps = {}, - config: FindConfig = {} - ) { - return ModulesSdkUtils.buildQuery(filters, config) } } diff --git a/packages/pricing/src/services/price-set-rule-type.ts b/packages/pricing/src/services/price-set-rule-type.ts index 27fa9e4b25..452050ebd6 100644 --- a/packages/pricing/src/services/price-set-rule-type.ts +++ b/packages/pricing/src/services/price-set-rule-type.ts @@ -1,5 +1,5 @@ -import { Context, DAL, FindConfig } from "@medusajs/types" -import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" +import { DAL } from "@medusajs/types" +import { ModulesSdkUtils } from "@medusajs/utils" import { PriceSetRuleType } from "@models" import { ServiceTypes } from "@types" @@ -14,46 +14,14 @@ export default class PriceSetRuleTypeService< { create: ServiceTypes.CreatePriceSetRuleTypeDTO update: ServiceTypes.UpdatePriceSetRuleTypeDTO + }, + { + list: ServiceTypes.FilterablePriceSetRuleTypeProps + listAndCount: ServiceTypes.FilterablePriceSetRuleTypeProps } >(PriceSetRuleType) { - protected readonly priceSetRuleTypeRepository_: DAL.RepositoryService - - constructor({ priceSetRuleTypeRepository }: InjectedDependencies) { + constructor(container: InjectedDependencies) { // @ts-ignore super(...arguments) - this.priceSetRuleTypeRepository_ = priceSetRuleTypeRepository - } - - @InjectManager("priceSetRuleTypeRepository_") - async list( - filters: ServiceTypes.FilterablePriceSetRuleTypeProps = {}, - config: FindConfig = {}, - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.priceSetRuleTypeRepository_.find( - this.buildQueryForList(filters, config), - sharedContext - ) - } - - @InjectManager("priceSetRuleTypeRepository_") - async listAndCount( - filters: ServiceTypes.FilterablePriceSetRuleTypeProps = {}, - config: FindConfig = {}, - @MedusaContext() sharedContext: Context = {} - ): Promise<[TEntity[], number]> { - return await this.priceSetRuleTypeRepository_.findAndCount( - this.buildQueryForList(filters, config), - sharedContext - ) - } - - private buildQueryForList< - TEntityMethod = ServiceTypes.PriceSetMoneyAmountDTO - >( - filters: ServiceTypes.FilterablePriceSetRuleTypeProps = {}, - config: FindConfig = {} - ) { - return ModulesSdkUtils.buildQuery(filters, config) } } diff --git a/packages/pricing/src/types/repositories/index.ts b/packages/pricing/src/types/repositories/index.ts index a1e262b975..117d7bda46 100644 --- a/packages/pricing/src/types/repositories/index.ts +++ b/packages/pricing/src/types/repositories/index.ts @@ -1,3 +1,44 @@ +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 "./money-amount" export * from "./price-list-rule-value" @@ -9,3 +50,119 @@ export * from "./price-set-money-amount" export * from "./price-set-rule-type" export * from "./price-set" export * from "./rule-type" + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ICurrencyRepository + 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 + extends DAL.RepositoryService< + TEntity, + { + create: CreatePriceListDTO + update: UpdatePriceListDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IPriceRuleRepository + 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 + extends DAL.RepositoryService< + TEntity, + { + create: CreatePriceSetDTO + update: UpdatePriceSetDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IRuleTypeRepository + extends DAL.RepositoryService< + TEntity, + { + create: CreateRuleTypeDTO + update: UpdateRuleTypeDTO + } + > {} diff --git a/packages/product/integration-tests/__tests__/services/product-category/index.ts b/packages/product/integration-tests/__tests__/services/product-category/index.ts index 483c7bbe32..a9d0ae6922 100644 --- a/packages/product/integration-tests/__tests__/services/product-category/index.ts +++ b/packages/product/integration-tests/__tests__/services/product-category/index.ts @@ -1,12 +1,17 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" import { ProductCategory } from "@models" -import { ProductCategoryRepository } from "@repositories" import { ProductCategoryService } from "@services" import { createProductCategories } from "../../../__fixtures__/product-category" -import { productCategoriesData, productCategoriesRankData } from "../../../__fixtures__/product-category/data" +import { + productCategoriesData, + productCategoriesRankData, +} from "../../../__fixtures__/product-category/data" import { TestDatabase } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -20,13 +25,12 @@ describe("Product category Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productCategoryRepository = new ProductCategoryRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new ProductCategoryService({ - productCategoryRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productCategoryService") }) afterEach(async () => { @@ -244,13 +248,11 @@ describe("Product category Service", () => { }) it("should return category for the given id", async () => { - const productCategoryResults = await service.retrieve( - categoryOneId, - ) + const productCategoryResults = await service.retrieve(categoryOneId) expect(productCategoryResults).toEqual( expect.objectContaining({ - id: categoryOneId + id: categoryOneId, }) ) }) @@ -264,7 +266,9 @@ describe("Product category Service", () => { error = e } - expect(error.message).toEqual('ProductCategory with id: does-not-exist was not found') + expect(error.message).toEqual( + "ProductCategory with id: does-not-exist was not found" + ) }) it("should throw an error when an id is not provided", async () => { @@ -280,44 +284,38 @@ describe("Product category Service", () => { }) it("should return category based on config select param", async () => { - const productCategoryResults = await service.retrieve( - categoryOneId, - { - select: ["id", "parent_category_id"], - } - ) + const productCategoryResults = await service.retrieve(categoryOneId, { + select: ["id", "parent_category_id"], + }) expect(productCategoryResults).toEqual( expect.objectContaining({ - id: categoryOneId, + id: categoryOneId, parent_category_id: "category-0", }) ) }) it("should return category based on config relation param", async () => { - const productCategoryResults = await service.retrieve( - categoryOneId, - { - select: ["id", "parent_category_id"], - relations: ["parent_category"] - } - ) + const productCategoryResults = await service.retrieve(categoryOneId, { + select: ["id", "parent_category_id"], + relations: ["parent_category"], + }) expect(productCategoryResults).toEqual( expect.objectContaining({ - id: categoryOneId, + id: categoryOneId, category_children: [ expect.objectContaining({ - id: 'category-1-a', + id: "category-1-a", }), expect.objectContaining({ - id: 'category-1-b', - }) + id: "category-1-b", + }), ], parent_category: expect.objectContaining({ - id: "category-0" - }) + id: "category-0", + }), }) ) }) @@ -352,7 +350,7 @@ describe("Product category Service", () => { {}, { take: 1, - skip: 1 + skip: 1, } ) @@ -377,7 +375,7 @@ describe("Product category Service", () => { expect(productCategoryResults[0]).toEqual([ expect.objectContaining({ id: "category-0", - parent_category: null + parent_category: null, }), expect.objectContaining({ id: "category-1", @@ -568,11 +566,14 @@ describe("Product category Service", () => { parent_category_id: null, }) - const [productCategory] = await service.list({ - name: "New Category" - }, { - select: ["name", "rank"] - }) + const [productCategory] = await service.list( + { + name: "New Category", + }, + { + select: ["name", "rank"], + } + ) expect(productCategory).toEqual( expect.objectContaining({ @@ -586,7 +587,7 @@ describe("Product category Service", () => { await service.create({ name: "New Category", parent_category_id: null, - rank: 0 + rank: 0, }) await service.create({ @@ -594,11 +595,14 @@ describe("Product category Service", () => { parent_category_id: null, }) - const [productCategoryNew] = await service.list({ - name: "New Category 2" - }, { - select: ["name", "rank"] - }) + const [productCategoryNew] = await service.list( + { + name: "New Category 2", + }, + { + select: ["name", "rank"], + } + ) expect(productCategoryNew).toEqual( expect.objectContaining({ @@ -612,11 +616,14 @@ describe("Product category Service", () => { parent_category_id: productCategoryNew.id, }) - const [productCategoryWithParent] = await service.list({ - name: "New Category 2.1" - }, { - select: ["name", "rank", "parent_category_id"] - }) + const [productCategoryWithParent] = await service.list( + { + name: "New Category 2.1", + }, + { + select: ["name", "rank", "parent_category_id"], + } + ) expect(productCategoryWithParent).toEqual( expect.objectContaining({ @@ -655,11 +662,11 @@ describe("Product category Service", () => { it("should update the name of the category successfully", async () => { await service.update(productCategoryZero.id, { - name: "New Category" + name: "New Category", }) const productCategory = await service.retrieve(productCategoryZero.id, { - select: ["name"] + select: ["name"], }) expect(productCategory.name).toEqual("New Category") @@ -670,13 +677,15 @@ describe("Product category Service", () => { try { await service.update("does-not-exist", { - name: "New Category" + name: "New Category", }) } catch (e) { error = e } - expect(error.message).toEqual(`ProductCategory not found ({ id: 'does-not-exist' })`) + expect(error.message).toEqual( + `ProductCategory not found ({ id: 'does-not-exist' })` + ) }) it("should reorder rank successfully in the same parent", async () => { @@ -684,11 +693,14 @@ describe("Product category Service", () => { rank: 0, }) - const productCategories = await service.list({ - parent_category_id: null - }, { - select: ["name", "rank"] - }) + const productCategories = await service.list( + { + parent_category_id: null, + }, + { + select: ["name", "rank"], + } + ) expect(productCategories).toEqual( expect.arrayContaining([ @@ -703,7 +715,7 @@ describe("Product category Service", () => { expect.objectContaining({ id: productCategoryOne.id, rank: "2", - }) + }), ]) ) }) @@ -711,14 +723,17 @@ describe("Product category Service", () => { it("should reorder rank successfully when changing parent", async () => { await service.update(productCategoryTwo.id, { rank: 0, - parent_category_id: productCategoryZero.id + parent_category_id: productCategoryZero.id, }) - const productCategories = await service.list({ - parent_category_id: productCategoryZero.id - }, { - select: ["name", "rank"] - }) + const productCategories = await service.list( + { + parent_category_id: productCategoryZero.id, + }, + { + select: ["name", "rank"], + } + ) expect(productCategories).toEqual( expect.arrayContaining([ @@ -737,7 +752,7 @@ describe("Product category Service", () => { expect.objectContaining({ id: productCategoryZeroTwo.id, rank: "3", - }) + }), ]) ) }) @@ -745,14 +760,17 @@ describe("Product category Service", () => { it("should reorder rank successfully when changing parent and in first position", async () => { await service.update(productCategoryTwo.id, { rank: 0, - parent_category_id: productCategoryZero.id + parent_category_id: productCategoryZero.id, }) - const productCategories = await service.list({ - parent_category_id: productCategoryZero.id - }, { - select: ["name", "rank"] - }) + const productCategories = await service.list( + { + parent_category_id: productCategoryZero.id, + }, + { + select: ["name", "rank"], + } + ) expect(productCategories).toEqual( expect.arrayContaining([ @@ -771,7 +789,7 @@ describe("Product category Service", () => { expect.objectContaining({ id: productCategoryZeroTwo.id, rank: "3", - }) + }), ]) ) }) @@ -805,7 +823,9 @@ describe("Product category Service", () => { error = e } - expect(error.message).toEqual(`ProductCategory not found ({ id: 'does-not-exist' })`) + expect(error.message).toEqual( + `ProductCategory not found ({ id: 'does-not-exist' })` + ) }) it("should throw an error when it has children", async () => { @@ -817,17 +837,22 @@ describe("Product category Service", () => { error = e } - expect(error.message).toEqual(`Deleting ProductCategory (category-0-0) with category children is not allowed`) + expect(error.message).toEqual( + `Deleting ProductCategory (category-0-0) with category children is not allowed` + ) }) it("should reorder siblings rank successfully on deleting", async () => { await service.delete(productCategoryOne.id) - const productCategories = await service.list({ - parent_category_id: null - }, { - select: ["id", "rank"] - }) + const productCategories = await service.list( + { + parent_category_id: null, + }, + { + select: ["id", "rank"], + } + ) expect(productCategories).toEqual( expect.arrayContaining([ @@ -838,7 +863,7 @@ describe("Product category Service", () => { expect.objectContaining({ id: productCategoryTwo.id, rank: "1", - }) + }), ]) ) }) diff --git a/packages/product/integration-tests/__tests__/services/product-collection/index.ts b/packages/product/integration-tests/__tests__/services/product-collection/index.ts index 31a29c06d0..98dc40be6c 100644 --- a/packages/product/integration-tests/__tests__/services/product-collection/index.ts +++ b/packages/product/integration-tests/__tests__/services/product-collection/index.ts @@ -1,11 +1,13 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" import { ProductCollection } from "@models" -import { ProductCollectionRepository } from "@repositories" import { ProductCollectionService } from "@services" import { createCollections } from "../../../__fixtures__/product" import { TestDatabase } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -19,13 +21,12 @@ describe("Product collection Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productCollectionRepository = new ProductCollectionRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new ProductCollectionService({ - productCollectionRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productCollectionService") }) afterEach(async () => { @@ -93,7 +94,9 @@ describe("Product collection Service", () => { }) it("list product collections by title matching string", async () => { - const productCollectionResults = await service.list({ title: "col 3 extra" }) + const productCollectionResults = await service.list({ + title: "col 3 extra", + }) expect(productCollectionResults).toEqual([ expect.objectContaining({ @@ -155,7 +158,9 @@ describe("Product collection Service", () => { }) it("should return count and collections based on filter data", async () => { - const [productCollectionResults, count] = await service.listAndCount({ id: data![0].id }) + const [productCollectionResults, count] = await service.listAndCount({ + id: data![0].id, + }) const serialized = JSON.parse(JSON.stringify(productCollectionResults)) expect(count).toEqual(1) @@ -168,12 +173,15 @@ describe("Product collection Service", () => { }) it("should return count and collections based on config data", async () => { - const [productCollectionResults, count] = await service.listAndCount({}, { - relations: ['products'], - select: ['title'], - take: 1, - skip: 1, - }) + const [productCollectionResults, count] = await service.listAndCount( + {}, + { + relations: ["products"], + select: ["title"], + take: 1, + skip: 1, + } + ) const serialized = JSON.parse(JSON.stringify(productCollectionResults)) expect(count).toEqual(4) @@ -181,7 +189,7 @@ describe("Product collection Service", () => { { id: "test-2", title: "col 2", - products: [] + products: [], }, ]) }) @@ -200,13 +208,11 @@ describe("Product collection Service", () => { }) it("should return collection for the given id", async () => { - const productCollectionResults = await service.retrieve( - collectionData.id, - ) + const productCollectionResults = await service.retrieve(collectionData.id) expect(productCollectionResults).toEqual( expect.objectContaining({ - id: collectionData.id + id: collectionData.id, }) ) }) @@ -220,7 +226,9 @@ describe("Product collection Service", () => { error = e } - expect(error.message).toEqual('ProductCollection with id: does-not-exist was not found') + expect(error.message).toEqual( + "ProductCollection with id: does-not-exist was not found" + ) }) it("should throw an error when an id is not provided", async () => { @@ -245,12 +253,10 @@ describe("Product collection Service", () => { const serialized = JSON.parse(JSON.stringify(productCollectionResults)) - expect(serialized).toEqual( - { - id: collectionData.id, - title: collectionData.title, - } - ) + expect(serialized).toEqual({ + id: collectionData.id, + title: collectionData.title, + }) }) it("should return collection based on config relation param", async () => { @@ -258,19 +264,17 @@ describe("Product collection Service", () => { collectionData.id, { select: ["id", "title"], - relations: ["products"] + relations: ["products"], } ) const serialized = JSON.parse(JSON.stringify(productCollectionResults)) - expect(serialized).toEqual( - { - id: collectionData.id, - title: collectionData.title, - products: [] - } - ) + expect(serialized).toEqual({ + id: collectionData.id, + title: collectionData.title, + products: [], + }) }) }) @@ -288,12 +292,10 @@ describe("Product collection Service", () => { }) it("should delete the product collection given an ID successfully", async () => { - await service.delete( - [collectionId], - ) + await service.delete([collectionId]) const collections = await service.list({ - id: collectionId + id: collectionId, }) expect(collections).toHaveLength(0) @@ -314,12 +316,12 @@ describe("Product collection Service", () => { }) it("should update the value of the collection successfully", async () => { - await service.update( - [{ + await service.update([ + { id: collectionId, - title: "New Collection" - }] - ) + title: "New Collection", + }, + ]) const productCollection = await service.retrieve(collectionId) @@ -331,29 +333,31 @@ describe("Product collection Service", () => { try { await service.update([ - { - id: "does-not-exist", - title: "New Collection" - } - ]) + { + id: "does-not-exist", + title: "New Collection", + }, + ]) } catch (e) { error = e } - expect(error.message).toEqual('ProductCollection with id "does-not-exist" not found') + expect(error.message).toEqual( + 'ProductCollection with id "does-not-exist" not found' + ) }) }) describe("create", () => { it("should create a collection successfully", async () => { - await service.create( - [{ - title: "New Collection" - }] - ) + await service.create([ + { + title: "New Collection", + }, + ]) const [productCollection] = await service.list({ - title: "New Collection" + title: "New Collection", }) expect(productCollection.title).toEqual("New Collection") diff --git a/packages/product/integration-tests/__tests__/services/product-option/index.ts b/packages/product/integration-tests/__tests__/services/product-option/index.ts index 61f552c292..3c0a26c0e4 100644 --- a/packages/product/integration-tests/__tests__/services/product-option/index.ts +++ b/packages/product/integration-tests/__tests__/services/product-option/index.ts @@ -1,12 +1,14 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" import { ProductOptionService } from "@services" -import { ProductOptionRepository } from "@repositories" import { Product } from "@models" import { TestDatabase } from "../../../utils" import { createOptions } from "../../../__fixtures__/product" import { ProductTypes } from "@medusajs/types" +import { asValue } from "awilix" +import { createMedusaContainer } from "@medusajs/utils" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -34,13 +36,12 @@ describe("ProductOption Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productOptionRepository = new ProductOptionRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new ProductOptionService({ - productOptionRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productOptionService") testManager = await TestDatabase.forkManager() productOne = testManager.create(Product, productOneData) diff --git a/packages/product/integration-tests/__tests__/services/product-tag/index.ts b/packages/product/integration-tests/__tests__/services/product-tag/index.ts index aed57e8951..c0a6ebe557 100644 --- a/packages/product/integration-tests/__tests__/services/product-tag/index.ts +++ b/packages/product/integration-tests/__tests__/services/product-tag/index.ts @@ -1,12 +1,14 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" import { Product } from "@models" -import { ProductTagRepository } from "@repositories" import { ProductTagService } from "@services" import { ProductTypes } from "@medusajs/types" import { createProductAndTags } from "../../../__fixtures__/product" import { TestDatabase } from "../../../utils" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -53,13 +55,12 @@ describe("ProductTag Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productTagRepository = new ProductTagRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new ProductTagService({ - productTagRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productTagService") testManager = await TestDatabase.forkManager() @@ -143,7 +144,9 @@ describe("ProductTag Service", () => { }) it("should return product tags and count when filtered", async () => { - const [tagsResults, count] = await service.listAndCount({ id: data[0].tags![0].id }) + const [tagsResults, count] = await service.listAndCount({ + id: data[0].tags![0].id, + }) expect(count).toEqual(1) expect(tagsResults).toEqual([ @@ -154,7 +157,10 @@ describe("ProductTag Service", () => { }) it("should return product tags and count when using skip and take", async () => { - const [tagsResults, count] = await service.listAndCount({}, { skip: 1, take: 2 }) + const [tagsResults, count] = await service.listAndCount( + {}, + { skip: 1, take: 2 } + ) expect(count).toEqual(4) expect(tagsResults).toEqual([ @@ -168,11 +174,14 @@ describe("ProductTag Service", () => { }) it("should return requested fields and relations", async () => { - const [tagsResults, count] = await service.listAndCount({}, { - take: 1, - select: ["value", "products.id"], - relations: ["products"] - }) + const [tagsResults, count] = await service.listAndCount( + {}, + { + take: 1, + select: ["value", "products.id"], + relations: ["products"], + } + ) const serialized = JSON.parse(JSON.stringify(tagsResults)) @@ -180,9 +189,11 @@ describe("ProductTag Service", () => { expect(serialized).toEqual([ expect.objectContaining({ id: "tag-1", - products: [{ - id: "test-1" - }] + products: [ + { + id: "test-1", + }, + ], }), ]) }) @@ -194,13 +205,11 @@ describe("ProductTag Service", () => { const productId = "test-1" it("should return tag for the given id", async () => { - const tag = await service.retrieve( - tagId, - ) + const tag = await service.retrieve(tagId) expect(tag).toEqual( expect.objectContaining({ - id: tagId + id: tagId, }) ) }) @@ -214,7 +223,9 @@ describe("ProductTag Service", () => { error = e } - expect(error.message).toEqual('ProductTag with id: does-not-exist was not found') + expect(error.message).toEqual( + "ProductTag with id: does-not-exist was not found" + ) }) it("should throw an error when an id is not provided", async () => { @@ -230,43 +241,35 @@ describe("ProductTag Service", () => { }) it("should return tag based on config select param", async () => { - const tag = await service.retrieve( - tagId, - { - select: ["id", "value"], - } - ) + const tag = await service.retrieve(tagId, { + select: ["id", "value"], + }) const serialized = JSON.parse(JSON.stringify(tag)) - expect(serialized).toEqual( - { - id: tagId, - value: tagValue, - } - ) + expect(serialized).toEqual({ + id: tagId, + value: tagValue, + }) }) it("should return tag based on config relation param", async () => { - const tag = await service.retrieve( - tagId, - { - select: ["id", "value", "products.id"], - relations: ["products"] - } - ) + const tag = await service.retrieve(tagId, { + select: ["id", "value", "products.id"], + relations: ["products"], + }) const serialized = JSON.parse(JSON.stringify(tag)) - expect(serialized).toEqual( - { - id: tagId, - value: tagValue, - products: [{ - id: productId - }] - } - ) + expect(serialized).toEqual({ + id: tagId, + value: tagValue, + products: [ + { + id: productId, + }, + ], + }) }) }) @@ -274,12 +277,10 @@ describe("ProductTag Service", () => { const tagId = "tag-1" it("should delete the product tag given an ID successfully", async () => { - await service.delete( - [tagId], - ) + await service.delete([tagId]) const tags = await service.list({ - id: tagId + id: tagId, }) expect(tags).toHaveLength(0) @@ -290,12 +291,12 @@ describe("ProductTag Service", () => { const tagId = "tag-1" it("should update the value of the tag successfully", async () => { - await service.update( - [{ + await service.update([ + { id: tagId, - value: "UK" - }] - ) + value: "UK", + }, + ]) const productTag = await service.retrieve(tagId) @@ -307,29 +308,31 @@ describe("ProductTag Service", () => { try { await service.update([ - { - id: "does-not-exist", - value: "UK" - } - ]) + { + id: "does-not-exist", + value: "UK", + }, + ]) } catch (e) { error = e } - expect(error.message).toEqual('ProductTag with id "does-not-exist" not found') + expect(error.message).toEqual( + 'ProductTag with id "does-not-exist" not found' + ) }) }) describe("create", () => { it("should create a tag successfully", async () => { - await service.create( - [{ - value: "UK" - }] - ) + await service.create([ + { + value: "UK", + }, + ]) const [productTag] = await service.list({ - value: "UK" + value: "UK", }) expect(productTag.value).toEqual("UK") diff --git a/packages/product/integration-tests/__tests__/services/product-type/index.ts b/packages/product/integration-tests/__tests__/services/product-type/index.ts index 40ed973f6e..9a878d308e 100644 --- a/packages/product/integration-tests/__tests__/services/product-type/index.ts +++ b/packages/product/integration-tests/__tests__/services/product-type/index.ts @@ -1,12 +1,14 @@ import { SqlEntityManager } from "@mikro-orm/postgresql" +import ContainerLoader from "../../../../src/loaders/container" import { ProductTypeService } from "@services" -import { ProductTypeRepository } from "@repositories" import { Product } from "@models" import { TestDatabase } from "../../../utils" import { createProductAndTypes } from "../../../__fixtures__/product" import { ProductTypes } from "@medusajs/types" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" jest.setTimeout(30000) @@ -33,7 +35,7 @@ describe("ProductType Service", () => { type: { id: "type-2", value: "Type 2", - } + }, }, ] @@ -41,13 +43,12 @@ describe("ProductType Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productTypeRepository = new ProductTypeRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new ProductTypeService({ - productTypeRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productTypeService") testManager = await TestDatabase.forkManager() @@ -115,7 +116,9 @@ describe("ProductType Service", () => { }) it("should return product type and count when filtered", async () => { - const [typeResults, count] = await service.listAndCount({ id: data[0].type.id }) + const [typeResults, count] = await service.listAndCount({ + id: data[0].type.id, + }) expect(count).toEqual(1) expect(typeResults).toEqual([ @@ -126,7 +129,10 @@ describe("ProductType Service", () => { }) it("should return product type and count when using skip and take", async () => { - const [typeResults, count] = await service.listAndCount({}, { skip: 1, take: 1 }) + const [typeResults, count] = await service.listAndCount( + {}, + { skip: 1, take: 1 } + ) expect(count).toEqual(2) expect(typeResults).toEqual([ @@ -137,10 +143,13 @@ describe("ProductType Service", () => { }) it("should return requested fields", async () => { - const [typeResults, count] = await service.listAndCount({}, { - take: 1, - select: ["value"], - }) + const [typeResults, count] = await service.listAndCount( + {}, + { + take: 1, + select: ["value"], + } + ) const serialized = JSON.parse(JSON.stringify(typeResults)) @@ -158,13 +167,11 @@ describe("ProductType Service", () => { const typeValue = "Type 1" it("should return type for the given id", async () => { - const type = await service.retrieve( - typeId, - ) + const type = await service.retrieve(typeId) expect(type).toEqual( expect.objectContaining({ - id: typeId + id: typeId, }) ) }) @@ -178,7 +185,9 @@ describe("ProductType Service", () => { error = e } - expect(error.message).toEqual('ProductType with id: does-not-exist was not found') + expect(error.message).toEqual( + "ProductType with id: does-not-exist was not found" + ) }) it("should throw an error when an id is not provided", async () => { @@ -194,21 +203,16 @@ describe("ProductType Service", () => { }) it("should return type based on config select param", async () => { - const type = await service.retrieve( - typeId, - { - select: ["id", "value"], - } - ) + const type = await service.retrieve(typeId, { + select: ["id", "value"], + }) const serialized = JSON.parse(JSON.stringify(type)) - expect(serialized).toEqual( - { - id: typeId, - value: typeValue, - } - ) + expect(serialized).toEqual({ + id: typeId, + value: typeValue, + }) }) }) @@ -216,12 +220,10 @@ describe("ProductType Service", () => { const typeId = "type-1" it("should delete the product type given an ID successfully", async () => { - await service.delete( - [typeId], - ) + await service.delete([typeId]) const types = await service.list({ - id: typeId + id: typeId, }) expect(types).toHaveLength(0) @@ -232,12 +234,12 @@ describe("ProductType Service", () => { const typeId = "type-1" it("should update the value of the type successfully", async () => { - await service.update( - [{ + await service.update([ + { id: typeId, - value: "UK" - }] - ) + value: "UK", + }, + ]) const productType = await service.retrieve(typeId) @@ -249,29 +251,31 @@ describe("ProductType Service", () => { try { await service.update([ - { - id: "does-not-exist", - value: "UK" - } - ]) + { + id: "does-not-exist", + value: "UK", + }, + ]) } catch (e) { error = e } - expect(error.message).toEqual('ProductType with id "does-not-exist" not found') + expect(error.message).toEqual( + 'ProductType with id "does-not-exist" not found' + ) }) }) describe("create", () => { it("should create a type successfully", async () => { - await service.create( - [{ - value: "UK" - }] - ) + await service.create([ + { + value: "UK", + }, + ]) const [productType] = await service.list({ - value: "UK" + value: "UK", }) expect(productType.value).toEqual("UK") diff --git a/packages/product/integration-tests/__tests__/services/product-variant/index.ts b/packages/product/integration-tests/__tests__/services/product-variant/index.ts index 4492174bad..8f608d6dd8 100644 --- a/packages/product/integration-tests/__tests__/services/product-variant/index.ts +++ b/packages/product/integration-tests/__tests__/services/product-variant/index.ts @@ -1,6 +1,5 @@ import { TestDatabase } from "../../../utils" -import { ProductService, ProductVariantService } from "@services" -import { ProductRepository, ProductVariantRepository } from "@repositories" +import { ProductVariantService } from "@services" import { Product, ProductTag, ProductVariant } from "@models" import { SqlEntityManager } from "@mikro-orm/postgresql" import { Collection } from "@mikro-orm/core" @@ -13,6 +12,9 @@ import { } from "../../../__fixtures__/product" import { productsData, variantsData } from "../../../__fixtures__/product/data" import { buildProductVariantOnlyData } from "../../../__fixtures__/variant/data/create-variant" +import { createMedusaContainer } from "@medusajs/utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" describe("ProductVariant Service", () => { let service: ProductVariantService @@ -27,20 +29,12 @@ describe("ProductVariant Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productVariantRepository = new ProductVariantRepository({ - manager: repositoryManager, - }) - const productRepository = new ProductRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - const productService = new ProductService({ - productRepository, - }) - service = new ProductVariantService({ - productService, - productVariantRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productVariantService") }) afterEach(async () => { diff --git a/packages/product/integration-tests/__tests__/services/product/index.ts b/packages/product/integration-tests/__tests__/services/product/index.ts index 2d65223cc6..c4aaaddb1c 100644 --- a/packages/product/integration-tests/__tests__/services/product/index.ts +++ b/packages/product/integration-tests/__tests__/services/product/index.ts @@ -21,12 +21,13 @@ import { } from "../../../__fixtures__/product/data" import { ProductDTO, ProductTypes } from "@medusajs/types" -import { kebabCase } from "@medusajs/utils" +import { createMedusaContainer, kebabCase } from "@medusajs/utils" import { SqlEntityManager } from "@mikro-orm/postgresql" -import { ProductRepository } from "@repositories" import { ProductService } from "@services" import { createProductCategories } from "../../../__fixtures__/product-category" import { TestDatabase } from "../../../utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -44,13 +45,12 @@ describe("Product Service", () => { await TestDatabase.setupDatabase() repositoryManager = await TestDatabase.forkManager() - const productRepository = new ProductRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new ProductService({ - productRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("productService") }) afterEach(async () => { diff --git a/packages/product/src/loaders/container.ts b/packages/product/src/loaders/container.ts index 7375d3a9ef..28ea110f2d 100644 --- a/packages/product/src/loaders/container.ts +++ b/packages/product/src/loaders/container.ts @@ -1,108 +1,10 @@ -import * as DefaultRepositories from "@repositories" -import { - BaseRepository, - ProductCategoryRepository, - ProductCollectionRepository, - ProductImageRepository, - ProductOptionRepository, - ProductOptionValueRepository, - ProductRepository, - ProductTagRepository, - ProductTypeRepository, - ProductVariantRepository, -} from "@repositories" -import { Constructor, DAL, ModulesSdkTypes } from "@medusajs/types" -import { - ProductCategoryService, - ProductCollectionService, - ProductImageService, - ProductModuleService, - ProductOptionService, - ProductOptionValueService, - ProductService, - ProductTagService, - ProductTypeService, - ProductVariantService, -} from "@services" +import { ModulesSdkUtils } from "@medusajs/utils" +import * as ModuleModels from "@models" +import * as ModuleRepositories from "@repositories" +import * as ModuleServices from "@services" -import { LoaderOptions } from "@medusajs/modules-sdk" -import { asClass } from "awilix" -import { lowerCaseFirst } from "@medusajs/utils" - -export default async ({ - container, - options, -}: LoaderOptions< - | ModulesSdkTypes.ModuleServiceInitializeOptions - | ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions ->): Promise => { - const customRepositories = ( - options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions - )?.repositories - - container.register({ - productModuleService: asClass(ProductModuleService).singleton(), - productService: asClass(ProductService).singleton(), - productCategoryService: asClass(ProductCategoryService).singleton(), - productVariantService: asClass(ProductVariantService).singleton(), - productTagService: asClass(ProductTagService).singleton(), - productCollectionService: asClass(ProductCollectionService).singleton(), - productImageService: asClass(ProductImageService).singleton(), - productTypeService: asClass(ProductTypeService).singleton(), - productOptionService: asClass(ProductOptionService).singleton(), - productOptionValueService: asClass(ProductOptionValueService).singleton(), - }) - - if (customRepositories) { - loadCustomRepositories({ customRepositories, container }) - } else { - loadDefaultRepositories({ container }) - } -} - -function loadDefaultRepositories({ container }) { - container.register({ - baseRepository: asClass(BaseRepository).singleton(), - productImageRepository: asClass(ProductImageRepository).singleton(), - productCategoryRepository: asClass(ProductCategoryRepository).singleton(), - productCollectionRepository: asClass( - ProductCollectionRepository - ).singleton(), - productRepository: asClass(ProductRepository).singleton(), - productTagRepository: asClass(ProductTagRepository).singleton(), - productTypeRepository: asClass(ProductTypeRepository).singleton(), - productOptionRepository: asClass(ProductOptionRepository).singleton(), - productOptionValueRepository: asClass( - ProductOptionValueRepository - ).singleton(), - productVariantRepository: asClass(ProductVariantRepository).singleton(), - }) -} - -/** - * Load the repositories from the custom repositories object. If a repository is not - * present in the custom repositories object, the default repository will be used. - * - * @param customRepositories - * @param container - */ -function loadCustomRepositories({ customRepositories, container }) { - const customRepositoriesMap = new Map(Object.entries(customRepositories)) - - Object.entries(DefaultRepositories).forEach(([key, DefaultRepository]) => { - let finalRepository = customRepositoriesMap.get(key) - - if ( - !finalRepository || - !(finalRepository as Constructor).prototype.find - ) { - finalRepository = DefaultRepository - } - - container.register({ - [lowerCaseFirst(key)]: asClass( - finalRepository as Constructor - ).singleton(), - }) - }) -} +export default ModulesSdkUtils.moduleContainerLoaderFactory({ + moduleModels: ModuleModels, + moduleRepositories: ModuleRepositories, + moduleServices: ModuleServices, +}) diff --git a/packages/product/src/repositories/index.ts b/packages/product/src/repositories/index.ts index b1f0ab1e37..41294be81a 100644 --- a/packages/product/src/repositories/index.ts +++ b/packages/product/src/repositories/index.ts @@ -1,10 +1,4 @@ export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils" export { ProductRepository } from "./product" -export { ProductTagRepository } from "./product-tag" -export { ProductVariantRepository } from "./product-variant" -export { ProductCollectionRepository } from "./product-collection" export { ProductCategoryRepository } from "./product-category" export { ProductImageRepository } from "./product-image" -export { ProductTypeRepository } from "./product-type" -export { ProductOptionRepository } from "./product-option" -export { ProductOptionValueRepository } from "./product-option-value" diff --git a/packages/product/src/repositories/product-collection.ts b/packages/product/src/repositories/product-collection.ts deleted file mode 100644 index 6a8310e0f4..0000000000 --- a/packages/product/src/repositories/product-collection.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Context, ProductTypes } from "@medusajs/types" -import { DALUtils } from "@medusajs/utils" -import { ProductCollection } from "@models" - -type UpdateProductCollection = ProductTypes.UpdateProductCollectionDTO & { - products?: string[] -} - -type CreateProductCollection = ProductTypes.CreateProductCollectionDTO & { - products?: string[] -} - -// eslint-disable-next-line max-len -export class ProductCollectionRepository extends DALUtils.mikroOrmBaseRepositoryFactory( - ProductCollection -) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async create( - data: CreateProductCollection[], - context: Context = {} - ): Promise { - const productCollections = data.map((collectionData) => { - if (collectionData.product_ids) { - collectionData.products = collectionData.product_ids - - delete collectionData.product_ids - } - - return collectionData - }) - - return await super.create(productCollections, context) - } - - async update( - data: UpdateProductCollection[], - context: Context = {} - ): Promise { - const productCollections = data.map((collectionData) => { - if (collectionData.product_ids) { - collectionData.products = collectionData.product_ids - - delete collectionData.product_ids - } - - return collectionData - }) - - return await super.update(productCollections, context) - } -} diff --git a/packages/product/src/repositories/product-image.ts b/packages/product/src/repositories/product-image.ts index 5dc1799b1c..90eb181c0c 100644 --- a/packages/product/src/repositories/product-image.ts +++ b/packages/product/src/repositories/product-image.ts @@ -1,7 +1,6 @@ -import { Context } from "@medusajs/types" import { Image } from "@models" -import { SqlEntityManager } from "@mikro-orm/postgresql" import { DALUtils } from "@medusajs/utils" +import { Context } from "@medusajs/types" // eslint-disable-next-line max-len export class ProductImageRepository extends DALUtils.mikroOrmBaseRepositoryFactory( @@ -13,41 +12,8 @@ export class ProductImageRepository extends DALUtils.mikroOrmBaseRepositoryFacto } async upsert(urls: string[], context: Context = {}): Promise { - const manager = this.getActiveManager(context) + const data = urls.map((url) => ({ url })) - const existingImages = await this.find( - { - where: { - url: { - $in: urls, - }, - }, - }, - context - ) - - const existingImagesMap = new Map( - existingImages.map<[string, Image]>((img) => [img.url, img]) - ) - - const upsertedImgs: Image[] = [] - const imageToCreate: Image[] = [] - - urls.forEach((url) => { - const aImg = existingImagesMap.get(url) - if (aImg) { - upsertedImgs.push(aImg) - } else { - const newImg = (manager as SqlEntityManager).create(Image, { url }) - imageToCreate.push(newImg) - } - }) - - if (imageToCreate.length) { - manager.persist(imageToCreate) - upsertedImgs.push(...imageToCreate) - } - - return upsertedImgs + return await super.upsert(data, context) } } diff --git a/packages/product/src/repositories/product-option-value.ts b/packages/product/src/repositories/product-option-value.ts deleted file mode 100644 index 2b29297430..0000000000 --- a/packages/product/src/repositories/product-option-value.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { Context } from "@medusajs/types" -import { - CreateProductOptionValueDTO, - UpdateProductOptionValueDTO, -} from "../types/services/product-option-value" - -import { DALUtils } from "@medusajs/utils" -import { ProductOptionValue } from "@models" -import { SqlEntityManager } from "@mikro-orm/postgresql" - -export class ProductOptionValueRepository extends DALUtils.mikroOrmBaseRepositoryFactory( - ProductOptionValue -) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async upsert( - optionValues: (UpdateProductOptionValueDTO | CreateProductOptionValueDTO)[], - context: Context = {} - ): Promise { - const manager = this.getActiveManager(context) - - const optionValueIds: string[] = [] - - for (const optionValue of optionValues) { - if (optionValue.id) { - optionValueIds.push(optionValue.id) - } - } - - const existingOptionValues = await this.find( - { - where: { - id: { - $in: optionValueIds, - }, - }, - }, - context - ) - - const existingOptionValuesMap = new Map( - existingOptionValues.map<[string, ProductOptionValue]>((optionValue) => [ - optionValue.id, - optionValue, - ]) - ) - - const upsertedOptionValues: ProductOptionValue[] = [] - const optionValuesToCreate: ProductOptionValue[] = [] - const optionValuesToUpdate: ProductOptionValue[] = [] - - optionValues.forEach(({ option_id, ...optionValue }) => { - const existingOptionValue = optionValue.id - ? existingOptionValuesMap.get(optionValue.id) - : undefined - - if (optionValue.id && existingOptionValue) { - const updatedOptionValue = manager.assign(existingOptionValue, { - option: option_id, - ...optionValue, - }) - optionValuesToUpdate.push(updatedOptionValue) - return - } - - const newOptionValue = manager.create(ProductOptionValue, { - option: option_id, - variant: (optionValue as CreateProductOptionValueDTO).variant_id, - ...optionValue, - }) - optionValuesToCreate.push(newOptionValue) - }) - - if (optionValuesToCreate.length) { - manager.persist(optionValuesToCreate) - upsertedOptionValues.push(...optionValuesToCreate) - } - - if (optionValuesToUpdate.length) { - manager.persist(optionValuesToUpdate) - upsertedOptionValues.push(...optionValuesToUpdate) - } - - return upsertedOptionValues - } -} diff --git a/packages/product/src/repositories/product-option.ts b/packages/product/src/repositories/product-option.ts deleted file mode 100644 index fc4616acd0..0000000000 --- a/packages/product/src/repositories/product-option.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { Context, ProductTypes } from "@medusajs/types" -import { DALUtils } from "@medusajs/utils" -import { SqlEntityManager } from "@mikro-orm/postgresql" -import { Product, ProductOption } from "@models" - -// eslint-disable-next-line max-len -export class ProductOptionRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - ProductOption, - { - update: ProductTypes.UpdateProductOptionDTO - } ->(ProductOption) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async create( - data: ProductTypes.CreateProductOptionDTO[], - context: Context = {} - ): Promise { - const manager = this.getActiveManager(context) - const productIds: string[] = [] - - data.forEach((d) => d.product_id && productIds.push(d.product_id)) - - const existingProducts = await manager.find(Product, { - id: { $in: productIds }, - }) - - const existingProductsMap = new Map( - existingProducts.map<[string, Product]>((product) => [ - product.id, - product, - ]) - ) - - const productOptions = data.map((optionData) => { - const productId = optionData.product_id - - delete optionData.product_id - - if (productId) { - const product = existingProductsMap.get(productId) - - optionData.product_id = product?.id - } - - return optionData - }) - - return await super.create(productOptions, context) - } - - async upsert( - data: - | ProductTypes.CreateProductOptionDTO[] - | ProductTypes.UpdateProductOptionDTO[], - context: Context = {} - ): Promise { - const manager = this.getActiveManager(context) - - const optionIds = data.map((optionData) => optionData.id).filter((o) => o) - - let existingOptions - let existingOptionsMap = new Map() - - if (optionIds.length) { - existingOptions = await this.find( - { - where: { - id: { - $in: optionIds, - }, - }, - }, - context - ) - - existingOptionsMap = new Map( - existingOptions.map((option) => [option.id, option]) - ) - } - - const upsertedOptions: ProductOption[] = [] - const optionsToCreate: ProductOption[] = [] - const optionsToUpdate: ProductOption[] = [] - - data.forEach((option) => { - const existingOption = existingOptionsMap.get(option.id) - if (existingOption) { - const updatedOption = manager.assign(existingOption, option) - optionsToUpdate.push(updatedOption) - } else { - const newOption = manager.create(ProductOption, option) - optionsToCreate.push(newOption) - } - }) - - if (optionsToCreate.length) { - manager.persist(optionsToCreate) - upsertedOptions.push(...optionsToCreate) - } - - if (optionsToUpdate.length) { - manager.persist(optionsToUpdate) - upsertedOptions.push(...optionsToUpdate) - } - - return upsertedOptions - } -} diff --git a/packages/product/src/repositories/product-tag.ts b/packages/product/src/repositories/product-tag.ts deleted file mode 100644 index e3eae1543c..0000000000 --- a/packages/product/src/repositories/product-tag.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ProductTag } from "@models" -import { - Context, - CreateProductTagDTO, - UpdateProductTagDTO, - UpsertProductTagDTO, -} from "@medusajs/types" -import { SqlEntityManager } from "@mikro-orm/postgresql" -import { DALUtils } from "@medusajs/utils" - -export class ProductTagRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - ProductTag, - { - create: CreateProductTagDTO - update: UpdateProductTagDTO - } ->(ProductTag) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async upsert( - tags: UpsertProductTagDTO[], - context: Context = {} - ): Promise { - const manager = this.getActiveManager(context) - const tagsValues = tags.map((tag) => tag.value) - const existingTags = await this.find( - { - where: { - value: { - $in: tagsValues, - }, - }, - }, - context - ) - - const existingTagsMap = new Map( - existingTags.map<[string, ProductTag]>((tag) => [tag.value, tag]) - ) - - const upsertedTags: ProductTag[] = [] - const tagsToCreate: ProductTag[] = [] - const tagsToUpdate: ProductTag[] = [] - - tags.forEach((tag) => { - const aTag = existingTagsMap.get(tag.value) - if (aTag) { - const updatedTag = manager.assign(aTag, tag) - tagsToUpdate.push(updatedTag) - } else { - const newTag = manager.create(ProductTag, tag) - tagsToCreate.push(newTag) - } - }) - - if (tagsToCreate.length) { - manager.persist(tagsToCreate) - upsertedTags.push(...tagsToCreate) - } - - if (tagsToUpdate.length) { - manager.persist(tagsToUpdate) - upsertedTags.push(...tagsToUpdate) - } - - return upsertedTags - } -} diff --git a/packages/product/src/repositories/product-type.ts b/packages/product/src/repositories/product-type.ts deleted file mode 100644 index 352ff1ace8..0000000000 --- a/packages/product/src/repositories/product-type.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { ProductType } from "@models" -import { - Context, - CreateProductTypeDTO, - UpdateProductTypeDTO, -} from "@medusajs/types" -import { SqlEntityManager } from "@mikro-orm/postgresql" -import { DALUtils } from "@medusajs/utils" - -export class ProductTypeRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - ProductType, - { - create: CreateProductTypeDTO - update: UpdateProductTypeDTO - } ->(ProductType) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } - - async upsert( - types: CreateProductTypeDTO[], - context: Context = {} - ): Promise { - const manager = this.getActiveManager(context) - - const typesValues = types.map((type) => type.value) - const existingTypes = await this.find( - { - where: { - value: { - $in: typesValues, - }, - }, - }, - context - ) - - const existingTypesMap = new Map( - existingTypes.map<[string, ProductType]>((type) => [type.value, type]) - ) - - const upsertedTypes: ProductType[] = [] - const typesToCreate: ProductType[] = [] - const typesToUpdate: ProductType[] = [] - - types.forEach((type) => { - const aType = existingTypesMap.get(type.value) - if (aType) { - const updatedType = manager.assign(aType, type) - typesToUpdate.push(updatedType) - } else { - const newType = manager.create(ProductType, type) - typesToCreate.push(newType) - } - }) - - if (typesToCreate.length) { - manager.persist(typesToCreate) - upsertedTypes.push(...typesToCreate) - } - - if (typesToUpdate.length) { - manager.persist(typesToUpdate) - upsertedTypes.push(...typesToUpdate) - } - - return upsertedTypes - } -} diff --git a/packages/product/src/repositories/product-variant.ts b/packages/product/src/repositories/product-variant.ts deleted file mode 100644 index f792a8e3be..0000000000 --- a/packages/product/src/repositories/product-variant.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ProductVariant } from "@models" -import { DALUtils } from "@medusajs/utils" -import { RequiredEntityData } from "@mikro-orm/core" -import { WithRequiredProperty } from "@medusajs/types" -import { ProductVariantServiceTypes } from "../types/services" - -// eslint-disable-next-line max-len -export class ProductVariantRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - ProductVariant, - { - create: RequiredEntityData - update: WithRequiredProperty< - ProductVariantServiceTypes.UpdateProductVariantDTO, - "id" - > - } ->(ProductVariant) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/product/src/services/product-collection.ts b/packages/product/src/services/product-collection.ts index 31e85c8731..5ace64dea3 100644 --- a/packages/product/src/services/product-collection.ts +++ b/packages/product/src/services/product-collection.ts @@ -1,7 +1,20 @@ import { Context, DAL, FindConfig, ProductTypes } from "@medusajs/types" -import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" +import { + InjectManager, + InjectTransactionManager, + MedusaContext, + ModulesSdkUtils, +} from "@medusajs/utils" import { ProductCollection } from "@models" +import { + IProductCollectionRepository, + ProductCollectionServiceTypes, +} from "@types" +import { + CreateProductCollection, + UpdateProductCollection, +} from "../types/services/product-collection" type InjectedDependencies = { productCollectionRepository: DAL.RepositoryService @@ -12,12 +25,12 @@ export default class ProductCollectionService< > extends ModulesSdkUtils.abstractServiceFactory< InjectedDependencies, { - create: ProductTypes.CreateProductCollectionDTO - update: ProductTypes.UpdateProductCollectionDTO + create: CreateProductCollection + update: UpdateProductCollection } >(ProductCollection) { // eslint-disable-next-line max-len - protected readonly productCollectionRepository_: DAL.RepositoryService + protected readonly productCollectionRepository_: IProductCollectionRepository constructor(container: InjectedDependencies) { super(container) @@ -66,4 +79,40 @@ export default class ProductCollectionService< return queryOptions } + + @InjectTransactionManager("productCollectionRepository_") + async create( + data: ProductCollectionServiceTypes.CreateProductCollection[], + context: Context = {} + ): Promise { + const productCollections = data.map((collectionData) => { + if (collectionData.product_ids) { + collectionData.products = collectionData.product_ids + + delete collectionData.product_ids + } + + return collectionData + }) + + return super.create(productCollections, context) + } + + @InjectTransactionManager("productCollectionRepository_") + async update( + data: ProductCollectionServiceTypes.UpdateProductCollection[], + context: Context = {} + ): Promise { + const productCollections = data.map((collectionData) => { + if (collectionData.product_ids) { + collectionData.products = collectionData.product_ids + + delete collectionData.product_ids + } + + return collectionData + }) + + return super.update(productCollections, context) + } } diff --git a/packages/product/src/services/product-image.ts b/packages/product/src/services/product-image.ts index d6c6a62368..50ab03044e 100644 --- a/packages/product/src/services/product-image.ts +++ b/packages/product/src/services/product-image.ts @@ -1,23 +1,18 @@ import { Image } from "@models" -import { Context, DAL } from "@medusajs/types" -import { InjectTransactionManager, MedusaContext } from "@medusajs/utils" +import { DAL } from "@medusajs/types" +import { ModulesSdkUtils } from "@medusajs/utils" type InjectedDependencies = { productImageRepository: DAL.RepositoryService } -export default class ProductImageService { - protected readonly productImageRepository_: DAL.RepositoryService - - constructor({ productImageRepository }: InjectedDependencies) { - this.productImageRepository_ = productImageRepository - } - - @InjectTransactionManager("productImageRepository_") - async upsert( - urls: string[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.productImageRepository_.upsert!(urls, sharedContext) +export default class ProductImageService< + TEntity extends Image = Image +> extends ModulesSdkUtils.abstractServiceFactory( + Image +) { + constructor(container: InjectedDependencies) { + // @ts-ignore + super(...arguments) } } diff --git a/packages/product/src/services/product-option-value.ts b/packages/product/src/services/product-option-value.ts index b66069c87a..62c9bfa9f7 100644 --- a/packages/product/src/services/product-option-value.ts +++ b/packages/product/src/services/product-option-value.ts @@ -1,6 +1,6 @@ import { ProductOptionValue } from "@models" -import { Context, DAL } from "@medusajs/types" -import { InjectTransactionManager, MedusaContext } from "@medusajs/utils" +import { DAL } from "@medusajs/types" +import { ModulesSdkUtils } from "@medusajs/utils" import { ProductOptionValueServiceTypes } from "@types" type InjectedDependencies = { @@ -9,30 +9,15 @@ type InjectedDependencies = { export default class ProductOptionValueService< TEntity extends ProductOptionValue = ProductOptionValue -> { - // eslint-disable-next-line max-len - protected readonly productOptionValueRepository_: DAL.RepositoryService - - constructor({ productOptionValueRepository }: InjectedDependencies) { - this.productOptionValueRepository_ = productOptionValueRepository +> extends ModulesSdkUtils.abstractServiceFactory< + InjectedDependencies, + { + create: ProductOptionValueServiceTypes.CreateProductOptionValueDTO + update: ProductOptionValueServiceTypes.UpdateProductOptionValueDTO } - - @InjectTransactionManager("productOptionValueRepository_") - async delete( - ids: string[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.productOptionValueRepository_.delete(ids, sharedContext) - } - - @InjectTransactionManager("productOptionValueRepository_") - async upsert( - data: ( - | ProductOptionValueServiceTypes.UpdateProductOptionValueDTO - | ProductOptionValueServiceTypes.CreateProductOptionValueDTO - )[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.productOptionValueRepository_.upsert!(data, sharedContext) +>(ProductOptionValue) { + constructor(container: InjectedDependencies) { + // @ts-ignore + super(...arguments) } } diff --git a/packages/product/src/services/product-option.ts b/packages/product/src/services/product-option.ts index c0258996a4..026c2a6b81 100644 --- a/packages/product/src/services/product-option.ts +++ b/packages/product/src/services/product-option.ts @@ -1,11 +1,7 @@ import { ProductOption } from "@models" import { Context, DAL, FindConfig, ProductTypes } from "@medusajs/types" -import { - InjectManager, - InjectTransactionManager, - MedusaContext, - ModulesSdkUtils, -} from "@medusajs/utils" +import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" +import { IProductOptionRepository } from "@types" type InjectedDependencies = { productOptionRepository: DAL.RepositoryService @@ -20,7 +16,7 @@ export default class ProductOptionService< update: ProductTypes.UpdateProductOptionDTO } >(ProductOption) { - protected readonly productOptionRepository_: DAL.RepositoryService + protected readonly productOptionRepository_: IProductOptionRepository constructor(container: InjectedDependencies) { super(container) @@ -65,14 +61,4 @@ export default class ProductOptionService< return queryOptions } - - @InjectTransactionManager("productOptionRepository_") - async upsert( - data: - | ProductTypes.CreateProductOptionDTO[] - | ProductTypes.UpdateProductOptionDTO[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.productOptionRepository_.upsert!(data, sharedContext) - } } diff --git a/packages/product/src/services/product-tag.ts b/packages/product/src/services/product-tag.ts index 400d92ae7c..a6d8522307 100644 --- a/packages/product/src/services/product-tag.ts +++ b/packages/product/src/services/product-tag.ts @@ -1,17 +1,7 @@ import { ProductTag } from "@models" -import { - Context, - DAL, - FindConfig, - ProductTypes, - UpsertProductTagDTO, -} from "@medusajs/types" -import { - InjectManager, - InjectTransactionManager, - MedusaContext, - ModulesSdkUtils, -} from "@medusajs/utils" +import { Context, DAL, FindConfig, ProductTypes } from "@medusajs/types" +import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" +import { IProductTagRepository } from "@types" type InjectedDependencies = { productTagRepository: DAL.RepositoryService @@ -26,7 +16,7 @@ export default class ProductTagService< update: ProductTypes.UpdateProductTagDTO } >(ProductTag) { - protected readonly productTagRepository_: DAL.RepositoryService + protected readonly productTagRepository_: IProductTagRepository constructor(container: InjectedDependencies) { super(container) @@ -70,12 +60,4 @@ export default class ProductTagService< return queryOptions } - - @InjectTransactionManager("productTagRepository_") - async upsert( - data: UpsertProductTagDTO[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.productTagRepository_.upsert!(data, sharedContext) - } } diff --git a/packages/product/src/services/product-type.ts b/packages/product/src/services/product-type.ts index ddab918b2a..da5587f316 100644 --- a/packages/product/src/services/product-type.ts +++ b/packages/product/src/services/product-type.ts @@ -1,17 +1,7 @@ import { ProductType } from "@models" -import { - Context, - DAL, - FindConfig, - ProductTypes, - UpsertProductTypeDTO, -} from "@medusajs/types" -import { - InjectManager, - InjectTransactionManager, - MedusaContext, - ModulesSdkUtils, -} from "@medusajs/utils" +import { Context, DAL, FindConfig, ProductTypes } from "@medusajs/types" +import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" +import { IProductTypeRepository } from "@types" type InjectedDependencies = { productTypeRepository: DAL.RepositoryService @@ -26,7 +16,7 @@ export default class ProductTypeService< update: ProductTypes.UpdateProductTypeDTO } >(ProductType) { - protected readonly productTypeRepository_: DAL.RepositoryService + protected readonly productTypeRepository_: IProductTypeRepository constructor(container: InjectedDependencies) { super(container) @@ -71,12 +61,4 @@ export default class ProductTypeService< return queryOptions } - - @InjectTransactionManager("productTypeRepository_") - async upsert( - types: UpsertProductTypeDTO[], - @MedusaContext() sharedContext: Context = {} - ): Promise { - return await this.productTypeRepository_.upsert!(types, sharedContext) - } } diff --git a/packages/product/src/services/product-variant.ts b/packages/product/src/services/product-variant.ts index 38abaf1b4d..e1a247aa1c 100644 --- a/packages/product/src/services/product-variant.ts +++ b/packages/product/src/services/product-variant.ts @@ -7,7 +7,7 @@ import { } from "@medusajs/utils" import { Product, ProductVariant } from "@models" -import { ProductVariantServiceTypes } from "@types" +import { IProductVariantRepository, ProductVariantServiceTypes } from "@types" import ProductService from "./product" type InjectedDependencies = { @@ -25,7 +25,7 @@ export default class ProductVariantService< update: ProductVariantServiceTypes.UpdateProductVariantDTO } >(ProductVariant) { - protected readonly productVariantRepository_: DAL.RepositoryService + protected readonly productVariantRepository_: IProductVariantRepository protected readonly productService_: ProductService constructor({ diff --git a/packages/product/src/services/product.ts b/packages/product/src/services/product.ts index d438fb7513..3c514c0abe 100644 --- a/packages/product/src/services/product.ts +++ b/packages/product/src/services/product.ts @@ -1,7 +1,7 @@ import { Context, DAL, FindConfig, ProductTypes } from "@medusajs/types" import { InjectManager, MedusaContext, ModulesSdkUtils } from "@medusajs/utils" import { Product } from "@models" -import { ProductServiceTypes } from "@types" +import { IProductRepository, ProductServiceTypes } from "@types" type InjectedDependencies = { productRepository: DAL.RepositoryService @@ -16,7 +16,7 @@ export default class ProductService< update: ProductServiceTypes.UpdateProductDTO } >(Product) { - protected readonly productRepository_: DAL.RepositoryService + protected readonly productRepository_: IProductRepository constructor({ productRepository }: InjectedDependencies) { // @ts-ignore diff --git a/packages/product/src/types/index.ts b/packages/product/src/types/index.ts index f9546de664..051d3d01a8 100644 --- a/packages/product/src/types/index.ts +++ b/packages/product/src/types/index.ts @@ -1,5 +1,3 @@ -export * from "./services" - import { IEventBusModuleService, Logger } from "@medusajs/types" export type InitializeModuleInjectableDependencies = { @@ -8,3 +6,4 @@ export type InitializeModuleInjectableDependencies = { } export * from "./services" +export * from "./repositories" diff --git a/packages/product/src/types/repositories.ts b/packages/product/src/types/repositories.ts new file mode 100644 index 0000000000..6f7f3a0510 --- /dev/null +++ b/packages/product/src/types/repositories.ts @@ -0,0 +1,100 @@ +import { DAL, ProductTypes, WithRequiredProperty } from "@medusajs/types" +import { + Image, + Product, + ProductCollection, + ProductOption, + ProductOptionValue, + ProductTag, + ProductType, + ProductVariant, +} from "@models" +import { UpdateProductDTO } from "./services/product" +import { + CreateProductCollection, + UpdateProductCollection, +} from "./services/product-collection" +import { + CreateProductOptionValueDTO, + UpdateProductOptionValueDTO, +} from "./services/product-option-value" +import { UpdateProductVariantDTO } from "./services/product-variant" + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductRepository + extends DAL.RepositoryService< + TEntity, + { + create: WithRequiredProperty + update: WithRequiredProperty + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductCollectionRepository< + TEntity extends ProductCollection = ProductCollection +> extends DAL.RepositoryService< + TEntity, + { + create: CreateProductCollection + update: UpdateProductCollection + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductImageRepository + extends DAL.RepositoryService {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductOptionRepository< + TEntity extends ProductOption = ProductOption +> extends DAL.RepositoryService< + TEntity, + { + create: ProductTypes.CreateProductOptionDTO + update: ProductTypes.UpdateProductOptionDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductOptionValueRepository< + TEntity extends ProductOptionValue = ProductOptionValue +> extends DAL.RepositoryService< + TEntity, + { + create: CreateProductOptionValueDTO + update: UpdateProductOptionValueDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductTagRepository + extends DAL.RepositoryService< + TEntity, + { + create: ProductTypes.CreateProductTagDTO + update: ProductTypes.UpdateProductTagDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductTypeRepository< + TEntity extends ProductType = ProductType +> extends DAL.RepositoryService< + TEntity, + { + create: ProductTypes.CreateProductTypeDTO + update: ProductTypes.UpdateProductTypeDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IProductVariantRepository< + TEntity extends ProductVariant = ProductVariant +> extends DAL.RepositoryService< + TEntity, + { + create: ProductTypes.CreateProductVariantOnlyDTO + update: UpdateProductVariantDTO + } + > {} diff --git a/packages/product/src/types/services/product-collection.ts b/packages/product/src/types/services/product-collection.ts index 20b46495bb..825f449cfe 100644 --- a/packages/product/src/types/services/product-collection.ts +++ b/packages/product/src/types/services/product-collection.ts @@ -1,3 +1,5 @@ +import { ProductTypes } from "@medusajs/types" + export type ProductCollectionEventData = { id: string } @@ -7,3 +9,13 @@ export enum ProductCollectionEvents { COLLECTION_CREATED = "product-collection.created", COLLECTION_DELETED = "product-collection.deleted", } + +export type UpdateProductCollection = + ProductTypes.UpdateProductCollectionDTO & { + products?: string[] + } + +export type CreateProductCollection = + ProductTypes.CreateProductCollectionDTO & { + products?: string[] + } diff --git a/packages/promotion/integration-tests/__tests__/services/promotion/index.spec.ts b/packages/promotion/integration-tests/__tests__/services/promotion/index.spec.ts index 0f47bdae3a..452efa8585 100644 --- a/packages/promotion/integration-tests/__tests__/services/promotion/index.spec.ts +++ b/packages/promotion/integration-tests/__tests__/services/promotion/index.spec.ts @@ -1,9 +1,10 @@ -import { PromotionType } from "@medusajs/utils" +import { createMedusaContainer, PromotionType } from "@medusajs/utils" import { SqlEntityManager } from "@mikro-orm/postgresql" -import { PromotionRepository } from "@repositories" import { PromotionService } from "@services" import { createPromotions } from "../../../__fixtures__/promotion" import { MikroOrmWrapper } from "../../../utils" +import { asValue } from "awilix" +import ContainerLoader from "../../../../src/loaders/container" jest.setTimeout(30000) @@ -17,13 +18,12 @@ describe("Promotion Service", () => { repositoryManager = await MikroOrmWrapper.forkManager() testManager = await MikroOrmWrapper.forkManager() - const promotionRepository = new PromotionRepository({ - manager: repositoryManager, - }) + const container = createMedusaContainer() + container.register("manager", asValue(repositoryManager)) - service = new PromotionService({ - promotionRepository: promotionRepository, - }) + await ContainerLoader({ container }) + + service = container.resolve("promotionService") await createPromotions(testManager) }) diff --git a/packages/promotion/package.json b/packages/promotion/package.json index ae0f7f3b93..80f1246d4a 100644 --- a/packages/promotion/package.json +++ b/packages/promotion/package.json @@ -11,8 +11,6 @@ "node": ">=16" }, "bin": { - "medusa-promotion-migrations-down": "dist/scripts/bin/run-migration-down.js", - "medusa-promotion-migrations-up": "dist/scripts/bin/run-migration-up.js", "medusa-promotion-seed": "dist/scripts/bin/run-seed.js" }, "repository": { diff --git a/packages/promotion/src/index.ts b/packages/promotion/src/index.ts index 4ea0e7c3e3..220ccf1f5c 100644 --- a/packages/promotion/src/index.ts +++ b/packages/promotion/src/index.ts @@ -1,7 +1,22 @@ import { moduleDefinition } from "./module-definition" +import { Modules } from "@medusajs/modules-sdk" +import * as Models from "@models" +import { ModulesSdkUtils } from "@medusajs/utils" export default moduleDefinition +const migrationScriptOptions = { + moduleName: Modules.PROMOTION, + models: Models, + pathToMigrations: __dirname + "/migrations", +} + +export const runMigrations = ModulesSdkUtils.buildMigrationScript( + migrationScriptOptions +) +export const revertMigration = ModulesSdkUtils.buildRevertMigrationScript( + migrationScriptOptions +) + export * from "./initialize" export * from "./loaders" -export * from "./scripts" diff --git a/packages/promotion/src/loaders/container.ts b/packages/promotion/src/loaders/container.ts index 9168c3c5a1..28ea110f2d 100644 --- a/packages/promotion/src/loaders/container.ts +++ b/packages/promotion/src/loaders/container.ts @@ -1,70 +1,10 @@ -import * as defaultRepositories from "@repositories" +import { ModulesSdkUtils } from "@medusajs/utils" +import * as ModuleModels from "@models" +import * as ModuleRepositories from "@repositories" +import * as ModuleServices from "@services" -import { LoaderOptions } from "@medusajs/modules-sdk" -import { ModulesSdkTypes } from "@medusajs/types" -import { loadCustomRepositories } from "@medusajs/utils" -import * as defaultServices from "@services" -import { asClass } from "awilix" - -export default async ({ - container, - options, -}: LoaderOptions< - | ModulesSdkTypes.ModuleServiceInitializeOptions - | ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions ->): Promise => { - const customRepositories = ( - options as ModulesSdkTypes.ModuleServiceInitializeCustomDataLayerOptions - )?.repositories - - container.register({ - promotionService: asClass(defaultServices.PromotionService).singleton(), - promotionRuleService: asClass( - defaultServices.PromotionRuleService - ).singleton(), - promotionRuleValueService: asClass( - defaultServices.PromotionRuleValueService - ).singleton(), - applicationMethodService: asClass( - defaultServices.ApplicationMethodService - ).singleton(), - campaignService: asClass(defaultServices.CampaignService).singleton(), - campaignBudgetService: asClass( - defaultServices.CampaignBudgetService - ).singleton(), - }) - - if (customRepositories) { - loadCustomRepositories({ - defaultRepositories, - customRepositories, - container, - }) - } else { - loadDefaultRepositories({ container }) - } -} - -function loadDefaultRepositories({ container }) { - container.register({ - baseRepository: asClass(defaultRepositories.BaseRepository).singleton(), - applicationMethodRepository: asClass( - defaultRepositories.ApplicationMethodRepository - ).singleton(), - promotionRepository: asClass( - defaultRepositories.PromotionRepository - ).singleton(), - promotionRuleRepository: asClass( - defaultRepositories.PromotionRuleRepository - ).singleton(), - promotionRuleValueRepository: asClass( - defaultRepositories.PromotionRuleValueRepository - ).singleton(), - campaignRepository: asClass( - defaultRepositories.CampaignRepository - ).singleton(), - campaignBudgetRepository: asClass( - defaultRepositories.CampaignBudgetRepository - ).singleton(), - }) -} +export default ModulesSdkUtils.moduleContainerLoaderFactory({ + moduleModels: ModuleModels, + moduleRepositories: ModuleRepositories, + moduleServices: ModuleServices, +}) diff --git a/packages/promotion/src/repositories/application-method.ts b/packages/promotion/src/repositories/application-method.ts deleted file mode 100644 index fd666d995b..0000000000 --- a/packages/promotion/src/repositories/application-method.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { ApplicationMethod } from "@models" -import { CreateApplicationMethodDTO, UpdateApplicationMethodDTO } from "@types" - -export class ApplicationMethodRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - ApplicationMethod, - { - create: CreateApplicationMethodDTO - update: UpdateApplicationMethodDTO - } ->(ApplicationMethod) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/promotion/src/repositories/campaign-budget.ts b/packages/promotion/src/repositories/campaign-budget.ts deleted file mode 100644 index 32e4b98edd..0000000000 --- a/packages/promotion/src/repositories/campaign-budget.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { CampaignBudget } from "@models" -import { CreateCampaignBudgetDTO, UpdateCampaignBudgetDTO } from "@types" - -export class CampaignBudgetRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - CampaignBudget, - { - create: CreateCampaignBudgetDTO - update: UpdateCampaignBudgetDTO - } ->(CampaignBudget) {} diff --git a/packages/promotion/src/repositories/index.ts b/packages/promotion/src/repositories/index.ts index 724cb68578..db193bb79f 100644 --- a/packages/promotion/src/repositories/index.ts +++ b/packages/promotion/src/repositories/index.ts @@ -1,7 +1,2 @@ export { MikroOrmBaseRepository as BaseRepository } from "@medusajs/utils" -export { ApplicationMethodRepository } from "./application-method" export { CampaignRepository } from "./campaign" -export { CampaignBudgetRepository } from "./campaign-budget" -export { PromotionRepository } from "./promotion" -export { PromotionRuleRepository } from "./promotion-rule" -export { PromotionRuleValueRepository } from "./promotion-rule-value" diff --git a/packages/promotion/src/repositories/promotion-rule-value.ts b/packages/promotion/src/repositories/promotion-rule-value.ts deleted file mode 100644 index 7587fa295c..0000000000 --- a/packages/promotion/src/repositories/promotion-rule-value.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { PromotionRuleValue } from "@models" -import { - CreatePromotionRuleValueDTO, - UpdatePromotionRuleValueDTO, -} from "@types" - -export class PromotionRuleValueRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PromotionRuleValue, - { - create: CreatePromotionRuleValueDTO - update: UpdatePromotionRuleValueDTO - } ->(PromotionRuleValue) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/promotion/src/repositories/promotion-rule.ts b/packages/promotion/src/repositories/promotion-rule.ts deleted file mode 100644 index aceb5d33dd..0000000000 --- a/packages/promotion/src/repositories/promotion-rule.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { PromotionRule } from "@models" -import { CreatePromotionRuleDTO, UpdatePromotionRuleDTO } from "@types" - -export class PromotionRuleRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - PromotionRule, - { - create: CreatePromotionRuleDTO - update: UpdatePromotionRuleDTO - } ->(PromotionRule) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/promotion/src/repositories/promotion.ts b/packages/promotion/src/repositories/promotion.ts deleted file mode 100644 index c6732c74ba..0000000000 --- a/packages/promotion/src/repositories/promotion.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { DALUtils } from "@medusajs/utils" -import { Promotion } from "@models" -import { CreatePromotionDTO, UpdatePromotionDTO } from "@types" - -export class PromotionRepository extends DALUtils.mikroOrmBaseRepositoryFactory< - Promotion, - { - create: CreatePromotionDTO - Update: UpdatePromotionDTO - } ->(Promotion) { - constructor(...args: any[]) { - // @ts-ignore - super(...arguments) - } -} diff --git a/packages/promotion/src/scripts/bin/run-migration-down.ts b/packages/promotion/src/scripts/bin/run-migration-down.ts deleted file mode 100644 index e352048fd4..0000000000 --- a/packages/promotion/src/scripts/bin/run-migration-down.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { revertMigration } = await import("../migration-down") - const { config } = await import("dotenv") - config() - await revertMigration() -})() diff --git a/packages/promotion/src/scripts/bin/run-migration-up.ts b/packages/promotion/src/scripts/bin/run-migration-up.ts deleted file mode 100644 index 35f3bee853..0000000000 --- a/packages/promotion/src/scripts/bin/run-migration-up.ts +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env node - -export default (async () => { - const { runMigrations } = await import("../migration-up") - const { config } = await import("dotenv") - config() - await runMigrations() -})() diff --git a/packages/promotion/src/scripts/bin/run-seed.ts b/packages/promotion/src/scripts/bin/run-seed.ts deleted file mode 100644 index 823708ccf4..0000000000 --- a/packages/promotion/src/scripts/bin/run-seed.ts +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env node - -import { EOL } from "os" -import { run } from "../seed" - -const args = process.argv -const path = args.pop() as string - -export default (async () => { - const { config } = await import("dotenv") - config() - if (!path) { - throw new Error( - `filePath is required.${EOL}Example: medusa-promotion-seed ` - ) - } - - await run({ path }) -})() diff --git a/packages/promotion/src/scripts/index.ts b/packages/promotion/src/scripts/index.ts deleted file mode 100644 index cfa5c5ddf5..0000000000 --- a/packages/promotion/src/scripts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./migration-up" -export * from "./migration-down" diff --git a/packages/promotion/src/scripts/migration-down.ts b/packages/promotion/src/scripts/migration-down.ts deleted file mode 100644 index 9272bb3685..0000000000 --- a/packages/promotion/src/scripts/migration-down.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk" -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types" -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils" -import { EntitySchema } from "@mikro-orm/core" -import * as PromotionModels from "@models" - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of reverting the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function revertMigration({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig(Modules.PROMOTION, options)! - const entities = Object.values(PromotionModels) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - await migrator.down() - - logger?.info("Promotion module migration executed") - } catch (error) { - logger?.error(`Promotion module migration failed to run - Error: ${error}`) - } - - await orm.close() -} diff --git a/packages/promotion/src/scripts/migration-up.ts b/packages/promotion/src/scripts/migration-up.ts deleted file mode 100644 index 704086e02b..0000000000 --- a/packages/promotion/src/scripts/migration-up.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk" -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types" -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils" -import { EntitySchema } from "@mikro-orm/core" -import * as PromotionModels from "@models" - -/** - * This script is only valid for mikro orm managers. If a user provide a custom manager - * he is in charge of running the migrations. - * @param options - * @param logger - * @param moduleDeclaration - */ -export async function runMigrations({ - options, - logger, -}: Pick< - LoaderOptions, - "options" | "logger" -> = {}) { - logger ??= console as unknown as Logger - - const dbData = ModulesSdkUtils.loadDatabaseConfig(Modules.PROMOTION, options)! - const entities = Object.values(PromotionModels) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - try { - const migrator = orm.getMigrator() - - const pendingMigrations = await migrator.getPendingMigrations() - logger.info( - `Running pending migrations: ${JSON.stringify( - pendingMigrations, - null, - 2 - )}` - ) - - await migrator.up({ - migrations: pendingMigrations.map((m) => m.name), - }) - - logger.info("Promotion module migration executed") - } catch (error) { - logger.error(`Promotion module migration failed to run - Error: ${error}`) - } - - await orm.close() -} diff --git a/packages/promotion/src/scripts/seed.ts b/packages/promotion/src/scripts/seed.ts deleted file mode 100644 index eb51fa0095..0000000000 --- a/packages/promotion/src/scripts/seed.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Modules } from "@medusajs/modules-sdk" -import { LoaderOptions, Logger, ModulesSdkTypes } from "@medusajs/types" -import { DALUtils, ModulesSdkUtils } from "@medusajs/utils" -import { EntitySchema } from "@mikro-orm/core" -import * as PromotionModels from "@models" -import { EOL } from "os" -import { resolve } from "path" - -export async function run({ - options, - logger, - path, -}: Partial< - Pick< - LoaderOptions, - "options" | "logger" - > -> & { - path: string -}) { - logger ??= console as unknown as Logger - - logger.info(`Loading seed data from ${path}...`) - - const { promotionsData } = await import(resolve(process.cwd(), path)).catch( - (e) => { - logger?.error( - `Failed to load seed data from ${path}. Please, provide a relative path and check that you export the following: promotionsData.${EOL}${e}` - ) - throw e - } - ) - - const dbData = ModulesSdkUtils.loadDatabaseConfig(Modules.PROMOTION, options)! - const entities = Object.values(PromotionModels) as unknown as EntitySchema[] - const pathToMigrations = __dirname + "/../migrations" - - const orm = await DALUtils.mikroOrmCreateConnection( - dbData, - entities, - pathToMigrations - ) - - const manager = orm.em.fork() - - try { - logger.info("Inserting promotions..") - - // TODO: implement promotions seed data - // await createPromotions(manager, promotionsData) - } catch (e) { - logger.error( - `Failed to insert the seed data in the PostgreSQL database ${dbData.clientUrl}.${EOL}${e}` - ) - } - - await orm.close(true) -} diff --git a/packages/promotion/src/types/index.ts b/packages/promotion/src/types/index.ts index 145c717bae..80891678e3 100644 --- a/packages/promotion/src/types/index.ts +++ b/packages/promotion/src/types/index.ts @@ -10,3 +10,4 @@ export * from "./campaign-budget" export * from "./promotion" export * from "./promotion-rule" export * from "./promotion-rule-value" +export * from "./repositories" diff --git a/packages/promotion/src/types/repositories.ts b/packages/promotion/src/types/repositories.ts new file mode 100644 index 0000000000..bfa06a3073 --- /dev/null +++ b/packages/promotion/src/types/repositories.ts @@ -0,0 +1,91 @@ +import { + ApplicationMethod, + Campaign, + CampaignBudget, + Promotion, + PromotionRule, + PromotionRuleValue, +} from "@models" +import { DAL } from "@medusajs/types" +import { + CreateApplicationMethodDTO, + UpdateApplicationMethodDTO, +} from "./application-method" +import { CreateCampaignDTO, UpdateCampaignDTO } from "./campaign" +import { + CreateCampaignBudgetDTO, + UpdateCampaignBudgetDTO, +} from "./campaign-budget" +import { CreatePromotionDTO, UpdatePromotionDTO } from "./promotion" +import { + CreatePromotionRuleDTO, + UpdatePromotionRuleDTO, +} from "./promotion-rule" +import { + CreatePromotionRuleValueDTO, + UpdatePromotionRuleValueDTO, +} from "./promotion-rule-value" + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IApplicationMethodRepository< + TEntity extends ApplicationMethod = ApplicationMethod +> extends DAL.RepositoryService< + TEntity, + { + create: CreateApplicationMethodDTO + update: UpdateApplicationMethodDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ICampaignRepository + extends DAL.RepositoryService< + TEntity, + { + create: CreateCampaignDTO + update: UpdateCampaignDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface ICampaignBudgetRepository< + TEntity extends CampaignBudget = CampaignBudget +> extends DAL.RepositoryService< + TEntity, + { + create: CreateCampaignBudgetDTO + update: UpdateCampaignBudgetDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IPromotionRepository + extends DAL.RepositoryService< + TEntity, + { + create: CreatePromotionDTO + Update: UpdatePromotionDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IPromotionRuleRepository< + TEntity extends PromotionRule = PromotionRule +> extends DAL.RepositoryService< + TEntity, + { + create: CreatePromotionRuleDTO + update: UpdatePromotionRuleDTO + } + > {} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface IPromotionRuleValueRepository< + TEntity extends PromotionRuleValue = PromotionRuleValue +> extends DAL.RepositoryService< + TEntity, + { + create: CreatePromotionRuleValueDTO + update: UpdatePromotionRuleValueDTO + } + > {} diff --git a/packages/types/src/dal/repository-service.ts b/packages/types/src/dal/repository-service.ts index 6e294475c6..652a3a9b02 100644 --- a/packages/types/src/dal/repository-service.ts +++ b/packages/types/src/dal/repository-service.ts @@ -27,7 +27,14 @@ interface BaseRepositoryService { ): Promise } -export interface RepositoryService extends BaseRepositoryService { +type DtoBasedMutationMethods = "create" | "update" + +export interface RepositoryService< + T = any, + TDTOs extends { [K in DtoBasedMutationMethods]?: any } = { + [K in DtoBasedMutationMethods]?: any + } +> extends BaseRepositoryService { find(options?: FindOptions, context?: Context): Promise findAndCount( @@ -35,9 +42,9 @@ export interface RepositoryService extends BaseRepositoryService { context?: Context ): Promise<[T[], number]> - create(data: unknown[], context?: Context): Promise + create(data: TDTOs["create"][], context?: Context): Promise - update(data: unknown[], context?: Context): Promise + update(data: TDTOs["update"][], context?: Context): Promise delete(ids: string[], context?: Context): Promise @@ -59,7 +66,10 @@ export interface RepositoryService extends BaseRepositoryService { context?: Context ): Promise<[T[], Record]> - upsert?(data: unknown[], context?: Context): Promise + upsert( + data: (TDTOs["create"] | TDTOs["update"])[], + context?: Context + ): Promise } export interface TreeRepositoryService diff --git a/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts b/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts index 5adfae04a5..5cd91f6a0f 100644 --- a/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts +++ b/packages/utils/src/dal/mikro-orm/mikro-orm-repository.ts @@ -2,6 +2,7 @@ import { Context, DAL, FilterQuery as InternalFilterQuery, + RepositoryService, RepositoryTransformOptions, } from "@medusajs/types" import { @@ -16,9 +17,9 @@ import { EntityName, FilterQuery as MikroFilterQuery, } from "@mikro-orm/core/typings" -import { MedusaError, isString } from "../../common" +import { isString, MedusaError } from "../../common" import { MedusaContext } from "../../decorators" -import { InjectTransactionManager, buildQuery } from "../../modules-sdk" +import { buildQuery, InjectTransactionManager } from "../../modules-sdk" import { getSoftDeletedCascadedEntitiesIdsMappedBy, transactionWrapper, @@ -104,6 +105,10 @@ export class MikroOrmBaseRepository< throw new Error("Method not implemented.") } + upsert(data: unknown[], context: Context = {}): Promise { + throw new Error("Method not implemented.") + } + @InjectTransactionManager() async softDelete( idsOrFilter: string[] | InternalFilterQuery, @@ -228,7 +233,10 @@ export function mikroOrmBaseRepositoryFactory< [K in DtoBasedMutationMethods]?: any } >(entity: EntityClass | EntitySchema) { - class MikroOrmAbstractBaseRepository_ extends MikroOrmBaseRepository { + class MikroOrmAbstractBaseRepository_ + extends MikroOrmBaseRepository + implements RepositoryService + { // @ts-ignore constructor(...args: any[]) { // @ts-ignore @@ -411,6 +419,83 @@ export function mikroOrmBaseRepositoryFactory< findOptions_.options as MikroOptions ) } + + async upsert( + data: (TDTOs["create"] | TDTOs["update"])[], + context: Context = {} + ): Promise { + // TODO: Move this logic to the service packages/utils/src/modules-sdk/abstract-service-factory.ts + const manager = this.getActiveManager(context) + + const primaryKeys = + MikroOrmAbstractBaseRepository_.retrievePrimaryKeys(entity) + + let primaryKeysCriteria: { [key: string]: any }[] = [] + if (primaryKeys.length === 1) { + primaryKeysCriteria.push({ + [primaryKeys[0]]: data.map((d) => d[primaryKeys[0]]), + }) + } else { + primaryKeysCriteria = data.map((d) => ({ + $and: primaryKeys.map((key) => ({ [key]: d[key] })), + })) + } + + const allEntities = await Promise.all( + primaryKeysCriteria.map( + async (criteria) => + await this.find({ where: criteria } as DAL.FindOptions, context) + ) + ) + + const existingEntities = allEntities.flat() + + const existingEntitiesMap = new Map() + existingEntities.forEach((entity) => { + if (entity) { + const key = + MikroOrmAbstractBaseRepository_.buildUniqueCompositeKeyValue( + primaryKeys, + entity + ) + existingEntitiesMap.set(key, entity) + } + }) + + const upsertedEntities: T[] = [] + const createdEntities: T[] = [] + const updatedEntities: T[] = [] + + data.forEach((data_) => { + // In case the data provided are just strings, then we build an object with the primary key as the key and the data as the valuecd - + const key = + MikroOrmAbstractBaseRepository_.buildUniqueCompositeKeyValue( + primaryKeys, + data_ + ) + + const existingEntity = existingEntitiesMap.get(key) + if (existingEntity) { + const updatedType = manager.assign(existingEntity, data_) + updatedEntities.push(updatedType) + } else { + const newEntity = manager.create(entity, data_) + createdEntities.push(newEntity) + } + }) + + if (createdEntities.length) { + manager.persist(createdEntities) + upsertedEntities.push(...createdEntities) + } + + if (updatedEntities.length) { + manager.persist(updatedEntities) + upsertedEntities.push(...updatedEntities) + } + + return upsertedEntities + } } return MikroOrmAbstractBaseRepository_ diff --git a/packages/utils/src/dal/repository.ts b/packages/utils/src/dal/repository.ts index 062b0dcc77..0958676662 100644 --- a/packages/utils/src/dal/repository.ts +++ b/packages/utils/src/dal/repository.ts @@ -1,5 +1,6 @@ import { Context, DAL, RepositoryTransformOptions } from "@medusajs/types" import { MedusaContext } from "../decorators" +import { transactionWrapper } from "./utils" class AbstractBase { protected readonly manager_: any @@ -49,6 +50,8 @@ export abstract class AbstractBaseRepository abstract delete(ids: string[], context?: Context): Promise + abstract upsert(data: unknown[], context?: Context): Promise + abstract softDelete( ids: string[], context?: Context diff --git a/packages/utils/src/modules-sdk/abstract-service-factory.ts b/packages/utils/src/modules-sdk/abstract-service-factory.ts index b176d6ff45..c877acd549 100644 --- a/packages/utils/src/modules-sdk/abstract-service-factory.ts +++ b/packages/utils/src/modules-sdk/abstract-service-factory.ts @@ -64,6 +64,10 @@ export interface AbstractService< idsOrFilter: string[] | InternalFilterQuery, sharedContext?: Context ): Promise<[TEntity[], Record]> + upsert( + data: (TDTOs["create"] | TDTOs["update"])[], + sharedContext?: Context + ): Promise } export function abstractServiceFactory< @@ -75,7 +79,7 @@ export function abstractServiceFactory< >( model: new (...args: any[]) => any ): { - new (container: TContainer): AbstractService< + new (container: TContainer): AbstractService< TEntity, TContainer, TDTOs, @@ -237,6 +241,14 @@ export function abstractServiceFactory< sharedContext ) } + + @InjectTransactionManager(propertyRepositoryName) + async upsert( + data: (TDTOs["create"] | TDTOs["update"])[], + @MedusaContext() sharedContext: Context = {} + ): Promise { + return await this[propertyRepositoryName].upsert(data, sharedContext) + } } return AbstractService_ as unknown as new ( diff --git a/packages/utils/src/modules-sdk/index.ts b/packages/utils/src/modules-sdk/index.ts index b63a859db6..f4c31ebb23 100644 --- a/packages/utils/src/modules-sdk/index.ts +++ b/packages/utils/src/modules-sdk/index.ts @@ -2,6 +2,7 @@ export * from "./load-module-database-config" export * from "./decorators" export * from "./build-query" export * from "./loaders/mikro-orm-connection-loader" +export * from "./loaders/container-loader-factory" export * from "./create-pg-connection" export * from "./migration-scripts" export * from "./abstract-service-factory" diff --git a/packages/utils/src/modules-sdk/loaders/container-loader-factory.ts b/packages/utils/src/modules-sdk/loaders/container-loader-factory.ts new file mode 100644 index 0000000000..3d48981505 --- /dev/null +++ b/packages/utils/src/modules-sdk/loaders/container-loader-factory.ts @@ -0,0 +1,170 @@ +import { + Constructor, + LoaderOptions, + MedusaContainer, + ModuleServiceInitializeCustomDataLayerOptions, + ModuleServiceInitializeOptions, + RepositoryService, +} from "@medusajs/types" +import { lowerCaseFirst } from "../../common" +import { asClass } from "awilix" +import { abstractServiceFactory } from "../abstract-service-factory" +import { mikroOrmBaseRepositoryFactory } from "../../dal" + +type RepositoryLoaderOptions = { + moduleModels: Record + moduleRepositories?: Record + customRepositories: Record + container: MedusaContainer +} + +type ServiceLoaderOptions = { + moduleModels: Record + moduleServices: Record + container: MedusaContainer +} + +/** + * Factory for creating a container loader for a module. + * + * @param moduleModels + * @param moduleServices + * @param moduleRepositories + * @param customRepositoryLoader The default repository loader is based on mikro orm. If you want to use a custom repository loader, you can pass it here. + */ +export function moduleContainerLoaderFactory({ + moduleModels, + moduleServices, + moduleRepositories = {}, + customRepositoryLoader = loadModuleRepositories, +}: { + moduleModels: Record + moduleServices: Record + moduleRepositories?: Record + customRepositoryLoader?: (options: RepositoryLoaderOptions) => void +}): ({ container, options }: LoaderOptions) => Promise { + return async ({ + container, + options, + }: LoaderOptions< + | ModuleServiceInitializeOptions + | ModuleServiceInitializeCustomDataLayerOptions + >) => { + const customRepositories = ( + options as ModuleServiceInitializeCustomDataLayerOptions + )?.repositories + + loadModuleServices({ + moduleModels, + moduleServices, + container, + }) + + const repositoryLoader = customRepositoryLoader ?? loadModuleRepositories + repositoryLoader({ + moduleModels, + moduleRepositories, + customRepositories: customRepositories ?? {}, + container, + }) + } +} + +/** + * Load the services from the module services object. If a service is not + * present a default service will be created for the model. + * + * @param moduleModels + * @param moduleServices + * @param container + */ +export function loadModuleServices({ + moduleModels, + moduleServices, + container, +}: ServiceLoaderOptions) { + const moduleServicesMap = new Map( + Object.entries(moduleServices).map(([key, repository]) => [ + lowerCaseFirst(key), + repository, + ]) + ) + + // Build default services for all models that are not present in the module services + Object.values(moduleModels).forEach((Model) => { + const mappedServiceName = lowerCaseFirst(Model.name) + "Service" + const finalService = moduleServicesMap.get(mappedServiceName) + + if (!finalService) { + moduleServicesMap.set(mappedServiceName, abstractServiceFactory(Model)) + } + }) + + const allServices = [...moduleServicesMap] + + allServices.forEach(([key, service]) => { + container.register({ + [lowerCaseFirst(key)]: asClass(service as Constructor).singleton(), + }) + }) +} + +/** + * Load the repositories from the custom repositories object. If a repository is not + * present in the custom repositories object, the default repository will be used from the module repository. + * If none are present, a default repository will be created for the model. + * + * @param moduleModels + * @param moduleRepositories + * @param customRepositories + * @param container + */ +export function loadModuleRepositories({ + moduleModels, + moduleRepositories = {}, + customRepositories, + container, +}: RepositoryLoaderOptions) { + const customRepositoriesMap = new Map( + Object.entries(customRepositories).map(([key, repository]) => [ + lowerCaseFirst(key), + repository, + ]) + ) + const moduleRepositoriesMap = new Map( + Object.entries(moduleRepositories).map(([key, repository]) => [ + lowerCaseFirst(key), + repository, + ]) + ) + + // Build default repositories for all models that are not present in the custom repositories or module repositories + Object.values(moduleModels).forEach((Model) => { + const mappedRepositoryName = lowerCaseFirst(Model.name) + "Repository" + let finalRepository = customRepositoriesMap.get(mappedRepositoryName) + finalRepository ??= moduleRepositoriesMap.get(mappedRepositoryName) + + if (!finalRepository) { + moduleRepositoriesMap.set( + mappedRepositoryName, + mikroOrmBaseRepositoryFactory(Model) + ) + } + }) + + const allRepositories = [...customRepositoriesMap, ...moduleRepositoriesMap] + + allRepositories.forEach(([key, repository]) => { + let finalRepository = customRepositoriesMap.get(key) + + if (!finalRepository) { + finalRepository = repository + } + + container.register({ + [lowerCaseFirst(key)]: asClass( + finalRepository as Constructor + ).singleton(), + }) + }) +} diff --git a/yarn.lock b/yarn.lock index c945955f06..ee39d59dc0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7862,8 +7862,6 @@ __metadata: tsc-alias: ^1.8.6 typescript: ^5.1.6 bin: - medusa-authentication-migrations-down: dist/scripts/bin/run-migration-down.js - medusa-authentication-migrations-up: dist/scripts/bin/run-migration-up.js medusa-authentication-seed: dist/scripts/bin/run-seed.js languageName: unknown linkType: soft @@ -7921,8 +7919,6 @@ __metadata: tsc-alias: ^1.8.6 typescript: ^5.1.6 bin: - medusa-cart-migrations-down: dist/scripts/bin/run-migration-down.js - medusa-cart-migrations-up: dist/scripts/bin/run-migration-up.js medusa-cart-seed: dist/scripts/bin/run-seed.js languageName: unknown linkType: soft @@ -8453,8 +8449,6 @@ __metadata: tsc-alias: ^1.8.6 typescript: ^5.1.6 bin: - medusa-pricing-migrations-down: dist/scripts/bin/run-migration-down.js - medusa-pricing-migrations-up: dist/scripts/bin/run-migration-up.js medusa-pricing-seed: dist/scripts/bin/run-seed.js languageName: unknown linkType: soft @@ -8512,8 +8506,6 @@ __metadata: tsc-alias: ^1.8.6 typescript: ^5.1.6 bin: - medusa-promotion-migrations-down: dist/scripts/bin/run-migration-down.js - medusa-promotion-migrations-up: dist/scripts/bin/run-migration-up.js medusa-promotion-seed: dist/scripts/bin/run-seed.js languageName: unknown linkType: soft