feat(region): Add admin region get + list endpoints (#6322)
**What** Add `GET /admin/regions` Add `GET /admin/regions/:id` Blocked by #6320 Co-authored-by: Adrien de Peretti <25098370+adrien2p@users.noreply.github.com>
This commit is contained in:
co-authored by
Adrien de Peretti
parent
b91a1ca5b8
commit
95d0e58d31
@@ -11,6 +11,7 @@ const { dropDatabase } = require("pg-god")
|
|||||||
const { DataSource } = require("typeorm")
|
const { DataSource } = require("typeorm")
|
||||||
const dbFactory = require("./use-template-db")
|
const dbFactory = require("./use-template-db")
|
||||||
const { ContainerRegistrationKeys } = require("@medusajs/utils")
|
const { ContainerRegistrationKeys } = require("@medusajs/utils")
|
||||||
|
const { migrateMedusaApp } = require("@medusajs/medusa/dist/loaders/medusa-app")
|
||||||
|
|
||||||
const DB_HOST = process.env.DB_HOST
|
const DB_HOST = process.env.DB_HOST
|
||||||
const DB_USERNAME = process.env.DB_USERNAME
|
const DB_USERNAME = process.env.DB_USERNAME
|
||||||
@@ -155,35 +156,26 @@ module.exports = {
|
|||||||
const featureFlagLoader =
|
const featureFlagLoader =
|
||||||
require("@medusajs/medusa/dist/loaders/feature-flags").default
|
require("@medusajs/medusa/dist/loaders/feature-flags").default
|
||||||
|
|
||||||
const medusaAppLoader =
|
|
||||||
require("@medusajs/medusa/dist/loaders/medusa-app").default
|
|
||||||
|
|
||||||
const container = createMedusaContainer()
|
const container = createMedusaContainer()
|
||||||
|
|
||||||
const featureFlagRouter = await featureFlagLoader(configModule)
|
const featureFlagRouter = await featureFlagLoader(configModule)
|
||||||
|
|
||||||
|
const pgConnection = await pgConnectionLoader({ configModule, container })
|
||||||
|
|
||||||
container.register({
|
container.register({
|
||||||
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
|
[ContainerRegistrationKeys.CONFIG_MODULE]: asValue(configModule),
|
||||||
[ContainerRegistrationKeys.LOGGER]: asValue(console),
|
[ContainerRegistrationKeys.LOGGER]: asValue(console),
|
||||||
[ContainerRegistrationKeys.MANAGER]: asValue(dbDataSource.manager),
|
[ContainerRegistrationKeys.MANAGER]: asValue(dbDataSource.manager),
|
||||||
|
[ContainerRegistrationKeys.PG_CONNECTION]: asValue(pgConnection),
|
||||||
featureFlagRouter: asValue(featureFlagRouter),
|
featureFlagRouter: asValue(featureFlagRouter),
|
||||||
})
|
})
|
||||||
|
|
||||||
const pgConnection = await pgConnectionLoader({ configModule, container })
|
|
||||||
instance.setPgConnection(pgConnection)
|
instance.setPgConnection(pgConnection)
|
||||||
|
|
||||||
const { runMigrations } = await medusaAppLoader(
|
await migrateMedusaApp(
|
||||||
{ configModule, container },
|
{ configModule, container },
|
||||||
{ registerInContainer: false }
|
{ registerInContainer: false }
|
||||||
)
|
)
|
||||||
|
|
||||||
const options = {
|
|
||||||
database: {
|
|
||||||
clientUrl: DB_URL,
|
|
||||||
connection: pgConnection,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
await runMigrations(options)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dbDataSource
|
return dbDataSource
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
|
||||||
import { ICustomerModuleService } from "@medusajs/types"
|
|
||||||
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
import { ICustomerModuleService } from "@medusajs/types"
|
||||||
import { getContainer } from "../../../../environment-helpers/use-container"
|
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
import { useApi } from "../../../../environment-helpers/use-api"
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
|
import { createAuthenticatedCustomer } from "../../../helpers/create-authenticated-customer"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IRegionModuleService } from "@medusajs/types"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
import adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/regions/:id", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let regionModuleService: IRegionModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
regionModuleService = appContainer.resolve(ModuleRegistrationName.REGION)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get a region", async () => {
|
||||||
|
const [region] = await regionModuleService.create([
|
||||||
|
{
|
||||||
|
name: "Test",
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(`/admin/regions/${region.id}`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.region).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: region.id,
|
||||||
|
name: "Test",
|
||||||
|
currency_code: "usd",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IRegionModuleService } from "@medusajs/types"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../../environment-helpers/use-api"
|
||||||
|
import { getContainer } from "../../../../environment-helpers/use-container"
|
||||||
|
import { initDb, useDb } from "../../../../environment-helpers/use-db"
|
||||||
|
import adminSeeder from "../../../../helpers/admin-seeder"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/regions", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let regionModuleService: IRegionModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
regionModuleService = appContainer.resolve(ModuleRegistrationName.REGION)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should get all regions and count", async () => {
|
||||||
|
await regionModuleService.create([
|
||||||
|
{
|
||||||
|
name: "Test",
|
||||||
|
currency_code: "usd",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi() as any
|
||||||
|
const response = await api.get(`/admin/regions`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.regions).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: expect.any(String),
|
||||||
|
name: "Test",
|
||||||
|
currency_code: "usd",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -91,5 +91,10 @@ module.exports = {
|
|||||||
resources: "shared",
|
resources: "shared",
|
||||||
resolve: "@medusajs/cart",
|
resolve: "@medusajs/cart",
|
||||||
},
|
},
|
||||||
|
[Modules.REGION]: {
|
||||||
|
scope: "internal",
|
||||||
|
resources: "shared",
|
||||||
|
resolve: "@medusajs/region",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"@medusajs/pricing": "workspace:^",
|
"@medusajs/pricing": "workspace:^",
|
||||||
"@medusajs/product": "workspace:^",
|
"@medusajs/product": "workspace:^",
|
||||||
"@medusajs/promotion": "workspace:^",
|
"@medusajs/promotion": "workspace:^",
|
||||||
|
"@medusajs/region": "workspace:^",
|
||||||
"@medusajs/utils": "workspace:^",
|
"@medusajs/utils": "workspace:^",
|
||||||
"faker": "^5.5.3",
|
"faker": "^5.5.3",
|
||||||
"medusa-fulfillment-webshipper": "workspace:*",
|
"medusa-fulfillment-webshipper": "workspace:*",
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||||
|
import { defaultAdminRegionFields } from "../query-config"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const remoteQuery = req.scope.resolve("remoteQuery")
|
||||||
|
|
||||||
|
const variables = { id: req.params.id }
|
||||||
|
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "region",
|
||||||
|
variables,
|
||||||
|
fields: defaultAdminRegionFields,
|
||||||
|
})
|
||||||
|
|
||||||
|
const [region] = await remoteQuery(queryObject)
|
||||||
|
|
||||||
|
res.status(200).json({ region })
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import { transformQuery } from "../../../api/middlewares"
|
||||||
|
import { MiddlewareRoute } from "../../../loaders/helpers/routing/types"
|
||||||
|
import * as QueryConfig from "./query-config"
|
||||||
|
import {
|
||||||
|
AdminGetRegionsParams,
|
||||||
|
AdminGetRegionsRegionParams,
|
||||||
|
} from "./validators"
|
||||||
|
|
||||||
|
export const adminRegionRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/regions",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetRegionsParams,
|
||||||
|
QueryConfig.listTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/regions/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetRegionsRegionParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
export const defaultAdminRegionFields = [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"currency_code",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
"metadata",
|
||||||
|
"countries.id",
|
||||||
|
"countries.iso_2",
|
||||||
|
"countries.iso_3",
|
||||||
|
"countries.num_code",
|
||||||
|
"countries.name",
|
||||||
|
"currency.code",
|
||||||
|
"currency.symbol",
|
||||||
|
"currency.symbol_native",
|
||||||
|
"currency.name",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const retrieveTransformQueryConfig = {
|
||||||
|
isList: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listTransformQueryConfig = {
|
||||||
|
defaultLimit: 20,
|
||||||
|
isList: true,
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { remoteQueryObjectFromString } from "@medusajs/utils"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||||
|
import { defaultAdminRegionFields } from "./query-config"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const remoteQuery = req.scope.resolve("remoteQuery")
|
||||||
|
|
||||||
|
const variables = { filters: req.filterableFields }
|
||||||
|
|
||||||
|
const queryObject = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "region",
|
||||||
|
variables,
|
||||||
|
fields: defaultAdminRegionFields,
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: Add count, offset, limit
|
||||||
|
const regions = await remoteQuery(queryObject)
|
||||||
|
|
||||||
|
res.json({ regions })
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import { OperatorMap } from "@medusajs/types"
|
||||||
|
import { Type } from "class-transformer"
|
||||||
|
import { IsOptional, IsString, ValidateNested } from "class-validator"
|
||||||
|
import { FindParams, extendedFindParamsMixin } from "../../../types/common"
|
||||||
|
import { OperatorMapValidator } from "../../../types/validators/operator-map"
|
||||||
|
|
||||||
|
export class AdminGetRegionsRegionParams extends FindParams {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters used to filter and configure the pagination of the retrieved regions.
|
||||||
|
*/
|
||||||
|
export class AdminGetRegionsParams extends extendedFindParamsMixin({
|
||||||
|
limit: 50,
|
||||||
|
offset: 0,
|
||||||
|
}) {
|
||||||
|
/**
|
||||||
|
* Search parameter for regions.
|
||||||
|
*/
|
||||||
|
@IsString({ each: true })
|
||||||
|
@IsOptional()
|
||||||
|
id?: string | string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by currency code
|
||||||
|
*/
|
||||||
|
@IsString({ each: true })
|
||||||
|
@IsOptional()
|
||||||
|
code?: string | string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter by region name
|
||||||
|
*/
|
||||||
|
@IsString({ each: true })
|
||||||
|
@IsOptional()
|
||||||
|
name?: string | string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the regions' `created_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
created_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the regions' `updated_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
updated_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the regions' `deleted_at` date.
|
||||||
|
*/
|
||||||
|
@ValidateNested()
|
||||||
|
@IsOptional()
|
||||||
|
@Type(() => OperatorMapValidator)
|
||||||
|
deleted_at?: OperatorMap<string>
|
||||||
|
|
||||||
|
// Additional filters from BaseFilterable
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => AdminGetRegionsParams)
|
||||||
|
$and?: AdminGetRegionsParams[]
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested({ each: true })
|
||||||
|
@Type(() => AdminGetRegionsParams)
|
||||||
|
$or?: AdminGetRegionsParams[]
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
import { MiddlewaresConfig } from "../loaders/helpers/routing/types"
|
import { MiddlewaresConfig } from "../loaders/helpers/routing/types"
|
||||||
import { adminCampaignRoutesMiddlewares } from "./admin/campaigns/middlewares"
|
import { adminCampaignRoutesMiddlewares } from "./admin/campaigns/middlewares"
|
||||||
import { adminCustomerGroupRoutesMiddlewares } from "./admin/customer-groups/middlewares"
|
import { adminCustomerGroupRoutesMiddlewares } from "./admin/customer-groups/middlewares"
|
||||||
import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
|
||||||
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
|
import { adminCustomerRoutesMiddlewares } from "./admin/customers/middlewares"
|
||||||
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
import { adminPromotionRoutesMiddlewares } from "./admin/promotions/middlewares"
|
||||||
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
import { adminRegionRoutesMiddlewares } from "./admin/regions/middlewares"
|
||||||
import { authRoutesMiddlewares } from "./auth/middlewares"
|
import { authRoutesMiddlewares } from "./auth/middlewares"
|
||||||
|
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
||||||
|
import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
||||||
|
|
||||||
export const config: MiddlewaresConfig = {
|
export const config: MiddlewaresConfig = {
|
||||||
routes: [
|
routes: [
|
||||||
@@ -16,5 +17,6 @@ export const config: MiddlewaresConfig = {
|
|||||||
...storeCustomerRoutesMiddlewares,
|
...storeCustomerRoutesMiddlewares,
|
||||||
...storeCartRoutesMiddlewares,
|
...storeCartRoutesMiddlewares,
|
||||||
...authRoutesMiddlewares,
|
...authRoutesMiddlewares,
|
||||||
|
...adminRegionRoutesMiddlewares,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import { Express, NextFunction, Request, Response } from "express"
|
|||||||
import databaseLoader, { dataSource } from "./database"
|
import databaseLoader, { dataSource } from "./database"
|
||||||
import pluginsLoader, { registerPluginModels } from "./plugins"
|
import pluginsLoader, { registerPluginModels } from "./plugins"
|
||||||
|
|
||||||
import { ContainerRegistrationKeys, isString } from "@medusajs/utils"
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
isString
|
||||||
|
} from "@medusajs/utils"
|
||||||
import { asValue } from "awilix"
|
import { asValue } from "awilix"
|
||||||
import { createMedusaContainer } from "medusa-core-utils"
|
import { createMedusaContainer } from "medusa-core-utils"
|
||||||
import { track } from "medusa-telemetry"
|
import { track } from "medusa-telemetry"
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import {
|
import {
|
||||||
MODULE_PACKAGE_NAMES,
|
|
||||||
MedusaApp,
|
MedusaApp,
|
||||||
|
MedusaAppMigrateUp,
|
||||||
MedusaAppOutput,
|
MedusaAppOutput,
|
||||||
MedusaModule,
|
MedusaModule,
|
||||||
|
MODULE_PACKAGE_NAMES,
|
||||||
Modules,
|
Modules,
|
||||||
ModulesDefinition,
|
ModulesDefinition,
|
||||||
} from "@medusajs/modules-sdk"
|
} from "@medusajs/modules-sdk"
|
||||||
@@ -12,9 +13,12 @@ import {
|
|||||||
MedusaContainer,
|
MedusaContainer,
|
||||||
ModuleDefinition,
|
ModuleDefinition,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import { FlagRouter, MedusaV2Flag } from "@medusajs/utils"
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
import { ContainerRegistrationKeys, isObject } from "@medusajs/utils"
|
FlagRouter,
|
||||||
|
isObject,
|
||||||
|
MedusaV2Flag,
|
||||||
|
} from "@medusajs/utils"
|
||||||
import { asValue } from "awilix"
|
import { asValue } from "awilix"
|
||||||
import { remoteQueryFetchData } from ".."
|
import { remoteQueryFetchData } from ".."
|
||||||
import { joinerConfig } from "../joiner-config"
|
import { joinerConfig } from "../joiner-config"
|
||||||
@@ -37,6 +41,67 @@ export function mergeDefaultModules(
|
|||||||
return configModules
|
return configModules
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function migrateMedusaApp(
|
||||||
|
{
|
||||||
|
configModule,
|
||||||
|
container,
|
||||||
|
}: {
|
||||||
|
configModule: {
|
||||||
|
modules?: CommonTypes.ConfigModule["modules"]
|
||||||
|
projectConfig: CommonTypes.ConfigModule["projectConfig"]
|
||||||
|
}
|
||||||
|
container: MedusaContainer
|
||||||
|
},
|
||||||
|
config = { registerInContainer: true }
|
||||||
|
): Promise<void> {
|
||||||
|
const featureFlagRouter = container.resolve<FlagRouter>("featureFlagRouter")
|
||||||
|
const isMedusaV2Enabled = featureFlagRouter.isFeatureEnabled(MedusaV2Flag.key)
|
||||||
|
const injectedDependencies = {
|
||||||
|
[ContainerRegistrationKeys.PG_CONNECTION]: container.resolve(
|
||||||
|
ContainerRegistrationKeys.PG_CONNECTION
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharedResourcesConfig = {
|
||||||
|
database: {
|
||||||
|
clientUrl: configModule.projectConfig.database_url,
|
||||||
|
driverOptions: configModule.projectConfig.database_extra,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const configModules = mergeDefaultModules(configModule.modules)
|
||||||
|
|
||||||
|
// Apply default options to legacy modules
|
||||||
|
for (const moduleKey of Object.keys(configModules)) {
|
||||||
|
if (!ModulesDefinition[moduleKey].isLegacy) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObject(configModules[moduleKey])) {
|
||||||
|
;(
|
||||||
|
configModules[moduleKey] as Partial<InternalModuleDeclaration>
|
||||||
|
).options ??= {
|
||||||
|
database: {
|
||||||
|
type: "postgres",
|
||||||
|
url: configModule.projectConfig.database_url,
|
||||||
|
extra: configModule.projectConfig.database_extra,
|
||||||
|
schema: configModule.projectConfig.database_schema,
|
||||||
|
logging: configModule.projectConfig.database_logging,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await MedusaAppMigrateUp({
|
||||||
|
modulesConfig: configModules,
|
||||||
|
servicesConfig: joinerConfig,
|
||||||
|
remoteFetchData: remoteQueryFetchData(container),
|
||||||
|
sharedContainer: container,
|
||||||
|
sharedResourcesConfig,
|
||||||
|
injectedDependencies,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const loadMedusaApp = async (
|
export const loadMedusaApp = async (
|
||||||
{
|
{
|
||||||
configModule,
|
configModule,
|
||||||
|
|||||||
@@ -13,13 +13,20 @@ export const moduleLoader = async ({
|
|||||||
container,
|
container,
|
||||||
moduleResolutions,
|
moduleResolutions,
|
||||||
logger,
|
logger,
|
||||||
|
migrationOnly,
|
||||||
}: {
|
}: {
|
||||||
container: MedusaContainer
|
container: MedusaContainer
|
||||||
moduleResolutions: Record<string, ModuleResolution>
|
moduleResolutions: Record<string, ModuleResolution>
|
||||||
logger: Logger
|
logger: Logger
|
||||||
|
migrationOnly?: boolean
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
for (const resolution of Object.values(moduleResolutions ?? {})) {
|
for (const resolution of Object.values(moduleResolutions ?? {})) {
|
||||||
const registrationResult = await loadModule(container, resolution, logger!)
|
const registrationResult = await loadModule(
|
||||||
|
container,
|
||||||
|
resolution,
|
||||||
|
logger!,
|
||||||
|
migrationOnly
|
||||||
|
)
|
||||||
|
|
||||||
if (registrationResult?.error) {
|
if (registrationResult?.error) {
|
||||||
const { error } = registrationResult
|
const { error } = registrationResult
|
||||||
@@ -40,7 +47,8 @@ export const moduleLoader = async ({
|
|||||||
async function loadModule(
|
async function loadModule(
|
||||||
container: MedusaContainer,
|
container: MedusaContainer,
|
||||||
resolution: ModuleResolution,
|
resolution: ModuleResolution,
|
||||||
logger: Logger
|
logger: Logger,
|
||||||
|
migrationOnly?: boolean
|
||||||
): Promise<{ error?: Error } | void> {
|
): Promise<{ error?: Error } | void> {
|
||||||
const modDefinition = resolution.definition
|
const modDefinition = resolution.definition
|
||||||
const registrationName = modDefinition.registrationName
|
const registrationName = modDefinition.registrationName
|
||||||
@@ -77,5 +85,5 @@ async function loadModule(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return await loadInternalModule(container, resolution, logger)
|
return await loadInternalModule(container, resolution, logger, migrationOnly)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { asFunction, asValue } from "awilix"
|
|||||||
export async function loadInternalModule(
|
export async function loadInternalModule(
|
||||||
container: MedusaContainer,
|
container: MedusaContainer,
|
||||||
resolution: ModuleResolution,
|
resolution: ModuleResolution,
|
||||||
logger: Logger
|
logger: Logger,
|
||||||
|
migrationOnly?: boolean
|
||||||
): Promise<{ error?: Error } | void> {
|
): Promise<{ error?: Error } | void> {
|
||||||
const registrationName = resolution.definition.registrationName
|
const registrationName = resolution.definition.registrationName
|
||||||
|
|
||||||
@@ -64,6 +65,17 @@ export async function loadInternalModule(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (migrationOnly) {
|
||||||
|
// Partially loaded module, only register the service __joinerConfig function to be able to resolve it later
|
||||||
|
const moduleService = {
|
||||||
|
__joinerConfig: loadedModule.service.prototype.__joinerConfig,
|
||||||
|
}
|
||||||
|
container.register({
|
||||||
|
[registrationName]: asValue(moduleService),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const localContainer = createMedusaContainer()
|
const localContainer = createMedusaContainer()
|
||||||
|
|
||||||
const dependencies = resolution?.dependencies ?? []
|
const dependencies = resolution?.dependencies ?? []
|
||||||
|
|||||||
@@ -67,7 +67,11 @@ export type SharedResources = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadModules(modulesConfig, sharedContainer) {
|
async function loadModules(
|
||||||
|
modulesConfig,
|
||||||
|
sharedContainer,
|
||||||
|
migrationOnly = false
|
||||||
|
) {
|
||||||
const allModules = {}
|
const allModules = {}
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
@@ -106,6 +110,7 @@ async function loadModules(modulesConfig, sharedContainer) {
|
|||||||
sharedContainer,
|
sharedContainer,
|
||||||
moduleDefinition: definition as ModuleDefinition,
|
moduleDefinition: definition as ModuleDefinition,
|
||||||
moduleExports,
|
moduleExports,
|
||||||
|
migrationOnly,
|
||||||
})) as LoadedModule
|
})) as LoadedModule
|
||||||
|
|
||||||
const service = loaded[moduleName]
|
const service = loaded[moduleName]
|
||||||
@@ -190,18 +195,7 @@ export type MedusaAppOutput = {
|
|||||||
runMigrations: RunMigrationFn
|
runMigrations: RunMigrationFn
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function MedusaApp({
|
export type MedusaAppOptions = {
|
||||||
sharedContainer,
|
|
||||||
sharedResourcesConfig,
|
|
||||||
servicesConfig,
|
|
||||||
modulesConfigPath,
|
|
||||||
modulesConfigFileName,
|
|
||||||
modulesConfig,
|
|
||||||
linkModules,
|
|
||||||
remoteFetchData,
|
|
||||||
injectedDependencies,
|
|
||||||
onApplicationStartCb,
|
|
||||||
}: {
|
|
||||||
sharedContainer?: MedusaContainer
|
sharedContainer?: MedusaContainer
|
||||||
sharedResourcesConfig?: SharedResources
|
sharedResourcesConfig?: SharedResources
|
||||||
loadedModules?: LoadedModule[]
|
loadedModules?: LoadedModule[]
|
||||||
@@ -213,7 +207,21 @@ export async function MedusaApp({
|
|||||||
remoteFetchData?: RemoteFetchDataCallback
|
remoteFetchData?: RemoteFetchDataCallback
|
||||||
injectedDependencies?: any
|
injectedDependencies?: any
|
||||||
onApplicationStartCb?: () => void
|
onApplicationStartCb?: () => void
|
||||||
} = {}): Promise<{
|
}
|
||||||
|
|
||||||
|
async function MedusaApp_({
|
||||||
|
sharedContainer,
|
||||||
|
sharedResourcesConfig,
|
||||||
|
servicesConfig,
|
||||||
|
modulesConfigPath,
|
||||||
|
modulesConfigFileName,
|
||||||
|
modulesConfig,
|
||||||
|
linkModules,
|
||||||
|
remoteFetchData,
|
||||||
|
injectedDependencies = {},
|
||||||
|
onApplicationStartCb,
|
||||||
|
migrationOnly = false,
|
||||||
|
}: MedusaAppOptions & { migrationOnly?: boolean } = {}): Promise<{
|
||||||
modules: Record<string, LoadedModule | LoadedModule[]>
|
modules: Record<string, LoadedModule | LoadedModule[]>
|
||||||
link: RemoteLink | undefined
|
link: RemoteLink | undefined
|
||||||
query: (
|
query: (
|
||||||
@@ -224,8 +232,6 @@ export async function MedusaApp({
|
|||||||
notFound?: Record<string, Record<string, string>>
|
notFound?: Record<string, Record<string, string>>
|
||||||
runMigrations: RunMigrationFn
|
runMigrations: RunMigrationFn
|
||||||
}> {
|
}> {
|
||||||
injectedDependencies ??= {}
|
|
||||||
|
|
||||||
const sharedContainer_ = createMedusaContainer({}, sharedContainer)
|
const sharedContainer_ = createMedusaContainer({}, sharedContainer)
|
||||||
|
|
||||||
const modules: MedusaModuleConfig =
|
const modules: MedusaModuleConfig =
|
||||||
@@ -279,7 +285,7 @@ export async function MedusaApp({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const allModules = await loadModules(modules, sharedContainer_)
|
const allModules = await loadModules(modules, sharedContainer_, migrationOnly)
|
||||||
|
|
||||||
// Share Event bus with link modules
|
// Share Event bus with link modules
|
||||||
injectedDependencies[ModuleRegistrationName.EVENT_BUS] =
|
injectedDependencies[ModuleRegistrationName.EVENT_BUS] =
|
||||||
@@ -346,16 +352,35 @@ export async function MedusaApp({
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
return {
|
||||||
return {
|
modules: allModules,
|
||||||
modules: allModules,
|
link: remoteLink,
|
||||||
link: remoteLink,
|
query,
|
||||||
query,
|
entitiesMap: schema.getTypeMap(),
|
||||||
entitiesMap: schema.getTypeMap(),
|
notFound,
|
||||||
notFound,
|
runMigrations,
|
||||||
runMigrations,
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
MedusaModule.onApplicationStart(onApplicationStartCb)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function MedusaApp(
|
||||||
|
options: MedusaAppOptions = {}
|
||||||
|
): Promise<MedusaAppOutput> {
|
||||||
|
try {
|
||||||
|
return await MedusaApp_(options)
|
||||||
|
} finally {
|
||||||
|
MedusaModule.onApplicationStart(options.onApplicationStartCb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function MedusaAppMigrateUp(
|
||||||
|
options: MedusaAppOptions = {}
|
||||||
|
): Promise<void> {
|
||||||
|
const migrationOnly = true
|
||||||
|
|
||||||
|
const { runMigrations } = await MedusaApp_({
|
||||||
|
...options,
|
||||||
|
migrationOnly,
|
||||||
|
})
|
||||||
|
|
||||||
|
await runMigrations().finally(MedusaModule.clearInstances)
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import {
|
|||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
LinkModuleDefinition,
|
LinkModuleDefinition,
|
||||||
LoadedModule,
|
LoadedModule,
|
||||||
|
MedusaContainer,
|
||||||
MODULE_RESOURCE_TYPE,
|
MODULE_RESOURCE_TYPE,
|
||||||
MODULE_SCOPE,
|
MODULE_SCOPE,
|
||||||
MedusaContainer,
|
|
||||||
ModuleBootstrapDeclaration,
|
ModuleBootstrapDeclaration,
|
||||||
ModuleDefinition,
|
ModuleDefinition,
|
||||||
ModuleExports,
|
ModuleExports,
|
||||||
@@ -59,6 +59,11 @@ export type ModuleBootstrapOptions = {
|
|||||||
sharedContainer?: MedusaContainer
|
sharedContainer?: MedusaContainer
|
||||||
moduleDefinition?: ModuleDefinition
|
moduleDefinition?: ModuleDefinition
|
||||||
injectedDependencies?: Record<string, any>
|
injectedDependencies?: Record<string, any>
|
||||||
|
/**
|
||||||
|
* In this mode, all instances are partially loaded, meaning that the module will not be fully loaded and the services will not be available.
|
||||||
|
* Don't forget to clear the instances (MedusaModule.clearInstances()) after the migration are done.
|
||||||
|
*/
|
||||||
|
migrationOnly?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type LinkModuleBootstrapOptions = {
|
export type LinkModuleBootstrapOptions = {
|
||||||
@@ -213,6 +218,7 @@ export class MedusaModule {
|
|||||||
sharedContainer,
|
sharedContainer,
|
||||||
moduleDefinition,
|
moduleDefinition,
|
||||||
injectedDependencies,
|
injectedDependencies,
|
||||||
|
migrationOnly,
|
||||||
}: ModuleBootstrapOptions): Promise<{
|
}: ModuleBootstrapOptions): Promise<{
|
||||||
[key: string]: T
|
[key: string]: T
|
||||||
}> {
|
}> {
|
||||||
@@ -283,6 +289,7 @@ export class MedusaModule {
|
|||||||
container,
|
container,
|
||||||
moduleResolutions,
|
moduleResolutions,
|
||||||
logger,
|
logger,
|
||||||
|
migrationOnly,
|
||||||
})
|
})
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
errorLoading(err)
|
errorLoading(err)
|
||||||
|
|||||||
@@ -4,3 +4,5 @@ if (typeof process.env.DB_TEMP_NAME === "undefined") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
process.env.MEDUSA_REGION_DB_SCHEMA = "public"
|
process.env.MEDUSA_REGION_DB_SCHEMA = "public"
|
||||||
|
// TODO: Remove this when all modules are migrated to v2
|
||||||
|
process.env.MEDUSA_FF_MEDUSA_V2 = true
|
||||||
|
|||||||
@@ -1,28 +1,10 @@
|
|||||||
import { Modules } from "@medusajs/modules-sdk"
|
import {
|
||||||
import { ModulesSdkUtils } from "@medusajs/utils"
|
moduleDefinition,
|
||||||
|
revertMigration,
|
||||||
import * as RegionModels from "@models"
|
runMigrations,
|
||||||
|
} from "./module-definition"
|
||||||
import { moduleDefinition } from "./module-definition"
|
|
||||||
|
|
||||||
export default moduleDefinition
|
export default moduleDefinition
|
||||||
|
export { revertMigration, runMigrations }
|
||||||
const migrationScriptOptions = {
|
|
||||||
moduleName: Modules.REGION,
|
|
||||||
models: RegionModels,
|
|
||||||
pathToMigrations: __dirname + "/migrations",
|
|
||||||
}
|
|
||||||
|
|
||||||
export const runMigrations = ModulesSdkUtils.buildMigrationScript(
|
|
||||||
migrationScriptOptions
|
|
||||||
)
|
|
||||||
export const revertMigration = ModulesSdkUtils.buildRevertMigrationScript(
|
|
||||||
migrationScriptOptions
|
|
||||||
)
|
|
||||||
|
|
||||||
export * from "./initialize"
|
export * from "./initialize"
|
||||||
export * from "./loaders"
|
|
||||||
export * from "./models"
|
|
||||||
export * from "./services"
|
|
||||||
export * from "./types"
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
|||||||
import { IRegionModuleService, LoaderOptions } from "@medusajs/types"
|
import { IRegionModuleService, LoaderOptions } from "@medusajs/types"
|
||||||
|
|
||||||
export default async ({ container }: LoaderOptions): Promise<void> => {
|
export default async ({ container }: LoaderOptions): Promise<void> => {
|
||||||
const service: IRegionModuleService = container.resolve(ModuleRegistrationName.REGION)
|
const service: IRegionModuleService = container.resolve(
|
||||||
await service.createDefaultCountriesAndCurrencies()
|
ModuleRegistrationName.REGION
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Remove when legacy modules have been migrated
|
||||||
|
if (!!process.env.MEDUSA_FF_MEDUSA_V2) {
|
||||||
|
await service.createDefaultCountriesAndCurrencies()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { generatePostgresAlterColummnIfExistStatement } from "@medusajs/utils"
|
||||||
import { Migration } from "@mikro-orm/migrations"
|
import { Migration } from "@mikro-orm/migrations"
|
||||||
|
|
||||||
export class RegionModuleSetup20240205173216 extends Migration {
|
export class RegionModuleSetup20240205173216 extends Migration {
|
||||||
@@ -27,6 +28,13 @@ CREATE TABLE IF NOT EXISTS "region_currency" (
|
|||||||
-- Adjust "region" table
|
-- Adjust "region" table
|
||||||
ALTER TABLE "region" DROP CONSTRAINT IF EXISTS "FK_3bdd5896ec93be2f1c62a3309a5";
|
ALTER TABLE "region" DROP CONSTRAINT IF EXISTS "FK_3bdd5896ec93be2f1c62a3309a5";
|
||||||
ALTER TABLE "region" DROP CONSTRAINT IF EXISTS "FK_91f88052197680f9790272aaf5b";
|
ALTER TABLE "region" DROP CONSTRAINT IF EXISTS "FK_91f88052197680f9790272aaf5b";
|
||||||
|
|
||||||
|
${generatePostgresAlterColummnIfExistStatement(
|
||||||
|
"region",
|
||||||
|
["tax_rate", "gift_cards_taxable", "automatic_taxes", "includes_tax"],
|
||||||
|
"DROP NOT NULL"
|
||||||
|
)}
|
||||||
|
|
||||||
ALTER TABLE "region" ADD CONSTRAINT "region_currency_code_foreign" FOREIGN KEY ("currency_code") REFERENCES "region_currency" ("code") ON UPDATE CASCADE;
|
ALTER TABLE "region" ADD CONSTRAINT "region_currency_code_foreign" FOREIGN KEY ("currency_code") REFERENCES "region_currency" ("code") ON UPDATE CASCADE;
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS "IDX_region_currency_code" ON "region" ("currency_code");
|
CREATE INDEX IF NOT EXISTS "IDX_region_currency_code" ON "region" ("currency_code");
|
||||||
|
|||||||
@@ -1,14 +1,32 @@
|
|||||||
import { ModuleExports } from "@medusajs/types"
|
import { ModuleExports } from "@medusajs/types"
|
||||||
import { RegionModuleService } from "@services"
|
import { RegionModuleService } from "@services"
|
||||||
|
|
||||||
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
|
import { ModulesSdkUtils } from "@medusajs/utils"
|
||||||
|
import * as RegionModels from "@models"
|
||||||
import loadConnection from "./loaders/connection"
|
import loadConnection from "./loaders/connection"
|
||||||
import loadContainer from "./loaders/container"
|
import loadContainer from "./loaders/container"
|
||||||
import loadDefaults from "./loaders/defaults"
|
import loadDefaults from "./loaders/defaults"
|
||||||
|
|
||||||
|
const migrationScriptOptions = {
|
||||||
|
moduleName: Modules.REGION,
|
||||||
|
models: RegionModels,
|
||||||
|
pathToMigrations: __dirname + "/migrations",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const runMigrations = ModulesSdkUtils.buildMigrationScript(
|
||||||
|
migrationScriptOptions
|
||||||
|
)
|
||||||
|
export const revertMigration = ModulesSdkUtils.buildRevertMigrationScript(
|
||||||
|
migrationScriptOptions
|
||||||
|
)
|
||||||
|
|
||||||
const service = RegionModuleService
|
const service = RegionModuleService
|
||||||
const loaders = [loadContainer, loadConnection, loadDefaults] as any
|
const loaders = [loadContainer, loadConnection, loadDefaults] as any
|
||||||
|
|
||||||
export const moduleDefinition: ModuleExports = {
|
export const moduleDefinition: ModuleExports = {
|
||||||
service,
|
service,
|
||||||
loaders,
|
loaders,
|
||||||
|
runMigrations,
|
||||||
|
revertMigration,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ export default class RegionModuleService<
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const [countries, count] = await this.countryService_.listAndCount(
|
const [countries, count] = await this.countryService_.listAndCount(
|
||||||
{},
|
{},
|
||||||
{ select: ["id", "iso_2"], take: COUNTRIES_LIMIT },
|
{ select: ["iso_2"], take: COUNTRIES_LIMIT },
|
||||||
sharedContext
|
sharedContext
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BaseFilterable } from "../dal"
|
import { BaseFilterable, OperatorMap } from "../dal"
|
||||||
|
|
||||||
export interface RegionDTO {
|
export interface RegionDTO {
|
||||||
id: string
|
id: string
|
||||||
@@ -6,6 +6,9 @@ export interface RegionDTO {
|
|||||||
currency_code: string
|
currency_code: string
|
||||||
currency: RegionCurrencyDTO
|
currency: RegionCurrencyDTO
|
||||||
countries: CountryDTO[]
|
countries: CountryDTO[]
|
||||||
|
metadata?: Record<string, any>
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CountryDTO {
|
export interface CountryDTO {
|
||||||
@@ -19,8 +22,12 @@ export interface CountryDTO {
|
|||||||
|
|
||||||
export interface FilterableRegionProps
|
export interface FilterableRegionProps
|
||||||
extends BaseFilterable<FilterableRegionProps> {
|
extends BaseFilterable<FilterableRegionProps> {
|
||||||
id?: string[]
|
id?: string[] | string
|
||||||
name?: string[]
|
name?: string | OperatorMap<string>
|
||||||
|
currency_code?: string | OperatorMap<string>
|
||||||
|
metadata?: Record<string, unknown> | OperatorMap<Record<string, unknown>>
|
||||||
|
created_at?: OperatorMap<string>
|
||||||
|
updated_at?: OperatorMap<string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RegionCountryDTO {
|
export interface RegionCountryDTO {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
export function generatePostgresAlterColummnIfExistStatement(
|
||||||
|
tableName: string,
|
||||||
|
columns: string[],
|
||||||
|
alterExpression: string
|
||||||
|
) {
|
||||||
|
let script = `
|
||||||
|
DO $$
|
||||||
|
DECLARE
|
||||||
|
current_column text;
|
||||||
|
BEGIN`
|
||||||
|
|
||||||
|
columns.forEach((column) => {
|
||||||
|
script += `
|
||||||
|
current_column := '${column}';
|
||||||
|
IF EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM information_schema.columns
|
||||||
|
WHERE table_name = '${tableName}'
|
||||||
|
AND column_name = current_column
|
||||||
|
) THEN
|
||||||
|
EXECUTE format('ALTER TABLE %I ALTER COLUMN %I ${alterExpression}', '${tableName}', current_column);
|
||||||
|
ELSE
|
||||||
|
RAISE NOTICE 'Column % does not exist or alteration condition not met.', current_column;
|
||||||
|
END IF;`
|
||||||
|
})
|
||||||
|
|
||||||
|
script += `
|
||||||
|
END$$;
|
||||||
|
`
|
||||||
|
|
||||||
|
return script
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
export * from "./alter-columns-helper"
|
||||||
export * from "./array-difference"
|
export * from "./array-difference"
|
||||||
export * from "./build-query"
|
export * from "./build-query"
|
||||||
export * from "./camel-to-snake-case"
|
export * from "./camel-to-snake-case"
|
||||||
@@ -45,3 +46,4 @@ export * from "./to-pascal-case"
|
|||||||
export * from "./transaction"
|
export * from "./transaction"
|
||||||
export * from "./upper-case-first"
|
export * from "./upper-case-first"
|
||||||
export * from "./wrap-handler"
|
export * from "./wrap-handler"
|
||||||
|
|
||||||
|
|||||||
@@ -8605,7 +8605,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@medusajs/region@workspace:packages/region":
|
"@medusajs/region@workspace:^, @medusajs/region@workspace:packages/region":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@medusajs/region@workspace:packages/region"
|
resolution: "@medusajs/region@workspace:packages/region"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -31573,6 +31573,7 @@ __metadata:
|
|||||||
"@medusajs/pricing": "workspace:^"
|
"@medusajs/pricing": "workspace:^"
|
||||||
"@medusajs/product": "workspace:^"
|
"@medusajs/product": "workspace:^"
|
||||||
"@medusajs/promotion": "workspace:^"
|
"@medusajs/promotion": "workspace:^"
|
||||||
|
"@medusajs/region": "workspace:^"
|
||||||
"@medusajs/types": "workspace:^"
|
"@medusajs/types": "workspace:^"
|
||||||
"@medusajs/utils": "workspace:^"
|
"@medusajs/utils": "workspace:^"
|
||||||
babel-preset-medusa-package: "*"
|
babel-preset-medusa-package: "*"
|
||||||
|
|||||||
Reference in New Issue
Block a user