瀏覽代碼

feat(core): Move global stock & language settings into Channel

This allows better control for multivendor setups, so each channel can define its
own set of supported languages, currencies and stock settings
Michael Bromley 2 年之前
父節點
當前提交
2748a6e9fc

+ 15 - 0
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -352,6 +352,8 @@ export type Cancellation = Node &
     };
 
 export type Channel = Node & {
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -362,9 +364,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 
@@ -386,8 +390,10 @@ export type ChannelFilterParameter = {
     defaultCurrencyCode?: InputMaybe<StringOperators>;
     defaultLanguageCode?: InputMaybe<StringOperators>;
     id?: InputMaybe<IdOperators>;
+    outOfStockThreshold?: InputMaybe<NumberOperators>;
     pricesIncludeTax?: InputMaybe<BooleanOperators>;
     token?: InputMaybe<StringOperators>;
+    trackInventory?: InputMaybe<BooleanOperators>;
     updatedAt?: InputMaybe<DateOperators>;
 };
 
@@ -413,6 +419,7 @@ export type ChannelSortParameter = {
     code?: InputMaybe<SortOrder>;
     createdAt?: InputMaybe<SortOrder>;
     id?: InputMaybe<SortOrder>;
+    outOfStockThreshold?: InputMaybe<SortOrder>;
     token?: InputMaybe<SortOrder>;
     updatedAt?: InputMaybe<SortOrder>;
 };
@@ -679,15 +686,19 @@ export type CreateAssetInput = {
 export type CreateAssetResult = Asset | MimeTypeError;
 
 export type CreateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code: Scalars['String'];
     currencyCode: CurrencyCode;
     customFields?: InputMaybe<Scalars['JSON']>;
     defaultLanguageCode: LanguageCode;
     defaultShippingZoneId: Scalars['ID'];
     defaultTaxZoneId: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     sellerId?: InputMaybe<Scalars['ID']>;
     token: Scalars['String'];
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type CreateChannelResult = Channel | LanguageNotAvailableError;
@@ -5646,6 +5657,8 @@ export type UpdateAssetInput = {
 };
 
 export type UpdateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code?: InputMaybe<Scalars['String']>;
     currencyCode?: InputMaybe<CurrencyCode>;
     customFields?: InputMaybe<Scalars['JSON']>;
@@ -5653,9 +5666,11 @@ export type UpdateChannelInput = {
     defaultShippingZoneId?: InputMaybe<Scalars['ID']>;
     defaultTaxZoneId?: InputMaybe<Scalars['ID']>;
     id: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax?: InputMaybe<Scalars['Boolean']>;
     sellerId?: InputMaybe<Scalars['ID']>;
     token?: InputMaybe<Scalars['String']>;
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type UpdateChannelResult = Channel | LanguageNotAvailableError;

+ 4 - 0
packages/common/src/generated-shop-types.ts

@@ -145,6 +145,8 @@ export type BooleanOperators = {
 
 export type Channel = Node & {
     __typename?: 'Channel';
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -155,9 +157,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 

+ 15 - 0
packages/common/src/generated-types.ts

@@ -347,6 +347,8 @@ export type Cancellation = Node & StockMovement & {
 
 export type Channel = Node & {
   __typename?: 'Channel';
+  availableCurrencyCodes: Array<CurrencyCode>;
+  availableLanguageCodes?: Maybe<Array<LanguageCode>>;
   code: Scalars['String'];
   createdAt: Scalars['DateTime'];
   /** @deprecated Use defaultCurrencyCode instead */
@@ -357,9 +359,11 @@ export type Channel = Node & {
   defaultShippingZone?: Maybe<Zone>;
   defaultTaxZone?: Maybe<Zone>;
   id: Scalars['ID'];
+  outOfStockThreshold?: Maybe<Scalars['Int']>;
   pricesIncludeTax: Scalars['Boolean'];
   seller?: Maybe<Seller>;
   token: Scalars['String'];
+  trackInventory?: Maybe<Scalars['Boolean']>;
   updatedAt: Scalars['DateTime'];
 };
 
@@ -382,8 +386,10 @@ export type ChannelFilterParameter = {
   defaultCurrencyCode?: InputMaybe<StringOperators>;
   defaultLanguageCode?: InputMaybe<StringOperators>;
   id?: InputMaybe<IdOperators>;
+  outOfStockThreshold?: InputMaybe<NumberOperators>;
   pricesIncludeTax?: InputMaybe<BooleanOperators>;
   token?: InputMaybe<StringOperators>;
+  trackInventory?: InputMaybe<BooleanOperators>;
   updatedAt?: InputMaybe<DateOperators>;
 };
 
@@ -410,6 +416,7 @@ export type ChannelSortParameter = {
   code?: InputMaybe<SortOrder>;
   createdAt?: InputMaybe<SortOrder>;
   id?: InputMaybe<SortOrder>;
+  outOfStockThreshold?: InputMaybe<SortOrder>;
   token?: InputMaybe<SortOrder>;
   updatedAt?: InputMaybe<SortOrder>;
 };
@@ -691,15 +698,19 @@ export type CreateAssetInput = {
 export type CreateAssetResult = Asset | MimeTypeError;
 
 export type CreateChannelInput = {
+  availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+  availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
   code: Scalars['String'];
   currencyCode: CurrencyCode;
   customFields?: InputMaybe<Scalars['JSON']>;
   defaultLanguageCode: LanguageCode;
   defaultShippingZoneId: Scalars['ID'];
   defaultTaxZoneId: Scalars['ID'];
+  outOfStockThreshold?: InputMaybe<Scalars['Int']>;
   pricesIncludeTax: Scalars['Boolean'];
   sellerId?: InputMaybe<Scalars['ID']>;
   token: Scalars['String'];
+  trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type CreateChannelResult = Channel | LanguageNotAvailableError;
@@ -5968,6 +5979,8 @@ export type UpdateAssetInput = {
 };
 
 export type UpdateChannelInput = {
+  availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+  availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
   code?: InputMaybe<Scalars['String']>;
   currencyCode?: InputMaybe<CurrencyCode>;
   customFields?: InputMaybe<Scalars['JSON']>;
@@ -5975,9 +5988,11 @@ export type UpdateChannelInput = {
   defaultShippingZoneId?: InputMaybe<Scalars['ID']>;
   defaultTaxZoneId?: InputMaybe<Scalars['ID']>;
   id: Scalars['ID'];
+  outOfStockThreshold?: InputMaybe<Scalars['Int']>;
   pricesIncludeTax?: InputMaybe<Scalars['Boolean']>;
   sellerId?: InputMaybe<Scalars['ID']>;
   token?: InputMaybe<Scalars['String']>;
+  trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type UpdateChannelResult = Channel | LanguageNotAvailableError;

+ 15 - 0
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -352,6 +352,8 @@ export type Cancellation = Node &
     };
 
 export type Channel = Node & {
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -362,9 +364,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 
@@ -386,8 +390,10 @@ export type ChannelFilterParameter = {
     defaultCurrencyCode?: InputMaybe<StringOperators>;
     defaultLanguageCode?: InputMaybe<StringOperators>;
     id?: InputMaybe<IdOperators>;
+    outOfStockThreshold?: InputMaybe<NumberOperators>;
     pricesIncludeTax?: InputMaybe<BooleanOperators>;
     token?: InputMaybe<StringOperators>;
+    trackInventory?: InputMaybe<BooleanOperators>;
     updatedAt?: InputMaybe<DateOperators>;
 };
 
@@ -413,6 +419,7 @@ export type ChannelSortParameter = {
     code?: InputMaybe<SortOrder>;
     createdAt?: InputMaybe<SortOrder>;
     id?: InputMaybe<SortOrder>;
+    outOfStockThreshold?: InputMaybe<SortOrder>;
     token?: InputMaybe<SortOrder>;
     updatedAt?: InputMaybe<SortOrder>;
 };
@@ -679,15 +686,19 @@ export type CreateAssetInput = {
 export type CreateAssetResult = Asset | MimeTypeError;
 
 export type CreateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code: Scalars['String'];
     currencyCode: CurrencyCode;
     customFields?: InputMaybe<Scalars['JSON']>;
     defaultLanguageCode: LanguageCode;
     defaultShippingZoneId: Scalars['ID'];
     defaultTaxZoneId: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     sellerId?: InputMaybe<Scalars['ID']>;
     token: Scalars['String'];
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type CreateChannelResult = Channel | LanguageNotAvailableError;
@@ -5646,6 +5657,8 @@ export type UpdateAssetInput = {
 };
 
 export type UpdateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code?: InputMaybe<Scalars['String']>;
     currencyCode?: InputMaybe<CurrencyCode>;
     customFields?: InputMaybe<Scalars['JSON']>;
@@ -5653,9 +5666,11 @@ export type UpdateChannelInput = {
     defaultShippingZoneId?: InputMaybe<Scalars['ID']>;
     defaultTaxZoneId?: InputMaybe<Scalars['ID']>;
     id: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax?: InputMaybe<Scalars['Boolean']>;
     sellerId?: InputMaybe<Scalars['ID']>;
     token?: InputMaybe<Scalars['String']>;
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type UpdateChannelResult = Channel | LanguageNotAvailableError;

+ 4 - 0
packages/core/e2e/graphql/generated-e2e-shop-types.ts

@@ -137,6 +137,8 @@ export type BooleanOperators = {
 };
 
 export type Channel = Node & {
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -147,9 +149,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 

+ 8 - 0
packages/core/src/api/schema/admin-api/channel.api.graphql

@@ -29,8 +29,12 @@ input CreateChannelInput {
     code: String!
     token: String!
     defaultLanguageCode: LanguageCode!
+    availableLanguageCodes: [LanguageCode!]
     pricesIncludeTax: Boolean!
     currencyCode: CurrencyCode!
+    availableCurrencyCodes: [CurrencyCode!]
+    trackInventory: Boolean
+    outOfStockThreshold: Int
     defaultTaxZoneId: ID!
     defaultShippingZoneId: ID!
     sellerId: ID
@@ -41,8 +45,12 @@ input UpdateChannelInput {
     code: String
     token: String
     defaultLanguageCode: LanguageCode
+    availableLanguageCodes: [LanguageCode!]
     pricesIncludeTax: Boolean
     currencyCode: CurrencyCode
+    availableCurrencyCodes: [CurrencyCode!]
+    trackInventory: Boolean
+    outOfStockThreshold: Int
     defaultTaxZoneId: ID
     defaultShippingZoneId: ID
     sellerId: ID

+ 4 - 0
packages/core/src/api/schema/common/channel.type.graphql

@@ -7,8 +7,12 @@ type Channel implements Node {
     defaultTaxZone: Zone
     defaultShippingZone: Zone
     defaultLanguageCode: LanguageCode!
+    availableLanguageCodes: [LanguageCode!]
     currencyCode: CurrencyCode! @deprecated(reason: "Use defaultCurrencyCode instead")
     defaultCurrencyCode: CurrencyCode!
+    availableCurrencyCodes: [CurrencyCode!]!
+    trackInventory: Boolean
+    outOfStockThreshold: Int
     pricesIncludeTax: Boolean!
     seller: Seller
 }

+ 23 - 0
packages/core/src/entity/channel/channel.entity.ts

@@ -41,6 +41,9 @@ export class Channel extends VendureEntity {
 
     @Column('varchar') defaultLanguageCode: LanguageCode;
 
+    @Column('simple-array')
+    availableLanguageCodes: LanguageCode[];
+
     @Index()
     @ManyToOne(type => Zone)
     defaultTaxZone: Zone;
@@ -52,6 +55,26 @@ export class Channel extends VendureEntity {
     @Column('varchar')
     defaultCurrencyCode: CurrencyCode;
 
+    @Column('simple-array')
+    availableCurrencyCodes: CurrencyCode[];
+
+    /**
+     * @description
+     * Specifies the default value for inventory tracking for ProductVariants.
+     * Can be overridden per ProductVariant, but this value determines the default
+     * if not otherwise specified.
+     */
+    @Column({ default: true })
+    trackInventory: boolean;
+
+    /**
+     * @description
+     * Specifies the value of stockOnHand at which a given ProductVariant is considered
+     * out of stock.
+     */
+    @Column({ default: 0 })
+    outOfStockThreshold: number;
+
     @Column(type => CustomChannelFields)
     customFields: CustomChannelFields;
 

+ 7 - 0
packages/core/src/entity/global-settings/global-settings.entity.ts

@@ -12,6 +12,9 @@ export class GlobalSettings extends VendureEntity implements HasCustomFields {
         super(input);
     }
 
+    /**
+     * @deprecated use `Channel.availableLanguageCodes`
+     */
     @Column('simple-array')
     availableLanguages: LanguageCode[];
 
@@ -20,6 +23,8 @@ export class GlobalSettings extends VendureEntity implements HasCustomFields {
      * Specifies the default value for inventory tracking for ProductVariants.
      * Can be overridden per ProductVariant, but this value determines the default
      * if not otherwise specified.
+     *
+     * @deprecated use `Channel.trackInventory`
      */
     @Column({ default: true })
     trackInventory: boolean;
@@ -28,6 +33,8 @@ export class GlobalSettings extends VendureEntity implements HasCustomFields {
      * @description
      * Specifies the value of stockOnHand at which a given ProductVariant is considered
      * out of stock.
+     *
+     * @deprecated use `Channel.outOfStockThreshold`
      */
     @Column({ default: 0 })
     outOfStockThreshold: number;

+ 1 - 0
packages/core/src/service/services/channel.service.ts

@@ -228,6 +228,7 @@ export class ChannelService {
         const channel = new Channel({
             ...input,
             defaultCurrencyCode: input.currencyCode,
+            availableCurrencyCodes: input.availableCurrencyCodes ?? [input.currencyCode],
         });
         const defaultLanguageValidationResult = await this.validateDefaultLanguageCode(ctx, input);
         if (isGraphQlErrorResult(defaultLanguageValidationResult)) {

+ 277 - 1
packages/dev-server/dev-config.ts

@@ -3,10 +3,12 @@ import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
 import { AssetServerPlugin } from '@vendure/asset-server-plugin';
 import { ADMIN_API_PATH, API_PORT, SHOP_API_PATH } from '@vendure/common/lib/shared-constants';
 import {
+    Asset,
     DefaultJobQueuePlugin,
     DefaultLogger,
     DefaultSearchPlugin,
     dummyPaymentHandler,
+    LanguageCode,
     LogLevel,
     VendureConfig,
 } from '@vendure/core';
@@ -59,7 +61,281 @@ export const devConfig: VendureConfig = {
     paymentOptions: {
         paymentMethodHandlers: [dummyPaymentHandler],
     },
-    customFields: {},
+    /* customFields: {
+        ProductVariant: [
+            {
+                name: 'weight',
+                type: 'int',
+                defaultValue: 0,
+                nullable: false,
+                min: 0,
+                step: 1,
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Weight' }],
+                ui: { component: 'number-form-input', suffix: 'g' },
+            },
+            {
+                name: 'rrp',
+                type: 'int',
+                nullable: true,
+                min: 0,
+                step: 1,
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'RRP' }],
+                ui: { component: 'currency-form-input' },
+            },
+            {
+                name: 'gtin',
+                type: 'string',
+                nullable: true,
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'GTIN (barcode)' }],
+            },
+            {
+                name: 'additionalInformation',
+                type: 'text',
+                nullable: true,
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Additional Information' }],
+                ui: { component: 'json-editor-form-input' },
+            },
+        ],
+        Product: [
+            {
+                name: 'searchKeywords',
+                label: [{ languageCode: LanguageCode.en, value: 'Search keywords' }],
+                type: 'string',
+                defaultValue: '',
+                public: false,
+            },
+            {
+                name: 'pageType',
+                label: [{ languageCode: LanguageCode.en, value: 'Page type' }],
+                type: 'string',
+                defaultValue: 'default',
+                public: true,
+                options: [
+                    { value: 'default', label: [{ languageCode: LanguageCode.en, value: 'Default' }] },
+                    {
+                        value: 'colour-chart',
+                        label: [{ languageCode: LanguageCode.en, value: 'Colour chart' }],
+                    },
+                    {
+                        value: 'select-menu',
+                        label: [{ languageCode: LanguageCode.en, value: 'Select menu' }],
+                    },
+                    { value: 'gift-card', label: [{ languageCode: LanguageCode.en, value: 'Gift card' }] },
+                ],
+                ui: { tab: 'Display' },
+            },
+            {
+                name: 'keyFeatures',
+                label: [{ languageCode: LanguageCode.en, value: 'Key features' }],
+                type: 'text',
+                public: true,
+                nullable: true,
+                ui: { component: 'rich-text-form-input' },
+            },
+            {
+                name: 'videoUrls',
+                label: [{ languageCode: LanguageCode.en, value: 'Video urls' }],
+                type: 'string',
+                list: true,
+                public: true,
+                nullable: false,
+                defaultValue: [],
+            },
+            {
+                name: 'variantOrdering',
+                label: [{ languageCode: LanguageCode.en, value: 'Variant ordering' }],
+                type: 'string',
+                defaultValue: 'default',
+                public: true,
+                options: [
+                    { value: 'default', label: [{ languageCode: LanguageCode.en, value: 'Default' }] },
+                    {
+                        value: 'alphabetical',
+                        label: [{ languageCode: LanguageCode.en, value: 'Alphabetical' }],
+                    },
+                    {
+                        value: 'brush-size',
+                        label: [{ languageCode: LanguageCode.en, value: 'Brush size (000, 00, 0, 1, ...)' }],
+                    },
+                    {
+                        value: 'dimension',
+                        label: [
+                            { languageCode: LanguageCode.en, value: 'Dimension (5" x 5", 10" x 12",...)' },
+                        ],
+                    },
+                ],
+                ui: { tab: 'Display' },
+            },
+            {
+                name: 'seoTitle',
+                type: 'localeString',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'SEO Title' }],
+                nullable: true,
+                ui: { tab: 'SEO' },
+            },
+            {
+                name: 'seoDescription',
+                type: 'localeString',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'SEO Description' }],
+                nullable: true,
+                ui: { tab: 'SEO', component: 'textarea-form-input' },
+            },
+            {
+                name: 'seoImage',
+                type: 'relation',
+                entity: Asset,
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'SEO Image' }],
+                nullable: true,
+                ui: { tab: 'SEO' },
+            },
+            {
+                name: 'boost',
+                type: 'int',
+                public: true,
+                defaultValue: 0,
+                min: 0,
+                max: 5,
+                label: [{ languageCode: LanguageCode.en, value: 'Boost in list pages' }],
+                nullable: true,
+            },
+            {
+                name: 'minimumOrderQuantity',
+                type: 'int',
+                public: true,
+                min: 0,
+                label: [{ languageCode: LanguageCode.en, value: 'Minimum order quantity' }],
+                description: [
+                    {
+                        languageCode: LanguageCode.en,
+                        value: 'If set, the customer must order at least this number of any variants of this product',
+                    },
+                ],
+                nullable: true,
+            },
+        ],
+        Collection: [
+            {
+                name: 'excludeFromNavMenu',
+                label: [{ languageCode: LanguageCode.en, value: 'Exclude from nav menu' }],
+                type: 'boolean',
+                defaultValue: false,
+                public: true,
+            },
+            {
+                name: 'excludeFromSubCollections',
+                label: [{ languageCode: LanguageCode.en, value: 'Exclude from sub collections' }],
+                type: 'boolean',
+                defaultValue: false,
+                public: true,
+            },
+            {
+                name: 'noIndex',
+                label: [{ languageCode: LanguageCode.en, value: 'Do not allow crawlers to index' }],
+                type: 'boolean',
+                defaultValue: false,
+                public: true,
+                ui: { tab: 'SEO' },
+            },
+            {
+                name: 'searchKeywords',
+                label: [{ languageCode: LanguageCode.en, value: 'Search keywords' }],
+                type: 'string',
+                defaultValue: '',
+                public: false,
+            },
+            {
+                name: 'layout',
+                type: 'string',
+                public: true,
+                nullable: false,
+                defaultValue: 'fullWidth',
+                label: [{ languageCode: LanguageCode.en, value: 'Layout mode' }],
+                options: [
+                    { value: 'default', label: [{ languageCode: LanguageCode.en, value: 'Default' }] },
+                    { value: 'fullWidth', label: [{ languageCode: LanguageCode.en, value: 'Full width' }] },
+                ],
+            },
+            {
+                name: 'seoTitle',
+                type: 'localeString',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'SEO Meta Title' }],
+                nullable: true,
+                ui: { tab: 'SEO' },
+            },
+            {
+                name: 'seoDescription',
+                type: 'localeString',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'SEO Meta Description' }],
+                nullable: true,
+                ui: { tab: 'SEO', component: 'textarea-form-input' },
+            },
+            {
+                name: 'seoImage',
+                type: 'relation',
+                entity: Asset,
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'SEO Meta Image' }],
+                nullable: true,
+                ui: { tab: 'SEO' },
+            },
+            {
+                name: 'extendedDescription',
+                type: 'text',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Extended description' }],
+                nullable: true,
+                ui: { tab: 'SEO', component: 'rich-text-form-input' },
+            },
+            {
+                name: 'isOfferCollection',
+                type: 'boolean',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Is offer collecion' }],
+                nullable: true,
+                defaultValue: false,
+                ui: { tab: 'Offers' },
+            },
+            {
+                name: 'offerName',
+                type: 'string',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Offer name' }],
+                nullable: true,
+                ui: { tab: 'Offers' },
+            },
+            {
+                name: 'offerDescription',
+                type: 'string',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Offer description' }],
+                nullable: true,
+                ui: { tab: 'Offers', component: 'rich-text-form-input' },
+            },
+            {
+                name: 'displayRrpDiscount',
+                type: 'boolean',
+                public: true,
+                label: [{ languageCode: LanguageCode.en, value: 'Display RRP discount' }],
+                description: [
+                    {
+                        languageCode: LanguageCode.en,
+                        value: 'When enabled, the RRP discount of included products will be displayed in the storefront',
+                    },
+                ],
+                nullable: true,
+                ui: { tab: 'Offers' },
+            },
+        ],
+    }, */
     logger: new DefaultLogger({ level: LogLevel.Verbose }),
     importExportOptions: {
         importAssetsDir: path.join(__dirname, 'import-assets'),

+ 15 - 0
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -352,6 +352,8 @@ export type Cancellation = Node &
     };
 
 export type Channel = Node & {
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -362,9 +364,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 
@@ -386,8 +390,10 @@ export type ChannelFilterParameter = {
     defaultCurrencyCode?: InputMaybe<StringOperators>;
     defaultLanguageCode?: InputMaybe<StringOperators>;
     id?: InputMaybe<IdOperators>;
+    outOfStockThreshold?: InputMaybe<NumberOperators>;
     pricesIncludeTax?: InputMaybe<BooleanOperators>;
     token?: InputMaybe<StringOperators>;
+    trackInventory?: InputMaybe<BooleanOperators>;
     updatedAt?: InputMaybe<DateOperators>;
 };
 
@@ -413,6 +419,7 @@ export type ChannelSortParameter = {
     code?: InputMaybe<SortOrder>;
     createdAt?: InputMaybe<SortOrder>;
     id?: InputMaybe<SortOrder>;
+    outOfStockThreshold?: InputMaybe<SortOrder>;
     token?: InputMaybe<SortOrder>;
     updatedAt?: InputMaybe<SortOrder>;
 };
@@ -679,15 +686,19 @@ export type CreateAssetInput = {
 export type CreateAssetResult = Asset | MimeTypeError;
 
 export type CreateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code: Scalars['String'];
     currencyCode: CurrencyCode;
     customFields?: InputMaybe<Scalars['JSON']>;
     defaultLanguageCode: LanguageCode;
     defaultShippingZoneId: Scalars['ID'];
     defaultTaxZoneId: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     sellerId?: InputMaybe<Scalars['ID']>;
     token: Scalars['String'];
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type CreateChannelResult = Channel | LanguageNotAvailableError;
@@ -5646,6 +5657,8 @@ export type UpdateAssetInput = {
 };
 
 export type UpdateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code?: InputMaybe<Scalars['String']>;
     currencyCode?: InputMaybe<CurrencyCode>;
     customFields?: InputMaybe<Scalars['JSON']>;
@@ -5653,9 +5666,11 @@ export type UpdateChannelInput = {
     defaultShippingZoneId?: InputMaybe<Scalars['ID']>;
     defaultTaxZoneId?: InputMaybe<Scalars['ID']>;
     id: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax?: InputMaybe<Scalars['Boolean']>;
     sellerId?: InputMaybe<Scalars['ID']>;
     token?: InputMaybe<Scalars['String']>;
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type UpdateChannelResult = Channel | LanguageNotAvailableError;

+ 15 - 0
packages/payments-plugin/e2e/graphql/generated-admin-types.ts

@@ -352,6 +352,8 @@ export type Cancellation = Node &
     };
 
 export type Channel = Node & {
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -362,9 +364,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 
@@ -386,8 +390,10 @@ export type ChannelFilterParameter = {
     defaultCurrencyCode?: InputMaybe<StringOperators>;
     defaultLanguageCode?: InputMaybe<StringOperators>;
     id?: InputMaybe<IdOperators>;
+    outOfStockThreshold?: InputMaybe<NumberOperators>;
     pricesIncludeTax?: InputMaybe<BooleanOperators>;
     token?: InputMaybe<StringOperators>;
+    trackInventory?: InputMaybe<BooleanOperators>;
     updatedAt?: InputMaybe<DateOperators>;
 };
 
@@ -413,6 +419,7 @@ export type ChannelSortParameter = {
     code?: InputMaybe<SortOrder>;
     createdAt?: InputMaybe<SortOrder>;
     id?: InputMaybe<SortOrder>;
+    outOfStockThreshold?: InputMaybe<SortOrder>;
     token?: InputMaybe<SortOrder>;
     updatedAt?: InputMaybe<SortOrder>;
 };
@@ -679,15 +686,19 @@ export type CreateAssetInput = {
 export type CreateAssetResult = Asset | MimeTypeError;
 
 export type CreateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code: Scalars['String'];
     currencyCode: CurrencyCode;
     customFields?: InputMaybe<Scalars['JSON']>;
     defaultLanguageCode: LanguageCode;
     defaultShippingZoneId: Scalars['ID'];
     defaultTaxZoneId: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     sellerId?: InputMaybe<Scalars['ID']>;
     token: Scalars['String'];
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type CreateChannelResult = Channel | LanguageNotAvailableError;
@@ -5646,6 +5657,8 @@ export type UpdateAssetInput = {
 };
 
 export type UpdateChannelInput = {
+    availableCurrencyCodes?: InputMaybe<Array<CurrencyCode>>;
+    availableLanguageCodes?: InputMaybe<Array<LanguageCode>>;
     code?: InputMaybe<Scalars['String']>;
     currencyCode?: InputMaybe<CurrencyCode>;
     customFields?: InputMaybe<Scalars['JSON']>;
@@ -5653,9 +5666,11 @@ export type UpdateChannelInput = {
     defaultShippingZoneId?: InputMaybe<Scalars['ID']>;
     defaultTaxZoneId?: InputMaybe<Scalars['ID']>;
     id: Scalars['ID'];
+    outOfStockThreshold?: InputMaybe<Scalars['Int']>;
     pricesIncludeTax?: InputMaybe<Scalars['Boolean']>;
     sellerId?: InputMaybe<Scalars['ID']>;
     token?: InputMaybe<Scalars['String']>;
+    trackInventory?: InputMaybe<Scalars['Boolean']>;
 };
 
 export type UpdateChannelResult = Channel | LanguageNotAvailableError;

+ 4 - 0
packages/payments-plugin/e2e/graphql/generated-shop-types.ts

@@ -137,6 +137,8 @@ export type BooleanOperators = {
 };
 
 export type Channel = Node & {
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -147,9 +149,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 

+ 4 - 0
packages/payments-plugin/src/mollie/graphql/generated-shop-types.ts

@@ -149,6 +149,8 @@ export type BooleanOperators = {
 
 export type Channel = Node & {
     __typename?: 'Channel';
+    availableCurrencyCodes: Array<CurrencyCode>;
+    availableLanguageCodes?: Maybe<Array<LanguageCode>>;
     code: Scalars['String'];
     createdAt: Scalars['DateTime'];
     /** @deprecated Use defaultCurrencyCode instead */
@@ -159,9 +161,11 @@ export type Channel = Node & {
     defaultShippingZone?: Maybe<Zone>;
     defaultTaxZone?: Maybe<Zone>;
     id: Scalars['ID'];
+    outOfStockThreshold?: Maybe<Scalars['Int']>;
     pricesIncludeTax: Scalars['Boolean'];
     seller?: Maybe<Seller>;
     token: Scalars['String'];
+    trackInventory?: Maybe<Scalars['Boolean']>;
     updatedAt: Scalars['DateTime'];
 };
 

文件差異過大導致無法顯示
+ 0 - 0
schema-admin.json


文件差異過大導致無法顯示
+ 0 - 0
schema-shop.json


部分文件因文件數量過多而無法顯示