diff --git a/.changeset/plain-bobcats-glow.md b/.changeset/plain-bobcats-glow.md new file mode 100644 index 0000000000..27848850b0 --- /dev/null +++ b/.changeset/plain-bobcats-glow.md @@ -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 diff --git a/integration-tests/http/__tests__/cart/store/cart-translation.spec.ts b/integration-tests/http/__tests__/cart/store/cart-translation.spec.ts index 635434fd70..11d5c0467b 100644 --- a/integration-tests/http/__tests__/cart/store/cart-translation.spec.ts +++ b/integration-tests/http/__tests__/cart/store/cart-translation.spec.ts @@ -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" }, ], diff --git a/integration-tests/http/__tests__/draft-order/admin/draft-order-translation.spec.ts b/integration-tests/http/__tests__/draft-order/admin/draft-order-translation.spec.ts index 795094c047..04f9f3823e 100644 --- a/integration-tests/http/__tests__/draft-order/admin/draft-order-translation.spec.ts +++ b/integration-tests/http/__tests__/draft-order/admin/draft-order-translation.spec.ts @@ -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" }, ], diff --git a/integration-tests/http/__tests__/exchanges/exchange-translation.spec.ts b/integration-tests/http/__tests__/exchanges/exchange-translation.spec.ts index f440a9acea..cfa04ad088 100644 --- a/integration-tests/http/__tests__/exchanges/exchange-translation.spec.ts +++ b/integration-tests/http/__tests__/exchanges/exchange-translation.spec.ts @@ -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" }, ], diff --git a/integration-tests/http/__tests__/order-edits/order-edit-translation.spec.ts b/integration-tests/http/__tests__/order-edits/order-edit-translation.spec.ts index d0cdb3d12b..35d0d2d284 100644 --- a/integration-tests/http/__tests__/order-edits/order-edit-translation.spec.ts +++ b/integration-tests/http/__tests__/order-edits/order-edit-translation.spec.ts @@ -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" }, ], diff --git a/integration-tests/http/__tests__/order/admin/order-translation.spec.ts b/integration-tests/http/__tests__/order/admin/order-translation.spec.ts index 78b2a5f995..dc4ce1fd4a 100644 --- a/integration-tests/http/__tests__/order/admin/order-translation.spec.ts +++ b/integration-tests/http/__tests__/order/admin/order-translation.spec.ts @@ -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" }, ], diff --git a/integration-tests/http/__tests__/translation/admin/translation.spec.ts b/integration-tests/http/__tests__/translation/admin/translation.spec.ts index 58b47d8587..859b38c28f 100644 --- a/integration-tests/http/__tests__/translation/admin/translation.spec.ts +++ b/integration-tests/http/__tests__/translation/admin/translation.spec.ts @@ -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" }, ], diff --git a/packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx b/packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx index 0785c02884..097cd27df8 100644 --- a/packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx +++ b/packages/admin/dashboard/src/routes/store/store-add-locales/components/add-locales-form/add-locales-form.tsx @@ -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, })), }, { diff --git a/packages/admin/dashboard/src/routes/store/store-detail/components/store-general-section/store-general-section.tsx b/packages/admin/dashboard/src/routes/store/store-detail/components/store-general-section/store-general-section.tsx index 3c2140dc28..a590dde31b 100644 --- a/packages/admin/dashboard/src/routes/store/store-detail/components/store-general-section/store-general-section.tsx +++ b/packages/admin/dashboard/src/routes/store/store-detail/components/store-general-section/store-general-section.tsx @@ -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) => { )} - {isTranslationsEnabled && ( -
- - {t("store.defaultLocale")} - - {defaultLocale ? ( -
- - {defaultLocale.locale_code?.toUpperCase()} - - - {defaultLocale.locale?.name} - -
- ) : ( - - - - - )} -
- )}
{t("store.defaultRegion")} diff --git a/packages/admin/dashboard/src/routes/store/store-detail/components/store-locale-section/store-locale-section.tsx b/packages/admin/dashboard/src/routes/store/store-detail/components/store-locale-section/store-locale-section.tsx index 28317e201a..01a47e538c 100644 --- a/packages/admin/dashboard/src/routes/store/store-detail/components/store-locale-section/store-locale-section.tsx +++ b/packages/admin/dashboard/src/routes/store/store-detail/components/store-locale-section/store-locale-section.tsx @@ -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: , 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} /> ) }, diff --git a/packages/admin/dashboard/src/routes/store/store-edit/components/edit-store-form/edit-store-form.tsx b/packages/admin/dashboard/src/routes/store/store-edit/components/edit-store-form/edit-store-form.tsx index bd1bc317bf..2619b5eaea 100644 --- a/packages/admin/dashboard/src/routes/store/store-edit/components/edit-store-form/edit-store-form.tsx +++ b/packages/admin/dashboard/src/routes/store/store-edit/components/edit-store-form/edit-store-form.tsx @@ -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>({ 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 && ( - { - return ( - - {t("store.defaultLocale")} - - - - - ) - }} - /> - )} locale.is_default - )?.locale_code - return next() - } - return next() } diff --git a/packages/core/types/src/http/store/admin/entities.ts b/packages/core/types/src/http/store/admin/entities.ts index 4be4e64d4c..70c4443ecd 100644 --- a/packages/core/types/src/http/store/admin/entities.ts +++ b/packages/core/types/src/http/store/admin/entities.ts @@ -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. */ diff --git a/packages/core/types/src/http/store/admin/payloads.ts b/packages/core/types/src/http/store/admin/payloads.ts index 6c0095fc6f..8ef2bbdf3d 100644 --- a/packages/core/types/src/http/store/admin/payloads.ts +++ b/packages/core/types/src/http/store/admin/payloads.ts @@ -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 } /** diff --git a/packages/core/types/src/store/common/store.ts b/packages/core/types/src/store/common/store.ts index c157173528..9918a1cbe3 100644 --- a/packages/core/types/src/store/common/store.ts +++ b/packages/core/types/src/store/common/store.ts @@ -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. */ diff --git a/packages/core/types/src/store/mutations/store.ts b/packages/core/types/src/store/mutations/store.ts index b650ea1d73..de44998b71 100644 --- a/packages/core/types/src/store/mutations/store.ts +++ b/packages/core/types/src/store/mutations/store.ts @@ -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 } /** diff --git a/packages/medusa/src/api/admin/stores/validators.ts b/packages/medusa/src/api/admin/stores/validators.ts index a9e3cafd4e..1973d06102 100644 --- a/packages/medusa/src/api/admin/stores/validators.ts +++ b/packages/medusa/src/api/admin/stores/validators.ts @@ -35,7 +35,6 @@ export const AdminUpdateStore = z.object({ .array( z.object({ locale_code: z.string(), - is_default: z.boolean().optional(), }) ) .optional(), diff --git a/packages/modules/store/integration-tests/__fixtures__/index.ts b/packages/modules/store/integration-tests/__fixtures__/index.ts index 7088c063aa..41ca50954f 100644 --- a/packages/modules/store/integration-tests/__fixtures__/index.ts +++ b/packages/modules/store/integration-tests/__fixtures__/index.ts @@ -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", diff --git a/packages/modules/store/integration-tests/__tests__/store-module-service.spec.ts b/packages/modules/store/integration-tests/__tests__/store-module-service.spec.ts index 0d04ca15cd..26757aff67 100644 --- a/packages/modules/store/integration-tests/__tests__/store-module-service.spec.ts +++ b/packages/modules/store/integration-tests/__tests__/store-module-service.spec.ts @@ -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({ "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({ ) }) - 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({ 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", () => { diff --git a/packages/modules/store/src/migrations/.snapshot-medusa-store.json b/packages/modules/store/src/migrations/.snapshot-medusa-store.json index 30f592ce9d..a8e089c2f6 100644 --- a/packages/modules/store/src/migrations/.snapshot-medusa-store.json +++ b/packages/modules/store/src/migrations/.snapshot-medusa-store.json @@ -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", diff --git a/packages/modules/store/src/migrations/Migration20251212161429.ts b/packages/modules/store/src/migrations/Migration20251212161429.ts new file mode 100644 index 0000000000..9405ebf0fa --- /dev/null +++ b/packages/modules/store/src/migrations/Migration20251212161429.ts @@ -0,0 +1,13 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20251212161429 extends Migration { + + override async up(): Promise { + this.addSql(`alter table if exists "store_locale" drop column if exists "is_default";`); + } + + override async down(): Promise { + this.addSql(`alter table if exists "store_locale" add column if not exists "is_default" boolean not null default false;`); + } + +} diff --git a/packages/modules/store/src/models/locale.ts b/packages/modules/store/src/models/locale.ts index 88806a6f2c..cf523d312a 100644 --- a/packages/modules/store/src/models/locale.ts +++ b/packages/modules/store/src/models/locale.ts @@ -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", diff --git a/packages/modules/store/src/services/store-module-service.ts b/packages/modules/store/src/services/store-module-service.ts index 33ceafc85d..86daf8d8b8 100644 --- a/packages/modules/store/src/services/store-module-service.ts +++ b/packages/modules/store/src/services/store-module-service.ts @@ -227,55 +227,48 @@ 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" ) + + let seenDefault = false + store.supported_currencies.forEach((currency) => { + if (currency.is_default) { + if (seenDefault) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `Only one default currency is allowed` + ) + } + seenDefault = true + } + }) + + if (!seenDefault) { + throw new MedusaError( + MedusaError.Types.INVALID_DATA, + `There should be a default currency set for the store` + ) + } } - // 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, + StoreModuleService.validateUnique( + store.supported_locales.map((locale) => locale.locale_code), "locale" ) } } } - private static validateSupportedItems( - items: T[], - getCode: (item: T) => string, - typeName: string - ) { - const duplicates = getDuplicates(items.map(getCode)) + private static validateUnique = (items: string[], fieldName: string) => { + const duplicates = getDuplicates(items) 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) { - if (seenDefault) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `Only one default ${typeName} is allowed` - ) - } - seenDefault = true - } - }) - - if (!seenDefault) { - throw new MedusaError( - MedusaError.Types.INVALID_DATA, - `There should be a default ${typeName} set for the store` + `Duplicate ${fieldName} codes: ${duplicates.join(", ")}` ) } }