Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions packages/core/e2e/product.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,47 @@ describe('Product resolver', () => {
),
);

// #4884 — concurrent updates adding the same not-yet-existing language must not
// create two translation rows for that (product, languageCode) pair
it('concurrent updates adding the same new language do not create duplicate translations', async () => {
const { createProduct } = await adminClient.query(createProductDocument, {
input: {
translations: [
{
languageCode: LanguageCode.en,
name: 'en Concurrent Potato',
slug: 'en-concurrent-potato',
description: 'A potato',
},
],
},
});

const input = {
id: createProduct.id,
translations: [
{
languageCode: LanguageCode.de,
name: 'de Concurrent Potato',
slug: 'de-concurrent-potato',
description: 'Ein Erdapfel',
},
],
};

await Promise.all([
adminClient.query(updateProductDocument, { input }),
adminClient.query(updateProductDocument, { input }),
]);

const { product } = await adminClient.query(getProductWithVariantsDocument, {
id: createProduct.id,
});
productGuard.assertSuccess(product);
const deTranslations = product.translations.filter(t => t.languageCode === LanguageCode.de);
expect(deTranslations.length).toBe(1);
});

it('addOptionGroupToProduct adds an option group', async () => {
const optionGroup = await createOptionGroup('Quark-type', ['Charm', 'Strange']);
const result = await adminClient.query(addOptionGroupToProductDocument, {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomApiKeyFieldsTranslation } from '../custom-entity-fields';
import { ApiKey } from './api-key.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class ApiKeyTranslation extends VendureEntity implements Translation<ApiKey>, HasCustomFields {
constructor(input?: DeepPartial<Translation<ApiKey>>) {
super(input);
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/entity/asset/asset-translation.entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomAssetFieldsTranslation } from '../custom-entity-fields';
import { Asset } from './asset.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class AssetTranslation extends VendureEntity implements Translation<Asset>, HasCustomFields {
constructor(input?: DeepPartial<Translation<Asset>>) {
super(input);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomCollectionFieldsTranslation } from '../custom-entity-fields';
import { Collection } from './collection.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class CollectionTranslation extends VendureEntity implements Translation<Collection>, HasCustomFields {
constructor(input?: DeepPartial<Translation<Collection>>) {
super(input);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { VendureEntity } from '../base/base.entity';
Expand All @@ -9,6 +9,7 @@ import { CustomFacetValueFieldsTranslation } from '../custom-entity-fields';
import { FacetValue } from './facet-value.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class FacetValueTranslation extends VendureEntity implements Translation<FacetValue> {
constructor(input?: DeepPartial<Translation<FacetValue>>) {
super(input);
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/entity/facet/facet-translation.entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomFacetFieldsTranslation } from '../custom-entity-fields';
import { Facet } from './facet.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class FacetTranslation extends VendureEntity implements Translation<Facet>, HasCustomFields {
constructor(input?: DeepPartial<Translation<FacetTranslation>>) {
super(input);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomPaymentMethodFieldsTranslation } from '../custom-entity-fields';
import { PaymentMethod } from './payment-method.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class PaymentMethodTranslation
extends VendureEntity
implements Translation<PaymentMethod>, HasCustomFields
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomProductOptionGroupFieldsTranslation } from '../custom-entity-fiel
import { ProductOptionGroup } from './product-option-group.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class ProductOptionGroupTranslation
extends VendureEntity
implements Translation<ProductOptionGroup>, HasCustomFields
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomProductOptionFieldsTranslation } from '../custom-entity-fields';
import { ProductOption } from './product-option.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class ProductOptionTranslation
extends VendureEntity
implements Translation<ProductOption>, HasCustomFields
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomProductVariantFieldsTranslation } from '../custom-entity-fields';
import { ProductVariant } from './product-variant.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class ProductVariantTranslation
extends VendureEntity
implements Translation<ProductVariant>, HasCustomFields
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomProductFieldsTranslation } from '../custom-entity-fields';
import { Product } from './product.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class ProductTranslation extends VendureEntity implements Translation<Product>, HasCustomFields {
constructor(input?: DeepPartial<Translation<Product>>) {
super(input);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomPromotionFieldsTranslation } from '../custom-entity-fields';
import { Promotion } from './promotion.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class PromotionTranslation extends VendureEntity implements Translation<Promotion>, HasCustomFields {
constructor(input?: DeepPartial<Translation<Promotion>>) {
super(input);
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/entity/region/region-translation.entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -10,6 +10,7 @@ import { CustomRegionFieldsTranslation } from '../custom-entity-fields';
import { Region } from './region.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class RegionTranslation extends VendureEntity implements Translation<Region>, HasCustomFields {
constructor(input?: DeepPartial<Translation<RegionTranslation>>) {
super(input);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { LanguageCode } from '@vendure/common/lib/generated-types';
import { DeepPartial } from '@vendure/common/lib/shared-types';
import { Column, Entity, Index, ManyToOne } from 'typeorm';
import { Column, Entity, Index, ManyToOne, Unique } from 'typeorm';

import { Translation } from '../../common/types/locale-types';
import { HasCustomFields } from '../../config/custom-field/custom-field-types';
Expand All @@ -11,6 +11,7 @@ import { Product } from '../product/product.entity';
import { ShippingMethod } from './shipping-method.entity';

@Entity()
@Unique(['languageCode', 'base'])
export class ShippingMethodTranslation
extends VendureEntity
implements Translation<ShippingMethod>, HasCustomFields
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/migration-utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { migrateAssetTranslationData } from './v3_6_asset_translations';
export { migrateProductOptionGroupData } from './v3_6_shared_option_groups';
export { deduplicateTranslations } from './translation-deduplication';
Loading
Loading