From 1d91b7429beebd6f09d5027f7f7e1fe74ce3a8ff Mon Sep 17 00:00:00 2001 From: Adrien de Peretti Date: Mon, 19 Feb 2024 13:33:46 +0100 Subject: [PATCH] feat(fulfillment): implementation part 2 (#6408) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **What** > [!NOTE] > I can see this pr becoming huge, so I d like to get this partial one merged 👍 - Fixes shared connection usage (mikro orm compare the instance to its own package and therefore was resulting in not trully reusing the provided connection leading to exhausting the connection pool as multiple connections was created and end up not being all destroyed properly under the hood, discovered in my integration tests) - Create shipping options method implementation - DTO's definition and service interface update - integration tests - Re work of the indexes with new util update - Test runner utils to remove a big chunk of the boilerplate of the packages integrations FIXES CORE-1742 --- .changeset/real-teachers-yawn.md | 8 + .../auth/integration-tests/utils/database.ts | 12 +- .../cart/integration-tests/utils/database.ts | 12 +- .../integration-tests/utils/database.ts | 12 +- .../integration-tests/__fixtures__/index.ts | 1 - .../fulfillment-module-service.spec.ts | 2569 +++++++++-------- .../integration-tests/setup-env.js | 6 - .../fulfillment/integration-tests/setup.js | 3 - .../integration-tests/utils/database.ts | 13 - .../utils/get-init-module-config.ts | 33 - .../integration-tests/utils/index.ts | 2 - packages/fulfillment/jest.config.js | 3 +- packages/fulfillment/package.json | 2 +- .../.snapshot-medusa-fulfillment.json | 122 +- ...14103108.ts => Migration20240219115644.ts} | 25 +- packages/fulfillment/src/models/address.ts | 23 +- .../src/models/fulfillment-item.ts | 45 +- .../src/models/fulfillment-label.ts | 23 +- .../fulfillment/src/models/fulfillment.ts | 53 +- .../fulfillment/src/models/fullfilment-set.ts | 23 +- packages/fulfillment/src/models/geo-zone.ts | 56 +- .../src/models/service-provider.ts | 12 +- .../fulfillment/src/models/service-zone.ts | 22 +- .../src/models/shipping-option-rule.ts | 26 +- .../src/models/shipping-option-type.ts | 29 +- .../fulfillment/src/models/shipping-option.ts | 101 +- .../src/models/shipping-profile.ts | 26 +- packages/fulfillment/src/module-definition.ts | 2 +- .../services/fulfillment-module-service.ts | 142 +- packages/medusa-test-utils/src/database.ts | 62 +- packages/medusa-test-utils/src/index.ts | 1 + .../medusa-test-utils/src/init-modules.ts | 28 +- .../src/module-test-runner.ts | 128 + .../order/integration-tests/utils/database.ts | 7 +- .../integration-tests/utils/database.ts | 14 +- .../integration-tests/utils/database.ts | 12 +- .../integration-tests/__tests__/module.ts | 2 +- .../integration-tests/utils/database.ts | 14 +- .../integration-tests/utils/database.ts | 14 +- .../integration-tests/utils/database.ts | 14 +- .../tax/integration-tests/utils/database.ts | 7 +- packages/types/src/dal/index.ts | 2 +- .../src/fulfillment/common/service-zone.ts | 6 +- .../common/shipping-option-rule.ts | 10 +- .../common/shipping-option-type.ts | 10 +- .../src/fulfillment/common/shipping-option.ts | 11 +- .../fulfillment/common/shipping-profile.ts | 15 +- .../src/fulfillment/mutations/geo-zone.ts | 18 +- .../types/src/fulfillment/mutations/index.ts | 1 + .../src/fulfillment/mutations/service-zone.ts | 22 +- .../fulfillment/mutations/shipping-option.ts | 16 +- .../fulfillment/mutations/shipping-profile.ts | 8 + packages/types/src/fulfillment/service.ts | 90 + .../user/integration-tests/utils/database.ts | 14 +- .../__tests__/create-psql-index-helper.ts | 2 +- .../src/common/create-psql-index-helper.ts | 4 +- .../abstract-module-service-factory.ts | 7 - .../src/modules-sdk/create-pg-connection.ts | 2 +- .../integration-tests/__tests__/index.spec.ts | 7 +- 59 files changed, 2213 insertions(+), 1741 deletions(-) create mode 100644 .changeset/real-teachers-yawn.md delete mode 100644 packages/fulfillment/integration-tests/__fixtures__/index.ts delete mode 100644 packages/fulfillment/integration-tests/setup-env.js delete mode 100644 packages/fulfillment/integration-tests/setup.js delete mode 100644 packages/fulfillment/integration-tests/utils/database.ts delete mode 100644 packages/fulfillment/integration-tests/utils/get-init-module-config.ts delete mode 100644 packages/fulfillment/integration-tests/utils/index.ts rename packages/fulfillment/src/migrations/{Migration20240214103108.ts => Migration20240219115644.ts} (86%) create mode 100644 packages/medusa-test-utils/src/module-test-runner.ts create mode 100644 packages/types/src/fulfillment/mutations/shipping-profile.ts diff --git a/.changeset/real-teachers-yawn.md b/.changeset/real-teachers-yawn.md new file mode 100644 index 0000000000..37a5f48bf3 --- /dev/null +++ b/.changeset/real-teachers-yawn.md @@ -0,0 +1,8 @@ +--- +"@medusajs/medusa": patch +"medusa-test-utils": patch +"@medusajs/product": patch +"@medusajs/types": patch +--- + +feat(fulfillment): implementation part 2 diff --git a/packages/auth/integration-tests/utils/database.ts b/packages/auth/integration-tests/utils/database.ts index c510b64d39..2b708a0eb7 100644 --- a/packages/auth/integration-tests/utils/database.ts +++ b/packages/auth/integration-tests/utils/database.ts @@ -5,14 +5,14 @@ import { TestDatabaseUtils } from "medusa-test-utils" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = AuthModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/cart/integration-tests/utils/database.ts b/packages/cart/integration-tests/utils/database.ts index c385f6d4b4..1fc3ae99c0 100644 --- a/packages/cart/integration-tests/utils/database.ts +++ b/packages/cart/integration-tests/utils/database.ts @@ -5,14 +5,14 @@ import * as CartModels from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = CartModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/customer/integration-tests/utils/database.ts b/packages/customer/integration-tests/utils/database.ts index 118464d4d7..284863d2c7 100644 --- a/packages/customer/integration-tests/utils/database.ts +++ b/packages/customer/integration-tests/utils/database.ts @@ -5,14 +5,14 @@ import * as Models from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = Models as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/fulfillment/integration-tests/__fixtures__/index.ts b/packages/fulfillment/integration-tests/__fixtures__/index.ts deleted file mode 100644 index 172f1ae6a4..0000000000 --- a/packages/fulfillment/integration-tests/__fixtures__/index.ts +++ /dev/null @@ -1 +0,0 @@ -// noop diff --git a/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service.spec.ts b/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service.spec.ts index eb85670c2e..5922f8e9b6 100644 --- a/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service.spec.ts +++ b/packages/fulfillment/integration-tests/__tests__/fulfillment-module-service.spec.ts @@ -1,403 +1,526 @@ import { Modules } from "@medusajs/modules-sdk" -import { initModules } from "medusa-test-utils/dist" import { CreateFulfillmentSetDTO, CreateGeoZoneDTO, CreateServiceZoneDTO, + CreateShippingOptionDTO, + CreateShippingProfileDTO, GeoZoneDTO, IFulfillmentModuleService, ServiceZoneDTO, UpdateFulfillmentSetDTO, UpdateGeoZoneDTO, + UpdateServiceZoneDTO, } from "@medusajs/types" -import { getInitModuleConfig, MikroOrmWrapper } from "../utils" import { GeoZoneType } from "@medusajs/utils" +import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils" -describe("fulfillment module service", function () { - let service: IFulfillmentModuleService - let shutdownFunc: () => Promise +jest.setTimeout(100000) - beforeAll(async () => { - const initModulesConfig = getInitModuleConfig() - - const { medusaApp, shutdown } = await initModules(initModulesConfig) - - service = medusaApp.modules[Modules.FULFILLMENT] - - shutdownFunc = shutdown - }) - - beforeEach(async () => { - await MikroOrmWrapper.setupDatabase() - }) - - afterEach(async () => { - await MikroOrmWrapper.clearDatabase() - }) - - afterAll(async () => { - await shutdownFunc() - }) - - describe("read", () => { - describe("fulfillment set", () => { - it("should list fulfillment sets with a filter", async function () { - const createdSet1 = await service.create({ - name: "test", - type: "test-type", - }) - const createdSet2 = await service.create({ - name: "test2", - type: "test-type", - service_zones: [ - { +moduleIntegrationTestRunner({ + moduleName: Modules.FULFILLMENT, + testSuite: ({ + MikroOrmWrapper, + service, + }: SuiteOptions) => { + describe("Fulfillment Module Service", () => { + describe("read", () => { + describe("fulfillment set", () => { + it("should list fulfillment sets with a filter", async function () { + const createdSet1 = await service.create({ name: "test", + type: "test-type", + }) + const createdSet2 = await service.create({ + name: "test2", + type: "test-type", + service_zones: [ + { + name: "test", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + }) + + let listedSets = await service.list({ + type: createdSet1.type, + }) + + expect(listedSets).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet1.id }), + expect.objectContaining({ id: createdSet2.id }), + ]) + ) + + listedSets = await service.list({ + name: createdSet2.name, + }) + + expect(listedSets).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet2.id }), + ]) + ) + expect(listedSets).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet1.id }), + ]) + ) + + listedSets = await service.list({ + service_zones: { name: "test" }, + }) + + expect(listedSets).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet2.id }), + ]) + ) + expect(listedSets).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet1.id }), + ]) + ) + + listedSets = await service.list({ + service_zones: { geo_zones: { country_code: "fr" } }, + }) + + expect(listedSets).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet2.id }), + ]) + ) + expect(listedSets).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdSet1.id }), + ]) + ) + }) + }) + + describe("service zones", () => { + it("should list service zones with a filter", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + + const createdZone1 = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) + const createdZone2 = await service.createServiceZones({ + name: "test2", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, country_code: "fr", }, ], - }, - ], + }) + + let listedZones = await service.listServiceZones({ + name: createdZone2.name, + }) + + expect(listedZones).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone2.id }), + ]) + ) + expect(listedZones).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone1.id }), + ]) + ) + + listedZones = await service.listServiceZones({ + geo_zones: { country_code: "fr" }, + }) + + expect(listedZones).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone2.id }), + ]) + ) + expect(listedZones).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone1.id }), + ]) + ) + }) }) - let listedSets = await service.list({ type: createdSet1.type }) + describe("geo zones", () => { + it("should list geo zones with a filter", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) - expect(listedSets).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet1.id }), - expect.objectContaining({ id: createdSet2.id }), - ]) - ) - - listedSets = await service.list({ name: createdSet2.name }) - - expect(listedSets).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet2.id }), - ]) - ) - expect(listedSets).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet1.id }), - ]) - ) - - listedSets = await service.list({ service_zones: { name: "test" } }) - - expect(listedSets).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet2.id }), - ]) - ) - expect(listedSets).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet1.id }), - ]) - ) - - listedSets = await service.list({ - service_zones: { geo_zones: { country_code: "fr" } }, - }) - - expect(listedSets).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet2.id }), - ]) - ) - expect(listedSets).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdSet1.id }), - ]) - ) - }) - }) - - describe("service zones", () => { - it("should list service zones with a filter", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - - const createdZone1 = await service.createServiceZones({ - name: "test", - fulfillment_set_id: fulfillmentSet.id, - }) - const createdZone2 = await service.createServiceZones({ - name: "test2", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { + const createdZone1 = await service.createGeoZones({ + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, country_code: "fr", - }, - ], - }) - - let listedZones = await service.listServiceZones({ - name: createdZone2.name, - }) - - expect(listedZones).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone2.id }), - ]) - ) - expect(listedZones).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone1.id }), - ]) - ) - - listedZones = await service.listServiceZones({ - geo_zones: { country_code: "fr" }, - }) - - expect(listedZones).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone2.id }), - ]) - ) - expect(listedZones).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone1.id }), - ]) - ) - }) - }) - - describe("geo zones", () => { - it("should list geo zones with a filter", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - const serviceZone = await service.createServiceZones({ - name: "test", - fulfillment_set_id: fulfillmentSet.id, - }) - - const createdZone1 = await service.createGeoZones({ - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "fr", - }) - const createdZone2 = await service.createGeoZones({ - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "us", - }) - - let listedZones = await service.listGeoZones({ - type: createdZone1.type, - }) - - expect(listedZones).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone1.id }), - expect.objectContaining({ id: createdZone2.id }), - ]) - ) - - listedZones = await service.listGeoZones({ - country_code: createdZone2.country_code, - }) - - expect(listedZones).toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone2.id }), - ]) - ) - expect(listedZones).not.toEqual( - expect.arrayContaining([ - expect.objectContaining({ id: createdZone1.id }), - ]) - ) - }) - }) - }) - - describe("mutations", () => { - describe("on create", () => { - it("should create a new fulfillment set", async function () { - const data: CreateFulfillmentSetDTO = { - name: "test", - type: "test-type", - } - - const fulfillmentSet = await service.create(data) - - expect(fulfillmentSet).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data.name, - type: data.type, - }) - ) - }) - - it("should create a collection of fulfillment sets", async function () { - const data = [ - { - name: "test", - type: "test-type", - }, - { - name: "test2", - type: "test-type2", - }, - ] - - const fulfillmentSets = await service.create(data) - - expect(fulfillmentSets).toHaveLength(2) - - let i = 0 - for (const data_ of data) { - expect(fulfillmentSets[i]).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data_.name, - type: data_.type, }) - ) - ++i - } + const createdZone2 = await service.createGeoZones({ + service_zone_id: serviceZone.id, + type: GeoZoneType.COUNTRY, + country_code: "us", + }) + + let listedZones = await service.listGeoZones({ + type: createdZone1.type, + }) + + expect(listedZones).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone1.id }), + expect.objectContaining({ id: createdZone2.id }), + ]) + ) + + listedZones = await service.listGeoZones({ + country_code: createdZone2.country_code, + }) + + expect(listedZones).toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone2.id }), + ]) + ) + expect(listedZones).not.toEqual( + expect.arrayContaining([ + expect.objectContaining({ id: createdZone1.id }), + ]) + ) + }) + }) }) - it("should create a new fulfillment set with new service zones", async function () { - const data = { - name: "test", - type: "test-type", - service_zones: [ - { + describe("mutations", () => { + describe("on create", () => { + it("should create a new fulfillment set", async function () { + const data: CreateFulfillmentSetDTO = { name: "test", - }, - ], - } + type: "test-type", + } - const fulfillmentSet = await service.create(data) + const fulfillmentSet = await service.create(data) - expect(fulfillmentSet).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data.name, - type: data.type, - service_zones: expect.arrayContaining([ + expect(fulfillmentSet).toEqual( expect.objectContaining({ id: expect.any(String), - name: data.service_zones[0].name, - }), - ]), + name: data.name, + type: data.type, + }) + ) }) - ) - }) - it("should create a collection of fulfillment sets with new service zones", async function () { - const data = [ - { - name: "test", - type: "test-type", - service_zones: [ + it("should create a collection of fulfillment sets", async function () { + const data = [ { name: "test", + type: "test-type", }, - ], - }, - { - name: "test2", - type: "test-type2", - service_zones: [ { name: "test2", + type: "test-type2", }, - ], - }, - { - name: "test3", - type: "test-type3", - service_zones: [ - { - name: "test3", - }, - ], - }, - ] + ] - const fulfillmentSets = await service.create(data) + const fulfillmentSets = await service.create(data) - expect(fulfillmentSets).toHaveLength(3) + expect(fulfillmentSets).toHaveLength(2) - let i = 0 - for (const data_ of data) { - expect(fulfillmentSets[i]).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data_.name, - type: data_.type, - service_zones: expect.arrayContaining([ + let i = 0 + for (const data_ of data) { + expect(fulfillmentSets[i]).toEqual( expect.objectContaining({ id: expect.any(String), - name: data_.service_zones[0].name, - }), - ]), - }) - ) - ++i - } - }) + name: data_.name, + type: data_.type, + }) + ) + ++i + } + }) - it("should create a new fulfillment set with new service zones and new geo zones", async function () { - const data: CreateFulfillmentSetDTO = { - name: "test", - type: "test-type", - service_zones: [ - { + it("should create a new fulfillment set with new service zones", async function () { + const data = { name: "test", + type: "test-type", + service_zones: [ + { + name: "test", + }, + ], + } + + const fulfillmentSet = await service.create(data) + + expect(fulfillmentSet).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: data.name, + type: data.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + name: data.service_zones[0].name, + }), + ]), + }) + ) + }) + + it("should create a collection of fulfillment sets with new service zones", async function () { + const data = [ + { + name: "test", + type: "test-type", + service_zones: [ + { + name: "test", + }, + ], + }, + { + name: "test2", + type: "test-type2", + service_zones: [ + { + name: "test2", + }, + ], + }, + { + name: "test3", + type: "test-type3", + service_zones: [ + { + name: "test3", + }, + ], + }, + ] + + const fulfillmentSets = await service.create(data) + + expect(fulfillmentSets).toHaveLength(3) + + let i = 0 + for (const data_ of data) { + expect(fulfillmentSets[i]).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: data_.name, + type: data_.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + name: data_.service_zones[0].name, + }), + ]), + }) + ) + ++i + } + }) + + it("should create a new fulfillment set with new service zones and new geo zones", async function () { + const data: CreateFulfillmentSetDTO = { + name: "test", + type: "test-type", + service_zones: [ + { + name: "test", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + } + + const fulfillmentSet = await service.create(data) + + expect(fulfillmentSet).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: data.name, + type: data.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + name: (data.service_zones![0] as any).name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + type: (data.service_zones![0] as any).geo_zones[0].type, + country_code: (data.service_zones![0] as any) + .geo_zones[0].country_code, + }), + ]), + }), + ]), + }) + ) + }) + + it("should create a collection of fulfillment sets with new service zones and new geo zones", async function () { + const data: CreateFulfillmentSetDTO[] = [ + { + name: "test", + type: "test-type", + service_zones: [ + { + name: "test", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + }, + { + name: "test2", + type: "test-type2", + service_zones: [ + { + name: "test2", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + }, + { + name: "test3", + type: "test-type3", + service_zones: [ + { + name: "test3", + geo_zones: [ + { + type: GeoZoneType.CITY, + country_code: "fr", + city: "lyon", + }, + ], + }, + ], + }, + ] + + const fulfillmentSets = await service.create(data) + + expect(fulfillmentSets).toHaveLength(3) + + let i = 0 + for (const data_ of data) { + expect(fulfillmentSets[i]).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: data_.name, + type: data_.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + name: (data_.service_zones![0] as any).name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + type: (data_.service_zones![0] as any).geo_zones[0] + .type, + country_code: (data_.service_zones![0] as any) + .geo_zones[0].country_code, + }), + ]), + }), + ]), + }) + ) + ++i + } + }) + + it(`should fail on duplicated fulfillment set name`, async function () { + const data: CreateFulfillmentSetDTO = { + name: "test", + type: "test-type", + } + + await service.create(data) + const err = await service.create(data).catch((e) => e) + + expect(err).toBeDefined() + expect(err.constraint).toBe("IDX_fulfillment_set_name_unique") + }) + }) + + describe("on create service zones", () => { + it("should create a new service zone", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + + const data: CreateServiceZoneDTO = { + name: "test", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, country_code: "fr", }, ], - }, - ], - } + } - const fulfillmentSet = await service.create(data) + const serviceZone = await service.createServiceZones(data) - expect(fulfillmentSet).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data.name, - type: data.type, - service_zones: expect.arrayContaining([ + expect(serviceZone).toEqual( expect.objectContaining({ id: expect.any(String), - name: (data.service_zones![0] as any).name, + name: data.name, geo_zones: expect.arrayContaining([ expect.objectContaining({ - type: (data.service_zones![0] as any).geo_zones[0].type, - country_code: (data.service_zones![0] as any).geo_zones[0] + type: (data.geo_zones![0] as GeoZoneDTO).type, + country_code: (data.geo_zones![0] as GeoZoneDTO) .country_code, }), ]), - }), - ]), + }) + ) }) - ) - }) - it("should create a collection of fulfillment sets with new service zones and new geo zones", async function () { - const data: CreateFulfillmentSetDTO[] = [ - { - name: "test", - type: "test-type", - service_zones: [ + it("should create a collection of service zones", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + + const data: CreateServiceZoneDTO[] = [ { name: "test", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, @@ -405,14 +528,9 @@ describe("fulfillment module service", function () { }, ], }, - ], - }, - { - name: "test2", - type: "test-type2", - service_zones: [ { name: "test2", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, @@ -420,502 +538,896 @@ describe("fulfillment module service", function () { }, ], }, - ], - }, - { - name: "test3", - type: "test-type3", - service_zones: [ { name: "test3", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { - type: GeoZoneType.CITY, - country_code: "fr", - city: "lyon", + type: GeoZoneType.COUNTRY, + country_code: "uk", }, ], }, - ], - }, - ] + ] - const fulfillmentSets = await service.create(data) + const serviceZones = await service.createServiceZones(data) - expect(fulfillmentSets).toHaveLength(3) + expect(serviceZones).toHaveLength(3) - let i = 0 - for (const data_ of data) { - expect(fulfillmentSets[i]).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data_.name, - type: data_.type, - service_zones: expect.arrayContaining([ + let i = 0 + for (const data_ of data) { + expect(serviceZones[i]).toEqual( expect.objectContaining({ id: expect.any(String), - name: (data_.service_zones![0] as any).name, + name: data_.name, geo_zones: expect.arrayContaining([ expect.objectContaining({ - type: (data_.service_zones![0] as any).geo_zones[0].type, - country_code: (data_.service_zones![0] as any) - .geo_zones[0].country_code, + type: (data_.geo_zones![0] as GeoZoneDTO).type, + country_code: (data_.geo_zones![0] as GeoZoneDTO) + .country_code, }), ]), - }), - ]), + }) + ) + ++i + } + }) + + it("should fail on duplicated service zone name", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", }) - ) - ++i - } - }) - it(`should fail on duplicated fulfillment set name`, async function () { - const data: CreateFulfillmentSetDTO = { - name: "test", - type: "test-type", - } + const data: CreateServiceZoneDTO = { + name: "test", + fulfillment_set_id: fulfillmentSet.id, + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + } - await service.create(data) - const err = await service.create(data).catch((e) => e) + await service.createServiceZones(data) + const err = await service.createServiceZones(data).catch((e) => e) - expect(err).toBeDefined() - expect(err.constraint).toBe("IDX_fulfillment_set_name_unique") - }) - }) - - describe("on create service zones", () => { - it("should create a new service zone", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", + expect(err).toBeDefined() + expect(err.constraint).toBe("IDX_service_zone_name_unique") + }) }) - const data: CreateServiceZoneDTO = { - name: "test", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { + describe("on create geo zones", () => { + it("should create a new geo zone", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) + + const data: CreateGeoZoneDTO = { + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, country_code: "fr", - }, - ], - } + } - const serviceZone = await service.createServiceZones(data) + const geoZone = await service.createGeoZones(data) - expect(serviceZone).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data.name, - geo_zones: expect.arrayContaining([ + expect(geoZone).toEqual( expect.objectContaining({ - type: (data.geo_zones![0] as GeoZoneDTO).type, - country_code: (data.geo_zones![0] as GeoZoneDTO).country_code, - }), - ]), + id: expect.any(String), + type: data.type, + country_code: data.country_code, + }) + ) }) - ) - }) - it("should create a collection of service zones", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) + it("should create a collection of geo zones", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) - const data: CreateServiceZoneDTO[] = [ - { - name: "test", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ + const data: CreateGeoZoneDTO[] = [ { + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, country_code: "fr", }, - ], - }, - { - name: "test2", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ { + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, - country_code: "fr", + country_code: "us", }, - ], - }, - { - name: "test3", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "uk", - }, - ], - }, - ] + ] - const serviceZones = await service.createServiceZones(data) + const geoZones = await service.createGeoZones(data) - expect(serviceZones).toHaveLength(3) + expect(geoZones).toHaveLength(2) - let i = 0 - for (const data_ of data) { - expect(serviceZones[i]).toEqual( - expect.objectContaining({ - id: expect.any(String), - name: data_.name, - geo_zones: expect.arrayContaining([ + let i = 0 + for (const data_ of data) { + expect(geoZones[i]).toEqual( expect.objectContaining({ - type: (data_.geo_zones![0] as GeoZoneDTO).type, - country_code: (data_.geo_zones![0] as GeoZoneDTO) - .country_code, - }), - ]), - }) - ) - ++i - } - }) - - it("should fail on duplicated service zone name", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - - const data: CreateServiceZoneDTO = { - name: "test", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "fr", - }, - ], - } - - await service.createServiceZones(data) - const err = await service.createServiceZones(data).catch((e) => e) - - expect(err).toBeDefined() - expect(err.constraint).toBe("IDX_service_zone_name_unique") - }) - }) - - describe("on create geo zones", () => { - it("should create a new geo zone", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - const serviceZone = await service.createServiceZones({ - name: "test", - fulfillment_set_id: fulfillmentSet.id, - }) - - const data: CreateGeoZoneDTO = { - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "fr", - } - - const geoZone = await service.createGeoZones(data) - - expect(geoZone).toEqual( - expect.objectContaining({ - id: expect.any(String), - type: data.type, - country_code: data.country_code, + id: expect.any(String), + type: data_.type, + country_code: data_.country_code, + }) + ) + ++i + } }) - ) - }) - - it("should create a collection of geo zones", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - const serviceZone = await service.createServiceZones({ - name: "test", - fulfillment_set_id: fulfillmentSet.id, }) - const data: CreateGeoZoneDTO[] = [ - { - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "fr", - }, - { - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "us", - }, - ] + describe("on create shipping profiles", () => { + it("should create a new shipping profile", async function () { + const createData: CreateShippingProfileDTO = { + name: "test-default-profile", + type: "default", + } - const geoZones = await service.createGeoZones(data) + const createdShippingProfile = await service.createShippingProfiles( + createData + ) - expect(geoZones).toHaveLength(2) - - let i = 0 - for (const data_ of data) { - expect(geoZones[i]).toEqual( - expect.objectContaining({ - id: expect.any(String), - type: data_.type, - country_code: data_.country_code, - }) - ) - ++i - } - }) - }) - - describe("on update", () => { - it("should update an existing fulfillment set", async function () { - const createData: CreateFulfillmentSetDTO = { - name: "test", - type: "test-type", - } - - const createdFulfillmentSet = await service.create(createData) - - const updateData = { - id: createdFulfillmentSet.id, - name: "updated-test", - type: "updated-test-type", - } - - const updatedFulfillmentSets = await service.update(updateData) - - expect(updatedFulfillmentSets).toEqual( - expect.objectContaining({ - id: createdFulfillmentSet.id, - name: updateData.name, - type: updateData.type, - }) - ) - }) - - it("should update a collection of fulfillment sets", async function () { - const createData = [ - { - name: "test", - type: "test-type", - }, - { - name: "test2", - type: "test-type2", - }, - ] - - const createdFulfillmentSets = await service.create(createData) - - const updateData = createdFulfillmentSets.map( - (fulfillmentSet, index) => ({ - id: fulfillmentSet.id, - name: `updated-test${index + 1}`, - type: `updated-test-type${index + 1}`, - }) - ) - - const updatedFulfillmentSets = await service.update(updateData) - - expect(updatedFulfillmentSets).toHaveLength(2) - - let i = 0 - for (const data_ of updateData) { - expect(updatedFulfillmentSets[i]).toEqual( - expect.objectContaining({ - id: createdFulfillmentSets[i].id, - name: data_.name, - type: data_.type, - }) - ) - ++i - } - }) - - it("should update an existing fulfillment set and replace old service zones by a new one", async function () { - const createData: CreateFulfillmentSetDTO = { - name: "test", - type: "test-type", - service_zones: [ - { - name: "service-zone-test", - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "fr", - }, - ], - }, - ], - } - - const createdFulfillmentSet = await service.create(createData) - - const createServiceZoneData: CreateServiceZoneDTO = { - fulfillment_set_id: createdFulfillmentSet.id, - name: "service-zone-test2", - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "us", - }, - ], - } - - const updateData: UpdateFulfillmentSetDTO = { - id: createdFulfillmentSet.id, - name: "updated-test", - type: "updated-test-type", - service_zones: [createServiceZoneData], - } - - const updatedFulfillmentSet = await service.update(updateData) - - expect(updatedFulfillmentSet).toEqual( - expect.objectContaining({ - id: updateData.id, - name: updateData.name, - type: updateData.type, - service_zones: expect.arrayContaining([ + expect(createdShippingProfile).toEqual( expect.objectContaining({ - id: expect.any(String), - name: (updateData.service_zones![0] as ServiceZoneDTO).name, - geo_zones: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(String), - type: (updateData.service_zones![0] as ServiceZoneDTO) - .geo_zones[0].type, - country_code: ( - updateData.service_zones![0] as ServiceZoneDTO - ).geo_zones[0].country_code, - }), - ]), - }), - ]), + name: createData.name, + type: createData.type, + }) + ) }) - ) - const serviceZones = await service.listServiceZones() - - expect(serviceZones).toHaveLength(1) - expect(serviceZones[0]).toEqual( - expect.objectContaining({ - id: updatedFulfillmentSet.service_zones[0].id, - }) - ) - }) - - it("should update an existing fulfillment set and add a new service zone", async function () { - const createData: CreateFulfillmentSetDTO = { - name: "test", - type: "test-type", - service_zones: [ - { - name: "service-zone-test", - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "fr", - }, - ], - }, - ], - } - - const createdFulfillmentSet = await service.create(createData) - - const createServiceZoneData: CreateServiceZoneDTO = { - fulfillment_set_id: createdFulfillmentSet.id, - name: "service-zone-test2", - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "us", - }, - ], - } - - const updateData: UpdateFulfillmentSetDTO = { - id: createdFulfillmentSet.id, - name: "updated-test", - type: "updated-test-type", - service_zones: [ - { id: createdFulfillmentSet.service_zones[0].id }, - createServiceZoneData, - ], - } - - const updatedFulfillmentSet = await service.update(updateData) - - expect(updatedFulfillmentSet).toEqual( - expect.objectContaining({ - id: updateData.id, - name: updateData.name, - type: updateData.type, - service_zones: expect.arrayContaining([ - expect.objectContaining({ - id: createdFulfillmentSet.service_zones[0].id, - }), - expect.objectContaining({ - id: expect.any(String), - name: (updateData.service_zones![1] as ServiceZoneDTO).name, - geo_zones: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(String), - type: (updateData.service_zones![1] as ServiceZoneDTO) - .geo_zones[0].type, - country_code: ( - updateData.service_zones![1] as ServiceZoneDTO - ).geo_zones[0].country_code, - }), - ]), - }), - ]), - }) - ) - }) - - it("should fail on duplicated fulfillment set name", async function () { - const createData = [ - { - name: "test", - type: "test-type", - }, - { - name: "test2", - type: "test-type2", - }, - ] - - const createdFulfillmentSets = await service.create(createData) - - const updateData = { - id: createdFulfillmentSets[1].id, - name: "test", // This is the name of the first fulfillment set - type: "updated-test-type2", - } - - const err = await service.update(updateData).catch((e) => e) - - expect(err).toBeDefined() - expect(err.constraint).toBe("IDX_fulfillment_set_name_unique") - }) - - it("should update a collection of fulfillment sets and replace old service zones by new ones", async function () { - const createData: CreateFulfillmentSetDTO[] = [ - { - name: "test1", - type: "test-type1", - service_zones: [ + it("should create multiple new shipping profiles", async function () { + const createData: CreateShippingProfileDTO[] = [ { - name: "service-zone-test1", + name: "test-profile-1", + type: "default", + }, + { + name: "test-profile-2", + type: "custom", + }, + ] + + const createdShippingProfiles = + await service.createShippingProfiles(createData) + + expect(createdShippingProfiles).toHaveLength(2) + + let i = 0 + for (const data_ of createData) { + expect(createdShippingProfiles[i]).toEqual( + expect.objectContaining({ + name: data_.name, + type: data_.type, + }) + ) + ++i + } + }) + + it("should fail on duplicated shipping profile name", async function () { + const createData: CreateShippingProfileDTO = { + name: "test-default-profile", + type: "default", + } + + await service.createShippingProfiles(createData) + + const err = await service + .createShippingProfiles(createData) + .catch((e) => e) + + expect(err).toBeDefined() + expect(err.constraint).toBe("IDX_shipping_profile_name_unique") + }) + }) + + describe("on create shipping options", () => { + it("should create a new shipping option", async function () { + const shippingProfile = await service.createShippingProfiles({ + name: "test", + type: "default", + }) + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) + + // TODO: change that for a real provider instead of fake data manual inserted data + const [{ id: providerId }] = + await MikroOrmWrapper.forkManager().execute( + "insert into service_provider (id) values ('sp_jdafwfleiwuonl') returning id" + ) + + const createData: CreateShippingOptionDTO = { + name: "test-option", + price_type: "flat", + service_zone_id: serviceZone.id, + shipping_profile_id: shippingProfile.id, + service_provider_id: providerId, + type: { + code: "test-type", + description: "test-description", + label: "test-label", + }, + data: { + amount: 1000, + }, + rules: [ + { + attribute: "test-attribute", + operator: "in", + value: "test-value", + }, + ], + } + + const createdShippingOption = await service.createShippingOptions( + createData + ) + + expect(createdShippingOption).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: createData.name, + price_type: createData.price_type, + service_zone_id: createData.service_zone_id, + shipping_profile_id: createData.shipping_profile_id, + service_provider_id: createData.service_provider_id, + shipping_option_type_id: expect.any(String), + type: expect.objectContaining({ + id: expect.any(String), + code: createData.type.code, + description: createData.type.description, + label: createData.type.label, + }), + data: createData.data, + rules: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + attribute: createData.rules![0].attribute, + operator: createData.rules![0].operator, + value: createData.rules![0].value, + }), + ]), + }) + ) + }) + + it("should create multiple new shipping options", async function () { + const shippingProfile = await service.createShippingProfiles({ + name: "test", + type: "default", + }) + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) + + // TODO: change that for a real provider instead of fake data manual inserted data + const [{ id: providerId }] = + await MikroOrmWrapper.forkManager().execute( + "insert into service_provider (id) values ('sp_jdafwfleiwuonl') returning id" + ) + + const createData: CreateShippingOptionDTO[] = [ + { + name: "test-option", + price_type: "flat", + service_zone_id: serviceZone.id, + shipping_profile_id: shippingProfile.id, + service_provider_id: providerId, + type: { + code: "test-type", + description: "test-description", + label: "test-label", + }, + data: { + amount: 1000, + }, + rules: [ + { + attribute: "test-attribute", + operator: "in", + value: "test-value", + }, + ], + }, + { + name: "test-option-2", + price_type: "calculated", + service_zone_id: serviceZone.id, + shipping_profile_id: shippingProfile.id, + service_provider_id: providerId, + type: { + code: "test-type", + description: "test-description", + label: "test-label", + }, + data: { + amount: 1000, + }, + rules: [ + { + attribute: "test-attribute", + operator: "in", + value: "test-value", + }, + ], + }, + ] + + const createdShippingOptions = await service.createShippingOptions( + createData + ) + + expect(createdShippingOptions).toHaveLength(2) + + let i = 0 + for (const data_ of createData) { + expect(createdShippingOptions[i]).toEqual( + expect.objectContaining({ + id: expect.any(String), + name: data_.name, + price_type: data_.price_type, + service_zone_id: data_.service_zone_id, + shipping_profile_id: data_.shipping_profile_id, + service_provider_id: data_.service_provider_id, + shipping_option_type_id: expect.any(String), + type: expect.objectContaining({ + id: expect.any(String), + code: data_.type.code, + description: data_.type.description, + label: data_.type.label, + }), + data: data_.data, + rules: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + attribute: data_.rules![0].attribute, + operator: data_.rules![0].operator, + value: data_.rules![0].value, + }), + ]), + }) + ) + ++i + } + }) + }) + + describe("on update", () => { + it("should update an existing fulfillment set", async function () { + const createData: CreateFulfillmentSetDTO = { + name: "test", + type: "test-type", + } + + const createdFulfillmentSet = await service.create(createData) + + const updateData = { + id: createdFulfillmentSet.id, + name: "updated-test", + type: "updated-test-type", + } + + const updatedFulfillmentSets = await service.update(updateData) + + expect(updatedFulfillmentSets).toEqual( + expect.objectContaining({ + id: createdFulfillmentSet.id, + name: updateData.name, + type: updateData.type, + }) + ) + }) + + it("should update a collection of fulfillment sets", async function () { + const createData = [ + { + name: "test", + type: "test-type", + }, + { + name: "test2", + type: "test-type2", + }, + ] + + const createdFulfillmentSets = await service.create(createData) + + const updateData = createdFulfillmentSets.map( + (fulfillmentSet, index) => ({ + id: fulfillmentSet.id, + name: `updated-test${index + 1}`, + type: `updated-test-type${index + 1}`, + }) + ) + + const updatedFulfillmentSets = await service.update(updateData) + + expect(updatedFulfillmentSets).toHaveLength(2) + + let i = 0 + for (const data_ of updateData) { + expect(updatedFulfillmentSets[i]).toEqual( + expect.objectContaining({ + id: createdFulfillmentSets[i].id, + name: data_.name, + type: data_.type, + }) + ) + ++i + } + }) + + it("should update an existing fulfillment set and replace old service zones by a new one", async function () { + const createData: CreateFulfillmentSetDTO = { + name: "test", + type: "test-type", + service_zones: [ + { + name: "service-zone-test", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + } + + const createdFulfillmentSet = await service.create(createData) + + const createServiceZoneData: CreateServiceZoneDTO = { + fulfillment_set_id: createdFulfillmentSet.id, + name: "service-zone-test2", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "us", + }, + ], + } + + const updateData: UpdateFulfillmentSetDTO = { + id: createdFulfillmentSet.id, + name: "updated-test", + type: "updated-test-type", + service_zones: [createServiceZoneData], + } + + const updatedFulfillmentSet = await service.update(updateData) + + expect(updatedFulfillmentSet).toEqual( + expect.objectContaining({ + id: updateData.id, + name: updateData.name, + type: updateData.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + name: (updateData.service_zones![0] as ServiceZoneDTO).name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + type: (updateData.service_zones![0] as ServiceZoneDTO) + .geo_zones[0].type, + country_code: ( + updateData.service_zones![0] as ServiceZoneDTO + ).geo_zones[0].country_code, + }), + ]), + }), + ]), + }) + ) + + const serviceZones = await service.listServiceZones() + + expect(serviceZones).toHaveLength(1) + expect(serviceZones[0]).toEqual( + expect.objectContaining({ + id: updatedFulfillmentSet.service_zones[0].id, + }) + ) + }) + + it("should update an existing fulfillment set and add a new service zone", async function () { + const createData: CreateFulfillmentSetDTO = { + name: "test", + type: "test-type", + service_zones: [ + { + name: "service-zone-test", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + } + + const createdFulfillmentSet = await service.create(createData) + + const createServiceZoneData: CreateServiceZoneDTO = { + fulfillment_set_id: createdFulfillmentSet.id, + name: "service-zone-test2", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "us", + }, + ], + } + + const updateData: UpdateFulfillmentSetDTO = { + id: createdFulfillmentSet.id, + name: "updated-test", + type: "updated-test-type", + service_zones: [ + { id: createdFulfillmentSet.service_zones[0].id }, + createServiceZoneData, + ], + } + + const updatedFulfillmentSet = await service.update(updateData) + + expect(updatedFulfillmentSet).toEqual( + expect.objectContaining({ + id: updateData.id, + name: updateData.name, + type: updateData.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: createdFulfillmentSet.service_zones[0].id, + }), + expect.objectContaining({ + id: expect.any(String), + name: (updateData.service_zones![1] as ServiceZoneDTO).name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + type: (updateData.service_zones![1] as ServiceZoneDTO) + .geo_zones[0].type, + country_code: ( + updateData.service_zones![1] as ServiceZoneDTO + ).geo_zones[0].country_code, + }), + ]), + }), + ]), + }) + ) + }) + + it("should fail on duplicated fulfillment set name", async function () { + const createData = [ + { + name: "test", + type: "test-type", + }, + { + name: "test2", + type: "test-type2", + }, + ] + + const createdFulfillmentSets = await service.create(createData) + + const updateData = { + id: createdFulfillmentSets[1].id, + name: "test", // This is the name of the first fulfillment set + type: "updated-test-type2", + } + + const err = await service.update(updateData).catch((e) => e) + + expect(err).toBeDefined() + expect(err.constraint).toBe("IDX_fulfillment_set_name_unique") + }) + + it("should update a collection of fulfillment sets and replace old service zones by new ones", async function () { + const createData: CreateFulfillmentSetDTO[] = [ + { + name: "test1", + type: "test-type1", + service_zones: [ + { + name: "service-zone-test1", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + }, + { + name: "test2", + type: "test-type2", + service_zones: [ + { + name: "service-zone-test2", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "us", + }, + ], + }, + ], + }, + ] + + const createdFulfillmentSets = await service.create(createData) + + const updateData: UpdateFulfillmentSetDTO[] = + createdFulfillmentSets.map((fulfillmentSet, index) => ({ + id: fulfillmentSet.id, + name: `updated-test${index + 1}`, + type: `updated-test-type${index + 1}`, + service_zones: [ + { + name: `new-service-zone-test${index + 1}`, + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "test", + }, + ], + }, + ], + })) + + const updatedFulfillmentSets = await service.update(updateData) + + expect(updatedFulfillmentSets).toHaveLength(2) + + let i = 0 + for (const data_ of updateData) { + expect(updatedFulfillmentSets[i]).toEqual( + expect.objectContaining({ + id: data_.id, + name: data_.name, + type: data_.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + name: (data_.service_zones![0] as ServiceZoneDTO).name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + type: (data_.service_zones![0] as ServiceZoneDTO) + .geo_zones[0].type, + country_code: ( + data_.service_zones![0] as ServiceZoneDTO + ).geo_zones[0].country_code, + }), + ]), + }), + ]), + }) + ) + ++i + } + + const serviceZones = await service.listServiceZones() + + expect(serviceZones).toHaveLength(2) + expect(serviceZones).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: (updateData[0].service_zones![0] as ServiceZoneDTO) + .name, + }), + expect.objectContaining({ + name: (updateData[1].service_zones![0] as ServiceZoneDTO) + .name, + }), + ]) + ) + }) + + it("should update a collection of fulfillment sets and add new service zones", async function () { + const createData: CreateFulfillmentSetDTO[] = [ + { + name: "test1", + type: "test-type1", + service_zones: [ + { + name: "service-zone-test1", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + }, + ], + }, + { + name: "test2", + type: "test-type2", + service_zones: [ + { + name: "service-zone-test2", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "us", + }, + ], + }, + ], + }, + ] + + const createdFulfillmentSets = await service.create(createData) + + const updateData: UpdateFulfillmentSetDTO[] = + createdFulfillmentSets.map((fulfillmentSet, index) => ({ + id: fulfillmentSet.id, + name: `updated-test${index + 1}`, + type: `updated-test-type${index + 1}`, + service_zones: [ + ...fulfillmentSet.service_zones, + { + name: `added-service-zone-test${index + 1}`, + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "test", + }, + ], + }, + ], + })) + + const updatedFulfillmentSets = await service.update(updateData) + + expect(updatedFulfillmentSets).toHaveLength(2) + + let i = 0 + for (const data_ of updateData) { + expect(updatedFulfillmentSets[i]).toEqual( + expect.objectContaining({ + id: data_.id, + name: data_.name, + type: data_.type, + service_zones: expect.arrayContaining([ + expect.objectContaining({ + id: createdFulfillmentSets[i].service_zones[0].id, + }), + expect.objectContaining({ + id: expect.any(String), + name: (data_.service_zones![1] as ServiceZoneDTO).name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + id: expect.any(String), + type: (data_.service_zones![1] as ServiceZoneDTO) + .geo_zones[0].type, + country_code: ( + data_.service_zones![1] as ServiceZoneDTO + ).geo_zones[0].country_code, + }), + ]), + }), + ]), + }) + ) + ++i + } + + const serviceZones = await service.listServiceZones() + + expect(serviceZones).toHaveLength(4) + expect(serviceZones).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + name: createdFulfillmentSets[0].service_zones![0].name, + }), + expect.objectContaining({ + name: createdFulfillmentSets[1].service_zones![0].name, + }), + expect.objectContaining({ + name: (updateData[0].service_zones![1] as ServiceZoneDTO) + .name, + }), + expect.objectContaining({ + name: (updateData[1].service_zones![1] as ServiceZoneDTO) + .name, + }), + ]) + ) + }) + }) + + describe("on update service zones", () => { + it("should update an existing service zone", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + + const createData: CreateServiceZoneDTO = { + name: "service-zone-test", + fulfillment_set_id: fulfillmentSet.id, + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "fr", + }, + ], + } + + const createdServiceZone = await service.createServiceZones( + createData + ) + + const updateData = { + id: createdServiceZone.id, + name: "updated-service-zone-test", + geo_zones: [ + { + id: createdServiceZone.geo_zones[0].id, + type: GeoZoneType.COUNTRY, + country_code: "us", + }, + ], + } + + const updatedServiceZone = await service.updateServiceZones( + updateData + ) + + expect(updatedServiceZone).toEqual( + expect.objectContaining({ + id: updateData.id, + name: updateData.name, + geo_zones: expect.arrayContaining([ + expect.objectContaining({ + id: updateData.geo_zones[0].id, + type: updateData.geo_zones[0].type, + country_code: updateData.geo_zones[0].country_code, + }), + ]), + }) + ) + }) + + it("should update a collection of service zones", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + + const createData: CreateServiceZoneDTO[] = [ + { + name: "service-zone-test", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, @@ -923,14 +1435,9 @@ describe("fulfillment module service", function () { }, ], }, - ], - }, - { - name: "test2", - type: "test-type2", - service_zones: [ { name: "service-zone-test2", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, @@ -938,84 +1445,60 @@ describe("fulfillment module service", function () { }, ], }, - ], - }, - ] + ] - const createdFulfillmentSets = await service.create(createData) + const createdServiceZones = await service.createServiceZones( + createData + ) - const updateData: UpdateFulfillmentSetDTO[] = - createdFulfillmentSets.map((fulfillmentSet, index) => ({ - id: fulfillmentSet.id, - name: `updated-test${index + 1}`, - type: `updated-test-type${index + 1}`, - service_zones: [ - { - name: `new-service-zone-test${index + 1}`, + const updateData: UpdateServiceZoneDTO[] = createdServiceZones.map( + (serviceZone, index) => ({ + id: serviceZone.id, + name: `updated-service-zone-test${index + 1}`, geo_zones: [ { type: GeoZoneType.COUNTRY, - country_code: "test", + country_code: index % 2 === 0 ? "us" : "fr", }, ], - }, - ], - })) + }) + ) - const updatedFulfillmentSets = await service.update(updateData) + const updatedServiceZones = await service.updateServiceZones( + updateData + ) - expect(updatedFulfillmentSets).toHaveLength(2) + expect(updatedServiceZones).toHaveLength(2) - let i = 0 - for (const data_ of updateData) { - expect(updatedFulfillmentSets[i]).toEqual( - expect.objectContaining({ - id: data_.id, - name: data_.name, - type: data_.type, - service_zones: expect.arrayContaining([ + let i = 0 + for (const data_ of updateData) { + expect(updatedServiceZones[i]).toEqual( expect.objectContaining({ - id: expect.any(String), - name: (data_.service_zones![0] as ServiceZoneDTO).name, + id: data_.id, + name: data_.name, geo_zones: expect.arrayContaining([ expect.objectContaining({ - id: expect.any(String), - type: (data_.service_zones![0] as ServiceZoneDTO) - .geo_zones[0].type, - country_code: (data_.service_zones![0] as ServiceZoneDTO) - .geo_zones[0].country_code, + type: (data_.geo_zones![0] as GeoZoneDTO).type, + country_code: (data_.geo_zones![0] as GeoZoneDTO) + .country_code, }), ]), - }), - ]), + }) + ) + ++i + } + }) + + it("should fail on duplicated service zone name", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", }) - ) - ++i - } - const serviceZones = await service.listServiceZones() - - expect(serviceZones).toHaveLength(2) - expect(serviceZones).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - name: updateData[0].service_zones![0].name, - }), - expect.objectContaining({ - name: updateData[1].service_zones![0].name, - }), - ]) - ) - }) - - it("should update a collection of fulfillment sets and add new service zones", async function () { - const createData: CreateFulfillmentSetDTO[] = [ - { - name: "test1", - type: "test-type1", - service_zones: [ + const createData: CreateServiceZoneDTO[] = [ { - name: "service-zone-test1", + name: "service-zone-test", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, @@ -1023,14 +1506,9 @@ describe("fulfillment module service", function () { }, ], }, - ], - }, - { - name: "test2", - type: "test-type2", - service_zones: [ { name: "service-zone-test2", + fulfillment_set_id: fulfillmentSet.id, geo_zones: [ { type: GeoZoneType.COUNTRY, @@ -1038,336 +1516,121 @@ describe("fulfillment module service", function () { }, ], }, - ], - }, - ] + ] - const createdFulfillmentSets = await service.create(createData) + const createdServiceZones = await service.createServiceZones( + createData + ) - const updateData: UpdateFulfillmentSetDTO[] = - createdFulfillmentSets.map((fulfillmentSet, index) => ({ - id: fulfillmentSet.id, - name: `updated-test${index + 1}`, - type: `updated-test-type${index + 1}`, - service_zones: [ - ...fulfillmentSet.service_zones, - { - name: `added-service-zone-test${index + 1}`, - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "test", - }, - ], - }, - ], - })) + const updateData: UpdateServiceZoneDTO = { + id: createdServiceZones[1].id, + name: "service-zone-test", + geo_zones: [ + { + type: GeoZoneType.COUNTRY, + country_code: "us", + }, + ], + } - const updatedFulfillmentSets = await service.update(updateData) + const err = await service + .updateServiceZones(updateData) + .catch((e) => e) - expect(updatedFulfillmentSets).toHaveLength(2) - - let i = 0 - for (const data_ of updateData) { - expect(updatedFulfillmentSets[i]).toEqual( - expect.objectContaining({ - id: data_.id, - name: data_.name, - type: data_.type, - service_zones: expect.arrayContaining([ - expect.objectContaining({ - id: createdFulfillmentSets[i].service_zones[0].id, - }), - expect.objectContaining({ - id: expect.any(String), - name: (data_.service_zones![1] as ServiceZoneDTO).name, - geo_zones: expect.arrayContaining([ - expect.objectContaining({ - id: expect.any(String), - type: (data_.service_zones![1] as ServiceZoneDTO) - .geo_zones[0].type, - country_code: (data_.service_zones![1] as ServiceZoneDTO) - .geo_zones[0].country_code, - }), - ]), - }), - ]), - }) - ) - ++i - } - - const serviceZones = await service.listServiceZones() - - expect(serviceZones).toHaveLength(4) - expect(serviceZones).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - name: createdFulfillmentSets[0].service_zones![0].name, - }), - expect.objectContaining({ - name: createdFulfillmentSets[1].service_zones![0].name, - }), - expect.objectContaining({ - name: updateData[0].service_zones![1].name, - }), - expect.objectContaining({ - name: updateData[1].service_zones![1].name, - }), - ]) - ) - }) - }) - - describe("on update service zones", () => { - it("should update an existing service zone", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", + expect(err).toBeDefined() + expect(err.constraint).toBe("IDX_service_zone_name_unique") + }) }) - const createData: CreateServiceZoneDTO = { - name: "service-zone-test", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { + describe("on update geo zones", () => { + it("should update an existing geo zone", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) + + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) + + const createData: CreateGeoZoneDTO = { + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, country_code: "fr", - }, - ], - } + } - const createdServiceZone = await service.createServiceZones(createData) + const createdGeoZone = await service.createGeoZones(createData) - const updateData = { - id: createdServiceZone.id, - name: "updated-service-zone-test", - geo_zones: [ - { - id: createdServiceZone.geo_zones[0].id, + const updateData: UpdateGeoZoneDTO = { + id: createdGeoZone.id, type: GeoZoneType.COUNTRY, country_code: "us", - }, - ], - } + } - const updatedServiceZone = await service.updateServiceZones(updateData) + const updatedGeoZone = await service.updateGeoZones(updateData) - expect(updatedServiceZone).toEqual( - expect.objectContaining({ - id: updateData.id, - name: updateData.name, - geo_zones: expect.arrayContaining([ + expect(updatedGeoZone).toEqual( expect.objectContaining({ - id: updateData.geo_zones[0].id, - type: updateData.geo_zones[0].type, - country_code: updateData.geo_zones[0].country_code, - }), - ]), + id: updateData.id, + type: updateData.type, + country_code: updateData.country_code, + }) + ) }) - ) - }) - it("should update a collection of service zones", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) + it("should update a collection of geo zones", async function () { + const fulfillmentSet = await service.create({ + name: "test", + type: "test-type", + }) - const createData: CreateServiceZoneDTO[] = [ - { - name: "service-zone-test", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ + const serviceZone = await service.createServiceZones({ + name: "test", + fulfillment_set_id: fulfillmentSet.id, + }) + + const createData: CreateGeoZoneDTO[] = [ { + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, country_code: "fr", }, - ], - }, - { - name: "service-zone-test2", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ { + service_zone_id: serviceZone.id, type: GeoZoneType.COUNTRY, country_code: "us", }, - ], - }, - ] + ] - const createdServiceZones = await service.createServiceZones(createData) + const createdGeoZones = await service.createGeoZones(createData) - const updateData = createdServiceZones.map((serviceZone, index) => ({ - id: serviceZone.id, - name: `updated-service-zone-test${index + 1}`, - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: index % 2 === 0 ? "us" : "fr", - }, - ], - })) + const updateData: UpdateGeoZoneDTO[] = createdGeoZones.map( + (geoZone, index) => ({ + id: geoZone.id, + type: GeoZoneType.COUNTRY, + country_code: index % 2 === 0 ? "us" : "fr", + }) + ) - const updatedServiceZones = await service.updateServiceZones(updateData) + const updatedGeoZones = await service.updateGeoZones(updateData) - expect(updatedServiceZones).toHaveLength(2) + expect(updatedGeoZones).toHaveLength(2) - let i = 0 - for (const data_ of updateData) { - expect(updatedServiceZones[i]).toEqual( - expect.objectContaining({ - id: data_.id, - name: data_.name, - geo_zones: expect.arrayContaining([ + let i = 0 + for (const data_ of updateData) { + expect(updatedGeoZones[i]).toEqual( expect.objectContaining({ - type: data_.geo_zones[0].type, - country_code: data_.geo_zones[0].country_code, - }), - ]), - }) - ) - ++i - } - }) - - it("should fail on duplicated service zone name", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", + id: data_.id, + type: data_.type, + country_code: data_.country_code, + }) + ) + ++i + } + }) }) - - const createData: CreateServiceZoneDTO[] = [ - { - name: "service-zone-test", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "fr", - }, - ], - }, - { - name: "service-zone-test2", - fulfillment_set_id: fulfillmentSet.id, - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "us", - }, - ], - }, - ] - - const createdServiceZones = await service.createServiceZones(createData) - - const updateData = { - id: createdServiceZones[1].id, - name: "service-zone-test", - geo_zones: [ - { - type: GeoZoneType.COUNTRY, - country_code: "us", - }, - ], - } - - const err = await service.updateServiceZones(updateData).catch((e) => e) - - expect(err).toBeDefined() - expect(err.constraint).toBe("IDX_service_zone_name_unique") }) }) - - describe("on update geo zones", () => { - it("should update an existing geo zone", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - - const serviceZone = await service.createServiceZones({ - name: "test", - fulfillment_set_id: fulfillmentSet.id, - }) - - const createData: CreateGeoZoneDTO = { - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "fr", - } - - const createdGeoZone = await service.createGeoZones(createData) - - const updateData: UpdateGeoZoneDTO = { - id: createdGeoZone.id, - type: GeoZoneType.COUNTRY, - country_code: "us", - } - - const updatedGeoZone = await service.updateGeoZones(updateData) - - expect(updatedGeoZone).toEqual( - expect.objectContaining({ - id: updateData.id, - type: updateData.type, - country_code: updateData.country_code, - }) - ) - }) - - it("should update a collection of geo zones", async function () { - const fulfillmentSet = await service.create({ - name: "test", - type: "test-type", - }) - - const serviceZone = await service.createServiceZones({ - name: "test", - fulfillment_set_id: fulfillmentSet.id, - }) - - const createData: CreateGeoZoneDTO[] = [ - { - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "fr", - }, - { - service_zone_id: serviceZone.id, - type: GeoZoneType.COUNTRY, - country_code: "us", - }, - ] - - const createdGeoZones = await service.createGeoZones(createData) - - const updateData: UpdateGeoZoneDTO[] = createdGeoZones.map( - (geoZone, index) => ({ - id: geoZone.id, - type: GeoZoneType.COUNTRY, - country_code: index % 2 === 0 ? "us" : "fr", - }) - ) - - const updatedGeoZones = await service.updateGeoZones(updateData) - - expect(updatedGeoZones).toHaveLength(2) - - let i = 0 - for (const data_ of updateData) { - expect(updatedGeoZones[i]).toEqual( - expect.objectContaining({ - id: data_.id, - type: data_.type, - country_code: data_.country_code, - }) - ) - ++i - } - }) - }) - }) + }, }) diff --git a/packages/fulfillment/integration-tests/setup-env.js b/packages/fulfillment/integration-tests/setup-env.js deleted file mode 100644 index e8e2a6b17a..0000000000 --- a/packages/fulfillment/integration-tests/setup-env.js +++ /dev/null @@ -1,6 +0,0 @@ -if (typeof process.env.DB_TEMP_NAME === "undefined") { - const tempName = parseInt(process.env.JEST_WORKER_ID || "1") - process.env.DB_TEMP_NAME = `medusa-fulfillment-integration-${tempName}` -} - -process.env.MEDUSA_FULFILLMENT_DB_SCHEMA = "public" diff --git a/packages/fulfillment/integration-tests/setup.js b/packages/fulfillment/integration-tests/setup.js deleted file mode 100644 index 43f99aab4a..0000000000 --- a/packages/fulfillment/integration-tests/setup.js +++ /dev/null @@ -1,3 +0,0 @@ -import { JestUtils } from "medusa-test-utils" - -JestUtils.afterAllHookDropDatabase() diff --git a/packages/fulfillment/integration-tests/utils/database.ts b/packages/fulfillment/integration-tests/utils/database.ts deleted file mode 100644 index d1ba6a830c..0000000000 --- a/packages/fulfillment/integration-tests/utils/database.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TestDatabaseUtils } from "medusa-test-utils" - -import * as Models from "@models" - -const mikroOrmEntities = Models as unknown as any[] - -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( - mikroOrmEntities, - null, - process.env.MEDUSA_FULFILLMENT_DB_SCHEMA -) - -export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/fulfillment/integration-tests/utils/get-init-module-config.ts b/packages/fulfillment/integration-tests/utils/get-init-module-config.ts deleted file mode 100644 index 5ebb110c29..0000000000 --- a/packages/fulfillment/integration-tests/utils/get-init-module-config.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Modules, ModulesDefinition } from "@medusajs/modules-sdk" - -import { DB_URL } from "./database" - -export function getInitModuleConfig() { - const moduleOptions = { - defaultAdapterOptions: { - database: { - clientUrl: DB_URL, - schema: process.env.MEDUSA_FULFILLMENT_DB_SCHEMA, - }, - }, - } - - const injectedDependencies = {} - - const modulesConfig_ = { - [Modules.FULFILLMENT]: { - definition: ModulesDefinition[Modules.FULFILLMENT], - options: moduleOptions, - }, - } - - return { - injectedDependencies, - modulesConfig: modulesConfig_, - databaseConfig: { - clientUrl: DB_URL, - schema: process.env.MEDUSA_FULFILLMENT_DB_SCHEMA, - }, - joinerConfig: [], - } -} diff --git a/packages/fulfillment/integration-tests/utils/index.ts b/packages/fulfillment/integration-tests/utils/index.ts deleted file mode 100644 index ba28fb5523..0000000000 --- a/packages/fulfillment/integration-tests/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./database" -export * from "./get-init-module-config" diff --git a/packages/fulfillment/jest.config.js b/packages/fulfillment/jest.config.js index 456054fe8a..62656d9c23 100644 --- a/packages/fulfillment/jest.config.js +++ b/packages/fulfillment/jest.config.js @@ -17,6 +17,5 @@ module.exports = { testEnvironment: `node`, moduleFileExtensions: [`js`, `ts`], modulePathIgnorePatterns: ["dist/"], - setupFiles: ["/integration-tests/setup-env.js"], - setupFilesAfterEnv: ["/integration-tests/setup.js"], + /*setupFilesAfterEnv: ["/integration-tests/setup.js"],*/ } diff --git a/packages/fulfillment/package.json b/packages/fulfillment/package.json index 94fbac4399..970e92e8ee 100644 --- a/packages/fulfillment/package.json +++ b/packages/fulfillment/package.json @@ -29,7 +29,7 @@ "prepublishOnly": "cross-env NODE_ENV=production tsc --build && tsc-alias -p tsconfig.json", "build": "rimraf dist && tsc --build && tsc-alias -p tsconfig.json", "test": "jest --runInBand --bail --forceExit -- src/**/__tests__/**/*.ts", - "test:integration": "jest --runInBand --forceExit -- integration-tests/**/__tests__/**/*.ts", + "test:integration": "jest --runInBand --forceExit -- integration-tests/**/__tests__/**/*.spec.ts", "migration:generate": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:generate", "migration:initial": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create --initial", "migration:create": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create", diff --git a/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json b/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json index f2b6dde656..d1b7292ae5 100644 --- a/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json +++ b/packages/fulfillment/src/migrations/.snapshot-medusa-fulfillment.json @@ -493,20 +493,7 @@ } ], "checks": [], - "foreignKeys": { - "service_zone_fulfillment_set_id_foreign": { - "constraintName": "service_zone_fulfillment_set_id_foreign", - "columnNames": [ - "fulfillment_set_id" - ], - "localTableName": "public.service_zone", - "referencedColumnNames": [ - "id" - ], - "referencedTableName": "public.fulfillment_set", - "updateRule": "cascade" - } - } + "foreignKeys": {} }, { "columns": { @@ -686,20 +673,7 @@ } ], "checks": [], - "foreignKeys": { - "geo_zone_service_zone_id_foreign": { - "constraintName": "geo_zone_service_zone_id_foreign", - "columnNames": [ - "service_zone_id" - ], - "localTableName": "public.geo_zone", - "referencedColumnNames": [ - "id" - ], - "referencedTableName": "public.service_zone", - "updateRule": "cascade" - } - } + "foreignKeys": {} }, { "columns": { @@ -828,6 +802,24 @@ "nullable": false, "mappedType": "text" }, + "name": { + "name": "name", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, + "type": { + "name": "type", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": false, + "mappedType": "text" + }, "metadata": { "name": "metadata", "type": "jsonb", @@ -873,6 +865,16 @@ "name": "shipping_profile", "schema": "public", "indexes": [ + { + "keyName": "IDX_shipping_profile_name_unique", + "columnNames": [ + "name" + ], + "composite": false, + "primary": false, + "unique": false, + "expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_shipping_profile_name_unique\" ON \"shipping_profile\" (name) WHERE deleted_at IS NULL" + }, { "keyName": "IDX_shipping_profile_deleted_at", "columnNames": [ @@ -945,7 +947,7 @@ "unsigned": false, "autoincrement": false, "primary": false, - "nullable": false, + "nullable": true, "mappedType": "text" }, "service_provider_id": { @@ -954,15 +956,6 @@ "unsigned": false, "autoincrement": false, "primary": false, - "nullable": false, - "mappedType": "text" - }, - "shipping_option_type_id": { - "name": "shipping_option_type_id", - "type": "text", - "unsigned": false, - "autoincrement": false, - "primary": false, "nullable": true, "mappedType": "text" }, @@ -984,6 +977,15 @@ "nullable": true, "mappedType": "json" }, + "shipping_option_type_id": { + "name": "shipping_option_type_id", + "type": "text", + "unsigned": false, + "autoincrement": false, + "primary": false, + "nullable": true, + "mappedType": "text" + }, "created_at": { "name": "created_at", "type": "timestamptz", @@ -1091,18 +1093,6 @@ ], "checks": [], "foreignKeys": { - "shipping_option_service_zone_id_foreign": { - "constraintName": "shipping_option_service_zone_id_foreign", - "columnNames": [ - "service_zone_id" - ], - "localTableName": "public.shipping_option", - "referencedColumnNames": [ - "id" - ], - "referencedTableName": "public.service_zone", - "updateRule": "cascade" - }, "shipping_option_shipping_profile_id_foreign": { "constraintName": "shipping_option_shipping_profile_id_foreign", "columnNames": [ @@ -1113,6 +1103,7 @@ "id" ], "referencedTableName": "public.shipping_profile", + "deleteRule": "set null", "updateRule": "cascade" }, "shipping_option_service_provider_id_foreign": { @@ -1125,6 +1116,7 @@ "id" ], "referencedTableName": "public.service_provider", + "deleteRule": "set null", "updateRule": "cascade" }, "shipping_option_shipping_option_type_id_foreign": { @@ -1137,6 +1129,7 @@ "id" ], "referencedTableName": "public.shipping_option_type", + "deleteRule": "cascade", "updateRule": "cascade" } } @@ -1224,6 +1217,16 @@ "name": "shipping_option_rule", "schema": "public", "indexes": [ + { + "keyName": "IDX_shipping_option_rule_shipping_option_id", + "columnNames": [ + "shipping_option_id" + ], + "composite": false, + "primary": false, + "unique": false, + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_shipping_option_rule_shipping_option_id\" ON \"shipping_option_rule\" (shipping_option_id) WHERE deleted_at IS NULL" + }, { "keyName": "IDX_shipping_option_rule_deleted_at", "columnNames": [ @@ -1245,20 +1248,7 @@ } ], "checks": [], - "foreignKeys": { - "shipping_option_rule_shipping_option_id_foreign": { - "constraintName": "shipping_option_rule_shipping_option_id_foreign", - "columnNames": [ - "shipping_option_id" - ], - "localTableName": "public.shipping_option_rule", - "referencedColumnNames": [ - "id" - ], - "referencedTableName": "public.shipping_option", - "updateRule": "cascade" - } - } + "foreignKeys": {} }, { "columns": { @@ -1760,7 +1750,7 @@ "composite": false, "primary": false, "unique": false, - "expression": "CREATE INDEX IF NOT EXISTS \"IDX_fulfillment_item_fulfillment_id\" ON \"fulfillment_item\" (line_item_id) WHERE deleted_at IS NULL" + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_fulfillment_item_line_item_id\" ON \"fulfillment_item\" (line_item_id) WHERE deleted_at IS NULL" }, { "keyName": "IDX_fulfillment_item_inventory_item_id", @@ -1770,7 +1760,7 @@ "composite": false, "primary": false, "unique": false, - "expression": "CREATE INDEX IF NOT EXISTS \"IDX_fulfillment_item_fulfillment_id\" ON \"fulfillment_item\" (inventory_item_id) WHERE deleted_at IS NULL" + "expression": "CREATE INDEX IF NOT EXISTS \"IDX_fulfillment_item_inventory_item_id\" ON \"fulfillment_item\" (inventory_item_id) WHERE deleted_at IS NULL" }, { "keyName": "IDX_fulfillment_item_fulfillment_id", diff --git a/packages/fulfillment/src/migrations/Migration20240214103108.ts b/packages/fulfillment/src/migrations/Migration20240219115644.ts similarity index 86% rename from packages/fulfillment/src/migrations/Migration20240214103108.ts rename to packages/fulfillment/src/migrations/Migration20240219115644.ts index 1a7fa50ce5..aa1294981b 100644 --- a/packages/fulfillment/src/migrations/Migration20240214103108.ts +++ b/packages/fulfillment/src/migrations/Migration20240219115644.ts @@ -1,6 +1,6 @@ import { Migration } from '@mikro-orm/migrations'; -export class Migration20240214103108 extends Migration { +export class Migration20240219115644 extends Migration { async up(): Promise { this.addSql('create table if not exists "fulfillment_address" ("id" text not null, "fulfillment_id" text null, "company" text null, "first_name" text null, "last_name" text null, "address_1" text null, "address_2" text null, "city" text null, "country_code" text null, "province" text null, "postal_code" text null, "phone" text null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_address_pkey" primary key ("id"));'); @@ -30,10 +30,11 @@ export class Migration20240214103108 extends Migration { this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_type_shipping_option_id" ON "shipping_option_type" (shipping_option_id) WHERE deleted_at IS NULL;'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_type_deleted_at" ON "shipping_option_type" (deleted_at) WHERE deleted_at IS NOT NULL;'); - this.addSql('create table if not exists "shipping_profile" ("id" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_profile_pkey" primary key ("id"));'); + this.addSql('create table if not exists "shipping_profile" ("id" text not null, "name" text not null, "type" text not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_profile_pkey" primary key ("id"));'); + this.addSql('CREATE UNIQUE INDEX IF NOT EXISTS "IDX_shipping_profile_name_unique" ON "shipping_profile" (name) WHERE deleted_at IS NULL;'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_profile_deleted_at" ON "shipping_profile" (deleted_at) WHERE deleted_at IS NOT NULL;'); - this.addSql('create table if not exists "shipping_option" ("id" text not null, "name" text not null, "price_type" text check ("price_type" in (\'calculated\', \'flat\')) not null default \'calculated\', "service_zone_id" text not null, "shipping_profile_id" text not null, "service_provider_id" text not null, "shipping_option_type_id" text null, "data" jsonb null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_option_pkey" primary key ("id"));'); + this.addSql('create table if not exists "shipping_option" ("id" text not null, "name" text not null, "price_type" text check ("price_type" in (\'calculated\', \'flat\')) not null default \'calculated\', "service_zone_id" text not null, "shipping_profile_id" text null, "service_provider_id" text null, "data" jsonb null, "metadata" jsonb null, "shipping_option_type_id" text null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_option_pkey" primary key ("id"));'); this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_unique" unique ("shipping_option_type_id");'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_service_zone_id" ON "shipping_option" (service_zone_id) WHERE deleted_at IS NULL;'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_shipping_profile_id" ON "shipping_option" (shipping_profile_id) WHERE deleted_at IS NULL;'); @@ -42,6 +43,7 @@ export class Migration20240214103108 extends Migration { this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_deleted_at" ON "shipping_option" (deleted_at) WHERE deleted_at IS NOT NULL;'); this.addSql('create table if not exists "shipping_option_rule" ("id" text not null, "attribute" text not null, "operator" text not null, "value" jsonb null, "shipping_option_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "shipping_option_rule_pkey" primary key ("id"));'); + this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_rule_shipping_option_id" ON "shipping_option_rule" (shipping_option_id) WHERE deleted_at IS NULL;'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_shipping_option_rule_deleted_at" ON "shipping_option_rule" (deleted_at) WHERE deleted_at IS NOT NULL;'); this.addSql('create table if not exists "fulfillment" ("id" text not null, "location_id" text not null, "packed_at" timestamptz null, "shipped_at" timestamptz null, "delivered_at" timestamptz null, "canceled_at" timestamptz null, "data" jsonb null, "provider_id" text not null, "shipping_option_id" text null, "metadata" jsonb null, "delivery_address_id" text not null, "items_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_pkey" primary key ("id"));'); @@ -55,21 +57,14 @@ export class Migration20240214103108 extends Migration { this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_label_deleted_at" ON "fulfillment_label" (deleted_at) WHERE deleted_at IS NOT NULL;'); this.addSql('create table if not exists "fulfillment_item" ("id" text not null, "title" text not null, "sku" text not null, "barcode" text not null, "quantity" numeric not null, "line_item_id" text null, "inventory_item_id" text null, "fulfillment_id" text not null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "fulfillment_item_pkey" primary key ("id"));'); - this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (line_item_id) WHERE deleted_at IS NULL;'); - this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (inventory_item_id) WHERE deleted_at IS NULL;'); + this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_line_item_id" ON "fulfillment_item" (line_item_id) WHERE deleted_at IS NULL;'); + this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_inventory_item_id" ON "fulfillment_item" (inventory_item_id) WHERE deleted_at IS NULL;'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_fulfillment_id" ON "fulfillment_item" (fulfillment_id) WHERE deleted_at IS NULL;'); this.addSql('CREATE INDEX IF NOT EXISTS "IDX_fulfillment_item_deleted_at" ON "fulfillment_item" (deleted_at) WHERE deleted_at IS NOT NULL;'); - this.addSql('alter table if exists "service_zone" add constraint "service_zone_fulfillment_set_id_foreign" foreign key ("fulfillment_set_id") references "fulfillment_set" ("id") on update cascade;'); - - this.addSql('alter table if exists "geo_zone" add constraint "geo_zone_service_zone_id_foreign" foreign key ("service_zone_id") references "service_zone" ("id") on update cascade;'); - - this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_service_zone_id_foreign" foreign key ("service_zone_id") references "service_zone" ("id") on update cascade;'); - this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_profile_id_foreign" foreign key ("shipping_profile_id") references "shipping_profile" ("id") on update cascade;'); - this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_service_provider_id_foreign" foreign key ("service_provider_id") references "service_provider" ("id") on update cascade;'); - this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_foreign" foreign key ("shipping_option_type_id") references "shipping_option_type" ("id") on update cascade;'); - - this.addSql('alter table if exists "shipping_option_rule" add constraint "shipping_option_rule_shipping_option_id_foreign" foreign key ("shipping_option_id") references "shipping_option" ("id") on update cascade;'); + this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_profile_id_foreign" foreign key ("shipping_profile_id") references "shipping_profile" ("id") on update cascade on delete set null;'); + this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_service_provider_id_foreign" foreign key ("service_provider_id") references "service_provider" ("id") on update cascade on delete set null;'); + this.addSql('alter table if exists "shipping_option" add constraint "shipping_option_shipping_option_type_id_foreign" foreign key ("shipping_option_type_id") references "shipping_option_type" ("id") on update cascade on delete cascade;'); this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_shipping_option_id_foreign" foreign key ("shipping_option_id") references "shipping_option" ("id") on update cascade on delete set null;'); this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_provider_id_foreign" foreign key ("provider_id") references "service_provider" ("id") on update cascade;'); diff --git a/packages/fulfillment/src/models/address.ts b/packages/fulfillment/src/models/address.ts index 1bb2a1dcbb..b70907bdd4 100644 --- a/packages/fulfillment/src/models/address.ts +++ b/packages/fulfillment/src/models/address.ts @@ -6,7 +6,6 @@ import { import { BeforeCreate, Entity, - Index, OnInit, OptionalProps, PrimaryKey, @@ -15,21 +14,17 @@ import { type OptionalAddressProps = DAL.SoftDeletableEntityDateColumns -const fulfillmentIdIndexName = "IDX_fulfillment_address_fulfillment_id" -const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentIdIndexName, +const FulfillmentIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_address", columns: "fulfillment_id", where: "deleted_at IS NULL", -}).expression +}) -const fulfillmentDeletedAtIndexName = "IDX_fulfillment_address_deleted_at" -const fulfillmentDeletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentDeletedAtIndexName, +const FulfillmentDeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_address", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) @Entity({ tableName: "fulfillment_address" }) export default class Address { @@ -39,10 +34,7 @@ export default class Address { id!: string @Property({ columnType: "text", nullable: true }) - @Index({ - name: fulfillmentIdIndexName, - expression: fulfillmentIdIndexStatement, - }) + @FulfillmentIdIndex.MikroORMIndex() fulfillment_id: string | null = null @Property({ columnType: "text", nullable: true }) @@ -94,10 +86,7 @@ export default class Address { updated_at: Date @Property({ columnType: "timestamptz", nullable: true }) - @Index({ - name: fulfillmentDeletedAtIndexName, - expression: fulfillmentDeletedAtIndexStatement, - }) + @FulfillmentDeletedAtIndex.MikroORMIndex() deleted_at: Date | null = null @BeforeCreate() diff --git a/packages/fulfillment/src/models/fulfillment-item.ts b/packages/fulfillment/src/models/fulfillment-item.ts index b59a06cd9f..cde928de80 100644 --- a/packages/fulfillment/src/models/fulfillment-item.ts +++ b/packages/fulfillment/src/models/fulfillment-item.ts @@ -9,7 +9,6 @@ import { BeforeCreate, Entity, Filter, - Index, ManyToOne, OnInit, OptionalProps, @@ -20,37 +19,29 @@ import Fulfillment from "./fulfillment" type FulfillmentItemOptionalProps = DAL.SoftDeletableEntityDateColumns -const fulfillmentIdIndexName = "IDX_fulfillment_item_fulfillment_id" -const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentIdIndexName, +const FulfillmentIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_item", columns: "fulfillment_id", where: "deleted_at IS NULL", -}).expression +}) -const lineItemIndexName = "IDX_fulfillment_item_line_item_id" -const lineItemIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentIdIndexName, +const LineItemIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_item", columns: "line_item_id", where: "deleted_at IS NULL", -}).expression +}) -const inventoryItemIndexName = "IDX_fulfillment_item_inventory_item_id" -const inventoryItemIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentIdIndexName, +const InventoryItemIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_item", columns: "inventory_item_id", where: "deleted_at IS NULL", -}).expression +}) -const fulfillmentItemDeletedAtIndexName = "IDX_fulfillment_item_deleted_at" -const fulfillmentItemDeletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentItemDeletedAtIndexName, +const FulfillmentItemDeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_item", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -73,24 +64,15 @@ export default class FulfillmentItem { quantity: number // TODO: probably allow big numbers here @Property({ columnType: "text", nullable: true }) - @Index({ - name: lineItemIndexName, - expression: lineItemIdIndexStatement, - }) + @LineItemIdIndex.MikroORMIndex() line_item_id: string | null = null @Property({ columnType: "text", nullable: true }) - @Index({ - name: inventoryItemIndexName, - expression: inventoryItemIdIndexStatement, - }) + @InventoryItemIdIndex.MikroORMIndex() inventory_item_id: string | null = null @Property({ columnType: "text" }) - @Index({ - name: fulfillmentIdIndexName, - expression: fulfillmentIdIndexStatement, - }) + @FulfillmentIdIndex.MikroORMIndex() fulfillment_id: string @ManyToOne(() => Fulfillment) @@ -111,10 +93,7 @@ export default class FulfillmentItem { }) updated_at: Date - @Index({ - name: fulfillmentItemDeletedAtIndexName, - expression: fulfillmentItemDeletedAtIndexStatement, - }) + @FulfillmentItemDeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null diff --git a/packages/fulfillment/src/models/fulfillment-label.ts b/packages/fulfillment/src/models/fulfillment-label.ts index ae35ade0a1..8640e5117f 100644 --- a/packages/fulfillment/src/models/fulfillment-label.ts +++ b/packages/fulfillment/src/models/fulfillment-label.ts @@ -9,7 +9,6 @@ import { BeforeCreate, Entity, Filter, - Index, ManyToOne, OnInit, OptionalProps, @@ -20,21 +19,17 @@ import Fulfillment from "./fulfillment" type FulfillmentLabelOptionalProps = DAL.SoftDeletableEntityDateColumns -const fulfillmentIdIndexName = "IDX_fulfillment_label_fulfillment_id" -const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentIdIndexName, +const FulfillmentIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_label", columns: "fulfillment_id", where: "deleted_at IS NULL", -}).expression +}) -const deletedAtIndexName = "IDX_fulfillment_label_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_label", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -54,10 +49,7 @@ export default class FulfillmentLabel { label_url: string @Property({ columnType: "text" }) - @Index({ - name: fulfillmentIdIndexName, - expression: fulfillmentIdIndexStatement, - }) + @FulfillmentIdIndex.MikroORMIndex() fulfillment_id: string @ManyToOne(() => Fulfillment) @@ -79,10 +71,7 @@ export default class FulfillmentLabel { updated_at: Date @Property({ columnType: "timestamptz", nullable: true }) - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() deleted_at: Date | null = null @BeforeCreate() diff --git a/packages/fulfillment/src/models/fulfillment.ts b/packages/fulfillment/src/models/fulfillment.ts index f2cbca71a1..77b4e9cbbb 100644 --- a/packages/fulfillment/src/models/fulfillment.ts +++ b/packages/fulfillment/src/models/fulfillment.ts @@ -10,7 +10,6 @@ import { Collection, Entity, Filter, - Index, ManyToOne, OneToMany, OnInit, @@ -26,39 +25,29 @@ import ShippingOption from "./shipping-option" type FulfillmentOptionalProps = DAL.SoftDeletableEntityDateColumns -const fulfillmentDeletedAtIndexName = "IDX_fulfillment_deleted_at" -const fulfillmentDeletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentDeletedAtIndexName, +const FulfillmentDeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) -const fulfillmentProviderIdIndexName = "IDX_fulfillment_provider_id" -const fulfillmentProviderIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentProviderIdIndexName, +const FulfillmentProviderIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment", columns: "provider_id", where: "deleted_at IS NULL", -}).expression +}) -const fulfillmentLocationIdIndexName = "IDX_fulfillment_location_id" -const fulfillmentLocationIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentLocationIdIndexName, +const FulfillmentLocationIdIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment", columns: "location_id", where: "deleted_at IS NULL", -}).expression +}) -const fulfillmentShippingOptionIdIndexName = - "IDX_fulfillment_shipping_option_id" -const fulfillmentShippingOptionIdIndexStatement = - createPsqlIndexStatementHelper({ - name: fulfillmentShippingOptionIdIndexName, - tableName: "fulfillment", - columns: "shipping_option_id", - where: "deleted_at IS NULL", - }).expression +const FulfillmentShippingOptionIdIndex = createPsqlIndexStatementHelper({ + tableName: "fulfillment", + columns: "shipping_option_id", + where: "deleted_at IS NULL", +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -69,10 +58,7 @@ export default class Fulfillment { id: string @Property({ columnType: "text" }) - @Index({ - name: fulfillmentLocationIdIndexName, - expression: fulfillmentLocationIdIndexStatement, - }) + @FulfillmentLocationIdIndex.MikroORMIndex() location_id: string @Property({ @@ -103,17 +89,11 @@ export default class Fulfillment { data: Record | null = null @Property({ columnType: "text" }) - @Index({ - name: fulfillmentProviderIdIndexName, - expression: fulfillmentProviderIdIndexStatement, - }) + @FulfillmentProviderIdIndex.MikroORMIndex() provider_id: string @Property({ columnType: "text", nullable: true }) - @Index({ - name: fulfillmentShippingOptionIdIndexName, - expression: fulfillmentShippingOptionIdIndexStatement, - }) + @FulfillmentShippingOptionIdIndex.MikroORMIndex() shipping_option_id: string | null = null @Property({ columnType: "jsonb", nullable: true }) @@ -149,10 +129,7 @@ export default class Fulfillment { }) updated_at: Date - @Index({ - name: fulfillmentDeletedAtIndexName, - expression: fulfillmentDeletedAtIndexStatement, - }) + @FulfillmentDeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null diff --git a/packages/fulfillment/src/models/fullfilment-set.ts b/packages/fulfillment/src/models/fullfilment-set.ts index 55a4623565..ccf4e20230 100644 --- a/packages/fulfillment/src/models/fullfilment-set.ts +++ b/packages/fulfillment/src/models/fullfilment-set.ts @@ -11,7 +11,6 @@ import { Collection, Entity, Filter, - Index, OneToMany, OnInit, OptionalProps, @@ -22,22 +21,18 @@ import ServiceZone from "./service-zone" type FulfillmentSetOptionalProps = DAL.SoftDeletableEntityDateColumns -const deletedAtIndexName = "IDX_fulfillment_set_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_set", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) -const nameIndexName = "IDX_fulfillment_set_name_unique" -const nameIndexStatement = createPsqlIndexStatementHelper({ - name: nameIndexName, +const NameIndex = createPsqlIndexStatementHelper({ tableName: "fulfillment_set", columns: "name", unique: true, where: "deleted_at IS NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -48,10 +43,7 @@ export default class FulfillmentSet { id: string @Property({ columnType: "text" }) - @Index({ - name: nameIndexName, - expression: nameIndexStatement, - }) + @NameIndex.MikroORMIndex() name: string @Property({ columnType: "text" }) @@ -82,10 +74,7 @@ export default class FulfillmentSet { updated_at: Date @Property({ columnType: "timestamptz", nullable: true }) - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() deleted_at: Date | null = null @BeforeCreate() diff --git a/packages/fulfillment/src/models/geo-zone.ts b/packages/fulfillment/src/models/geo-zone.ts index 85d2f7ba72..3b557ead45 100644 --- a/packages/fulfillment/src/models/geo-zone.ts +++ b/packages/fulfillment/src/models/geo-zone.ts @@ -11,7 +11,6 @@ import { Entity, Enum, Filter, - Index, ManyToOne, OnInit, OptionalProps, @@ -22,45 +21,35 @@ import ServiceZone from "./service-zone" type GeoZoneOptionalProps = DAL.SoftDeletableEntityDateColumns -const deletedAtIndexName = "IDX_geo_zone_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "geo_zone", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) -const countryCodeIndexName = "IDX_geo_zone_country_code" -const countryCodeIndexStatement = createPsqlIndexStatementHelper({ - name: countryCodeIndexName, +const CountryCodeIndex = createPsqlIndexStatementHelper({ tableName: "geo_zone", columns: "country_code", where: "deleted_at IS NULL", -}).expression +}) -const provinceCodeIndexName = "IDX_geo_zone_province_code" -const provinceCodeIndexStatement = createPsqlIndexStatementHelper({ - name: provinceCodeIndexName, +const ProvinceCodeIndex = createPsqlIndexStatementHelper({ tableName: "geo_zone", columns: "province_code", where: "deleted_at IS NULL AND province_code IS NOT NULL", -}).expression +}) -const cityIndexName = "IDX_geo_zone_city" -const cityIndexStatement = createPsqlIndexStatementHelper({ - name: cityIndexName, +const CityIndex = createPsqlIndexStatementHelper({ tableName: "geo_zone", columns: "city", where: "deleted_at IS NULL AND city IS NOT NULL", -}).expression +}) -const serviceZoneIdIndexName = "IDX_geo_zone_service_zone_id" -const serviceZoneIdStatement = createPsqlIndexStatementHelper({ - name: serviceZoneIdIndexName, +const ServiceZoneIdIndex = createPsqlIndexStatementHelper({ tableName: "geo_zone", columns: "service_zone_id", where: "deleted_at IS NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -73,32 +62,20 @@ export default class GeoZone { @Enum({ items: () => GeoZoneType, default: GeoZoneType.COUNTRY }) type: GeoZoneType - @Index({ - name: countryCodeIndexName, - expression: countryCodeIndexStatement, - }) + @CountryCodeIndex.MikroORMIndex() @Property({ columnType: "text" }) country_code: string - @Index({ - name: provinceCodeIndexName, - expression: provinceCodeIndexStatement, - }) + @ProvinceCodeIndex.MikroORMIndex() @Property({ columnType: "text", nullable: true }) province_code: string | null = null - @Index({ - name: cityIndexName, - expression: cityIndexStatement, - }) + @CityIndex.MikroORMIndex() @Property({ columnType: "text", nullable: true }) city: string | null = null @Property({ columnType: "text" }) - @Index({ - name: serviceZoneIdIndexName, - expression: serviceZoneIdStatement, - }) + @ServiceZoneIdIndex.MikroORMIndex() service_zone_id: string // TODO: Do we have an example or idea of what would be stored in this field? like lat/long for example? @@ -128,10 +105,7 @@ export default class GeoZone { }) updated_at: Date - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null diff --git a/packages/fulfillment/src/models/service-provider.ts b/packages/fulfillment/src/models/service-provider.ts index 4855c60c4f..77784a969f 100644 --- a/packages/fulfillment/src/models/service-provider.ts +++ b/packages/fulfillment/src/models/service-provider.ts @@ -10,7 +10,6 @@ import { Collection, Entity, Filter, - Index, OneToMany, OnInit, OptionalProps, @@ -21,13 +20,11 @@ import ShippingOption from "./shipping-option" type ServiceProviderOptionalProps = DAL.SoftDeletableEntityDateColumns -const deletedAtIndexName = "IDX_service_provider_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "service_provider", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -61,10 +58,7 @@ export default class ServiceProvider { }) updated_at: Date - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null diff --git a/packages/fulfillment/src/models/service-zone.ts b/packages/fulfillment/src/models/service-zone.ts index fb5d511404..cb73a9f39a 100644 --- a/packages/fulfillment/src/models/service-zone.ts +++ b/packages/fulfillment/src/models/service-zone.ts @@ -33,22 +33,18 @@ const deletedAtIndexStatement = createPsqlIndexStatementHelper({ where: "deleted_at IS NOT NULL", }).expression -const nameIndexName = "IDX_service_zone_name_unique" -const nameIndexStatement = createPsqlIndexStatementHelper({ - name: nameIndexName, +const NameIndex = createPsqlIndexStatementHelper({ tableName: "service_zone", columns: "name", unique: true, where: "deleted_at IS NULL", -}).expression +}) -const fulfillmentSetIdIndexName = "IDX_service_zone_fulfillment_set_id" -const fulfillmentSetIdIndexStatement = createPsqlIndexStatementHelper({ - name: fulfillmentSetIdIndexName, +const FulfillmentSetIdIndex = createPsqlIndexStatementHelper({ tableName: "service_zone", columns: "fulfillment_set_id", where: "deleted_at IS NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -59,20 +55,14 @@ export default class ServiceZone { id: string @Property({ columnType: "text" }) - @Index({ - name: nameIndexName, - expression: nameIndexStatement, - }) + @NameIndex.MikroORMIndex() name: string @Property({ columnType: "jsonb", nullable: true }) metadata: Record | null = null @Property({ columnType: "text" }) - @Index({ - name: fulfillmentSetIdIndexName, - expression: fulfillmentSetIdIndexStatement, - }) + @FulfillmentSetIdIndex.MikroORMIndex() fulfillment_set_id: string @ManyToOne(() => FulfillmentSet, { persist: false }) diff --git a/packages/fulfillment/src/models/shipping-option-rule.ts b/packages/fulfillment/src/models/shipping-option-rule.ts index b4bc049b4e..5a0f4a7582 100644 --- a/packages/fulfillment/src/models/shipping-option-rule.ts +++ b/packages/fulfillment/src/models/shipping-option-rule.ts @@ -9,7 +9,6 @@ import { BeforeCreate, Entity, Filter, - Index, ManyToOne, OnInit, OptionalProps, @@ -20,16 +19,17 @@ import ShippingOption from "./shipping-option" type ShippingOptionRuleOptionalProps = DAL.SoftDeletableEntityDateColumns -// TODO: need some test to see if we continue with this kind of structure or we change it -// More adjustments can appear as I move forward - -const deletedAtIndexName = "IDX_shipping_option_rule_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option_rule", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) + +const ShippingOptionIdIndex = createPsqlIndexStatementHelper({ + tableName: "shipping_option_rule", + columns: "shipping_option_id", + where: "deleted_at IS NULL", +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -49,9 +49,10 @@ export default class ShippingOptionRule { value: { value: string | string[] } | null = null @Property({ columnType: "text" }) + @ShippingOptionIdIndex.MikroORMIndex() shipping_option_id: string - @ManyToOne(() => ShippingOption) + @ManyToOne(() => ShippingOption, { persist: false }) shipping_option: ShippingOption @Property({ @@ -69,20 +70,19 @@ export default class ShippingOptionRule { }) updated_at: Date - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null @BeforeCreate() onCreate() { this.id = generateEntityId(this.id, "sorul") + this.shipping_option_id ??= this.shipping_option?.id } @OnInit() onInit() { this.id = generateEntityId(this.id, "sorul") + this.shipping_option_id ??= this.shipping_option?.id } } diff --git a/packages/fulfillment/src/models/shipping-option-type.ts b/packages/fulfillment/src/models/shipping-option-type.ts index 80858b4511..ea643211fc 100644 --- a/packages/fulfillment/src/models/shipping-option-type.ts +++ b/packages/fulfillment/src/models/shipping-option-type.ts @@ -9,7 +9,6 @@ import { BeforeCreate, Entity, Filter, - Index, OneToOne, OnInit, OptionalProps, @@ -20,21 +19,17 @@ import ShippingOption from "./shipping-option" type ShippingOptionTypeOptionalProps = DAL.SoftDeletableEntityDateColumns -const deletedAtIndexName = "IDX_shipping_option_type_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option_type", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) -const shippingOptionIdIndexName = "IDX_shipping_option_type_shipping_option_id" -const shippingOptionIdIndexStatement = createPsqlIndexStatementHelper({ - name: shippingOptionIdIndexName, +const ShippingOptionIdIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option_type", columns: "shipping_option_id", where: "deleted_at IS NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -54,13 +49,12 @@ export default class ShippingOptionType { code: string @Property({ columnType: "text" }) - @Index({ - name: shippingOptionIdIndexName, - expression: shippingOptionIdIndexStatement, - }) + @ShippingOptionIdIndex.MikroORMIndex() shipping_option_id: string - @OneToOne(() => ShippingOption, (so) => so.shipping_option_type) + @OneToOne(() => ShippingOption, (so) => so.type, { + persist: false, + }) shipping_option: ShippingOption @Property({ @@ -78,20 +72,19 @@ export default class ShippingOptionType { }) updated_at: Date - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null @BeforeCreate() onCreate() { this.id = generateEntityId(this.id, "sotype") + this.shipping_option_id ??= this.shipping_option?.id } @OnInit() onInit() { this.id = generateEntityId(this.id, "sotype") + this.shipping_option_id ??= this.shipping_option?.id } } diff --git a/packages/fulfillment/src/models/shipping-option.ts b/packages/fulfillment/src/models/shipping-option.ts index 1c9d8ea267..7c5dfa43c6 100644 --- a/packages/fulfillment/src/models/shipping-option.ts +++ b/packages/fulfillment/src/models/shipping-option.ts @@ -8,11 +8,11 @@ import { import { DAL } from "@medusajs/types" import { BeforeCreate, + Cascade, Collection, Entity, Enum, Filter, - Index, ManyToOne, OneToMany, OneToOne, @@ -30,46 +30,35 @@ import ShippingProfile from "./shipping-profile" type ShippingOptionOptionalProps = DAL.SoftDeletableEntityDateColumns -const deletedAtIndexName = "IDX_shipping_option_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) -const serviceZoneIdIndexName = "IDX_shipping_option_service_zone_id" -const serviceZoneIdIndexStatement = createPsqlIndexStatementHelper({ - name: serviceZoneIdIndexName, +const ServiceZoneIdIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option", columns: "service_zone_id", where: "deleted_at IS NULL", -}).expression +}) -const shippingProfileIdIndexName = "IDX_shipping_option_shipping_profile_id" -const shippingProfileIdIndexStatement = createPsqlIndexStatementHelper({ - name: shippingProfileIdIndexName, +const ShippingProfileIdIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option", columns: "shipping_profile_id", where: "deleted_at IS NULL", -}).expression +}) -const serviceProviderIdIndexName = "IDX_shipping_option_service_provider_id" -const serviceProviderIdIndexStatement = createPsqlIndexStatementHelper({ - name: serviceProviderIdIndexName, +const ServiceProviderIdIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option", columns: "service_provider_id", where: "deleted_at IS NULL", -}).expression +}) -const shippingOptionTypeIdIndexName = - "IDX_shipping_option_shipping_option_type_id" -const shippingOptionTypeIdIndexStatement = createPsqlIndexStatementHelper({ - name: shippingOptionTypeIdIndexName, +const ShippingOptionTypeIdIndex = createPsqlIndexStatementHelper({ tableName: "shipping_option", columns: "shipping_option_type_id", where: "deleted_at IS NULL", -}).expression +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -88,32 +77,34 @@ export default class ShippingOption { }) price_type: ShippingOptionPriceType - @Property({ columnType: "text" }) - @Index({ - name: serviceZoneIdIndexName, - expression: serviceZoneIdIndexStatement, + @ManyToOne(() => ShippingProfile, { + type: "text", + fieldName: "service_zone_id", + mapToPk: true, }) + @ServiceZoneIdIndex.MikroORMIndex() service_zone_id: string - @Property({ columnType: "text" }) - @Index({ - name: shippingProfileIdIndexName, - expression: shippingProfileIdIndexStatement, + @ManyToOne(() => ShippingProfile, { + type: "text", + fieldName: "shipping_profile_id", + mapToPk: true, + nullable: true, }) - shipping_profile_id: string + @ShippingProfileIdIndex.MikroORMIndex() + shipping_profile_id: string | null - @Property({ columnType: "text" }) - @Index({ - name: serviceProviderIdIndexName, - expression: serviceProviderIdIndexStatement, + @ManyToOne(() => ServiceProvider, { + type: "text", + fieldName: "service_provider_id", + mapToPk: true, + nullable: true, }) + @ServiceProviderIdIndex.MikroORMIndex() service_provider_id: string - @Property({ columnType: "text", nullable: true }) - @Index({ - name: shippingOptionTypeIdIndexName, - expression: shippingOptionTypeIdIndexStatement, - }) + @Property({ columnType: "text", persist: false }) + @ShippingOptionTypeIdIndex.MikroORMIndex() shipping_option_type_id: string | null = null @Property({ columnType: "jsonb", nullable: true }) @@ -122,21 +113,30 @@ export default class ShippingOption { @Property({ columnType: "jsonb", nullable: true }) metadata: Record | null = null - @ManyToOne(() => ServiceZone) + @ManyToOne(() => ServiceZone, { persist: false }) service_zone: ServiceZone - @ManyToOne(() => ShippingProfile) - shipping_profile: ShippingProfile + @ManyToOne(() => ShippingProfile, { + persist: false, + }) + shipping_profile: ShippingProfile | null - @ManyToOne(() => ServiceProvider) - service_provider: ServiceProvider + @ManyToOne(() => ServiceProvider, { + persist: false, + }) + service_provider: ServiceProvider | null @OneToOne(() => ShippingOptionType, (so) => so.shipping_option, { owner: true, + cascade: [Cascade.PERSIST, Cascade.REMOVE, "soft-remove"] as any, + fieldName: "shipping_option_type_id", }) - shipping_option_type: ShippingOptionType + type: ShippingOptionType - @OneToMany(() => ShippingOptionRule, (sor) => sor.shipping_option) + @OneToMany(() => ShippingOptionRule, "shipping_option", { + cascade: [Cascade.PERSIST, "soft-remove"] as any, + orphanRemoval: true, + }) rules = new Collection(this) @OneToMany(() => Fulfillment, (fulfillment) => fulfillment.shipping_option) @@ -157,20 +157,19 @@ export default class ShippingOption { }) updated_at: Date - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null @BeforeCreate() onCreate() { this.id = generateEntityId(this.id, "so") + this.shipping_option_type_id ??= this.type?.id } @OnInit() onInit() { this.id = generateEntityId(this.id, "so") + this.shipping_option_type_id ??= this.type?.id } } diff --git a/packages/fulfillment/src/models/shipping-profile.ts b/packages/fulfillment/src/models/shipping-profile.ts index b8a359e64b..87db7f40b6 100644 --- a/packages/fulfillment/src/models/shipping-profile.ts +++ b/packages/fulfillment/src/models/shipping-profile.ts @@ -10,7 +10,6 @@ import { Collection, Entity, Filter, - Index, OneToMany, OnInit, OptionalProps, @@ -21,13 +20,18 @@ import ShippingOption from "./shipping-option" type ShippingProfileOptionalProps = DAL.SoftDeletableEntityDateColumns -const deletedAtIndexName = "IDX_shipping_profile_deleted_at" -const deletedAtIndexStatement = createPsqlIndexStatementHelper({ - name: deletedAtIndexName, +const DeletedAtIndex = createPsqlIndexStatementHelper({ tableName: "shipping_profile", columns: "deleted_at", where: "deleted_at IS NOT NULL", -}).expression +}) + +const ShippingProfileTypeIndex = createPsqlIndexStatementHelper({ + tableName: "shipping_profile", + columns: "name", + unique: true, + where: "deleted_at IS NULL", +}) @Entity() @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @@ -37,6 +41,13 @@ export default class ShippingProfile { @PrimaryKey({ columnType: "text" }) id: string + @Property({ columnType: "text" }) + @ShippingProfileTypeIndex.MikroORMIndex() + name: string + + @Property({ columnType: "text" }) + type: string + @OneToMany( () => ShippingOption, (shippingOption) => shippingOption.shipping_profile @@ -61,10 +72,7 @@ export default class ShippingProfile { }) updated_at: Date - @Index({ - name: deletedAtIndexName, - expression: deletedAtIndexStatement, - }) + @DeletedAtIndex.MikroORMIndex() @Property({ columnType: "timestamptz", nullable: true }) deleted_at: Date | null = null diff --git a/packages/fulfillment/src/module-definition.ts b/packages/fulfillment/src/module-definition.ts index db6f694b69..bc17d7d091 100644 --- a/packages/fulfillment/src/module-definition.ts +++ b/packages/fulfillment/src/module-definition.ts @@ -34,7 +34,7 @@ const connectionLoader = ModulesSdkUtils.mikroOrmConnectionLoaderFactory({ }) const service = FulfillmentModuleService -const loaders = [containerLoader, connectionLoader] as any +const loaders = [containerLoader, connectionLoader] export const moduleDefinition: ModuleExports = { service, diff --git a/packages/fulfillment/src/services/fulfillment-module-service.ts b/packages/fulfillment/src/services/fulfillment-module-service.ts index 2dbd8de4ef..e65c3be8c1 100644 --- a/packages/fulfillment/src/services/fulfillment-module-service.ts +++ b/packages/fulfillment/src/services/fulfillment-module-service.ts @@ -9,31 +9,46 @@ import { UpdateFulfillmentSetDTO, } from "@medusajs/types" import { + getSetDifference, InjectManager, InjectTransactionManager, MedusaContext, MedusaError, ModulesSdkUtils, promiseAll, - getSetDifference } from "@medusajs/utils" import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config" -import { FulfillmentSet, GeoZone, ServiceZone, ShippingOption } from "@models" +import { + FulfillmentSet, + GeoZone, + ServiceZone, + ShippingOption, + ShippingProfile, +} from "@models" -const generateMethodForModels = [ServiceZone, ShippingOption, GeoZone] +const generateMethodForModels = [ + ServiceZone, + ShippingOption, + GeoZone, + ShippingProfile, +] type InjectedDependencies = { baseRepository: DAL.RepositoryService fulfillmentSetService: ModulesSdkTypes.InternalModuleService serviceZoneService: ModulesSdkTypes.InternalModuleService geoZoneService: ModulesSdkTypes.InternalModuleService + shippingProfileService: ModulesSdkTypes.InternalModuleService + shippingOptionService: ModulesSdkTypes.InternalModuleService } export default class FulfillmentModuleService< TEntity extends FulfillmentSet = FulfillmentSet, TServiceZoneEntity extends ServiceZone = ServiceZone, - TGeoZoneEntity extends GeoZone = GeoZone + TGeoZoneEntity extends GeoZone = GeoZone, + TShippingProfileEntity extends ShippingProfile = ShippingProfile, + TShippingOptionEntity extends ShippingOption = ShippingOption > extends ModulesSdkUtils.abstractModuleServiceFactory< InjectedDependencies, @@ -43,6 +58,7 @@ export default class FulfillmentModuleService< ServiceZone: { dto: FulfillmentTypes.ServiceZoneDTO } ShippingOption: { dto: FulfillmentTypes.ShippingOptionDTO } GeoZone: { dto: FulfillmentTypes.GeoZoneDTO } + ShippingProfile: { dto: FulfillmentTypes.ShippingProfileDTO } } >(FulfillmentSet, generateMethodForModels, entityNameToLinkableKeysMap) implements IFulfillmentModuleService @@ -51,6 +67,8 @@ export default class FulfillmentModuleService< protected readonly fulfillmentSetService_: ModulesSdkTypes.InternalModuleService protected readonly serviceZoneService_: ModulesSdkTypes.InternalModuleService protected readonly geoZoneService_: ModulesSdkTypes.InternalModuleService + protected readonly shippingProfileService_: ModulesSdkTypes.InternalModuleService + protected readonly shippingOptionService_: ModulesSdkTypes.InternalModuleService constructor( { @@ -58,6 +76,8 @@ export default class FulfillmentModuleService< fulfillmentSetService, serviceZoneService, geoZoneService, + shippingProfileService, + shippingOptionService, }: InjectedDependencies, protected readonly moduleDeclaration: InternalModuleDeclaration ) { @@ -67,6 +87,8 @@ export default class FulfillmentModuleService< this.fulfillmentSetService_ = fulfillmentSetService this.serviceZoneService_ = serviceZoneService this.geoZoneService_ = geoZoneService + this.shippingProfileService_ = shippingProfileService + this.shippingOptionService_ = shippingOptionService } __joinerConfig(): ModuleJoinerConfig { @@ -179,7 +201,7 @@ export default class FulfillmentModuleService< sharedContext?: Context ): Promise - @InjectTransactionManager("baseRepository_") + @InjectManager("baseRepository_") async createShippingOptions( data: | FulfillmentTypes.CreateShippingOptionDTO[] @@ -188,7 +210,93 @@ export default class FulfillmentModuleService< ): Promise< FulfillmentTypes.ShippingOptionDTO | FulfillmentTypes.ShippingOptionDTO[] > { - return [] + const createdShippingOptions = await this.createShippingOptions_( + data, + sharedContext + ) + + return await this.baseRepository_.serialize< + FulfillmentTypes.ShippingOptionDTO | FulfillmentTypes.ShippingOptionDTO[] + >(createdShippingOptions, { + populate: true, + }) + } + + @InjectTransactionManager("baseRepository_") + async createShippingOptions_( + data: + | FulfillmentTypes.CreateShippingOptionDTO[] + | FulfillmentTypes.CreateShippingOptionDTO, + @MedusaContext() sharedContext: Context = {} + ): Promise { + let data_ = Array.isArray(data) ? data : [data] + + if (!data_.length) { + return [] + } + + const createdShippingOptions = await this.shippingOptionService_.create( + data_, + sharedContext + ) + + return Array.isArray(data) + ? createdShippingOptions + : createdShippingOptions[0] + } + + createShippingProfiles( + data: FulfillmentTypes.CreateShippingProfileDTO[], + sharedContext?: Context + ): Promise + createShippingProfiles( + data: FulfillmentTypes.CreateShippingProfileDTO, + sharedContext?: Context + ): Promise + + @InjectTransactionManager("baseRepository_") + async createShippingProfiles( + data: + | FulfillmentTypes.CreateShippingProfileDTO[] + | FulfillmentTypes.CreateShippingProfileDTO, + @MedusaContext() sharedContext: Context = {} + ): Promise< + FulfillmentTypes.ShippingProfileDTO | FulfillmentTypes.ShippingProfileDTO[] + > { + const createdShippingProfiles = await this.createShippingProfiles_( + data, + sharedContext + ) + + return await this.baseRepository_.serialize< + | FulfillmentTypes.ShippingProfileDTO + | FulfillmentTypes.ShippingProfileDTO[] + >(createdShippingProfiles, { + populate: true, + }) + } + + @InjectTransactionManager("baseRepository_") + async createShippingProfiles_( + data: + | FulfillmentTypes.CreateShippingProfileDTO[] + | FulfillmentTypes.CreateShippingProfileDTO, + @MedusaContext() sharedContext: Context = {} + ): Promise { + const data_ = Array.isArray(data) ? data : [data] + + if (!data_.length) { + return [] + } + + const createdShippingProfiles = await this.shippingProfileService_.create( + data_, + sharedContext + ) + + return Array.isArray(data) + ? createdShippingProfiles + : createdShippingProfiles[0] } createGeoZones( @@ -473,7 +581,6 @@ export default class FulfillmentModuleService< serviceZones.map((s) => [s.id, s]) ) - const serviceZoneIdsToDelete: string[] = [] const geoZoneIdsToDelete: string[] = [] data_.forEach((serviceZone) => { @@ -567,6 +674,27 @@ export default class FulfillmentModuleService< return [] } + updateShippingProfiles( + data: FulfillmentTypes.UpdateShippingProfileDTO[], + sharedContext?: Context + ): Promise + updateShippingProfiles( + data: FulfillmentTypes.UpdateShippingProfileDTO, + sharedContext?: Context + ): Promise + + @InjectTransactionManager("baseRepository_") + async updateShippingProfiles( + data: + | FulfillmentTypes.UpdateShippingProfileDTO + | FulfillmentTypes.UpdateShippingProfileDTO[], + @MedusaContext() sharedContext: Context = {} + ): Promise< + FulfillmentTypes.ShippingProfileDTO | FulfillmentTypes.ShippingProfileDTO[] + > { + return [] + } + updateGeoZones( data: FulfillmentTypes.UpdateGeoZoneDTO[], sharedContext?: Context diff --git a/packages/medusa-test-utils/src/database.ts b/packages/medusa-test-utils/src/database.ts index 30b513ef7a..dc8c454ff9 100644 --- a/packages/medusa-test-utils/src/database.ts +++ b/packages/medusa-test-utils/src/database.ts @@ -1,24 +1,28 @@ import { MikroORM, Options, SqlEntityManager } from "@mikro-orm/postgresql" -import * as process from "process" -import { Migrator } from "@mikro-orm/migrations" -export function getDatabaseURL(): string { +export function getDatabaseURL(dbName?: string): string { const DB_HOST = process.env.DB_HOST ?? "localhost" const DB_USERNAME = process.env.DB_USERNAME ?? "" const DB_PASSWORD = process.env.DB_PASSWORD - const DB_NAME = process.env.DB_TEMP_NAME + const DB_NAME = dbName ?? process.env.DB_TEMP_NAME return `postgres://${DB_USERNAME}${ DB_PASSWORD ? `:${DB_PASSWORD}` : "" }@${DB_HOST}/${DB_NAME}` } -export function getMikroOrmConfig( - mikroOrmEntities: any[], - pathToMigrations: string, // deprecated, auto inferred +export function getMikroOrmConfig({ + mikroOrmEntities, + pathToMigrations, + clientUrl, + schema, +}: { + mikroOrmEntities: any[] + pathToMigrations?: string + clientUrl?: string schema?: string -): Options { - const DB_URL = getDatabaseURL() +}): Options { + const DB_URL = clientUrl ?? getDatabaseURL() return { type: "postgresql", @@ -26,14 +30,18 @@ export function getMikroOrmConfig( entities: Object.values(mikroOrmEntities), schema: schema ?? process.env.MEDUSA_DB_SCHEMA, debug: false, - extensions: [Migrator], + migrations: { + pathTs: pathToMigrations, + silent: true, + }, } } export interface TestDatabase { mikroOrmEntities: any[] - pathToMigrations: any // deprecated, auto inferred + pathToMigrations?: string schema?: string + clientUrl?: string orm: MikroORM | null manager: SqlEntityManager | null @@ -45,14 +53,21 @@ export interface TestDatabase { getOrm(): MikroORM } -export function getMikroOrmWrapper( - mikroOrmEntities: any[], - pathToMigrations: string, // deprecated, auto inferred +export function getMikroOrmWrapper({ + mikroOrmEntities, + pathToMigrations, + clientUrl, + schema, +}: { + mikroOrmEntities: any[] + pathToMigrations?: string + clientUrl?: string schema?: string -): TestDatabase { +}): TestDatabase { return { mikroOrmEntities, - pathToMigrations, // deprecated, auto inferred + pathToMigrations, + clientUrl: clientUrl ?? getDatabaseURL(), schema: schema ?? process.env.MEDUSA_DB_SCHEMA, orm: null, @@ -83,11 +98,12 @@ export function getMikroOrmWrapper( }, async setupDatabase() { - const OrmConfig = getMikroOrmConfig( - this.mikroOrmEntities, - this.pathToMigrations, - this.schema - ) + const OrmConfig = getMikroOrmConfig({ + mikroOrmEntities: this.mikroOrmEntities, + pathToMigrations: this.pathToMigrations, + clientUrl: this.clientUrl, + schema: this.schema, + }) // Initializing the ORM this.orm = await MikroORM.init(OrmConfig) @@ -96,7 +112,9 @@ export function getMikroOrmWrapper( try { await this.orm.getSchemaGenerator().ensureDatabase() - } catch (err) {} + } catch (err) { + console.log(err) + } await this.manager?.execute( `CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";` diff --git a/packages/medusa-test-utils/src/index.ts b/packages/medusa-test-utils/src/index.ts index 8351d21097..b53e60a744 100644 --- a/packages/medusa-test-utils/src/index.ts +++ b/packages/medusa-test-utils/src/index.ts @@ -4,3 +4,4 @@ export * as JestUtils from "./jest" export { default as MockManager } from "./mock-manager" export { default as MockRepository } from "./mock-repository" export * from "./init-modules" +export * from "./module-test-runner" diff --git a/packages/medusa-test-utils/src/init-modules.ts b/packages/medusa-test-utils/src/init-modules.ts index 067c70a4c3..4e4c4ad02b 100644 --- a/packages/medusa-test-utils/src/init-modules.ts +++ b/packages/medusa-test-utils/src/init-modules.ts @@ -1,13 +1,12 @@ -import { knex } from "knex" import { MedusaApp, MedusaModule, MedusaModuleConfig, ModuleJoinerConfig, } from "@medusajs/modules-sdk" -import { ContainerRegistrationKeys } from "@medusajs/utils" +import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils" -interface InitModulesOptions { +export interface InitModulesOptions { injectedDependencies?: Record databaseConfig: { clientUrl: string @@ -15,6 +14,7 @@ interface InitModulesOptions { } modulesConfig: MedusaModuleConfig joinerConfig?: ModuleJoinerConfig[] + preventConnectionDestroyWarning?: boolean } export async function initModules({ @@ -22,19 +22,18 @@ export async function initModules({ databaseConfig, modulesConfig, joinerConfig, + preventConnectionDestroyWarning = false, }: InitModulesOptions) { injectedDependencies ??= {} let sharedPgConnection = injectedDependencies?.[ContainerRegistrationKeys.PG_CONNECTION] + let shouldDestroyConnectionAutomatically = !sharedPgConnection if (!sharedPgConnection) { - sharedPgConnection = knex({ - client: "pg", - searchPath: databaseConfig.schema, - connection: { - connectionString: databaseConfig.clientUrl, - }, + sharedPgConnection = ModulesSdkUtils.createPgConnection({ + clientUrl: databaseConfig.clientUrl, + schema: databaseConfig.schema, }) injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION] = @@ -48,7 +47,16 @@ export async function initModules({ }) async function shutdown() { - await (sharedPgConnection as any).context?.destroy() + if (shouldDestroyConnectionAutomatically) { + await (sharedPgConnection as any).context?.destroy() + await (sharedPgConnection as any).destroy() + } else { + if (!preventConnectionDestroyWarning) { + console.info( + `You are using a custom shared connection. The connection won't be destroyed automatically.` + ) + } + } MedusaModule.clearInstances() } diff --git a/packages/medusa-test-utils/src/module-test-runner.ts b/packages/medusa-test-utils/src/module-test-runner.ts new file mode 100644 index 0000000000..8907b633b9 --- /dev/null +++ b/packages/medusa-test-utils/src/module-test-runner.ts @@ -0,0 +1,128 @@ +import { getDatabaseURL, getMikroOrmWrapper, TestDatabase } from "./database" +import { MedusaAppOutput, ModulesDefinition } from "@medusajs/modules-sdk" +import { initModules, InitModulesOptions } from "./init-modules" +import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils" + +export interface SuiteOptions { + MikroOrmWrapper: TestDatabase + medusaApp: MedusaAppOutput + service: TService + dbConfig: { + schema: string + clientUrl: string + } +} + +export function moduleIntegrationTestRunner({ + moduleName, + moduleModels, + joinerConfig = [], + schema = "public", + testSuite, +}: { + moduleName: string + moduleModels?: any[] + joinerConfig?: any[] + schema?: string + dbName?: string + testSuite: (options: SuiteOptions) => () => void +}) { + moduleModels = Object.values(require(`${process.cwd()}/src/models`)) + // migrationPath ??= process.cwd() + "/src/migrations/!(*.d).{js,ts,cjs}" + + const tempName = parseInt(process.env.JEST_WORKER_ID || "1") + const dbName = `medusa-${moduleName.toLowerCase()}-integration-${tempName}` + + const dbConfig = { + clientUrl: getDatabaseURL(dbName), + schema, + } + + // Use a unique connection for all the entire suite + const connection = ModulesSdkUtils.createPgConnection(dbConfig) + + const MikroOrmWrapper = getMikroOrmWrapper({ + mikroOrmEntities: moduleModels, + clientUrl: dbConfig.clientUrl, + schema: dbConfig.schema, + }) + + const modulesConfig_ = { + [moduleName]: { + definition: ModulesDefinition[moduleName], + options: { + defaultAdapterOptions: { + database: dbConfig, + }, + }, + }, + } + + const moduleOptions: InitModulesOptions = { + injectedDependencies: { + [ContainerRegistrationKeys.PG_CONNECTION]: connection, + }, + modulesConfig: modulesConfig_, + databaseConfig: dbConfig, + joinerConfig, + preventConnectionDestroyWarning: true, + } + + let shutdown: () => Promise + let moduleService + let medusaApp: MedusaAppOutput = {} as MedusaAppOutput + + const options = { + MikroOrmWrapper, + medusaApp: new Proxy( + {}, + { + get: (target, prop) => { + return medusaApp[prop] + }, + } + ) as MedusaAppOutput, + service: new Proxy( + {}, + { + get: (target, prop) => { + return moduleService[prop] + }, + } + ), + } as SuiteOptions + + const beforeEach_ = async () => { + try { + await MikroOrmWrapper.setupDatabase() + const output = await initModules(moduleOptions) + shutdown = output.shutdown + medusaApp = output.medusaApp + moduleService = output.medusaApp.modules[moduleName] + } catch (error) { + console.error("Error setting up database:", error) + } + } + + const afterEach_ = async () => { + try { + await MikroOrmWrapper.clearDatabase() + await shutdown() + moduleService = {} + medusaApp = {} as MedusaAppOutput + } catch (error) { + console.error("Error tearing down database:", error) + } + } + + return describe("", () => { + beforeEach(beforeEach_) + afterEach(afterEach_) + afterAll(async () => { + await (connection as any).context?.destroy() + await (connection as any).destroy() + }) + + testSuite(options) + }) +} diff --git a/packages/order/integration-tests/utils/database.ts b/packages/order/integration-tests/utils/database.ts index 06c67a3bc2..dfd6467082 100644 --- a/packages/order/integration-tests/utils/database.ts +++ b/packages/order/integration-tests/utils/database.ts @@ -4,10 +4,9 @@ import * as Models from "@models" const mikroOrmEntities = Models as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - null, - process.env.MEDUSA_ORDER_DB_SCHEMA -) + schema: process.env.MEDUSA_ORDER_DB_SCHEMA, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/payment/integration-tests/utils/database.ts b/packages/payment/integration-tests/utils/database.ts index 0fbf6bdd1c..5afd38fe2c 100644 --- a/packages/payment/integration-tests/utils/database.ts +++ b/packages/payment/integration-tests/utils/database.ts @@ -1,18 +1,18 @@ -import { TestDatabaseUtils } from "medusa-test-utils" +import {TestDatabaseUtils} from "medusa-test-utils" import * as PaymentModules from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = PaymentModules as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/pricing/integration-tests/utils/database.ts b/packages/pricing/integration-tests/utils/database.ts index 0601587191..885476b676 100644 --- a/packages/pricing/integration-tests/utils/database.ts +++ b/packages/pricing/integration-tests/utils/database.ts @@ -5,14 +5,14 @@ import * as PricingModels from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = PricingModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/product/integration-tests/__tests__/module.ts b/packages/product/integration-tests/__tests__/module.ts index 7ff9606ef6..35e83bd6aa 100644 --- a/packages/product/integration-tests/__tests__/module.ts +++ b/packages/product/integration-tests/__tests__/module.ts @@ -1,7 +1,7 @@ import { MedusaModule, Modules } from "@medusajs/modules-sdk" import { IProductModuleService } from "@medusajs/types" import { kebabCase } from "@medusajs/utils" -import { knex } from "knex" +import { knex } from "@mikro-orm/knex" import { initModules } from "medusa-test-utils" import * as CustomRepositories from "../__fixtures__/module" import { diff --git a/packages/promotion/integration-tests/utils/database.ts b/packages/promotion/integration-tests/utils/database.ts index 8069e5a72f..825aa4b93c 100644 --- a/packages/promotion/integration-tests/utils/database.ts +++ b/packages/promotion/integration-tests/utils/database.ts @@ -1,18 +1,18 @@ -import { TestDatabaseUtils } from "medusa-test-utils" +import {TestDatabaseUtils} from "medusa-test-utils" import * as PromotionModels from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = PromotionModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/region/integration-tests/utils/database.ts b/packages/region/integration-tests/utils/database.ts index f412f49944..66272d1565 100644 --- a/packages/region/integration-tests/utils/database.ts +++ b/packages/region/integration-tests/utils/database.ts @@ -1,18 +1,18 @@ -import { TestDatabaseUtils } from "medusa-test-utils" +import {TestDatabaseUtils} from "medusa-test-utils" import * as RegionModels from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = RegionModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/sales-channel/integration-tests/utils/database.ts b/packages/sales-channel/integration-tests/utils/database.ts index 40496a5b41..26681dd7fc 100644 --- a/packages/sales-channel/integration-tests/utils/database.ts +++ b/packages/sales-channel/integration-tests/utils/database.ts @@ -1,18 +1,18 @@ -import { TestDatabaseUtils } from "medusa-test-utils" +import {TestDatabaseUtils} from "medusa-test-utils" import * as SalesChannelModels from "@models" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = SalesChannelModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/tax/integration-tests/utils/database.ts b/packages/tax/integration-tests/utils/database.ts index c3b4a6c848..dfd6467082 100644 --- a/packages/tax/integration-tests/utils/database.ts +++ b/packages/tax/integration-tests/utils/database.ts @@ -4,10 +4,9 @@ import * as Models from "@models" const mikroOrmEntities = Models as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - null, - process.env.MEDUSA_TAX_DB_SCHEMA -) + schema: process.env.MEDUSA_ORDER_DB_SCHEMA, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/types/src/dal/index.ts b/packages/types/src/dal/index.ts index 341a50dbee..ff519f167a 100644 --- a/packages/types/src/dal/index.ts +++ b/packages/types/src/dal/index.ts @@ -1,4 +1,4 @@ -import { Dictionary, FilterQuery, Order } from "./utils" +import { Dictionary, FilterQuery, OperatorMap, Order } from "./utils" export { FilterQuery, OperatorMap } from "./utils" diff --git a/packages/types/src/fulfillment/common/service-zone.ts b/packages/types/src/fulfillment/common/service-zone.ts index 8dcb3076f0..acb827500e 100644 --- a/packages/types/src/fulfillment/common/service-zone.ts +++ b/packages/types/src/fulfillment/common/service-zone.ts @@ -1,7 +1,7 @@ import { FulfillmentSetDTO } from "./fulfillment-set" import { FilterableGeoZoneProps, GeoZoneDTO } from "./geo-zone" import { ShippingOptionDTO } from "./shipping-option" -import { BaseFilterable } from "../../dal" +import { BaseFilterable, OperatorMap } from "../../dal" export interface ServiceZoneDTO { id: string @@ -17,8 +17,8 @@ export interface ServiceZoneDTO { export interface FilterableServiceZoneProps extends BaseFilterable { - id?: string | string[] - name?: string | string[] + id?: string | string[] | OperatorMap + name?: string | string[] | OperatorMap geo_zones?: FilterableGeoZoneProps shipping_options?: any // TODO } diff --git a/packages/types/src/fulfillment/common/shipping-option-rule.ts b/packages/types/src/fulfillment/common/shipping-option-rule.ts index dff66b4ca1..d9ac5f4f67 100644 --- a/packages/types/src/fulfillment/common/shipping-option-rule.ts +++ b/packages/types/src/fulfillment/common/shipping-option-rule.ts @@ -1,5 +1,5 @@ import { ShippingOptionDTO } from "./shipping-option" -import { BaseFilterable } from "../../dal" +import { BaseFilterable, OperatorMap } from "../../dal" export interface ShippingOptionRuleDTO { id: string @@ -15,8 +15,8 @@ export interface ShippingOptionRuleDTO { export interface FilterableShippingOptionRuleProps extends BaseFilterable { - id?: string | string[] - attribute?: string | string[] - operator?: string | string[] - value?: string | string[] + id?: string | string[] | OperatorMap + attribute?: string | string[] | OperatorMap + operator?: string | string[] | OperatorMap + value?: string | string[] | OperatorMap } diff --git a/packages/types/src/fulfillment/common/shipping-option-type.ts b/packages/types/src/fulfillment/common/shipping-option-type.ts index a2f86741c5..b52a1b93c4 100644 --- a/packages/types/src/fulfillment/common/shipping-option-type.ts +++ b/packages/types/src/fulfillment/common/shipping-option-type.ts @@ -1,5 +1,5 @@ import { ShippingOptionDTO } from "./shipping-option" -import { BaseFilterable } from "../../dal" +import { BaseFilterable, OperatorMap } from "../../dal" export interface ShippingOptionTypeDTO { id: string @@ -15,8 +15,8 @@ export interface ShippingOptionTypeDTO { export interface FilterableShippingOptionTypeProps extends BaseFilterable { - id?: string | string[] - label?: string | string[] - description?: string | string[] - code?: string | string[] + id?: string | string[] | OperatorMap + label?: string | string[] | OperatorMap + description?: string | string[] | OperatorMap + code?: string | string[] | OperatorMap } diff --git a/packages/types/src/fulfillment/common/shipping-option.ts b/packages/types/src/fulfillment/common/shipping-option.ts index 9243adfcae..fe2ab7ca2a 100644 --- a/packages/types/src/fulfillment/common/shipping-option.ts +++ b/packages/types/src/fulfillment/common/shipping-option.ts @@ -9,7 +9,7 @@ import { FilterableShippingOptionRuleProps, ShippingOptionRuleDTO, } from "./shipping-option-rule" -import { BaseFilterable } from "../../dal" +import { BaseFilterable, OperatorMap } from "../../dal" export type ShippingOptionPriceType = "calculated" | "flat" @@ -35,9 +35,12 @@ export interface ShippingOptionDTO { export interface FilterableShippingOptionProps extends BaseFilterable { - id?: string | string[] - name?: string | string[] - price_type?: ShippingOptionPriceType | ShippingOptionPriceType[] + id?: string | string[] | OperatorMap + name?: string | string[] | OperatorMap + price_type?: + | ShippingOptionPriceType + | ShippingOptionPriceType[] + | OperatorMap service_zone?: FilterableServiceZoneProps shipping_option_type?: FilterableShippingOptionTypeProps rules?: FilterableShippingOptionRuleProps diff --git a/packages/types/src/fulfillment/common/shipping-profile.ts b/packages/types/src/fulfillment/common/shipping-profile.ts index 3a2830e254..03336147ab 100644 --- a/packages/types/src/fulfillment/common/shipping-profile.ts +++ b/packages/types/src/fulfillment/common/shipping-profile.ts @@ -1,11 +1,24 @@ -import { ShippingOptionDTO } from "./shipping-option" +import { + FilterableShippingOptionProps, + ShippingOptionDTO, +} from "./shipping-option" +import { BaseFilterable, OperatorMap } from "../../dal" export interface ShippingProfileDTO { id: string name: string + type: string metadata: Record | null shipping_options: ShippingOptionDTO[] created_at: Date updated_at: Date deleted_at: Date | null } + +export interface FilterableShippingProfileProps + extends BaseFilterable { + id?: string | string[] | OperatorMap + name?: string | string[] | OperatorMap + type?: string | string[] | OperatorMap + shipping_options?: FilterableShippingOptionProps +} diff --git a/packages/types/src/fulfillment/mutations/geo-zone.ts b/packages/types/src/fulfillment/mutations/geo-zone.ts index 087e9f6ead..df2518316d 100644 --- a/packages/types/src/fulfillment/mutations/geo-zone.ts +++ b/packages/types/src/fulfillment/mutations/geo-zone.ts @@ -7,21 +7,21 @@ interface CreateGeoZoneBaseDTO { metadata?: Record | null } -interface CreateCountryGeoZoneDTO extends CreateGeoZoneBaseDTO { +export interface CreateCountryGeoZoneDTO extends CreateGeoZoneBaseDTO { type: "country" } -interface CreateProvinceGeoZoneDTO extends CreateGeoZoneBaseDTO { +export interface CreateProvinceGeoZoneDTO extends CreateGeoZoneBaseDTO { type: "province" province_code: string } -interface CreateCityGeoZoneDTO extends CreateGeoZoneBaseDTO { +export interface CreateCityGeoZoneDTO extends CreateGeoZoneBaseDTO { type: "city" city: string } -interface CreateZipGeoZoneDTO extends CreateGeoZoneBaseDTO { +export interface CreateZipGeoZoneDTO extends CreateGeoZoneBaseDTO { type: "zip" postal_expression: Record } @@ -32,25 +32,25 @@ export type CreateGeoZoneDTO = | CreateCityGeoZoneDTO | CreateZipGeoZoneDTO -interface UpdateGeoZoneBaseDTO extends Partial { +export interface UpdateGeoZoneBaseDTO extends Partial { id: string } -interface UpdateCountryGeoZoneDTO extends UpdateGeoZoneBaseDTO { +export interface UpdateCountryGeoZoneDTO extends UpdateGeoZoneBaseDTO { type: "country" } -interface UpdateProvinceGeoZoneDTO extends UpdateGeoZoneBaseDTO { +export interface UpdateProvinceGeoZoneDTO extends UpdateGeoZoneBaseDTO { type: "province" province_code: string } -interface UpdateCityGeoZoneDTO extends UpdateGeoZoneBaseDTO { +export interface UpdateCityGeoZoneDTO extends UpdateGeoZoneBaseDTO { type: "city" city: string } -interface UpdateZipGeoZoneDTO extends UpdateGeoZoneBaseDTO { +export interface UpdateZipGeoZoneDTO extends UpdateGeoZoneBaseDTO { type: "zip" postal_expression: Record } diff --git a/packages/types/src/fulfillment/mutations/index.ts b/packages/types/src/fulfillment/mutations/index.ts index 6f14b920ca..2f36038547 100644 --- a/packages/types/src/fulfillment/mutations/index.ts +++ b/packages/types/src/fulfillment/mutations/index.ts @@ -1,3 +1,4 @@ +export * from "./shipping-profile" export * from "./shipping-option-type" export * from "./shipping-option-rule" export * from "./geo-zone" diff --git a/packages/types/src/fulfillment/mutations/service-zone.ts b/packages/types/src/fulfillment/mutations/service-zone.ts index 8d678acc07..6c37b3264a 100644 --- a/packages/types/src/fulfillment/mutations/service-zone.ts +++ b/packages/types/src/fulfillment/mutations/service-zone.ts @@ -1,13 +1,29 @@ -import { CreateGeoZoneDTO } from "./geo-zone" +import { + CreateCityGeoZoneDTO, + CreateCountryGeoZoneDTO, + CreateProvinceGeoZoneDTO, + CreateZipGeoZoneDTO, +} from "./geo-zone" export interface CreateServiceZoneDTO { name: string fulfillment_set_id: string - geo_zones?: Omit[] + geo_zones?: ( + | Omit + | Omit + | Omit + | Omit + )[] } export interface UpdateServiceZoneDTO { id: string name?: string - geo_zones?: (Omit | { id: string })[] + geo_zones?: ( + | Omit + | Omit + | Omit + | Omit + | { id: string } + )[] } diff --git a/packages/types/src/fulfillment/mutations/shipping-option.ts b/packages/types/src/fulfillment/mutations/shipping-option.ts index d0967fb89b..3070870b07 100644 --- a/packages/types/src/fulfillment/mutations/shipping-option.ts +++ b/packages/types/src/fulfillment/mutations/shipping-option.ts @@ -1,12 +1,6 @@ -import { - CreateShippingOptionTypeDTO, - UpdateShippingOptionTypeDTO, -} from "./shipping-option-type" +import { CreateShippingOptionTypeDTO } from "./shipping-option-type" import { ShippingOptionPriceType } from "../common" -import { - CreateShippingOptionRuleDTO, - UpdateShippingOptionRuleDTO, -} from "./shipping-option-rule" +import { CreateShippingOptionRuleDTO } from "./shipping-option-rule" export interface CreateShippingOptionDTO { name: string @@ -26,12 +20,10 @@ export interface UpdateShippingOptionDTO { service_zone_id?: string shipping_profile_id?: string service_provider_id?: string - type: - | Omit - | Omit + type: Omit | { id: string } data?: Record | null rules?: ( | Omit - | Omit + | { id: string } )[] } diff --git a/packages/types/src/fulfillment/mutations/shipping-profile.ts b/packages/types/src/fulfillment/mutations/shipping-profile.ts new file mode 100644 index 0000000000..c663fa1616 --- /dev/null +++ b/packages/types/src/fulfillment/mutations/shipping-profile.ts @@ -0,0 +1,8 @@ +export interface CreateShippingProfileDTO { + name: string + type?: string + metadata?: Record +} + +export interface UpdateShippingProfileDTO + extends Partial {} diff --git a/packages/types/src/fulfillment/service.ts b/packages/types/src/fulfillment/service.ts index ef47d0651d..32a74855c5 100644 --- a/packages/types/src/fulfillment/service.ts +++ b/packages/types/src/fulfillment/service.ts @@ -4,10 +4,12 @@ import { FilterableGeoZoneProps, FilterableServiceZoneProps, FilterableShippingOptionProps, + FilterableShippingProfileProps, FulfillmentSetDTO, GeoZoneDTO, ServiceZoneDTO, ShippingOptionDTO, + ShippingProfileDTO, } from "./common" import { FindConfig } from "../common" import { Context } from "../shared-context" @@ -22,6 +24,7 @@ import { UpdateServiceZoneDTO, UpdateShippingOptionDTO, } from "./mutations" +import { CreateShippingProfileDTO } from "./mutations/shipping-profile" export interface IFulfillmentModuleService extends IModuleService { /** @@ -66,6 +69,21 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * Create a new shipping profile + * @param data + * @param sharedContext + */ + createShippingProfiles( + data: CreateShippingProfileDTO[], + sharedContext?: Context + ): Promise + + createShippingProfiles( + data: CreateShippingProfileDTO, + sharedContext?: Context + ): Promise + /** * Create a new geo zone * @param data @@ -122,6 +140,20 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * Update a shipping profile + * @param data + * @param sharedContext + */ + updateShippingProfiles( + data: CreateShippingProfileDTO[], + sharedContext?: Context + ): Promise + updateShippingProfiles( + data: CreateShippingProfileDTO, + sharedContext?: Context + ): Promise + /** * Update a geo zone * @param data @@ -160,6 +192,14 @@ export interface IFulfillmentModuleService extends IModuleService { deleteShippingOptions(ids: string[], sharedContext?: Context): Promise deleteShippingOptions(id: string, sharedContext?: Context): Promise + /** + * Delete a shipping profile + * @param ids + * @param sharedContext + */ + deleteShippingProfiles(ids: string[], sharedContext?: Context): Promise + deleteShippingProfiles(id: string, sharedContext?: Context): Promise + /** * Delete a geo zone * @param ids @@ -204,6 +244,18 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * Retrieve a shipping profile + * @param id + * @param config + * @param sharedContext + */ + retrieveShippingProfile( + id: string, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** * Retrieve a geo zone * @param id @@ -252,6 +304,18 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise + /** + * List shipping profiles + * @param filters + * @param config + * @param sharedContext + */ + listShippingProfiles( + filters?: FilterableShippingProfileProps, + config?: FindConfig, + sharedContext?: Context + ): Promise + /** * List geo zones * @param filters @@ -300,6 +364,18 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise<[ShippingOptionDTO[], number]> + /** + * List and count shipping profiles + * @param filters + * @param config + * @param sharedContext + */ + listAndCountShippingProfiles( + filters?: FilterableShippingProfileProps, + config?: FindConfig, + sharedContext?: Context + ): Promise<[ShippingProfileDTO[], number]> + /** * List and count geo zones * @param filters @@ -348,6 +424,18 @@ export interface IFulfillmentModuleService extends IModuleService { sharedContext?: Context ): Promise | void> + /** + * Soft delete shipping profiles + * @param shippingProfileIds + * @param config + * @param sharedContext + */ + softDeleteShippingProfiles( + shippingProfileIds: string[], + config?: SoftDeleteReturn, + sharedContext?: Context + ): Promise | void> + /** * Soft delete geo zones * @param geoZoneIds @@ -365,4 +453,6 @@ export interface IFulfillmentModuleService extends IModuleService { config?: RestoreReturn, sharedContext?: Context ): Promise | void> + + // TODO defined the other restore methods } diff --git a/packages/user/integration-tests/utils/database.ts b/packages/user/integration-tests/utils/database.ts index 7e67163fc7..507ff58bd2 100644 --- a/packages/user/integration-tests/utils/database.ts +++ b/packages/user/integration-tests/utils/database.ts @@ -1,18 +1,18 @@ import * as UserModels from "@models" -import { TestDatabaseUtils } from "medusa-test-utils" +import {TestDatabaseUtils} from "medusa-test-utils" const pathToMigrations = "../../src/migrations" const mikroOrmEntities = UserModels as unknown as any[] -export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( +export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) -export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( +export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({ mikroOrmEntities, - pathToMigrations -) + pathToMigrations, +}) export const DB_URL = TestDatabaseUtils.getDatabaseURL() diff --git a/packages/utils/src/common/__tests__/create-psql-index-helper.ts b/packages/utils/src/common/__tests__/create-psql-index-helper.ts index aea4935874..a275477716 100644 --- a/packages/utils/src/common/__tests__/create-psql-index-helper.ts +++ b/packages/utils/src/common/__tests__/create-psql-index-helper.ts @@ -84,7 +84,7 @@ describe("createPsqlIndexStatementHelper", function () { const indexStatement = createPsqlIndexStatementHelper(options) expect(indexStatement.expression).toEqual( - `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_table_name_column_name_1_column_name_2" ON "${ + `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_table_name_column_name_1_column_name_2_unique" ON "${ options.tableName }" (${options.columns.join(", ")}) WHERE ${options.where}` ) diff --git a/packages/utils/src/common/create-psql-index-helper.ts b/packages/utils/src/common/create-psql-index-helper.ts index 47852b8862..524efcd8e1 100644 --- a/packages/utils/src/common/create-psql-index-helper.ts +++ b/packages/utils/src/common/create-psql-index-helper.ts @@ -47,7 +47,7 @@ export function createPsqlIndexStatementHelper({ const columnsName = Array.isArray(columns) ? columns.join("_") : columns columns = Array.isArray(columns) ? columns.join(", ") : columns - name = name || `IDX_${tableName}_${columnsName}` + name = name || `IDX_${tableName}_${columnsName}${unique ? "_unique" : ""}` const typeStr = type ? ` USING ${type}` : "" const optionsStr = where ? ` WHERE ${where}` : "" @@ -63,7 +63,7 @@ export function createPsqlIndexStatementHelper({ }, name, expression, - MikroORMIndex: (options = {}) => { + MikroORMIndex: (options?: Parameters[0]) => { return Index({ name, expression, diff --git a/packages/utils/src/modules-sdk/abstract-module-service-factory.ts b/packages/utils/src/modules-sdk/abstract-module-service-factory.ts index e6e23257df..b4311abde0 100644 --- a/packages/utils/src/modules-sdk/abstract-module-service-factory.ts +++ b/packages/utils/src/modules-sdk/abstract-module-service-factory.ts @@ -97,13 +97,6 @@ export interface AbstractModuleServiceBase { ): Promise | void> } -/** - * Multiple issues on typescript around mapped types function are open, so - * when overriding a method from the base class that is mapped dynamically from the - * other models, we will have to ignore the error (2425) - * - * see: https://github.com/microsoft/TypeScript/issues/48125 - */ export type AbstractModuleService< TContainer, TMainModelDTO, diff --git a/packages/utils/src/modules-sdk/create-pg-connection.ts b/packages/utils/src/modules-sdk/create-pg-connection.ts index 4770c1a35f..be5d361d0b 100644 --- a/packages/utils/src/modules-sdk/create-pg-connection.ts +++ b/packages/utils/src/modules-sdk/create-pg-connection.ts @@ -1,4 +1,4 @@ -import knex from "knex" +import { knex } from "@mikro-orm/knex" import { ModuleServiceInitializeOptions } from "@medusajs/types" type Options = ModuleServiceInitializeOptions["database"] diff --git a/packages/workflow-engine-redis/integration-tests/__tests__/index.spec.ts b/packages/workflow-engine-redis/integration-tests/__tests__/index.spec.ts index 9d72daafb1..4a8493cf31 100644 --- a/packages/workflow-engine-redis/integration-tests/__tests__/index.spec.ts +++ b/packages/workflow-engine-redis/integration-tests/__tests__/index.spec.ts @@ -3,7 +3,7 @@ import { TransactionStepTimeoutError, TransactionTimeoutError, } from "@medusajs/orchestration" -import { RemoteJoinerQuery } from "@medusajs/types" +import { RemoteQueryFunction } from "@medusajs/types" import { TransactionHandlerType } from "@medusajs/utils" import { IWorkflowEngineService } from "@medusajs/workflows-sdk" import { knex } from "knex" @@ -27,10 +27,7 @@ const afterEach_ = async () => { describe("Workflow Orchestrator module", function () { describe("Testing basic workflow", function () { let workflowOrcModule: IWorkflowEngineService - let query: ( - query: string | RemoteJoinerQuery | object, - variables?: Record - ) => Promise + let query: RemoteQueryFunction afterEach(afterEach_)