chore(): Remove default_locale from StoreLocale (#14300)
## Summary
**What** — What changes are introduced in this PR?
Remove `default_locale` from Store <> Locale relation
**Why** — Why are these changes relevant or necessary?
*Please provide answer here*
**How** — How have these changes been implemented?
*Please provide answer here*
**Testing** — How have these changes been tested, or how can the reviewer test the feature?
*Please provide answer here*
---
## Examples
Provide examples or code snippets that demonstrate how this feature works, or how it can be used in practice.
This helps with documentation and ensures maintainers can quickly understand and verify the change.
```ts
// Example usage
```
---
## Checklist
Please ensure the following before requesting a review:
- [ ] I have added a **changeset** for this PR
- Every non-breaking change should be marked as a **patch**
- To add a changeset, run `yarn changeset` and follow the prompts
- [ ] The changes are covered by relevant **tests**
- [ ] I have verified the code works as intended locally
- [ ] I have linked the related issue(s) if applicable
---
## Additional Context
Add any additional context, related issues, or references that might help the reviewer understand this PR.
Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
9
.changeset/plain-bobcats-glow.md
Normal file
9
.changeset/plain-bobcats-glow.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
"@medusajs/dashboard": patch
|
||||
"@medusajs/framework": patch
|
||||
"@medusajs/store": patch
|
||||
"@medusajs/types": patch
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
chore(): Remove default_locale from StoreLocale
|
||||
@@ -1,11 +1,11 @@
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import { Modules, ProductStatus } from "@medusajs/utils"
|
||||
import {
|
||||
createAdminUser,
|
||||
generatePublishableKey,
|
||||
generateStoreHeaders,
|
||||
} from "../../../../helpers/create-admin-user"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
|
||||
jest.setTimeout(100000)
|
||||
|
||||
@@ -63,7 +63,7 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
await storeModule.updateStores(defaultStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "de-DE" },
|
||||
],
|
||||
|
||||
@@ -45,7 +45,7 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
await storeModule.updateStores(defaultStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "de-DE" },
|
||||
],
|
||||
|
||||
@@ -61,7 +61,7 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
await storeModule.updateStores(defaultStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "de-DE" },
|
||||
],
|
||||
|
||||
@@ -60,7 +60,7 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
await storeModule.updateStores(defaultStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "de-DE" },
|
||||
],
|
||||
|
||||
@@ -62,7 +62,7 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
await storeModule.updateStores(defaultStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "de-DE" },
|
||||
],
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { medusaIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import { Modules } from "@medusajs/utils"
|
||||
import {
|
||||
adminHeaders,
|
||||
createAdminUser,
|
||||
} from "../../../../helpers/create-admin-user"
|
||||
import { MedusaContainer } from "@medusajs/types"
|
||||
import { Modules } from "@medusajs/utils"
|
||||
|
||||
jest.setTimeout(100000)
|
||||
|
||||
@@ -32,7 +32,7 @@ medusaIntegrationTestRunner({
|
||||
)
|
||||
await storeModule.updateStores(defaultStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "de-DE" },
|
||||
],
|
||||
|
||||
@@ -100,19 +100,10 @@ export const AddLocalesForm = ({ store }: AddLocalesFormProps) => {
|
||||
new Set([...data.locales, ...preSelectedRows])
|
||||
) as string[]
|
||||
|
||||
let defaultLocale = store.supported_locales?.find(
|
||||
(l) => l.is_default
|
||||
)?.locale_code
|
||||
|
||||
if (!locales.includes(defaultLocale ?? "")) {
|
||||
defaultLocale = locales?.[0]
|
||||
}
|
||||
|
||||
await mutateAsync(
|
||||
{
|
||||
supported_locales: locales.map((l) => ({
|
||||
locale_code: l,
|
||||
is_default: l === defaultLocale,
|
||||
})),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -7,7 +7,6 @@ import { Link } from "react-router-dom"
|
||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
||||
import { useSalesChannel, useStockLocation } from "../../../../../hooks/api"
|
||||
import { useRegion } from "../../../../../hooks/api/regions"
|
||||
import { useFeatureFlag } from "../../../../../providers/feature-flag-provider"
|
||||
|
||||
type StoreGeneralSectionProps = {
|
||||
store: AdminStore
|
||||
@@ -15,14 +14,12 @@ type StoreGeneralSectionProps = {
|
||||
|
||||
export const StoreGeneralSection = ({ store }: StoreGeneralSectionProps) => {
|
||||
const { t } = useTranslation()
|
||||
const isTranslationsEnabled = useFeatureFlag("translation")
|
||||
|
||||
const { region } = useRegion(store.default_region_id!, undefined, {
|
||||
enabled: !!store.default_region_id,
|
||||
})
|
||||
|
||||
const defaultCurrency = store.supported_currencies?.find((c) => c.is_default)
|
||||
const defaultLocale = store.supported_locales?.find((l) => l.is_default)
|
||||
|
||||
const { sales_channel } = useSalesChannel(store.default_sales_channel_id!, {
|
||||
enabled: !!store.default_sales_channel_id,
|
||||
@@ -88,27 +85,6 @@ export const StoreGeneralSection = ({ store }: StoreGeneralSectionProps) => {
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
{isTranslationsEnabled && (
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
||||
<Text size="small" leading="compact" weight="plus">
|
||||
{t("store.defaultLocale")}
|
||||
</Text>
|
||||
{defaultLocale ? (
|
||||
<div className="flex items-center gap-x-2">
|
||||
<Badge size="2xsmall">
|
||||
{defaultLocale.locale_code?.toUpperCase()}
|
||||
</Badge>
|
||||
<Text size="small" leading="compact">
|
||||
{defaultLocale.locale?.name}
|
||||
</Text>
|
||||
</div>
|
||||
) : (
|
||||
<Text size="small" leading="compact">
|
||||
-
|
||||
</Text>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="text-ui-fg-subtle grid grid-cols-2 px-6 py-4">
|
||||
<Text size="small" leading="compact" weight="plus">
|
||||
{t("store.defaultRegion")}
|
||||
|
||||
@@ -60,8 +60,6 @@ export const StoreLocaleSection = ({ store }: StoreLocaleSectionProps) => {
|
||||
meta: {
|
||||
storeId: store.id,
|
||||
supportedLocales: store.supported_locales,
|
||||
defaultLocaleCode: store.supported_locales?.find((l) => l.is_default)
|
||||
?.locale_code,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -165,12 +163,10 @@ const LocaleActions = ({
|
||||
storeId,
|
||||
locale,
|
||||
supportedLocales,
|
||||
defaultLocaleCode,
|
||||
}: {
|
||||
storeId: string
|
||||
locale: HttpTypes.AdminLocale
|
||||
supportedLocales: HttpTypes.AdminStoreLocale[]
|
||||
defaultLocaleCode: string
|
||||
}) => {
|
||||
const { mutateAsync } = useUpdateStore(storeId)
|
||||
const { t } = useTranslation()
|
||||
@@ -218,7 +214,6 @@ const LocaleActions = ({
|
||||
icon: <Trash />,
|
||||
label: t("actions.remove"),
|
||||
onClick: handleRemove,
|
||||
disabled: locale.code === defaultLocaleCode,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -267,9 +262,7 @@ const useColumns = () => {
|
||||
columnHelper.display({
|
||||
id: "actions",
|
||||
cell: ({ row, table }) => {
|
||||
const { supportedLocales, storeId, defaultLocaleCode } = table.options
|
||||
.meta as {
|
||||
defaultLocaleCode: string
|
||||
const { supportedLocales, storeId } = table.options.meta as {
|
||||
supportedLocales: HttpTypes.AdminStoreLocale[]
|
||||
storeId: string
|
||||
}
|
||||
@@ -279,7 +272,6 @@ const useColumns = () => {
|
||||
storeId={storeId}
|
||||
locale={row.original}
|
||||
supportedLocales={supportedLocales}
|
||||
defaultLocaleCode={defaultLocaleCode}
|
||||
/>
|
||||
)
|
||||
},
|
||||
|
||||
@@ -13,7 +13,6 @@ import { useUpdateStore } from "../../../../../hooks/api/store"
|
||||
import { useComboboxData } from "../../../../../hooks/use-combobox-data"
|
||||
import { sdk } from "../../../../../lib/client"
|
||||
import { useDocumentDirection } from "../../../../../hooks/use-document-direction"
|
||||
import { useFeatureFlag } from "../../../../../providers/feature-flag-provider"
|
||||
|
||||
type EditStoreFormProps = {
|
||||
store: HttpTypes.AdminStore
|
||||
@@ -22,7 +21,6 @@ type EditStoreFormProps = {
|
||||
const EditStoreSchema = z.object({
|
||||
name: z.string().min(1),
|
||||
default_currency_code: z.string().optional(),
|
||||
default_locale_code: z.string().optional(),
|
||||
default_region_id: z.string().optional(),
|
||||
default_sales_channel_id: z.string().optional(),
|
||||
default_location_id: z.string().optional(),
|
||||
@@ -30,16 +28,12 @@ const EditStoreSchema = z.object({
|
||||
|
||||
export const EditStoreForm = ({ store }: EditStoreFormProps) => {
|
||||
const { t } = useTranslation()
|
||||
const isTranslationsEnabled = useFeatureFlag("translation")
|
||||
const { handleSuccess } = useRouteModal()
|
||||
const direction = useDocumentDirection()
|
||||
const form = useForm<z.infer<typeof EditStoreSchema>>({
|
||||
defaultValues: {
|
||||
name: store.name,
|
||||
default_region_id: store.default_region_id || undefined,
|
||||
default_locale_code:
|
||||
store.supported_locales?.find((l) => l.is_default)?.locale_code ||
|
||||
undefined,
|
||||
default_currency_code:
|
||||
store.supported_currencies?.find((c) => c.is_default)?.currency_code ||
|
||||
undefined,
|
||||
@@ -79,14 +73,10 @@ export const EditStoreForm = ({ store }: EditStoreFormProps) => {
|
||||
})
|
||||
|
||||
const handleSubmit = form.handleSubmit(async (values) => {
|
||||
const { default_currency_code, default_locale_code, ...rest } = values
|
||||
const { default_currency_code, ...rest } = values
|
||||
|
||||
const normalizedMutation: HttpTypes.AdminUpdateStore = {
|
||||
...rest,
|
||||
supported_locales: store.supported_locales?.map((l) => ({
|
||||
...l,
|
||||
is_default: l.locale_code === default_locale_code,
|
||||
})),
|
||||
supported_currencies: store.supported_currencies?.map((c) => ({
|
||||
...c,
|
||||
is_default: c.currency_code === default_currency_code,
|
||||
@@ -156,40 +146,6 @@ export const EditStoreForm = ({ store }: EditStoreFormProps) => {
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{isTranslationsEnabled && (
|
||||
<Form.Field
|
||||
control={form.control}
|
||||
name="default_locale_code"
|
||||
render={({ field: { onChange, ...field } }) => {
|
||||
return (
|
||||
<Form.Item>
|
||||
<Form.Label>{t("store.defaultLocale")}</Form.Label>
|
||||
<Form.Control>
|
||||
<Select
|
||||
dir={direction}
|
||||
{...field}
|
||||
onValueChange={onChange}
|
||||
>
|
||||
<Select.Trigger ref={field.ref}>
|
||||
<Select.Value />
|
||||
</Select.Trigger>
|
||||
<Select.Content>
|
||||
{store.supported_locales?.map((locale) => (
|
||||
<Select.Item
|
||||
key={locale.locale_code}
|
||||
value={locale.locale_code}
|
||||
>
|
||||
{locale.locale_code}
|
||||
</Select.Item>
|
||||
))}
|
||||
</Select.Content>
|
||||
</Select>
|
||||
</Form.Control>
|
||||
</Form.Item>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Form.Field
|
||||
control={form.control}
|
||||
name="default_region_id"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ContainerRegistrationKeys, normalizeLocale } from "@medusajs/utils"
|
||||
import { normalizeLocale } from "@medusajs/utils"
|
||||
import type {
|
||||
MedusaNextFunction,
|
||||
MedusaRequest,
|
||||
@@ -35,30 +35,5 @@ export async function applyLocale(
|
||||
return next()
|
||||
}
|
||||
|
||||
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
||||
const {
|
||||
data: [store],
|
||||
} = await query.graph(
|
||||
{
|
||||
entity: "store",
|
||||
fields: ["id", "supported_locales"],
|
||||
pagination: {
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
cache: {
|
||||
enable: true,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if (store?.supported_locales?.length) {
|
||||
req.locale = store.supported_locales.find(
|
||||
(locale) => locale.is_default
|
||||
)?.locale_code
|
||||
return next()
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
|
||||
@@ -55,10 +55,6 @@ export interface AdminStoreLocale {
|
||||
* The ID of the store that the locale belongs to.
|
||||
*/
|
||||
store_id: string
|
||||
/**
|
||||
* Whether the locale is the default locale for the store.
|
||||
*/
|
||||
is_default: boolean
|
||||
/**
|
||||
* The locale's details.
|
||||
*/
|
||||
|
||||
@@ -26,10 +26,6 @@ export interface AdminUpdateStoreSupportedLocale {
|
||||
* The locale's BCP 47 language tag.
|
||||
*/
|
||||
locale_code: string
|
||||
/**
|
||||
* Whether this locale is the default locale in the store.
|
||||
*/
|
||||
is_default?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,10 +40,6 @@ export interface StoreLocaleDTO {
|
||||
* The locale code of the store locale.
|
||||
*/
|
||||
locale_code: string
|
||||
/**
|
||||
* Whether the locale is the default one for the store.
|
||||
*/
|
||||
is_default: boolean
|
||||
/**
|
||||
* The store ID associated with the locale.
|
||||
*/
|
||||
|
||||
@@ -14,10 +14,6 @@ export interface CreateStoreLocaleDTO {
|
||||
* The locale code of the store locale.
|
||||
*/
|
||||
locale_code: string
|
||||
/**
|
||||
* Whether the locale is the default one for the store.
|
||||
*/
|
||||
is_default?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,6 @@ export const AdminUpdateStore = z.object({
|
||||
.array(
|
||||
z.object({
|
||||
locale_code: z.string(),
|
||||
is_default: z.boolean().optional(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
|
||||
@@ -8,7 +8,7 @@ export const createStoreFixture: StoreTypes.CreateStoreDTO = {
|
||||
],
|
||||
supported_locales: [
|
||||
{ locale_code: "fr-FR" },
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "en-US" },
|
||||
],
|
||||
default_sales_channel_id: "test-sales-channel",
|
||||
default_region_id: "test-region",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IStoreModuleService } from "@medusajs/framework/types"
|
||||
import { Module, Modules } from "@medusajs/framework/utils"
|
||||
import { StoreModuleService } from "@services"
|
||||
import { moduleIntegrationTestRunner } from "@medusajs/test-utils"
|
||||
import { StoreModuleService } from "@services"
|
||||
import { createStoreFixture } from "../__fixtures__"
|
||||
|
||||
jest.setTimeout(100000)
|
||||
@@ -92,19 +92,6 @@ moduleIntegrationTestRunner<IStoreModuleService>({
|
||||
"There should be a default currency set for the store"
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail to get created if there is no default locale", async function () {
|
||||
const err = await service
|
||||
.createStores({
|
||||
...createStoreFixture,
|
||||
supported_locales: [{ locale_code: "en-US" }],
|
||||
})
|
||||
.catch((err) => err.message)
|
||||
|
||||
expect(err).toEqual(
|
||||
"There should be a default locale set for the store"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("upserting a store", () => {
|
||||
@@ -160,19 +147,6 @@ moduleIntegrationTestRunner<IStoreModuleService>({
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail updating locales without a default one", async function () {
|
||||
const createdStore = await service.createStores(createStoreFixture)
|
||||
const updateErr = await service
|
||||
.updateStores(createdStore.id, {
|
||||
supported_locales: [{ locale_code: "en-US" }],
|
||||
})
|
||||
.catch((err) => err.message)
|
||||
|
||||
expect(updateErr).toEqual(
|
||||
"There should be a default locale set for the store"
|
||||
)
|
||||
})
|
||||
|
||||
it("should fail updating currencies where a duplicate currency code exists", async function () {
|
||||
const createdStore = await service.createStores(createStoreFixture)
|
||||
const updateErr = await service
|
||||
@@ -214,20 +188,6 @@ moduleIntegrationTestRunner<IStoreModuleService>({
|
||||
|
||||
expect(updateErr).toEqual("Only one default currency is allowed")
|
||||
})
|
||||
|
||||
it("should fail updating locales where there is more than 1 default locale", async function () {
|
||||
const createdStore = await service.createStores(createStoreFixture)
|
||||
const updateErr = await service
|
||||
.updateStores(createdStore.id, {
|
||||
supported_locales: [
|
||||
{ locale_code: "en-US", is_default: true },
|
||||
{ locale_code: "fr-FR", is_default: true },
|
||||
],
|
||||
})
|
||||
.catch((err) => err.message)
|
||||
|
||||
expect(updateErr).toEqual("Only one default locale is allowed")
|
||||
})
|
||||
})
|
||||
|
||||
describe("deleting a store", () => {
|
||||
|
||||
@@ -263,16 +263,6 @@
|
||||
"nullable": false,
|
||||
"mappedType": "text"
|
||||
},
|
||||
"is_default": {
|
||||
"name": "is_default",
|
||||
"type": "boolean",
|
||||
"unsigned": false,
|
||||
"autoincrement": false,
|
||||
"primary": false,
|
||||
"nullable": false,
|
||||
"default": "false",
|
||||
"mappedType": "boolean"
|
||||
},
|
||||
"store_id": {
|
||||
"name": "store_id",
|
||||
"type": "text",
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Migration } from '@mikro-orm/migrations';
|
||||
|
||||
export class Migration20251212161429 extends Migration {
|
||||
|
||||
override async up(): Promise<void> {
|
||||
this.addSql(`alter table if exists "store_locale" drop column if exists "is_default";`);
|
||||
}
|
||||
|
||||
override async down(): Promise<void> {
|
||||
this.addSql(`alter table if exists "store_locale" add column if not exists "is_default" boolean not null default false;`);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import Store from "./store"
|
||||
const StoreLocale = model.define("StoreLocale", {
|
||||
id: model.id({ prefix: "stloc" }).primaryKey(),
|
||||
locale_code: model.text().searchable(),
|
||||
is_default: model.boolean().default(false),
|
||||
store: model
|
||||
.belongsTo(() => Store, {
|
||||
mappedBy: "supported_locales",
|
||||
|
||||
@@ -227,45 +227,18 @@ export default class StoreModuleService
|
||||
) {
|
||||
for (const store of stores) {
|
||||
if (store.supported_currencies?.length) {
|
||||
StoreModuleService.validateSupportedItems(
|
||||
store.supported_currencies,
|
||||
(c) => c.currency_code,
|
||||
StoreModuleService.validateUnique(
|
||||
store.supported_currencies.map((currency) => currency.currency_code),
|
||||
"currency"
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: If we are protecting this module behind a feature flag, we should check if the feature flag is enabled before validating the locales.
|
||||
if (store.supported_locales?.length) {
|
||||
StoreModuleService.validateSupportedItems(
|
||||
store.supported_locales,
|
||||
(l) => l.locale_code,
|
||||
"locale"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static validateSupportedItems<T extends { is_default?: boolean }>(
|
||||
items: T[],
|
||||
getCode: (item: T) => string,
|
||||
typeName: string
|
||||
) {
|
||||
const duplicates = getDuplicates(items.map(getCode))
|
||||
|
||||
if (duplicates.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Duplicate ${typeName} codes: ${duplicates.join(", ")}`
|
||||
)
|
||||
}
|
||||
|
||||
let seenDefault = false
|
||||
items.forEach((item) => {
|
||||
if (item.is_default) {
|
||||
store.supported_currencies.forEach((currency) => {
|
||||
if (currency.is_default) {
|
||||
if (seenDefault) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Only one default ${typeName} is allowed`
|
||||
`Only one default currency is allowed`
|
||||
)
|
||||
}
|
||||
seenDefault = true
|
||||
@@ -275,7 +248,27 @@ export default class StoreModuleService
|
||||
if (!seenDefault) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`There should be a default ${typeName} set for the store`
|
||||
`There should be a default currency set for the store`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (store.supported_locales?.length) {
|
||||
StoreModuleService.validateUnique(
|
||||
store.supported_locales.map((locale) => locale.locale_code),
|
||||
"locale"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static validateUnique = (items: string[], fieldName: string) => {
|
||||
const duplicates = getDuplicates(items)
|
||||
|
||||
if (duplicates.length) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.INVALID_DATA,
|
||||
`Duplicate ${fieldName} codes: ${duplicates.join(", ")}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user