feat(fulfillment): implementation part 2 (#6408)

**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
This commit is contained in:
Adrien de Peretti authored and GitHub committed 2024-02-19 12:33:46 +00:00
1 parent 680dfcdad3
commit 1d91b7429b
59 files changed
+1103 -631

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
---
"@medusajs/medusa": patch
"medusa-test-utils": patch
"@medusajs/product": patch
"@medusajs/types": patch
---
feat(fulfillment): implementation part 2
@@ -5,14 +5,14 @@ import { TestDatabaseUtils } from "medusa-test-utils"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = AuthModels as unknown as any[] const mikroOrmEntities = AuthModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -5,14 +5,14 @@ import * as CartModels from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = CartModels as unknown as any[] const mikroOrmEntities = CartModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -5,14 +5,14 @@ import * as Models from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = Models as unknown as any[] const mikroOrmEntities = Models as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -1 +0,0 @@
// noop
@@ -1,44 +1,29 @@
import { Modules } from "@medusajs/modules-sdk" import { Modules } from "@medusajs/modules-sdk"
import { initModules } from "medusa-test-utils/dist"
import { import {
CreateFulfillmentSetDTO, CreateFulfillmentSetDTO,
CreateGeoZoneDTO, CreateGeoZoneDTO,
CreateServiceZoneDTO, CreateServiceZoneDTO,
CreateShippingOptionDTO,
CreateShippingProfileDTO,
GeoZoneDTO, GeoZoneDTO,
IFulfillmentModuleService, IFulfillmentModuleService,
ServiceZoneDTO, ServiceZoneDTO,
UpdateFulfillmentSetDTO, UpdateFulfillmentSetDTO,
UpdateGeoZoneDTO, UpdateGeoZoneDTO,
UpdateServiceZoneDTO,
} from "@medusajs/types" } from "@medusajs/types"
import { getInitModuleConfig, MikroOrmWrapper } from "../utils"
import { GeoZoneType } from "@medusajs/utils" import { GeoZoneType } from "@medusajs/utils"
import { moduleIntegrationTestRunner, SuiteOptions } from "medusa-test-utils"
describe("fulfillment module service", function () { jest.setTimeout(100000)
let service: IFulfillmentModuleService
let shutdownFunc: () => Promise<void>
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()
})
moduleIntegrationTestRunner({
moduleName: Modules.FULFILLMENT,
testSuite: ({
MikroOrmWrapper,
service,
}: SuiteOptions<IFulfillmentModuleService>) => {
describe("Fulfillment Module Service", () => {
describe("read", () => { describe("read", () => {
describe("fulfillment set", () => { describe("fulfillment set", () => {
it("should list fulfillment sets with a filter", async function () { it("should list fulfillment sets with a filter", async function () {
@@ -62,7 +47,9 @@ describe("fulfillment module service", function () {
], ],
}) })
let listedSets = await service.list({ type: createdSet1.type }) let listedSets = await service.list({
type: createdSet1.type,
})
expect(listedSets).toEqual( expect(listedSets).toEqual(
expect.arrayContaining([ expect.arrayContaining([
@@ -71,7 +58,9 @@ describe("fulfillment module service", function () {
]) ])
) )
listedSets = await service.list({ name: createdSet2.name }) listedSets = await service.list({
name: createdSet2.name,
})
expect(listedSets).toEqual( expect(listedSets).toEqual(
expect.arrayContaining([ expect.arrayContaining([
@@ -84,7 +73,9 @@ describe("fulfillment module service", function () {
]) ])
) )
listedSets = await service.list({ service_zones: { name: "test" } }) listedSets = await service.list({
service_zones: { name: "test" },
})
expect(listedSets).toEqual( expect(listedSets).toEqual(
expect.arrayContaining([ expect.arrayContaining([
@@ -380,8 +371,8 @@ describe("fulfillment module service", function () {
geo_zones: expect.arrayContaining([ geo_zones: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
type: (data.service_zones![0] as any).geo_zones[0].type, type: (data.service_zones![0] as any).geo_zones[0].type,
country_code: (data.service_zones![0] as any).geo_zones[0] country_code: (data.service_zones![0] as any)
.country_code, .geo_zones[0].country_code,
}), }),
]), ]),
}), }),
@@ -457,7 +448,8 @@ describe("fulfillment module service", function () {
name: (data_.service_zones![0] as any).name, name: (data_.service_zones![0] as any).name,
geo_zones: expect.arrayContaining([ geo_zones: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
type: (data_.service_zones![0] as any).geo_zones[0].type, type: (data_.service_zones![0] as any).geo_zones[0]
.type,
country_code: (data_.service_zones![0] as any) country_code: (data_.service_zones![0] as any)
.geo_zones[0].country_code, .geo_zones[0].country_code,
}), }),
@@ -511,7 +503,8 @@ describe("fulfillment module service", function () {
geo_zones: expect.arrayContaining([ geo_zones: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
type: (data.geo_zones![0] as GeoZoneDTO).type, type: (data.geo_zones![0] as GeoZoneDTO).type,
country_code: (data.geo_zones![0] as GeoZoneDTO).country_code, country_code: (data.geo_zones![0] as GeoZoneDTO)
.country_code,
}), }),
]), ]),
}) })
@@ -674,6 +667,253 @@ describe("fulfillment module service", function () {
}) })
}) })
describe("on create shipping profiles", () => {
it("should create a new shipping profile", async function () {
const createData: CreateShippingProfileDTO = {
name: "test-default-profile",
type: "default",
}
const createdShippingProfile = await service.createShippingProfiles(
createData
)
expect(createdShippingProfile).toEqual(
expect.objectContaining({
name: createData.name,
type: createData.type,
})
)
})
it("should create multiple new shipping profiles", async function () {
const createData: CreateShippingProfileDTO[] = [
{
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", () => { describe("on update", () => {
it("should update an existing fulfillment set", async function () { it("should update an existing fulfillment set", async function () {
const createData: CreateFulfillmentSetDTO = { const createData: CreateFulfillmentSetDTO = {
@@ -982,8 +1222,9 @@ describe("fulfillment module service", function () {
id: expect.any(String), id: expect.any(String),
type: (data_.service_zones![0] as ServiceZoneDTO) type: (data_.service_zones![0] as ServiceZoneDTO)
.geo_zones[0].type, .geo_zones[0].type,
country_code: (data_.service_zones![0] as ServiceZoneDTO) country_code: (
.geo_zones[0].country_code, data_.service_zones![0] as ServiceZoneDTO
).geo_zones[0].country_code,
}), }),
]), ]),
}), }),
@@ -999,10 +1240,12 @@ describe("fulfillment module service", function () {
expect(serviceZones).toEqual( expect(serviceZones).toEqual(
expect.arrayContaining([ expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
name: updateData[0].service_zones![0].name, name: (updateData[0].service_zones![0] as ServiceZoneDTO)
.name,
}), }),
expect.objectContaining({ expect.objectContaining({
name: updateData[1].service_zones![0].name, name: (updateData[1].service_zones![0] as ServiceZoneDTO)
.name,
}), }),
]) ])
) )
@@ -1086,8 +1329,9 @@ describe("fulfillment module service", function () {
id: expect.any(String), id: expect.any(String),
type: (data_.service_zones![1] as ServiceZoneDTO) type: (data_.service_zones![1] as ServiceZoneDTO)
.geo_zones[0].type, .geo_zones[0].type,
country_code: (data_.service_zones![1] as ServiceZoneDTO) country_code: (
.geo_zones[0].country_code, data_.service_zones![1] as ServiceZoneDTO
).geo_zones[0].country_code,
}), }),
]), ]),
}), }),
@@ -1109,10 +1353,12 @@ describe("fulfillment module service", function () {
name: createdFulfillmentSets[1].service_zones![0].name, name: createdFulfillmentSets[1].service_zones![0].name,
}), }),
expect.objectContaining({ expect.objectContaining({
name: updateData[0].service_zones![1].name, name: (updateData[0].service_zones![1] as ServiceZoneDTO)
.name,
}), }),
expect.objectContaining({ expect.objectContaining({
name: updateData[1].service_zones![1].name, name: (updateData[1].service_zones![1] as ServiceZoneDTO)
.name,
}), }),
]) ])
) )
@@ -1137,7 +1383,9 @@ describe("fulfillment module service", function () {
], ],
} }
const createdServiceZone = await service.createServiceZones(createData) const createdServiceZone = await service.createServiceZones(
createData
)
const updateData = { const updateData = {
id: createdServiceZone.id, id: createdServiceZone.id,
@@ -1151,7 +1399,9 @@ describe("fulfillment module service", function () {
], ],
} }
const updatedServiceZone = await service.updateServiceZones(updateData) const updatedServiceZone = await service.updateServiceZones(
updateData
)
expect(updatedServiceZone).toEqual( expect(updatedServiceZone).toEqual(
expect.objectContaining({ expect.objectContaining({
@@ -1197,9 +1447,12 @@ describe("fulfillment module service", function () {
}, },
] ]
const createdServiceZones = await service.createServiceZones(createData) const createdServiceZones = await service.createServiceZones(
createData
)
const updateData = createdServiceZones.map((serviceZone, index) => ({ const updateData: UpdateServiceZoneDTO[] = createdServiceZones.map(
(serviceZone, index) => ({
id: serviceZone.id, id: serviceZone.id,
name: `updated-service-zone-test${index + 1}`, name: `updated-service-zone-test${index + 1}`,
geo_zones: [ geo_zones: [
@@ -1208,9 +1461,12 @@ describe("fulfillment module service", function () {
country_code: index % 2 === 0 ? "us" : "fr", country_code: index % 2 === 0 ? "us" : "fr",
}, },
], ],
})) })
)
const updatedServiceZones = await service.updateServiceZones(updateData) const updatedServiceZones = await service.updateServiceZones(
updateData
)
expect(updatedServiceZones).toHaveLength(2) expect(updatedServiceZones).toHaveLength(2)
@@ -1222,8 +1478,9 @@ describe("fulfillment module service", function () {
name: data_.name, name: data_.name,
geo_zones: expect.arrayContaining([ geo_zones: expect.arrayContaining([
expect.objectContaining({ expect.objectContaining({
type: data_.geo_zones[0].type, type: (data_.geo_zones![0] as GeoZoneDTO).type,
country_code: data_.geo_zones[0].country_code, country_code: (data_.geo_zones![0] as GeoZoneDTO)
.country_code,
}), }),
]), ]),
}) })
@@ -1261,9 +1518,11 @@ describe("fulfillment module service", function () {
}, },
] ]
const createdServiceZones = await service.createServiceZones(createData) const createdServiceZones = await service.createServiceZones(
createData
)
const updateData = { const updateData: UpdateServiceZoneDTO = {
id: createdServiceZones[1].id, id: createdServiceZones[1].id,
name: "service-zone-test", name: "service-zone-test",
geo_zones: [ geo_zones: [
@@ -1274,7 +1533,9 @@ describe("fulfillment module service", function () {
], ],
} }
const err = await service.updateServiceZones(updateData).catch((e) => e) const err = await service
.updateServiceZones(updateData)
.catch((e) => e)
expect(err).toBeDefined() expect(err).toBeDefined()
expect(err.constraint).toBe("IDX_service_zone_name_unique") expect(err.constraint).toBe("IDX_service_zone_name_unique")
@@ -1371,3 +1632,5 @@ describe("fulfillment module service", function () {
}) })
}) })
}) })
},
})
@@ -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"
@@ -1,3 +0,0 @@
import { JestUtils } from "medusa-test-utils"
JestUtils.afterAllHookDropDatabase()
@@ -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()
@@ -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: [],
}
}
@@ -1,2 +0,0 @@
export * from "./database"
export * from "./get-init-module-config"
+1 -2
View File
@@ -17,6 +17,5 @@ module.exports = {
testEnvironment: `node`, testEnvironment: `node`,
moduleFileExtensions: [`js`, `ts`], moduleFileExtensions: [`js`, `ts`],
modulePathIgnorePatterns: ["dist/"], modulePathIgnorePatterns: ["dist/"],
setupFiles: ["<rootDir>/integration-tests/setup-env.js"], /*setupFilesAfterEnv: ["<rootDir>/integration-tests/setup.js"],*/
setupFilesAfterEnv: ["<rootDir>/integration-tests/setup.js"],
} }
+1 -1
View File
@@ -29,7 +29,7 @@
"prepublishOnly": "cross-env NODE_ENV=production tsc --build && tsc-alias -p tsconfig.json", "prepublishOnly": "cross-env NODE_ENV=production tsc --build && tsc-alias -p tsconfig.json",
"build": "rimraf dist && 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": "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: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: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", "migration:create": " MIKRO_ORM_CLI=./mikro-orm.config.dev.ts mikro-orm migration:create",
@@ -493,20 +493,7 @@
} }
], ],
"checks": [], "checks": [],
"foreignKeys": { "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"
}
}
}, },
{ {
"columns": { "columns": {
@@ -686,20 +673,7 @@
} }
], ],
"checks": [], "checks": [],
"foreignKeys": { "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"
}
}
}, },
{ {
"columns": { "columns": {
@@ -828,6 +802,24 @@
"nullable": false, "nullable": false,
"mappedType": "text" "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": { "metadata": {
"name": "metadata", "name": "metadata",
"type": "jsonb", "type": "jsonb",
@@ -873,6 +865,16 @@
"name": "shipping_profile", "name": "shipping_profile",
"schema": "public", "schema": "public",
"indexes": [ "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", "keyName": "IDX_shipping_profile_deleted_at",
"columnNames": [ "columnNames": [
@@ -945,7 +947,7 @@
"unsigned": false, "unsigned": false,
"autoincrement": false, "autoincrement": false,
"primary": false, "primary": false,
"nullable": false, "nullable": true,
"mappedType": "text" "mappedType": "text"
}, },
"service_provider_id": { "service_provider_id": {
@@ -954,15 +956,6 @@
"unsigned": false, "unsigned": false,
"autoincrement": false, "autoincrement": false,
"primary": 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, "nullable": true,
"mappedType": "text" "mappedType": "text"
}, },
@@ -984,6 +977,15 @@
"nullable": true, "nullable": true,
"mappedType": "json" "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": { "created_at": {
"name": "created_at", "name": "created_at",
"type": "timestamptz", "type": "timestamptz",
@@ -1091,18 +1093,6 @@
], ],
"checks": [], "checks": [],
"foreignKeys": { "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": { "shipping_option_shipping_profile_id_foreign": {
"constraintName": "shipping_option_shipping_profile_id_foreign", "constraintName": "shipping_option_shipping_profile_id_foreign",
"columnNames": [ "columnNames": [
@@ -1113,6 +1103,7 @@
"id" "id"
], ],
"referencedTableName": "public.shipping_profile", "referencedTableName": "public.shipping_profile",
"deleteRule": "set null",
"updateRule": "cascade" "updateRule": "cascade"
}, },
"shipping_option_service_provider_id_foreign": { "shipping_option_service_provider_id_foreign": {
@@ -1125,6 +1116,7 @@
"id" "id"
], ],
"referencedTableName": "public.service_provider", "referencedTableName": "public.service_provider",
"deleteRule": "set null",
"updateRule": "cascade" "updateRule": "cascade"
}, },
"shipping_option_shipping_option_type_id_foreign": { "shipping_option_shipping_option_type_id_foreign": {
@@ -1137,6 +1129,7 @@
"id" "id"
], ],
"referencedTableName": "public.shipping_option_type", "referencedTableName": "public.shipping_option_type",
"deleteRule": "cascade",
"updateRule": "cascade" "updateRule": "cascade"
} }
} }
@@ -1224,6 +1217,16 @@
"name": "shipping_option_rule", "name": "shipping_option_rule",
"schema": "public", "schema": "public",
"indexes": [ "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", "keyName": "IDX_shipping_option_rule_deleted_at",
"columnNames": [ "columnNames": [
@@ -1245,20 +1248,7 @@
} }
], ],
"checks": [], "checks": [],
"foreignKeys": { "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"
}
}
}, },
{ {
"columns": { "columns": {
@@ -1760,7 +1750,7 @@
"composite": false, "composite": false,
"primary": false, "primary": false,
"unique": 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", "keyName": "IDX_fulfillment_item_inventory_item_id",
@@ -1770,7 +1760,7 @@
"composite": false, "composite": false,
"primary": false, "primary": false,
"unique": 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", "keyName": "IDX_fulfillment_item_fulfillment_id",
@@ -1,6 +1,6 @@
import { Migration } from '@mikro-orm/migrations'; import { Migration } from '@mikro-orm/migrations';
export class Migration20240214103108 extends Migration { export class Migration20240219115644 extends Migration {
async up(): Promise<void> { async up(): Promise<void> {
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"));'); 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_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 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 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('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_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;'); 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 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 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 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"));'); 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 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 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_line_item_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_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_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('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 "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 "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_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 "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 "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_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;'); this.addSql('alter table if exists "fulfillment" add constraint "fulfillment_provider_id_foreign" foreign key ("provider_id") references "service_provider" ("id") on update cascade;');
+6 -17
View File
@@ -6,7 +6,6 @@ import {
import { import {
BeforeCreate, BeforeCreate,
Entity, Entity,
Index,
OnInit, OnInit,
OptionalProps, OptionalProps,
PrimaryKey, PrimaryKey,
@@ -15,21 +14,17 @@ import {
type OptionalAddressProps = DAL.SoftDeletableEntityDateColumns type OptionalAddressProps = DAL.SoftDeletableEntityDateColumns
const fulfillmentIdIndexName = "IDX_fulfillment_address_fulfillment_id" const FulfillmentIdIndex = createPsqlIndexStatementHelper({
const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentIdIndexName,
tableName: "fulfillment_address", tableName: "fulfillment_address",
columns: "fulfillment_id", columns: "fulfillment_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const fulfillmentDeletedAtIndexName = "IDX_fulfillment_address_deleted_at" const FulfillmentDeletedAtIndex = createPsqlIndexStatementHelper({
const fulfillmentDeletedAtIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentDeletedAtIndexName,
tableName: "fulfillment_address", tableName: "fulfillment_address",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
@Entity({ tableName: "fulfillment_address" }) @Entity({ tableName: "fulfillment_address" })
export default class Address { export default class Address {
@@ -39,10 +34,7 @@ export default class Address {
id!: string id!: string
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
@Index({ @FulfillmentIdIndex.MikroORMIndex()
name: fulfillmentIdIndexName,
expression: fulfillmentIdIndexStatement,
})
fulfillment_id: string | null = null fulfillment_id: string | null = null
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
@@ -94,10 +86,7 @@ export default class Address {
updated_at: Date updated_at: Date
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
@Index({ @FulfillmentDeletedAtIndex.MikroORMIndex()
name: fulfillmentDeletedAtIndexName,
expression: fulfillmentDeletedAtIndexStatement,
})
deleted_at: Date | null = null deleted_at: Date | null = null
@BeforeCreate() @BeforeCreate()
@@ -9,7 +9,6 @@ import {
BeforeCreate, BeforeCreate,
Entity, Entity,
Filter, Filter,
Index,
ManyToOne, ManyToOne,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -20,37 +19,29 @@ import Fulfillment from "./fulfillment"
type FulfillmentItemOptionalProps = DAL.SoftDeletableEntityDateColumns type FulfillmentItemOptionalProps = DAL.SoftDeletableEntityDateColumns
const fulfillmentIdIndexName = "IDX_fulfillment_item_fulfillment_id" const FulfillmentIdIndex = createPsqlIndexStatementHelper({
const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentIdIndexName,
tableName: "fulfillment_item", tableName: "fulfillment_item",
columns: "fulfillment_id", columns: "fulfillment_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const lineItemIndexName = "IDX_fulfillment_item_line_item_id" const LineItemIdIndex = createPsqlIndexStatementHelper({
const lineItemIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentIdIndexName,
tableName: "fulfillment_item", tableName: "fulfillment_item",
columns: "line_item_id", columns: "line_item_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const inventoryItemIndexName = "IDX_fulfillment_item_inventory_item_id" const InventoryItemIdIndex = createPsqlIndexStatementHelper({
const inventoryItemIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentIdIndexName,
tableName: "fulfillment_item", tableName: "fulfillment_item",
columns: "inventory_item_id", columns: "inventory_item_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const fulfillmentItemDeletedAtIndexName = "IDX_fulfillment_item_deleted_at" const FulfillmentItemDeletedAtIndex = createPsqlIndexStatementHelper({
const fulfillmentItemDeletedAtIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentItemDeletedAtIndexName,
tableName: "fulfillment_item", tableName: "fulfillment_item",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -73,24 +64,15 @@ export default class FulfillmentItem {
quantity: number // TODO: probably allow big numbers here quantity: number // TODO: probably allow big numbers here
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
@Index({ @LineItemIdIndex.MikroORMIndex()
name: lineItemIndexName,
expression: lineItemIdIndexStatement,
})
line_item_id: string | null = null line_item_id: string | null = null
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
@Index({ @InventoryItemIdIndex.MikroORMIndex()
name: inventoryItemIndexName,
expression: inventoryItemIdIndexStatement,
})
inventory_item_id: string | null = null inventory_item_id: string | null = null
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @FulfillmentIdIndex.MikroORMIndex()
name: fulfillmentIdIndexName,
expression: fulfillmentIdIndexStatement,
})
fulfillment_id: string fulfillment_id: string
@ManyToOne(() => Fulfillment) @ManyToOne(() => Fulfillment)
@@ -111,10 +93,7 @@ export default class FulfillmentItem {
}) })
updated_at: Date updated_at: Date
@Index({ @FulfillmentItemDeletedAtIndex.MikroORMIndex()
name: fulfillmentItemDeletedAtIndexName,
expression: fulfillmentItemDeletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@@ -9,7 +9,6 @@ import {
BeforeCreate, BeforeCreate,
Entity, Entity,
Filter, Filter,
Index,
ManyToOne, ManyToOne,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -20,21 +19,17 @@ import Fulfillment from "./fulfillment"
type FulfillmentLabelOptionalProps = DAL.SoftDeletableEntityDateColumns type FulfillmentLabelOptionalProps = DAL.SoftDeletableEntityDateColumns
const fulfillmentIdIndexName = "IDX_fulfillment_label_fulfillment_id" const FulfillmentIdIndex = createPsqlIndexStatementHelper({
const fulfillmentIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentIdIndexName,
tableName: "fulfillment_label", tableName: "fulfillment_label",
columns: "fulfillment_id", columns: "fulfillment_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const deletedAtIndexName = "IDX_fulfillment_label_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "fulfillment_label", tableName: "fulfillment_label",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -54,10 +49,7 @@ export default class FulfillmentLabel {
label_url: string label_url: string
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @FulfillmentIdIndex.MikroORMIndex()
name: fulfillmentIdIndexName,
expression: fulfillmentIdIndexStatement,
})
fulfillment_id: string fulfillment_id: string
@ManyToOne(() => Fulfillment) @ManyToOne(() => Fulfillment)
@@ -79,10 +71,7 @@ export default class FulfillmentLabel {
updated_at: Date updated_at: Date
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
deleted_at: Date | null = null deleted_at: Date | null = null
@BeforeCreate() @BeforeCreate()
+12 -35
View File
@@ -10,7 +10,6 @@ import {
Collection, Collection,
Entity, Entity,
Filter, Filter,
Index,
ManyToOne, ManyToOne,
OneToMany, OneToMany,
OnInit, OnInit,
@@ -26,39 +25,29 @@ import ShippingOption from "./shipping-option"
type FulfillmentOptionalProps = DAL.SoftDeletableEntityDateColumns type FulfillmentOptionalProps = DAL.SoftDeletableEntityDateColumns
const fulfillmentDeletedAtIndexName = "IDX_fulfillment_deleted_at" const FulfillmentDeletedAtIndex = createPsqlIndexStatementHelper({
const fulfillmentDeletedAtIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentDeletedAtIndexName,
tableName: "fulfillment", tableName: "fulfillment",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const fulfillmentProviderIdIndexName = "IDX_fulfillment_provider_id" const FulfillmentProviderIdIndex = createPsqlIndexStatementHelper({
const fulfillmentProviderIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentProviderIdIndexName,
tableName: "fulfillment", tableName: "fulfillment",
columns: "provider_id", columns: "provider_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const fulfillmentLocationIdIndexName = "IDX_fulfillment_location_id" const FulfillmentLocationIdIndex = createPsqlIndexStatementHelper({
const fulfillmentLocationIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentLocationIdIndexName,
tableName: "fulfillment", tableName: "fulfillment",
columns: "location_id", columns: "location_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const fulfillmentShippingOptionIdIndexName = const FulfillmentShippingOptionIdIndex = createPsqlIndexStatementHelper({
"IDX_fulfillment_shipping_option_id"
const fulfillmentShippingOptionIdIndexStatement =
createPsqlIndexStatementHelper({
name: fulfillmentShippingOptionIdIndexName,
tableName: "fulfillment", tableName: "fulfillment",
columns: "shipping_option_id", columns: "shipping_option_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -69,10 +58,7 @@ export default class Fulfillment {
id: string id: string
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @FulfillmentLocationIdIndex.MikroORMIndex()
name: fulfillmentLocationIdIndexName,
expression: fulfillmentLocationIdIndexStatement,
})
location_id: string location_id: string
@Property({ @Property({
@@ -103,17 +89,11 @@ export default class Fulfillment {
data: Record<string, unknown> | null = null data: Record<string, unknown> | null = null
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @FulfillmentProviderIdIndex.MikroORMIndex()
name: fulfillmentProviderIdIndexName,
expression: fulfillmentProviderIdIndexStatement,
})
provider_id: string provider_id: string
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
@Index({ @FulfillmentShippingOptionIdIndex.MikroORMIndex()
name: fulfillmentShippingOptionIdIndexName,
expression: fulfillmentShippingOptionIdIndexStatement,
})
shipping_option_id: string | null = null shipping_option_id: string | null = null
@Property({ columnType: "jsonb", nullable: true }) @Property({ columnType: "jsonb", nullable: true })
@@ -149,10 +129,7 @@ export default class Fulfillment {
}) })
updated_at: Date updated_at: Date
@Index({ @FulfillmentDeletedAtIndex.MikroORMIndex()
name: fulfillmentDeletedAtIndexName,
expression: fulfillmentDeletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@@ -11,7 +11,6 @@ import {
Collection, Collection,
Entity, Entity,
Filter, Filter,
Index,
OneToMany, OneToMany,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -22,22 +21,18 @@ import ServiceZone from "./service-zone"
type FulfillmentSetOptionalProps = DAL.SoftDeletableEntityDateColumns type FulfillmentSetOptionalProps = DAL.SoftDeletableEntityDateColumns
const deletedAtIndexName = "IDX_fulfillment_set_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "fulfillment_set", tableName: "fulfillment_set",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const nameIndexName = "IDX_fulfillment_set_name_unique" const NameIndex = createPsqlIndexStatementHelper({
const nameIndexStatement = createPsqlIndexStatementHelper({
name: nameIndexName,
tableName: "fulfillment_set", tableName: "fulfillment_set",
columns: "name", columns: "name",
unique: true, unique: true,
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -48,10 +43,7 @@ export default class FulfillmentSet {
id: string id: string
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @NameIndex.MikroORMIndex()
name: nameIndexName,
expression: nameIndexStatement,
})
name: string name: string
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@@ -82,10 +74,7 @@ export default class FulfillmentSet {
updated_at: Date updated_at: Date
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
deleted_at: Date | null = null deleted_at: Date | null = null
@BeforeCreate() @BeforeCreate()
+15 -41
View File
@@ -11,7 +11,6 @@ import {
Entity, Entity,
Enum, Enum,
Filter, Filter,
Index,
ManyToOne, ManyToOne,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -22,45 +21,35 @@ import ServiceZone from "./service-zone"
type GeoZoneOptionalProps = DAL.SoftDeletableEntityDateColumns type GeoZoneOptionalProps = DAL.SoftDeletableEntityDateColumns
const deletedAtIndexName = "IDX_geo_zone_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "geo_zone", tableName: "geo_zone",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const countryCodeIndexName = "IDX_geo_zone_country_code" const CountryCodeIndex = createPsqlIndexStatementHelper({
const countryCodeIndexStatement = createPsqlIndexStatementHelper({
name: countryCodeIndexName,
tableName: "geo_zone", tableName: "geo_zone",
columns: "country_code", columns: "country_code",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const provinceCodeIndexName = "IDX_geo_zone_province_code" const ProvinceCodeIndex = createPsqlIndexStatementHelper({
const provinceCodeIndexStatement = createPsqlIndexStatementHelper({
name: provinceCodeIndexName,
tableName: "geo_zone", tableName: "geo_zone",
columns: "province_code", columns: "province_code",
where: "deleted_at IS NULL AND province_code IS NOT NULL", where: "deleted_at IS NULL AND province_code IS NOT NULL",
}).expression })
const cityIndexName = "IDX_geo_zone_city" const CityIndex = createPsqlIndexStatementHelper({
const cityIndexStatement = createPsqlIndexStatementHelper({
name: cityIndexName,
tableName: "geo_zone", tableName: "geo_zone",
columns: "city", columns: "city",
where: "deleted_at IS NULL AND city IS NOT NULL", where: "deleted_at IS NULL AND city IS NOT NULL",
}).expression })
const serviceZoneIdIndexName = "IDX_geo_zone_service_zone_id" const ServiceZoneIdIndex = createPsqlIndexStatementHelper({
const serviceZoneIdStatement = createPsqlIndexStatementHelper({
name: serviceZoneIdIndexName,
tableName: "geo_zone", tableName: "geo_zone",
columns: "service_zone_id", columns: "service_zone_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -73,32 +62,20 @@ export default class GeoZone {
@Enum({ items: () => GeoZoneType, default: GeoZoneType.COUNTRY }) @Enum({ items: () => GeoZoneType, default: GeoZoneType.COUNTRY })
type: GeoZoneType type: GeoZoneType
@Index({ @CountryCodeIndex.MikroORMIndex()
name: countryCodeIndexName,
expression: countryCodeIndexStatement,
})
@Property({ columnType: "text" }) @Property({ columnType: "text" })
country_code: string country_code: string
@Index({ @ProvinceCodeIndex.MikroORMIndex()
name: provinceCodeIndexName,
expression: provinceCodeIndexStatement,
})
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
province_code: string | null = null province_code: string | null = null
@Index({ @CityIndex.MikroORMIndex()
name: cityIndexName,
expression: cityIndexStatement,
})
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", nullable: true })
city: string | null = null city: string | null = null
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @ServiceZoneIdIndex.MikroORMIndex()
name: serviceZoneIdIndexName,
expression: serviceZoneIdStatement,
})
service_zone_id: string 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? // 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 updated_at: Date
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@@ -10,7 +10,6 @@ import {
Collection, Collection,
Entity, Entity,
Filter, Filter,
Index,
OneToMany, OneToMany,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -21,13 +20,11 @@ import ShippingOption from "./shipping-option"
type ServiceProviderOptionalProps = DAL.SoftDeletableEntityDateColumns type ServiceProviderOptionalProps = DAL.SoftDeletableEntityDateColumns
const deletedAtIndexName = "IDX_service_provider_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "service_provider", tableName: "service_provider",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -61,10 +58,7 @@ export default class ServiceProvider {
}) })
updated_at: Date updated_at: Date
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@@ -33,22 +33,18 @@ const deletedAtIndexStatement = createPsqlIndexStatementHelper({
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression }).expression
const nameIndexName = "IDX_service_zone_name_unique" const NameIndex = createPsqlIndexStatementHelper({
const nameIndexStatement = createPsqlIndexStatementHelper({
name: nameIndexName,
tableName: "service_zone", tableName: "service_zone",
columns: "name", columns: "name",
unique: true, unique: true,
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const fulfillmentSetIdIndexName = "IDX_service_zone_fulfillment_set_id" const FulfillmentSetIdIndex = createPsqlIndexStatementHelper({
const fulfillmentSetIdIndexStatement = createPsqlIndexStatementHelper({
name: fulfillmentSetIdIndexName,
tableName: "service_zone", tableName: "service_zone",
columns: "fulfillment_set_id", columns: "fulfillment_set_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -59,20 +55,14 @@ export default class ServiceZone {
id: string id: string
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @NameIndex.MikroORMIndex()
name: nameIndexName,
expression: nameIndexStatement,
})
name: string name: string
@Property({ columnType: "jsonb", nullable: true }) @Property({ columnType: "jsonb", nullable: true })
metadata: Record<string, unknown> | null = null metadata: Record<string, unknown> | null = null
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @FulfillmentSetIdIndex.MikroORMIndex()
name: fulfillmentSetIdIndexName,
expression: fulfillmentSetIdIndexStatement,
})
fulfillment_set_id: string fulfillment_set_id: string
@ManyToOne(() => FulfillmentSet, { persist: false }) @ManyToOne(() => FulfillmentSet, { persist: false })
@@ -9,7 +9,6 @@ import {
BeforeCreate, BeforeCreate,
Entity, Entity,
Filter, Filter,
Index,
ManyToOne, ManyToOne,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -20,16 +19,17 @@ import ShippingOption from "./shipping-option"
type ShippingOptionRuleOptionalProps = DAL.SoftDeletableEntityDateColumns type ShippingOptionRuleOptionalProps = DAL.SoftDeletableEntityDateColumns
// TODO: need some test to see if we continue with this kind of structure or we change it const DeletedAtIndex = createPsqlIndexStatementHelper({
// More adjustments can appear as I move forward
const deletedAtIndexName = "IDX_shipping_option_rule_deleted_at"
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "shipping_option_rule", tableName: "shipping_option_rule",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const ShippingOptionIdIndex = createPsqlIndexStatementHelper({
tableName: "shipping_option_rule",
columns: "shipping_option_id",
where: "deleted_at IS NULL",
})
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -49,9 +49,10 @@ export default class ShippingOptionRule {
value: { value: string | string[] } | null = null value: { value: string | string[] } | null = null
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@ShippingOptionIdIndex.MikroORMIndex()
shipping_option_id: string shipping_option_id: string
@ManyToOne(() => ShippingOption) @ManyToOne(() => ShippingOption, { persist: false })
shipping_option: ShippingOption shipping_option: ShippingOption
@Property({ @Property({
@@ -69,20 +70,19 @@ export default class ShippingOptionRule {
}) })
updated_at: Date updated_at: Date
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@BeforeCreate() @BeforeCreate()
onCreate() { onCreate() {
this.id = generateEntityId(this.id, "sorul") this.id = generateEntityId(this.id, "sorul")
this.shipping_option_id ??= this.shipping_option?.id
} }
@OnInit() @OnInit()
onInit() { onInit() {
this.id = generateEntityId(this.id, "sorul") this.id = generateEntityId(this.id, "sorul")
this.shipping_option_id ??= this.shipping_option?.id
} }
} }
@@ -9,7 +9,6 @@ import {
BeforeCreate, BeforeCreate,
Entity, Entity,
Filter, Filter,
Index,
OneToOne, OneToOne,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -20,21 +19,17 @@ import ShippingOption from "./shipping-option"
type ShippingOptionTypeOptionalProps = DAL.SoftDeletableEntityDateColumns type ShippingOptionTypeOptionalProps = DAL.SoftDeletableEntityDateColumns
const deletedAtIndexName = "IDX_shipping_option_type_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "shipping_option_type", tableName: "shipping_option_type",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const shippingOptionIdIndexName = "IDX_shipping_option_type_shipping_option_id" const ShippingOptionIdIndex = createPsqlIndexStatementHelper({
const shippingOptionIdIndexStatement = createPsqlIndexStatementHelper({
name: shippingOptionIdIndexName,
tableName: "shipping_option_type", tableName: "shipping_option_type",
columns: "shipping_option_id", columns: "shipping_option_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -54,13 +49,12 @@ export default class ShippingOptionType {
code: string code: string
@Property({ columnType: "text" }) @Property({ columnType: "text" })
@Index({ @ShippingOptionIdIndex.MikroORMIndex()
name: shippingOptionIdIndexName,
expression: shippingOptionIdIndexStatement,
})
shipping_option_id: string shipping_option_id: string
@OneToOne(() => ShippingOption, (so) => so.shipping_option_type) @OneToOne(() => ShippingOption, (so) => so.type, {
persist: false,
})
shipping_option: ShippingOption shipping_option: ShippingOption
@Property({ @Property({
@@ -78,20 +72,19 @@ export default class ShippingOptionType {
}) })
updated_at: Date updated_at: Date
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@BeforeCreate() @BeforeCreate()
onCreate() { onCreate() {
this.id = generateEntityId(this.id, "sotype") this.id = generateEntityId(this.id, "sotype")
this.shipping_option_id ??= this.shipping_option?.id
} }
@OnInit() @OnInit()
onInit() { onInit() {
this.id = generateEntityId(this.id, "sotype") this.id = generateEntityId(this.id, "sotype")
this.shipping_option_id ??= this.shipping_option?.id
} }
} }
@@ -8,11 +8,11 @@ import {
import { DAL } from "@medusajs/types" import { DAL } from "@medusajs/types"
import { import {
BeforeCreate, BeforeCreate,
Cascade,
Collection, Collection,
Entity, Entity,
Enum, Enum,
Filter, Filter,
Index,
ManyToOne, ManyToOne,
OneToMany, OneToMany,
OneToOne, OneToOne,
@@ -30,46 +30,35 @@ import ShippingProfile from "./shipping-profile"
type ShippingOptionOptionalProps = DAL.SoftDeletableEntityDateColumns type ShippingOptionOptionalProps = DAL.SoftDeletableEntityDateColumns
const deletedAtIndexName = "IDX_shipping_option_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "shipping_option", tableName: "shipping_option",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const serviceZoneIdIndexName = "IDX_shipping_option_service_zone_id" const ServiceZoneIdIndex = createPsqlIndexStatementHelper({
const serviceZoneIdIndexStatement = createPsqlIndexStatementHelper({
name: serviceZoneIdIndexName,
tableName: "shipping_option", tableName: "shipping_option",
columns: "service_zone_id", columns: "service_zone_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const shippingProfileIdIndexName = "IDX_shipping_option_shipping_profile_id" const ShippingProfileIdIndex = createPsqlIndexStatementHelper({
const shippingProfileIdIndexStatement = createPsqlIndexStatementHelper({
name: shippingProfileIdIndexName,
tableName: "shipping_option", tableName: "shipping_option",
columns: "shipping_profile_id", columns: "shipping_profile_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const serviceProviderIdIndexName = "IDX_shipping_option_service_provider_id" const ServiceProviderIdIndex = createPsqlIndexStatementHelper({
const serviceProviderIdIndexStatement = createPsqlIndexStatementHelper({
name: serviceProviderIdIndexName,
tableName: "shipping_option", tableName: "shipping_option",
columns: "service_provider_id", columns: "service_provider_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
const shippingOptionTypeIdIndexName = const ShippingOptionTypeIdIndex = createPsqlIndexStatementHelper({
"IDX_shipping_option_shipping_option_type_id"
const shippingOptionTypeIdIndexStatement = createPsqlIndexStatementHelper({
name: shippingOptionTypeIdIndexName,
tableName: "shipping_option", tableName: "shipping_option",
columns: "shipping_option_type_id", columns: "shipping_option_type_id",
where: "deleted_at IS NULL", where: "deleted_at IS NULL",
}).expression })
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -88,32 +77,34 @@ export default class ShippingOption {
}) })
price_type: ShippingOptionPriceType price_type: ShippingOptionPriceType
@Property({ columnType: "text" }) @ManyToOne(() => ShippingProfile, {
@Index({ type: "text",
name: serviceZoneIdIndexName, fieldName: "service_zone_id",
expression: serviceZoneIdIndexStatement, mapToPk: true,
}) })
@ServiceZoneIdIndex.MikroORMIndex()
service_zone_id: string service_zone_id: string
@Property({ columnType: "text" }) @ManyToOne(() => ShippingProfile, {
@Index({ type: "text",
name: shippingProfileIdIndexName, fieldName: "shipping_profile_id",
expression: shippingProfileIdIndexStatement, mapToPk: true,
nullable: true,
}) })
shipping_profile_id: string @ShippingProfileIdIndex.MikroORMIndex()
shipping_profile_id: string | null
@Property({ columnType: "text" }) @ManyToOne(() => ServiceProvider, {
@Index({ type: "text",
name: serviceProviderIdIndexName, fieldName: "service_provider_id",
expression: serviceProviderIdIndexStatement, mapToPk: true,
nullable: true,
}) })
@ServiceProviderIdIndex.MikroORMIndex()
service_provider_id: string service_provider_id: string
@Property({ columnType: "text", nullable: true }) @Property({ columnType: "text", persist: false })
@Index({ @ShippingOptionTypeIdIndex.MikroORMIndex()
name: shippingOptionTypeIdIndexName,
expression: shippingOptionTypeIdIndexStatement,
})
shipping_option_type_id: string | null = null shipping_option_type_id: string | null = null
@Property({ columnType: "jsonb", nullable: true }) @Property({ columnType: "jsonb", nullable: true })
@@ -122,21 +113,30 @@ export default class ShippingOption {
@Property({ columnType: "jsonb", nullable: true }) @Property({ columnType: "jsonb", nullable: true })
metadata: Record<string, unknown> | null = null metadata: Record<string, unknown> | null = null
@ManyToOne(() => ServiceZone) @ManyToOne(() => ServiceZone, { persist: false })
service_zone: ServiceZone service_zone: ServiceZone
@ManyToOne(() => ShippingProfile) @ManyToOne(() => ShippingProfile, {
shipping_profile: ShippingProfile persist: false,
})
shipping_profile: ShippingProfile | null
@ManyToOne(() => ServiceProvider) @ManyToOne(() => ServiceProvider, {
service_provider: ServiceProvider persist: false,
})
service_provider: ServiceProvider | null
@OneToOne(() => ShippingOptionType, (so) => so.shipping_option, { @OneToOne(() => ShippingOptionType, (so) => so.shipping_option, {
owner: true, 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<ShippingOptionRule>(this) rules = new Collection<ShippingOptionRule>(this)
@OneToMany(() => Fulfillment, (fulfillment) => fulfillment.shipping_option) @OneToMany(() => Fulfillment, (fulfillment) => fulfillment.shipping_option)
@@ -157,20 +157,19 @@ export default class ShippingOption {
}) })
updated_at: Date updated_at: Date
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@BeforeCreate() @BeforeCreate()
onCreate() { onCreate() {
this.id = generateEntityId(this.id, "so") this.id = generateEntityId(this.id, "so")
this.shipping_option_type_id ??= this.type?.id
} }
@OnInit() @OnInit()
onInit() { onInit() {
this.id = generateEntityId(this.id, "so") this.id = generateEntityId(this.id, "so")
this.shipping_option_type_id ??= this.type?.id
} }
} }
@@ -10,7 +10,6 @@ import {
Collection, Collection,
Entity, Entity,
Filter, Filter,
Index,
OneToMany, OneToMany,
OnInit, OnInit,
OptionalProps, OptionalProps,
@@ -21,13 +20,18 @@ import ShippingOption from "./shipping-option"
type ShippingProfileOptionalProps = DAL.SoftDeletableEntityDateColumns type ShippingProfileOptionalProps = DAL.SoftDeletableEntityDateColumns
const deletedAtIndexName = "IDX_shipping_profile_deleted_at" const DeletedAtIndex = createPsqlIndexStatementHelper({
const deletedAtIndexStatement = createPsqlIndexStatementHelper({
name: deletedAtIndexName,
tableName: "shipping_profile", tableName: "shipping_profile",
columns: "deleted_at", columns: "deleted_at",
where: "deleted_at IS NOT NULL", where: "deleted_at IS NOT NULL",
}).expression })
const ShippingProfileTypeIndex = createPsqlIndexStatementHelper({
tableName: "shipping_profile",
columns: "name",
unique: true,
where: "deleted_at IS NULL",
})
@Entity() @Entity()
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions) @Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
@@ -37,6 +41,13 @@ export default class ShippingProfile {
@PrimaryKey({ columnType: "text" }) @PrimaryKey({ columnType: "text" })
id: string id: string
@Property({ columnType: "text" })
@ShippingProfileTypeIndex.MikroORMIndex()
name: string
@Property({ columnType: "text" })
type: string
@OneToMany( @OneToMany(
() => ShippingOption, () => ShippingOption,
(shippingOption) => shippingOption.shipping_profile (shippingOption) => shippingOption.shipping_profile
@@ -61,10 +72,7 @@ export default class ShippingProfile {
}) })
updated_at: Date updated_at: Date
@Index({ @DeletedAtIndex.MikroORMIndex()
name: deletedAtIndexName,
expression: deletedAtIndexStatement,
})
@Property({ columnType: "timestamptz", nullable: true }) @Property({ columnType: "timestamptz", nullable: true })
deleted_at: Date | null = null deleted_at: Date | null = null
@@ -34,7 +34,7 @@ const connectionLoader = ModulesSdkUtils.mikroOrmConnectionLoaderFactory({
}) })
const service = FulfillmentModuleService const service = FulfillmentModuleService
const loaders = [containerLoader, connectionLoader] as any const loaders = [containerLoader, connectionLoader]
export const moduleDefinition: ModuleExports = { export const moduleDefinition: ModuleExports = {
service, service,
@@ -9,31 +9,46 @@ import {
UpdateFulfillmentSetDTO, UpdateFulfillmentSetDTO,
} from "@medusajs/types" } from "@medusajs/types"
import { import {
getSetDifference,
InjectManager, InjectManager,
InjectTransactionManager, InjectTransactionManager,
MedusaContext, MedusaContext,
MedusaError, MedusaError,
ModulesSdkUtils, ModulesSdkUtils,
promiseAll, promiseAll,
getSetDifference
} from "@medusajs/utils" } from "@medusajs/utils"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config" 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 = { type InjectedDependencies = {
baseRepository: DAL.RepositoryService baseRepository: DAL.RepositoryService
fulfillmentSetService: ModulesSdkTypes.InternalModuleService<any> fulfillmentSetService: ModulesSdkTypes.InternalModuleService<any>
serviceZoneService: ModulesSdkTypes.InternalModuleService<any> serviceZoneService: ModulesSdkTypes.InternalModuleService<any>
geoZoneService: ModulesSdkTypes.InternalModuleService<any> geoZoneService: ModulesSdkTypes.InternalModuleService<any>
shippingProfileService: ModulesSdkTypes.InternalModuleService<any>
shippingOptionService: ModulesSdkTypes.InternalModuleService<any>
} }
export default class FulfillmentModuleService< export default class FulfillmentModuleService<
TEntity extends FulfillmentSet = FulfillmentSet, TEntity extends FulfillmentSet = FulfillmentSet,
TServiceZoneEntity extends ServiceZone = ServiceZone, TServiceZoneEntity extends ServiceZone = ServiceZone,
TGeoZoneEntity extends GeoZone = GeoZone TGeoZoneEntity extends GeoZone = GeoZone,
TShippingProfileEntity extends ShippingProfile = ShippingProfile,
TShippingOptionEntity extends ShippingOption = ShippingOption
> >
extends ModulesSdkUtils.abstractModuleServiceFactory< extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies, InjectedDependencies,
@@ -43,6 +58,7 @@ export default class FulfillmentModuleService<
ServiceZone: { dto: FulfillmentTypes.ServiceZoneDTO } ServiceZone: { dto: FulfillmentTypes.ServiceZoneDTO }
ShippingOption: { dto: FulfillmentTypes.ShippingOptionDTO } ShippingOption: { dto: FulfillmentTypes.ShippingOptionDTO }
GeoZone: { dto: FulfillmentTypes.GeoZoneDTO } GeoZone: { dto: FulfillmentTypes.GeoZoneDTO }
ShippingProfile: { dto: FulfillmentTypes.ShippingProfileDTO }
} }
>(FulfillmentSet, generateMethodForModels, entityNameToLinkableKeysMap) >(FulfillmentSet, generateMethodForModels, entityNameToLinkableKeysMap)
implements IFulfillmentModuleService implements IFulfillmentModuleService
@@ -51,6 +67,8 @@ export default class FulfillmentModuleService<
protected readonly fulfillmentSetService_: ModulesSdkTypes.InternalModuleService<TEntity> protected readonly fulfillmentSetService_: ModulesSdkTypes.InternalModuleService<TEntity>
protected readonly serviceZoneService_: ModulesSdkTypes.InternalModuleService<TServiceZoneEntity> protected readonly serviceZoneService_: ModulesSdkTypes.InternalModuleService<TServiceZoneEntity>
protected readonly geoZoneService_: ModulesSdkTypes.InternalModuleService<TGeoZoneEntity> protected readonly geoZoneService_: ModulesSdkTypes.InternalModuleService<TGeoZoneEntity>
protected readonly shippingProfileService_: ModulesSdkTypes.InternalModuleService<TShippingProfileEntity>
protected readonly shippingOptionService_: ModulesSdkTypes.InternalModuleService<TShippingOptionEntity>
constructor( constructor(
{ {
@@ -58,6 +76,8 @@ export default class FulfillmentModuleService<
fulfillmentSetService, fulfillmentSetService,
serviceZoneService, serviceZoneService,
geoZoneService, geoZoneService,
shippingProfileService,
shippingOptionService,
}: InjectedDependencies, }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration protected readonly moduleDeclaration: InternalModuleDeclaration
) { ) {
@@ -67,6 +87,8 @@ export default class FulfillmentModuleService<
this.fulfillmentSetService_ = fulfillmentSetService this.fulfillmentSetService_ = fulfillmentSetService
this.serviceZoneService_ = serviceZoneService this.serviceZoneService_ = serviceZoneService
this.geoZoneService_ = geoZoneService this.geoZoneService_ = geoZoneService
this.shippingProfileService_ = shippingProfileService
this.shippingOptionService_ = shippingOptionService
} }
__joinerConfig(): ModuleJoinerConfig { __joinerConfig(): ModuleJoinerConfig {
@@ -179,7 +201,7 @@ export default class FulfillmentModuleService<
sharedContext?: Context sharedContext?: Context
): Promise<FulfillmentTypes.ShippingOptionDTO> ): Promise<FulfillmentTypes.ShippingOptionDTO>
@InjectTransactionManager("baseRepository_") @InjectManager("baseRepository_")
async createShippingOptions( async createShippingOptions(
data: data:
| FulfillmentTypes.CreateShippingOptionDTO[] | FulfillmentTypes.CreateShippingOptionDTO[]
@@ -188,9 +210,95 @@ export default class FulfillmentModuleService<
): Promise< ): Promise<
FulfillmentTypes.ShippingOptionDTO | FulfillmentTypes.ShippingOptionDTO[] FulfillmentTypes.ShippingOptionDTO | FulfillmentTypes.ShippingOptionDTO[]
> { > {
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<TShippingOptionEntity | TShippingOptionEntity[]> {
let data_ = Array.isArray(data) ? data : [data]
if (!data_.length) {
return [] return []
} }
const createdShippingOptions = await this.shippingOptionService_.create(
data_,
sharedContext
)
return Array.isArray(data)
? createdShippingOptions
: createdShippingOptions[0]
}
createShippingProfiles(
data: FulfillmentTypes.CreateShippingProfileDTO[],
sharedContext?: Context
): Promise<FulfillmentTypes.ShippingProfileDTO[]>
createShippingProfiles(
data: FulfillmentTypes.CreateShippingProfileDTO,
sharedContext?: Context
): Promise<FulfillmentTypes.ShippingProfileDTO>
@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<TShippingProfileEntity[] | TShippingProfileEntity> {
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( createGeoZones(
data: FulfillmentTypes.CreateGeoZoneDTO[], data: FulfillmentTypes.CreateGeoZoneDTO[],
sharedContext?: Context sharedContext?: Context
@@ -473,7 +581,6 @@ export default class FulfillmentModuleService<
serviceZones.map((s) => [s.id, s]) serviceZones.map((s) => [s.id, s])
) )
const serviceZoneIdsToDelete: string[] = []
const geoZoneIdsToDelete: string[] = [] const geoZoneIdsToDelete: string[] = []
data_.forEach((serviceZone) => { data_.forEach((serviceZone) => {
@@ -567,6 +674,27 @@ export default class FulfillmentModuleService<
return [] return []
} }
updateShippingProfiles(
data: FulfillmentTypes.UpdateShippingProfileDTO[],
sharedContext?: Context
): Promise<FulfillmentTypes.ShippingProfileDTO[]>
updateShippingProfiles(
data: FulfillmentTypes.UpdateShippingProfileDTO,
sharedContext?: Context
): Promise<FulfillmentTypes.ShippingProfileDTO>
@InjectTransactionManager("baseRepository_")
async updateShippingProfiles(
data:
| FulfillmentTypes.UpdateShippingProfileDTO
| FulfillmentTypes.UpdateShippingProfileDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<
FulfillmentTypes.ShippingProfileDTO | FulfillmentTypes.ShippingProfileDTO[]
> {
return []
}
updateGeoZones( updateGeoZones(
data: FulfillmentTypes.UpdateGeoZoneDTO[], data: FulfillmentTypes.UpdateGeoZoneDTO[],
sharedContext?: Context sharedContext?: Context
+40 -22
View File
@@ -1,24 +1,28 @@
import { MikroORM, Options, SqlEntityManager } from "@mikro-orm/postgresql" 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_HOST = process.env.DB_HOST ?? "localhost"
const DB_USERNAME = process.env.DB_USERNAME ?? "" const DB_USERNAME = process.env.DB_USERNAME ?? ""
const DB_PASSWORD = process.env.DB_PASSWORD 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}${ return `postgres://${DB_USERNAME}${
DB_PASSWORD ? `:${DB_PASSWORD}` : "" DB_PASSWORD ? `:${DB_PASSWORD}` : ""
}@${DB_HOST}/${DB_NAME}` }@${DB_HOST}/${DB_NAME}`
} }
export function getMikroOrmConfig( export function getMikroOrmConfig({
mikroOrmEntities: any[], mikroOrmEntities,
pathToMigrations: string, // deprecated, auto inferred pathToMigrations,
clientUrl,
schema,
}: {
mikroOrmEntities: any[]
pathToMigrations?: string
clientUrl?: string
schema?: string schema?: string
): Options { }): Options {
const DB_URL = getDatabaseURL() const DB_URL = clientUrl ?? getDatabaseURL()
return { return {
type: "postgresql", type: "postgresql",
@@ -26,14 +30,18 @@ export function getMikroOrmConfig(
entities: Object.values(mikroOrmEntities), entities: Object.values(mikroOrmEntities),
schema: schema ?? process.env.MEDUSA_DB_SCHEMA, schema: schema ?? process.env.MEDUSA_DB_SCHEMA,
debug: false, debug: false,
extensions: [Migrator], migrations: {
pathTs: pathToMigrations,
silent: true,
},
} }
} }
export interface TestDatabase { export interface TestDatabase {
mikroOrmEntities: any[] mikroOrmEntities: any[]
pathToMigrations: any // deprecated, auto inferred pathToMigrations?: string
schema?: string schema?: string
clientUrl?: string
orm: MikroORM | null orm: MikroORM | null
manager: SqlEntityManager | null manager: SqlEntityManager | null
@@ -45,14 +53,21 @@ export interface TestDatabase {
getOrm(): MikroORM getOrm(): MikroORM
} }
export function getMikroOrmWrapper( export function getMikroOrmWrapper({
mikroOrmEntities: any[], mikroOrmEntities,
pathToMigrations: string, // deprecated, auto inferred pathToMigrations,
clientUrl,
schema,
}: {
mikroOrmEntities: any[]
pathToMigrations?: string
clientUrl?: string
schema?: string schema?: string
): TestDatabase { }): TestDatabase {
return { return {
mikroOrmEntities, mikroOrmEntities,
pathToMigrations, // deprecated, auto inferred pathToMigrations,
clientUrl: clientUrl ?? getDatabaseURL(),
schema: schema ?? process.env.MEDUSA_DB_SCHEMA, schema: schema ?? process.env.MEDUSA_DB_SCHEMA,
orm: null, orm: null,
@@ -83,11 +98,12 @@ export function getMikroOrmWrapper(
}, },
async setupDatabase() { async setupDatabase() {
const OrmConfig = getMikroOrmConfig( const OrmConfig = getMikroOrmConfig({
this.mikroOrmEntities, mikroOrmEntities: this.mikroOrmEntities,
this.pathToMigrations, pathToMigrations: this.pathToMigrations,
this.schema clientUrl: this.clientUrl,
) schema: this.schema,
})
// Initializing the ORM // Initializing the ORM
this.orm = await MikroORM.init(OrmConfig) this.orm = await MikroORM.init(OrmConfig)
@@ -96,7 +112,9 @@ export function getMikroOrmWrapper(
try { try {
await this.orm.getSchemaGenerator().ensureDatabase() await this.orm.getSchemaGenerator().ensureDatabase()
} catch (err) {} } catch (err) {
console.log(err)
}
await this.manager?.execute( await this.manager?.execute(
`CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";` `CREATE SCHEMA IF NOT EXISTS "${this.schema ?? "public"}";`
+1
View File
@@ -4,3 +4,4 @@ export * as JestUtils from "./jest"
export { default as MockManager } from "./mock-manager" export { default as MockManager } from "./mock-manager"
export { default as MockRepository } from "./mock-repository" export { default as MockRepository } from "./mock-repository"
export * from "./init-modules" export * from "./init-modules"
export * from "./module-test-runner"
+17 -9
View File
@@ -1,13 +1,12 @@
import { knex } from "knex"
import { import {
MedusaApp, MedusaApp,
MedusaModule, MedusaModule,
MedusaModuleConfig, MedusaModuleConfig,
ModuleJoinerConfig, ModuleJoinerConfig,
} from "@medusajs/modules-sdk" } from "@medusajs/modules-sdk"
import { ContainerRegistrationKeys } from "@medusajs/utils" import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils"
interface InitModulesOptions { export interface InitModulesOptions {
injectedDependencies?: Record<string, unknown> injectedDependencies?: Record<string, unknown>
databaseConfig: { databaseConfig: {
clientUrl: string clientUrl: string
@@ -15,6 +14,7 @@ interface InitModulesOptions {
} }
modulesConfig: MedusaModuleConfig modulesConfig: MedusaModuleConfig
joinerConfig?: ModuleJoinerConfig[] joinerConfig?: ModuleJoinerConfig[]
preventConnectionDestroyWarning?: boolean
} }
export async function initModules({ export async function initModules({
@@ -22,19 +22,18 @@ export async function initModules({
databaseConfig, databaseConfig,
modulesConfig, modulesConfig,
joinerConfig, joinerConfig,
preventConnectionDestroyWarning = false,
}: InitModulesOptions) { }: InitModulesOptions) {
injectedDependencies ??= {} injectedDependencies ??= {}
let sharedPgConnection = let sharedPgConnection =
injectedDependencies?.[ContainerRegistrationKeys.PG_CONNECTION] injectedDependencies?.[ContainerRegistrationKeys.PG_CONNECTION]
let shouldDestroyConnectionAutomatically = !sharedPgConnection
if (!sharedPgConnection) { if (!sharedPgConnection) {
sharedPgConnection = knex<any, any>({ sharedPgConnection = ModulesSdkUtils.createPgConnection({
client: "pg", clientUrl: databaseConfig.clientUrl,
searchPath: databaseConfig.schema, schema: databaseConfig.schema,
connection: {
connectionString: databaseConfig.clientUrl,
},
}) })
injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION] = injectedDependencies[ContainerRegistrationKeys.PG_CONNECTION] =
@@ -48,7 +47,16 @@ export async function initModules({
}) })
async function shutdown() { async function shutdown() {
if (shouldDestroyConnectionAutomatically) {
await (sharedPgConnection as any).context?.destroy() 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() MedusaModule.clearInstances()
} }
@@ -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<TService = unknown> {
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: <TService = unknown>(options: SuiteOptions<TService>) => () => 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<void>
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)
})
}
@@ -4,10 +4,9 @@ import * as Models from "@models"
const mikroOrmEntities = Models as unknown as any[] const mikroOrmEntities = Models as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
null, schema: process.env.MEDUSA_ORDER_DB_SCHEMA,
process.env.MEDUSA_ORDER_DB_SCHEMA })
)
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -5,14 +5,14 @@ import * as PaymentModules from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = PaymentModules as unknown as any[] const mikroOrmEntities = PaymentModules as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -5,14 +5,14 @@ import * as PricingModels from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = PricingModels as unknown as any[] const mikroOrmEntities = PricingModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -1,7 +1,7 @@
import { MedusaModule, Modules } from "@medusajs/modules-sdk" import { MedusaModule, Modules } from "@medusajs/modules-sdk"
import { IProductModuleService } from "@medusajs/types" import { IProductModuleService } from "@medusajs/types"
import { kebabCase } from "@medusajs/utils" import { kebabCase } from "@medusajs/utils"
import { knex } from "knex" import { knex } from "@mikro-orm/knex"
import { initModules } from "medusa-test-utils" import { initModules } from "medusa-test-utils"
import * as CustomRepositories from "../__fixtures__/module" import * as CustomRepositories from "../__fixtures__/module"
import { import {
@@ -5,14 +5,14 @@ import * as PromotionModels from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = PromotionModels as unknown as any[] const mikroOrmEntities = PromotionModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -5,14 +5,14 @@ import * as RegionModels from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = RegionModels as unknown as any[] const mikroOrmEntities = RegionModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -5,14 +5,14 @@ import * as SalesChannelModels from "@models"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = SalesChannelModels as unknown as any[] const mikroOrmEntities = SalesChannelModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -4,10 +4,9 @@ import * as Models from "@models"
const mikroOrmEntities = Models as unknown as any[] const mikroOrmEntities = Models as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
null, schema: process.env.MEDUSA_ORDER_DB_SCHEMA,
process.env.MEDUSA_TAX_DB_SCHEMA })
)
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
+1 -1
View File
@@ -1,4 +1,4 @@
import { Dictionary, FilterQuery, Order } from "./utils" import { Dictionary, FilterQuery, OperatorMap, Order } from "./utils"
export { FilterQuery, OperatorMap } from "./utils" export { FilterQuery, OperatorMap } from "./utils"
@@ -1,7 +1,7 @@
import { FulfillmentSetDTO } from "./fulfillment-set" import { FulfillmentSetDTO } from "./fulfillment-set"
import { FilterableGeoZoneProps, GeoZoneDTO } from "./geo-zone" import { FilterableGeoZoneProps, GeoZoneDTO } from "./geo-zone"
import { ShippingOptionDTO } from "./shipping-option" import { ShippingOptionDTO } from "./shipping-option"
import { BaseFilterable } from "../../dal" import { BaseFilterable, OperatorMap } from "../../dal"
export interface ServiceZoneDTO { export interface ServiceZoneDTO {
id: string id: string
@@ -17,8 +17,8 @@ export interface ServiceZoneDTO {
export interface FilterableServiceZoneProps export interface FilterableServiceZoneProps
extends BaseFilterable<FilterableServiceZoneProps> { extends BaseFilterable<FilterableServiceZoneProps> {
id?: string | string[] id?: string | string[] | OperatorMap<string | string[]>
name?: string | string[] name?: string | string[] | OperatorMap<string | string[]>
geo_zones?: FilterableGeoZoneProps geo_zones?: FilterableGeoZoneProps
shipping_options?: any // TODO shipping_options?: any // TODO
} }
@@ -1,5 +1,5 @@
import { ShippingOptionDTO } from "./shipping-option" import { ShippingOptionDTO } from "./shipping-option"
import { BaseFilterable } from "../../dal" import { BaseFilterable, OperatorMap } from "../../dal"
export interface ShippingOptionRuleDTO { export interface ShippingOptionRuleDTO {
id: string id: string
@@ -15,8 +15,8 @@ export interface ShippingOptionRuleDTO {
export interface FilterableShippingOptionRuleProps export interface FilterableShippingOptionRuleProps
extends BaseFilterable<FilterableShippingOptionRuleProps> { extends BaseFilterable<FilterableShippingOptionRuleProps> {
id?: string | string[] id?: string | string[] | OperatorMap<string | string[]>
attribute?: string | string[] attribute?: string | string[] | OperatorMap<string | string[]>
operator?: string | string[] operator?: string | string[] | OperatorMap<string | string[]>
value?: string | string[] value?: string | string[] | OperatorMap<string | string[]>
} }
@@ -1,5 +1,5 @@
import { ShippingOptionDTO } from "./shipping-option" import { ShippingOptionDTO } from "./shipping-option"
import { BaseFilterable } from "../../dal" import { BaseFilterable, OperatorMap } from "../../dal"
export interface ShippingOptionTypeDTO { export interface ShippingOptionTypeDTO {
id: string id: string
@@ -15,8 +15,8 @@ export interface ShippingOptionTypeDTO {
export interface FilterableShippingOptionTypeProps export interface FilterableShippingOptionTypeProps
extends BaseFilterable<FilterableShippingOptionTypeProps> { extends BaseFilterable<FilterableShippingOptionTypeProps> {
id?: string | string[] id?: string | string[] | OperatorMap<string | string[]>
label?: string | string[] label?: string | string[] | OperatorMap<string | string[]>
description?: string | string[] description?: string | string[] | OperatorMap<string | string[]>
code?: string | string[] code?: string | string[] | OperatorMap<string | string[]>
} }
@@ -9,7 +9,7 @@ import {
FilterableShippingOptionRuleProps, FilterableShippingOptionRuleProps,
ShippingOptionRuleDTO, ShippingOptionRuleDTO,
} from "./shipping-option-rule" } from "./shipping-option-rule"
import { BaseFilterable } from "../../dal" import { BaseFilterable, OperatorMap } from "../../dal"
export type ShippingOptionPriceType = "calculated" | "flat" export type ShippingOptionPriceType = "calculated" | "flat"
@@ -35,9 +35,12 @@ export interface ShippingOptionDTO {
export interface FilterableShippingOptionProps export interface FilterableShippingOptionProps
extends BaseFilterable<FilterableShippingOptionProps> { extends BaseFilterable<FilterableShippingOptionProps> {
id?: string | string[] id?: string | string[] | OperatorMap<string | string[]>
name?: string | string[] name?: string | string[] | OperatorMap<string | string[]>
price_type?: ShippingOptionPriceType | ShippingOptionPriceType[] price_type?:
| ShippingOptionPriceType
| ShippingOptionPriceType[]
| OperatorMap<ShippingOptionPriceType | ShippingOptionPriceType[]>
service_zone?: FilterableServiceZoneProps service_zone?: FilterableServiceZoneProps
shipping_option_type?: FilterableShippingOptionTypeProps shipping_option_type?: FilterableShippingOptionTypeProps
rules?: FilterableShippingOptionRuleProps rules?: FilterableShippingOptionRuleProps
@@ -1,11 +1,24 @@
import { ShippingOptionDTO } from "./shipping-option" import {
FilterableShippingOptionProps,
ShippingOptionDTO,
} from "./shipping-option"
import { BaseFilterable, OperatorMap } from "../../dal"
export interface ShippingProfileDTO { export interface ShippingProfileDTO {
id: string id: string
name: string name: string
type: string
metadata: Record<string, unknown> | null metadata: Record<string, unknown> | null
shipping_options: ShippingOptionDTO[] shipping_options: ShippingOptionDTO[]
created_at: Date created_at: Date
updated_at: Date updated_at: Date
deleted_at: Date | null deleted_at: Date | null
} }
export interface FilterableShippingProfileProps
extends BaseFilterable<FilterableShippingProfileProps> {
id?: string | string[] | OperatorMap<string | string[]>
name?: string | string[] | OperatorMap<string | string[]>
type?: string | string[] | OperatorMap<string | string[]>
shipping_options?: FilterableShippingOptionProps
}
@@ -7,21 +7,21 @@ interface CreateGeoZoneBaseDTO {
metadata?: Record<string, any> | null metadata?: Record<string, any> | null
} }
interface CreateCountryGeoZoneDTO extends CreateGeoZoneBaseDTO { export interface CreateCountryGeoZoneDTO extends CreateGeoZoneBaseDTO {
type: "country" type: "country"
} }
interface CreateProvinceGeoZoneDTO extends CreateGeoZoneBaseDTO { export interface CreateProvinceGeoZoneDTO extends CreateGeoZoneBaseDTO {
type: "province" type: "province"
province_code: string province_code: string
} }
interface CreateCityGeoZoneDTO extends CreateGeoZoneBaseDTO { export interface CreateCityGeoZoneDTO extends CreateGeoZoneBaseDTO {
type: "city" type: "city"
city: string city: string
} }
interface CreateZipGeoZoneDTO extends CreateGeoZoneBaseDTO { export interface CreateZipGeoZoneDTO extends CreateGeoZoneBaseDTO {
type: "zip" type: "zip"
postal_expression: Record<string, any> postal_expression: Record<string, any>
} }
@@ -32,25 +32,25 @@ export type CreateGeoZoneDTO =
| CreateCityGeoZoneDTO | CreateCityGeoZoneDTO
| CreateZipGeoZoneDTO | CreateZipGeoZoneDTO
interface UpdateGeoZoneBaseDTO extends Partial<CreateGeoZoneBaseDTO> { export interface UpdateGeoZoneBaseDTO extends Partial<CreateGeoZoneBaseDTO> {
id: string id: string
} }
interface UpdateCountryGeoZoneDTO extends UpdateGeoZoneBaseDTO { export interface UpdateCountryGeoZoneDTO extends UpdateGeoZoneBaseDTO {
type: "country" type: "country"
} }
interface UpdateProvinceGeoZoneDTO extends UpdateGeoZoneBaseDTO { export interface UpdateProvinceGeoZoneDTO extends UpdateGeoZoneBaseDTO {
type: "province" type: "province"
province_code: string province_code: string
} }
interface UpdateCityGeoZoneDTO extends UpdateGeoZoneBaseDTO { export interface UpdateCityGeoZoneDTO extends UpdateGeoZoneBaseDTO {
type: "city" type: "city"
city: string city: string
} }
interface UpdateZipGeoZoneDTO extends UpdateGeoZoneBaseDTO { export interface UpdateZipGeoZoneDTO extends UpdateGeoZoneBaseDTO {
type: "zip" type: "zip"
postal_expression: Record<string, any> postal_expression: Record<string, any>
} }
@@ -1,3 +1,4 @@
export * from "./shipping-profile"
export * from "./shipping-option-type" export * from "./shipping-option-type"
export * from "./shipping-option-rule" export * from "./shipping-option-rule"
export * from "./geo-zone" export * from "./geo-zone"
@@ -1,13 +1,29 @@
import { CreateGeoZoneDTO } from "./geo-zone" import {
CreateCityGeoZoneDTO,
CreateCountryGeoZoneDTO,
CreateProvinceGeoZoneDTO,
CreateZipGeoZoneDTO,
} from "./geo-zone"
export interface CreateServiceZoneDTO { export interface CreateServiceZoneDTO {
name: string name: string
fulfillment_set_id: string fulfillment_set_id: string
geo_zones?: Omit<CreateGeoZoneDTO, "service_zone_id">[] geo_zones?: (
| Omit<CreateCountryGeoZoneDTO, "service_zone_id">
| Omit<CreateProvinceGeoZoneDTO, "service_zone_id">
| Omit<CreateCityGeoZoneDTO, "service_zone_id">
| Omit<CreateZipGeoZoneDTO, "service_zone_id">
)[]
} }
export interface UpdateServiceZoneDTO { export interface UpdateServiceZoneDTO {
id: string id: string
name?: string name?: string
geo_zones?: (Omit<CreateGeoZoneDTO, "service_zone_id"> | { id: string })[] geo_zones?: (
| Omit<CreateCountryGeoZoneDTO, "service_zone_id">
| Omit<CreateProvinceGeoZoneDTO, "service_zone_id">
| Omit<CreateCityGeoZoneDTO, "service_zone_id">
| Omit<CreateZipGeoZoneDTO, "service_zone_id">
| { id: string }
)[]
} }
@@ -1,12 +1,6 @@
import { import { CreateShippingOptionTypeDTO } from "./shipping-option-type"
CreateShippingOptionTypeDTO,
UpdateShippingOptionTypeDTO,
} from "./shipping-option-type"
import { ShippingOptionPriceType } from "../common" import { ShippingOptionPriceType } from "../common"
import { import { CreateShippingOptionRuleDTO } from "./shipping-option-rule"
CreateShippingOptionRuleDTO,
UpdateShippingOptionRuleDTO,
} from "./shipping-option-rule"
export interface CreateShippingOptionDTO { export interface CreateShippingOptionDTO {
name: string name: string
@@ -26,12 +20,10 @@ export interface UpdateShippingOptionDTO {
service_zone_id?: string service_zone_id?: string
shipping_profile_id?: string shipping_profile_id?: string
service_provider_id?: string service_provider_id?: string
type: type: Omit<CreateShippingOptionTypeDTO, "shipping_option_id"> | { id: string }
| Omit<CreateShippingOptionTypeDTO, "shipping_option_id">
| Omit<UpdateShippingOptionTypeDTO, "shipping_option_id">
data?: Record<string, unknown> | null data?: Record<string, unknown> | null
rules?: ( rules?: (
| Omit<CreateShippingOptionRuleDTO, "shipping_option_id"> | Omit<CreateShippingOptionRuleDTO, "shipping_option_id">
| Omit<UpdateShippingOptionRuleDTO, "shipping_option_id"> | { id: string }
)[] )[]
} }
@@ -0,0 +1,8 @@
export interface CreateShippingProfileDTO {
name: string
type?: string
metadata?: Record<string, unknown>
}
export interface UpdateShippingProfileDTO
extends Partial<CreateShippingProfileDTO> {}
+90
View File
@@ -4,10 +4,12 @@ import {
FilterableGeoZoneProps, FilterableGeoZoneProps,
FilterableServiceZoneProps, FilterableServiceZoneProps,
FilterableShippingOptionProps, FilterableShippingOptionProps,
FilterableShippingProfileProps,
FulfillmentSetDTO, FulfillmentSetDTO,
GeoZoneDTO, GeoZoneDTO,
ServiceZoneDTO, ServiceZoneDTO,
ShippingOptionDTO, ShippingOptionDTO,
ShippingProfileDTO,
} from "./common" } from "./common"
import { FindConfig } from "../common" import { FindConfig } from "../common"
import { Context } from "../shared-context" import { Context } from "../shared-context"
@@ -22,6 +24,7 @@ import {
UpdateServiceZoneDTO, UpdateServiceZoneDTO,
UpdateShippingOptionDTO, UpdateShippingOptionDTO,
} from "./mutations" } from "./mutations"
import { CreateShippingProfileDTO } from "./mutations/shipping-profile"
export interface IFulfillmentModuleService extends IModuleService { export interface IFulfillmentModuleService extends IModuleService {
/** /**
@@ -66,6 +69,21 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<ShippingOptionDTO> ): Promise<ShippingOptionDTO>
/**
* Create a new shipping profile
* @param data
* @param sharedContext
*/
createShippingProfiles(
data: CreateShippingProfileDTO[],
sharedContext?: Context
): Promise<ShippingProfileDTO[]>
createShippingProfiles(
data: CreateShippingProfileDTO,
sharedContext?: Context
): Promise<ShippingProfileDTO>
/** /**
* Create a new geo zone * Create a new geo zone
* @param data * @param data
@@ -122,6 +140,20 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<ShippingOptionDTO> ): Promise<ShippingOptionDTO>
/**
* Update a shipping profile
* @param data
* @param sharedContext
*/
updateShippingProfiles(
data: CreateShippingProfileDTO[],
sharedContext?: Context
): Promise<ShippingProfileDTO[]>
updateShippingProfiles(
data: CreateShippingProfileDTO,
sharedContext?: Context
): Promise<ShippingProfileDTO>
/** /**
* Update a geo zone * Update a geo zone
* @param data * @param data
@@ -160,6 +192,14 @@ export interface IFulfillmentModuleService extends IModuleService {
deleteShippingOptions(ids: string[], sharedContext?: Context): Promise<void> deleteShippingOptions(ids: string[], sharedContext?: Context): Promise<void>
deleteShippingOptions(id: string, sharedContext?: Context): Promise<void> deleteShippingOptions(id: string, sharedContext?: Context): Promise<void>
/**
* Delete a shipping profile
* @param ids
* @param sharedContext
*/
deleteShippingProfiles(ids: string[], sharedContext?: Context): Promise<void>
deleteShippingProfiles(id: string, sharedContext?: Context): Promise<void>
/** /**
* Delete a geo zone * Delete a geo zone
* @param ids * @param ids
@@ -204,6 +244,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<ShippingOptionDTO> ): Promise<ShippingOptionDTO>
/**
* Retrieve a shipping profile
* @param id
* @param config
* @param sharedContext
*/
retrieveShippingProfile(
id: string,
config?: FindConfig<ShippingProfileDTO>,
sharedContext?: Context
): Promise<ShippingProfileDTO>
/** /**
* Retrieve a geo zone * Retrieve a geo zone
* @param id * @param id
@@ -252,6 +304,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<ShippingOptionDTO[]> ): Promise<ShippingOptionDTO[]>
/**
* List shipping profiles
* @param filters
* @param config
* @param sharedContext
*/
listShippingProfiles(
filters?: FilterableShippingProfileProps,
config?: FindConfig<ShippingProfileDTO>,
sharedContext?: Context
): Promise<ShippingProfileDTO[]>
/** /**
* List geo zones * List geo zones
* @param filters * @param filters
@@ -300,6 +364,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<[ShippingOptionDTO[], number]> ): Promise<[ShippingOptionDTO[], number]>
/**
* List and count shipping profiles
* @param filters
* @param config
* @param sharedContext
*/
listAndCountShippingProfiles(
filters?: FilterableShippingProfileProps,
config?: FindConfig<ShippingProfileDTO>,
sharedContext?: Context
): Promise<[ShippingProfileDTO[], number]>
/** /**
* List and count geo zones * List and count geo zones
* @param filters * @param filters
@@ -348,6 +424,18 @@ export interface IFulfillmentModuleService extends IModuleService {
sharedContext?: Context sharedContext?: Context
): Promise<Record<string, string[]> | void> ): Promise<Record<string, string[]> | void>
/**
* Soft delete shipping profiles
* @param shippingProfileIds
* @param config
* @param sharedContext
*/
softDeleteShippingProfiles<TReturnableLinkableKeys extends string = string>(
shippingProfileIds: string[],
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
sharedContext?: Context
): Promise<Record<string, string[]> | void>
/** /**
* Soft delete geo zones * Soft delete geo zones
* @param geoZoneIds * @param geoZoneIds
@@ -365,4 +453,6 @@ export interface IFulfillmentModuleService extends IModuleService {
config?: RestoreReturn<TReturnableLinkableKeys>, config?: RestoreReturn<TReturnableLinkableKeys>,
sharedContext?: Context sharedContext?: Context
): Promise<Record<string, string[]> | void> ): Promise<Record<string, string[]> | void>
// TODO defined the other restore methods
} }
@@ -5,14 +5,14 @@ import { TestDatabaseUtils } from "medusa-test-utils"
const pathToMigrations = "../../src/migrations" const pathToMigrations = "../../src/migrations"
const mikroOrmEntities = UserModels as unknown as any[] const mikroOrmEntities = UserModels as unknown as any[]
export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper( export const MikroOrmWrapper = TestDatabaseUtils.getMikroOrmWrapper({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig( export const MikroOrmConfig = TestDatabaseUtils.getMikroOrmConfig({
mikroOrmEntities, mikroOrmEntities,
pathToMigrations pathToMigrations,
) })
export const DB_URL = TestDatabaseUtils.getDatabaseURL() export const DB_URL = TestDatabaseUtils.getDatabaseURL()
@@ -84,7 +84,7 @@ describe("createPsqlIndexStatementHelper", function () {
const indexStatement = createPsqlIndexStatementHelper(options) const indexStatement = createPsqlIndexStatementHelper(options)
expect(indexStatement.expression).toEqual( 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.tableName
}" (${options.columns.join(", ")}) WHERE ${options.where}` }" (${options.columns.join(", ")}) WHERE ${options.where}`
) )
@@ -47,7 +47,7 @@ export function createPsqlIndexStatementHelper({
const columnsName = Array.isArray(columns) ? columns.join("_") : columns const columnsName = Array.isArray(columns) ? columns.join("_") : columns
columns = 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 typeStr = type ? ` USING ${type}` : ""
const optionsStr = where ? ` WHERE ${where}` : "" const optionsStr = where ? ` WHERE ${where}` : ""
@@ -63,7 +63,7 @@ export function createPsqlIndexStatementHelper({
}, },
name, name,
expression, expression,
MikroORMIndex: (options = {}) => { MikroORMIndex: (options?: Parameters<typeof Index>[0]) => {
return Index({ return Index({
name, name,
expression, expression,
@@ -97,13 +97,6 @@ export interface AbstractModuleServiceBase<TContainer, TMainModelDTO> {
): Promise<Record<string, string[]> | void> ): Promise<Record<string, string[]> | 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< export type AbstractModuleService<
TContainer, TContainer,
TMainModelDTO, TMainModelDTO,
@@ -1,4 +1,4 @@
import knex from "knex" import { knex } from "@mikro-orm/knex"
import { ModuleServiceInitializeOptions } from "@medusajs/types" import { ModuleServiceInitializeOptions } from "@medusajs/types"
type Options = ModuleServiceInitializeOptions["database"] type Options = ModuleServiceInitializeOptions["database"]
@@ -3,7 +3,7 @@ import {
TransactionStepTimeoutError, TransactionStepTimeoutError,
TransactionTimeoutError, TransactionTimeoutError,
} from "@medusajs/orchestration" } from "@medusajs/orchestration"
import { RemoteJoinerQuery } from "@medusajs/types" import { RemoteQueryFunction } from "@medusajs/types"
import { TransactionHandlerType } from "@medusajs/utils" import { TransactionHandlerType } from "@medusajs/utils"
import { IWorkflowEngineService } from "@medusajs/workflows-sdk" import { IWorkflowEngineService } from "@medusajs/workflows-sdk"
import { knex } from "knex" import { knex } from "knex"
@@ -27,10 +27,7 @@ const afterEach_ = async () => {
describe("Workflow Orchestrator module", function () { describe("Workflow Orchestrator module", function () {
describe("Testing basic workflow", function () { describe("Testing basic workflow", function () {
let workflowOrcModule: IWorkflowEngineService let workflowOrcModule: IWorkflowEngineService
let query: ( let query: RemoteQueryFunction
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>
) => Promise<any>
afterEach(afterEach_) afterEach(afterEach_)