{"version":3,"file":"static/js/b2365a1245c283f707a2.bundle.js","mappings":"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","sources":["webpack://Msdyn365.Commerce.Online/../../src/get-categories-hierarchy.ts?acde","webpack://Msdyn365.Commerce.Online/../../src/get-categories.ts?8dc6","webpack://Msdyn365.Commerce.Online/../../../src/utilities/QueryResultSettingsProxy.ts?5e44","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/Url-builder/parameterize.ts?f5a5","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/Url-builder/category-url-builder.ts?e564","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/Url-builder/invoice-url-builder.ts?d542","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/Url-builder/product-url-builder.ts?baf1","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/data-structures/dictionary.ts?bab3","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/events/event.ts?15a9","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/extensions/array-extensions.ts?1a2a","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/extensions/enum-extensions.ts?cf51","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/extensions/string-extensions.ts?ab9f","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/extensions/object-extensions.ts?6388","webpack://Msdyn365.Commerce.Online/../../../src/utilities/input-data-parser.ts?027a","webpack://Msdyn365.Commerce.Online/../../../src/utilities/product-inventory-information.ts?0ec6","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/promise-queue/finite-promise-queue.ts?77bf","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/promise-queue/promise-queue.ts?e362","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/random/guid.ts?1947","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/random/index.ts?1f9d","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/regex/email-regex.ts?6a6a","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/regex/password-regex.ts?456d","webpack://Msdyn365.Commerce.Online/../../../../src/utilities/regex/phone-regex.ts?9ada","webpack://Msdyn365.Commerce.Online/../../../src/utilities/utils.ts?fbc0","webpack://Msdyn365.Commerce.Online/../../../src/utilities/validate-cartlines-inventory.ts?8b82"],"sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport {\n CacheType,\n createObservableDataAction,\n getCatalogId,\n IAction,\n IActionContext,\n IActionInput,\n IAny,\n ICommerceApiSettings,\n ICreateActionContext,\n IGeneric,\n IRequestContext\n} from '@msdyn365-commerce/core';\nimport { Category, TextValueTranslation } from '@msdyn365-commerce/retail-proxy';\n\nimport getCategoryAction, { CategoriesInput as RawCategoriesInput } from './get-categories';\nimport { getCategoryUrl } from './utilities/Url-builder';\nimport { generateCacheKey } from './utilities/utils';\n\n/**\n * Input for get-categories data action.\n */\nexport class CategoriesInput implements IActionInput {\n public readonly maxItems: number;\n\n public readonly channelId: number;\n\n public includeRootCategory?: boolean;\n\n private readonly catalogId: number;\n\n private readonly sitePath: string;\n\n private readonly _mappedToHierarchy: boolean;\n\n private readonly apiSettings: ICommerceApiSettings;\n\n private readonly locale?: string;\n\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number, includeRootCategory?: boolean) {\n this._mappedToHierarchy = mappedToHierarchy;\n this.includeRootCategory = includeRootCategory;\n this.maxItems = maxItems || 250;\n this.channelId = context && context.apiSettings && context.apiSettings.channelId ? +context.apiSettings.channelId : 0;\n this.sitePath = (context && context.sitePath) || '';\n this.apiSettings = context.apiSettings;\n this.locale = context.locale || '';\n this.catalogId = getCatalogId(context);\n }\n\n public getCacheKey = () =>\n generateCacheKey(\n this.apiSettings,\n { key: 'SitePath', value: this.sitePath },\n { key: 'IncludeRootCategory', value: this.includeRootCategory },\n { key: 'Top', value: this.maxItems },\n { key: 'CatalogId', value: this.catalogId },\n { key: 'Locale', value: this.locale }\n );\n\n public getCacheObjectType = () => (this._mappedToHierarchy ? 'CategoryHierarchy' : 'Category');\n\n public dataCacheType = (): CacheType => 'request';\n\n public getLocale = (): string => this.locale || '';\n}\n\nconst getFriendlyName = (locale?: string, nameTranslations?: TextValueTranslation[]): string | undefined => {\n let nameTranslation: TextValueTranslation | undefined;\n if (locale && nameTranslations && nameTranslations.length > 0) {\n nameTranslation = nameTranslations.find(item => item.Language!.toLowerCase() === locale.toLowerCase());\n }\n\n return nameTranslation && nameTranslation.Text;\n};\n\nexport interface ICategoryMap {\n [RecordId: number]: CategoryHierarchy;\n}\n\n/**\n * Creates a hierarchy of categories based on the ParentCategory property.\n * @param categoryList Categories that will be converted into a hierarchy.\n * @param ctx\n * @param locale\n * @returns Hierarchy of categories in array.\n */\nexport const mapCategoryToHierarchy = (\n categoryList: Category[],\n ctx: IActionContext,\n locale?: string,\n includeRootCategory?: boolean\n): CategoryHierarchy[] => {\n if (!categoryList || categoryList.length === 0) {\n return [];\n }\n\n const categoryMap: ICategoryMap = {};\n\n for (const category of categoryList) {\n const localName = getFriendlyName(locale, category.NameTranslations);\n const categoryHierarchy = { ...category };\n categoryHierarchy.NeutralizedName = category.Name;\n categoryHierarchy.Name = localName || categoryHierarchy.NeutralizedName;\n categoryMap[category.RecordId] = categoryHierarchy;\n }\n\n let rootCategory: CategoryHierarchy | undefined;\n\n for (const category of Object.values(categoryMap)) {\n const parentId = category.ParentCategory;\n category.Url = getCategoryUrl(category, ctx, categoryMap);\n if (parentId === 0) {\n rootCategory = category;\n continue;\n }\n\n const parent = parentId && categoryMap[parentId];\n if (parent) {\n parent.Children = parent.Children || [];\n parent.Children.push(category);\n }\n }\n\n if (!rootCategory) {\n return [];\n }\n\n if (includeRootCategory) {\n const categoryHierarchy: CategoryHierarchy[] = [];\n categoryHierarchy.push(rootCategory);\n return categoryHierarchy;\n }\n\n return rootCategory.Children ?? [];\n};\n\n/**\n * Creates the input required to make the retail api call.\n * @param inputData\n */\nexport const createCategoriesHierarchyInput = (inputData: ICreateActionContext>): IActionInput => {\n const topItems = inputData.config && inputData.config.topCategories && Number.parseInt(inputData.config.topCategories, 10);\n return new CategoriesInput(inputData.requestContext, true, topItems);\n};\n\n/**\n * Calls the Retail API and returns all the categories as a hierarchy.\n * @param input\n * @param ctx\n */\nexport async function getCategoryHierarchyAction(input: CategoriesInput, ctx: IActionContext): Promise {\n const categories = await getCategoryAction(new RawCategoriesInput(ctx.requestContext, false, input.maxItems), ctx);\n return mapCategoryToHierarchy(categories, ctx, input.getLocale(), input.includeRootCategory);\n}\n\nexport const getCategoryHierarchyActionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/retail-actions/get-categories-hierarchy',\n action: >getCategoryHierarchyAction,\n input: createCategoriesHierarchyInput\n});\n\nexport default getCategoryHierarchyActionDataAction;\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport {\n CacheType,\n createObservableDataAction,\n getCatalogId,\n IAction,\n IActionContext,\n IActionInput,\n IAny,\n ICreateActionContext,\n IGeneric,\n IRequestContext\n} from '@msdyn365-commerce/core';\nimport { CategoriesDataActions } from '@msdyn365-commerce/retail-proxy';\nimport { generateCacheKey } from './utilities';\n\n/**\n * Input for get-categories data action.\n */\nexport class CategoriesInput implements IActionInput {\n public readonly maxItems: number;\n\n public readonly channelId: number;\n\n public readonly catalogId?: number;\n\n private readonly _requestContext: IRequestContext;\n\n private readonly _mappedToHierarchy: boolean;\n\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number) {\n this._requestContext = context;\n this._mappedToHierarchy = mappedToHierarchy;\n this.maxItems = maxItems || 250;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Required.\n this.channelId = context?.apiSettings?.channelId ? Number(context.apiSettings.channelId) : 0;\n this.catalogId = getCatalogId(context);\n }\n\n /**\n * Get Cache Key.\n * @returns - Cache key string.\n */\n public getCacheKey = (): string =>\n generateCacheKey(\n this._requestContext.apiSettings,\n { key: 'Top', value: this.maxItems },\n { key: 'CatalogId', value: this.catalogId }\n );\n\n /**\n * Get Cache type Name.\n * @returns - Cache name string.\n */\n public getCacheObjectType = (): string => (this._mappedToHierarchy ? 'CategoryHierarchy' : 'Category');\n\n /**\n * Get Cache type.\n * @returns - CacheType enum.\n */\n public dataCacheType = (): CacheType => 'application';\n}\n\n/**\n * Creates the input required to make the retail api call.\n * @param inputData -- Input data.\n * @returns -- IActionInput.\n */\nexport const createCategoriesInput = (inputData: ICreateActionContext>): IActionInput => {\n const topItems = inputData.config?.topCategories && Number.parseInt(inputData.config.topCategories, 10);\n return new CategoriesInput(inputData.requestContext, false, topItems);\n};\n\n/**\n * Calls the Retail API and returns all the categories as a flat list.\n * @param input - Input.\n * @param ctx - Context.\n * @returns - CategoryHierarchy.\n */\nexport async function getCategoryAction(input: CategoriesInput, ctx: IActionContext): Promise {\n return ((await CategoriesDataActions.getCategoriesAsync(\n {\n callerContext: ctx\n },\n input.channelId,\n input.catalogId\n )) as unknown) as CategoryHierarchy[];\n}\n\n/**\n * The getCategory Data Action.\n */\nexport const getCategoryActionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/retail-actions/get-categories',\n action: getCategoryAction as IAction,\n input: createCategoriesInput\n});\n\nexport default getCategoryActionDataAction;\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { IAny, ICreateActionContext, IGeneric, IRequestContext } from '@msdyn365-commerce/core';\nimport { QueryResultSettings, SortColumn } from '@msdyn365-commerce/retail-proxy';\n\nimport { IQueryResultSettingsModuleConfig } from './IQueryResultSettingsModuleConfig';\n\n/**\n * Wrapper for query result settings, which guarantees some properties that are optional in the real subject\n * and includes some common utilities for data actions.\n */\nexport class QueryResultSettingsProxy {\n // Real subject\n private readonly queryResultSettings: QueryResultSettings;\n\n /**\n * Factory method for data actions.\n * @param inputData - Input data.\n * @returns - Returns query result settings proxy.\n */\n public static fromInputData(inputData: ICreateActionContext>): QueryResultSettingsProxy {\n const { requestContext, config } = inputData;\n return QueryResultSettingsProxy.fromModuleData(requestContext, config as IQueryResultSettingsModuleConfig);\n }\n\n /**\n * Factory method for modules.\n * @param requestContext - RequestContext.\n * @param config - Module config from props.\n * @returns - Returns query result settings proxy.\n */\n public static fromModuleData(requestContext: IRequestContext, config: IQueryResultSettingsModuleConfig): QueryResultSettingsProxy {\n const sortingCriteria = (config && config.sortingCriteria) || undefined;\n const query = requestContext && requestContext.query;\n const top = (query && query.top) || undefined;\n const skip = (query && query.skip) || undefined;\n\n const queryResultSettings = {\n Paging: {\n Skip: (skip && Number(skip)) || 0,\n Top: (top && Number(top)) || config?.itemsPerPage || 50\n },\n Sorting: sortingCriteria || {}\n };\n\n return new QueryResultSettingsProxy(queryResultSettings);\n }\n\n /**\n * Return the query result settings with default paging or with the passed value.\n * @param inputData - Input Data.\n * @returns - Query Result settings.\n */\n public static getPagingFromInputDataOrDefaultValue(inputData: ICreateActionContext>): QueryResultSettings {\n const config: IQueryResultSettingsModuleConfig | undefined = inputData.config;\n const defaultPageSize: number = 100;\n const queryResultSettings: QueryResultSettings = {\n Paging: {\n // eslint-disable-next-line max-len -- Disable max length for next line.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unnecessary-condition -- Reading from config.\n Top:\n config?.itemsPerPage ??\n Number.parseInt(inputData.requestContext?.app?.platform?.defaultPageSizeForAPI ?? defaultPageSize, 10)\n }\n };\n return queryResultSettings;\n }\n\n /**\n * Factory method.\n * @returns - Returns query result settings proxy.\n */\n public static getDefault(): QueryResultSettingsProxy {\n return new QueryResultSettingsProxy({ Paging: {}, Sorting: {} });\n }\n\n /**\n * Private constructor, expect instances to be created with the factory method.\n * @param queryResultSettings - Query result setting.\n */\n private constructor(queryResultSettings: QueryResultSettings) {\n this.queryResultSettings = queryResultSettings;\n }\n\n public get QueryResultSettings(): QueryResultSettings {\n return this.queryResultSettings;\n }\n\n /**\n * Gets the hints for the cache key based on query result settings.\n * @returns - Returns cache key hint.\n */\n public get cacheKeyHint(): string {\n // The factory method guarantees values are defined\n const topHint = `top-${this.queryResultSettings.Paging!.Top!}`;\n const skipHint = `skip-${this.queryResultSettings.Paging!.Skip!}`;\n const sortingHintData =\n (this.queryResultSettings.Sorting!.Columns || [])\n .map((column: SortColumn) => {\n return `${column.ColumnName}--${(column.IsDescending && 'desc') || 'asc'}`;\n })\n .join(',') || undefined;\n const sortingHint = `sortBy-${sortingHintData}`;\n return `${topHint}|${skipHint}|${sortingHint}`;\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport msdyn365Commerce, { IParameterizeFeatureFlags } from '@msdyn365-commerce/core';\n\nexport function parameterize(\n name: string = '',\n sep = '-',\n parameterizeFeatureFlags: IParameterizeFeatureFlags = {},\n neutralizedName?: string\n) {\n // If neutralizedName flag enabled, we use neutralizedName to construct string\n const candidateName =\n (msdyn365Commerce.platformSettings && msdyn365Commerce.platformSettings.enableUrlLocalization) ||\n parameterizeFeatureFlags.enableUrlLocalization\n ? name\n : neutralizedName || name;\n\n /*\n 1\t‘ ‘ (space)\t-> (single dash)\n 3\tAny character disallowed in URLs -> URL-encode\n 5\t‘ & ‘ (space ampersand space) -> (single dash)\n 6\t‘ - ‘ (space dash space) -> (single dash)\n 7\t‘ ‘ (2+ spaces) -> (single dash)\n 10\t[A-Z] (capital letters) -> [a-z] (lower-case)\n 12\tAny non-ASCII character outside of the set of disallowed characters -> URL-encode\n */\n if (\n parameterizeFeatureFlags.enableUrlEncoding ||\n (msdyn365Commerce.platformSettings && msdyn365Commerce.platformSettings.enableUrlEncoding)\n ) {\n // Replace url reserved characters with dash, and remove front and end dash;\n // &*!() reserved characters that can not be encoded by encodeURIComponent()\n return encodeURIComponent(\n candidateName\n .toLowerCase()\n .replace(/[\\s!&'()*]+/g, '-')\n .trim()\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '')\n );\n }\n return name\n .toLowerCase()\n .replace(/[^\\d_a-z\\-]+/g, ' ')\n .trim()\n .replace(/\\s+/g, sep);\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { getParameterizeFeatureFlags, getUrlSync, IActionContext, IParameterizeFeatureFlags } from '@msdyn365-commerce/core';\n\nimport { parameterize } from './parameterize';\n\ninterface ICategoryMap {\n [RecordId: number]: CategoryHierarchy;\n}\n\n/**\n * Builds slugs for category.\n * @param category\n * @param categoryMap\n * @param parameterizeFeatureFlags\n */\nexport function getCategorySlug(\n category: CategoryHierarchy,\n categoryMap: ICategoryMap,\n parameterizeFeatureFlags?: IParameterizeFeatureFlags\n): string {\n if (!category || !category.Name) {\n // Invalid category\n return '';\n }\n const categoryName = parameterize(category.Name, undefined, parameterizeFeatureFlags, category.NeutralizedName);\n if (!category.ParentCategory || category.ParentCategory === 0) {\n // Base case assign url\n category.Slug = category.Slug || `/${categoryName}`;\n } else if (category.ParentCategory) {\n category.Slug =\n category.Slug ||\n `${getCategorySlug(categoryMap[category.ParentCategory], categoryMap, parameterizeFeatureFlags)}/${categoryName}`;\n }\n\n return category.Slug || '';\n}\n\n/**\n * Gets Url for category hierarchy. Returns string and adds url to Url property of category hierarchy.\n * @param category Category to generate URL for.\n * @param ctx\n * @param categoryMap Dictionary of all categories.\n */\nexport function getCategoryUrl(category: CategoryHierarchy, ctx?: IActionContext, categoryMap?: ICategoryMap): string | undefined {\n if (!category.Url && ctx && categoryMap) {\n if (!category.Slug) {\n const parameterizeFeatureFlags: IParameterizeFeatureFlags = ctx.requestContext ? getParameterizeFeatureFlags(ctx) : {};\n category.Slug = getCategorySlug(category, categoryMap, parameterizeFeatureFlags);\n }\n category.Url = getUrlSync('category', ctx, { category });\n }\n return category.Url;\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { getUrlSync, IActionContext } from '@msdyn365-commerce/core';\n\n/**\n * Syncronously creates an invoice detail page url.\n * @param invoiceId Invoice Id.\n * @param ctx\n */\nexport function getInvoiceDetailsPageUrlSync(invoiceId: string, ctx: IActionContext): string {\n let url = getUrlSync('invoice-details', ctx) || '';\n url = url.includes('?') ? url.substr(0, url.indexOf('?')) : url;\n return `${url}?invoiceId=${invoiceId}`;\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { getUrlSync, IActionContext } from '@msdyn365-commerce/core';\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy';\n\n/**\n * Syncronously creates a product url.\n * @param product Simple product to get url from.\n * @param ctx\n * @param category Category to add to product url.\n */\nexport function getProductUrlSync(product: SimpleProduct, ctx: IActionContext, category?: CategoryHierarchy): string {\n const selectedProduct = { ...product, RecordId: product.MasterProductId || product.RecordId };\n\n return getProductPageUrlSync(selectedProduct.Name || '', selectedProduct.RecordId, ctx, category)!;\n}\n\n/**\n * Syncronously creates a product detail page url.\n * @param name Simple product name.\n * @param recordId Record id of product.\n * @param ctx\n * @param category\n */\nexport function getProductPageUrlSync(name: string, recordId: number, ctx: IActionContext, category?: CategoryHierarchy): string {\n return getUrlSync('product', ctx, {\n product: { Name: name || '', RecordId: recordId },\n category\n })!;\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/**\n * Represents a pair of two fields: key and value.\n * Used to initialize a dictionary.\n */\nexport interface IKeyValuePair {\n readonly key: Key;\n readonly value: Value;\n}\n\n/**\n * Represents a dictionary in memory storage.\n */\nexport class Dictionary {\n /**\n * Values stored in the dictionary.\n */\n private _values: { [eventName: string]: Value };\n\n /**\n * The number of values stored in the dictionary (does not include keys).\n */\n private _length: number;\n\n /**\n * Initializes an empty dictionary or a dictionary with the given key value pairs.\n * @param {IKeyValuePair[]} entries The key value pairs which should be stored in the dictionary initially.\n */\n public constructor(...entries: IKeyValuePair[]) {\n this._values = {};\n this._length = 0;\n entries.forEach(keyValuePair => {\n this.setValue(keyValuePair.key, keyValuePair.value);\n });\n }\n\n /**\n * Removes value from the dictionary for the given key.\n * @param {Key} key The key to retrieve the value.\n * @remark Does nothing in case the key is not present in the dictionary.\n */\n public removeValue(key: Key): void {\n if (!this.hasValue(key)) {\n return;\n }\n\n --this._length;\n delete this._values[key];\n }\n\n /**\n * Retrieves a value from the dictionary or returns undefined in case it's not found.\n * @param {Key} key The key to retrieve the value.\n * @returns {Value | undefined} The value stored in the dictionary or undefined in case it's not found.\n */\n public getValue(key: Key): Value | undefined {\n return this._values[key];\n }\n\n /**\n * Retrieves a value from the dictionary.\n * In case it's not found, adds the default value to the dictionary and returns it.\n * @param {Key} key The key to retrieve the value.\n * @param defaultValue\n * @returns {Value} The value stored in the dictionary or the default value in case it's not found.\n */\n public getValueWithDefaultValue(key: Key, defaultValue: Value): Value {\n if (!this.hasValue(key)) {\n this.setValue(key, defaultValue);\n }\n return this.getValue(key)!;\n }\n\n /**\n * Sets the value to the dictionary for the given key.\n * @remarks In case undefined was passed, removes the value from the dictionary instead.\n * @param {Key} key The key under which the value should be stored.\n * @param {Value} value The value which should be stored in the dictionary.\n */\n public setValue(key: Key, value: Value): void {\n if (value === undefined) {\n this.removeValue(key);\n return;\n }\n\n if (!this.hasValue(key)) {\n ++this._length;\n }\n\n this._values[key] = value;\n }\n\n /**\n * Checks if the dictionary stores some value (except undefined) for the given key.\n * @param {Key} key The key to retrieve the value.\n * @returns {boolean} True in case the value is present, false otherwise or if it's undefined.\n */\n public hasValue(key: Key): boolean {\n return this._values[key] !== undefined;\n }\n\n /**\n * Checks if the dictionary is empty.\n * @returns {boolean} True if the dictionary is empty, false otherwise.\n */\n public isEmpty(): boolean {\n return this.length === 0;\n }\n\n /**\n * Retrieves the number of values stored in the dictionary.\n * @remark Use `isEmpty` to check if the dictionary has any elements.\n * @returns {number} The number of values stored.\n */\n public get length(): number {\n return this._length;\n }\n\n /**\n * Clears the dictionary by removing all elements from the storage.\n */\n public clear(): void {\n this._values = {};\n this._length = 0;\n }\n\n /**\n * Returns all values stored in the dictionary.\n * @returns {Value[]} List of values.\n */\n public getValues(): Value[] {\n return this.getKeys().map(key => this._values[key]);\n }\n\n /**\n * Returns all keys stored in the dictionary.\n * @returns {string[]} List of keys.\n */\n public getKeys(): Key[] {\n return Object.keys(this._values);\n }\n\n /**\n * Returns all key value pairs stored in the dictionary.\n * @returns {IKeyValuePair[]} List of key value pairs.\n */\n public getKeyValuePairs(): IKeyValuePair[] {\n return this.getKeys().map(key => {\n return { key, value: this._values[key] };\n });\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { IEventSubscriber } from './event-subscriber';\n\n/**\n * Represents a simple event with subscribers. Notifies the subscribers once the event is triggered.\n */\nexport class Event {\n /**\n * The list of subscribers.\n */\n private _subscribers: IEventSubscriber[];\n\n /**\n * Initializes the event with a empty subscribers list.\n */\n public constructor() {\n this._subscribers = [];\n }\n\n /**\n * Subscribes given instance to the event.\n * @param {IEventSubscriber} instance The info about the subscriber.\n */\n public subscribe(instance: IEventSubscriber): void {\n this._subscribers.push(instance);\n }\n\n /**\n * Removes the subscriber from the list of subscribers watching the event.\n * @param {string} instanceId The unique identifier of the subscriber which was earlier passed in `subscribe` method in `IEventSubscriber`.\n */\n public unsubscribe(instanceId: string): void {\n this._subscribers = this._subscribers.filter(element => element.instanceId !== instanceId);\n }\n\n /**\n * Clears the list of subscriber removing all instances watching the event.\n */\n public unsubscribeAll(): void {\n this._subscribers = [];\n }\n\n /**\n * Triggers the event.\n * Notifies the subscribers that the event is triggered by calling `handler` method.\n */\n public trigger(): void {\n this._subscribers.forEach(subscriber => {\n subscriber.handler();\n });\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { ObjectExtensions } from './object-extensions';\n\n/**\n * Represents an array which is defined with at least one value.\n */\nexport type NonEmptyArray = [T, ...T[]];\n\n/**\n * Namespace which extends Array functionality.\n */\nexport namespace ArrayExtensions {\n /**\n * Verifies whether the object array has elements.\n * @param value - The array to examine.\n * @returns True if the object has at least one element in the array, false otherwise (if array is not defined or empty).\n */\n export function hasElements(value: NonEmptyArray | T[] | null | undefined): value is NonEmptyArray {\n const emptyArrayLength = 0;\n return !ObjectExtensions.isNullOrUndefined(value) && value.length > emptyArrayLength;\n }\n\n /**\n * Retrieves the first element in the array or default value if the array is empty.\n * @param values - The array with values.\n * @param defaultValue - Optional parameter to specify default value. If not specified, undefined will be used.\n * @returns First element or default value.\n */\n export function firstOrDefault(values: NonEmptyArray | T[] | null | undefined, defaultValue?: T): T | undefined {\n if (hasElements(values)) {\n return values[0];\n }\n return defaultValue;\n }\n\n /**\n * Remove duplicate elements in the array.\n * @param value - The array to examine.\n * @returns An array with only unique elements.\n */\n export function unique(value: T[]): T[] {\n if (!hasElements(value)) {\n return [];\n }\n\n return Array.from(new Set(value));\n }\n\n /**\n * Checks if all elements satisfy given condition.\n * @param value - The array to examine.\n * @param predicate - The function which checks an element.\n * @returns True if the array is empty or all the inner elements satisfy given condition,\n * false if at least one element does not pass the condition.\n */\n export function all(value: T[] | null | undefined, predicate: (value: T, index: number, array: T[]) => boolean): boolean {\n if (!hasElements(value)) {\n return true;\n }\n\n return value.filter(predicate).length === value.length;\n }\n\n /**\n * Filters out null and undefined values from the given array.\n * @param value - The array with possibly undefined/null items.\n * @returns All items which are not null or undefined.\n */\n export function validValues(value: (T | undefined | null)[] | undefined | null): T[] {\n if (!hasElements(value)) {\n return [];\n }\n\n return value.filter(item => !ObjectExtensions.isNullOrUndefined(item)) as T[];\n }\n\n /**\n * Merges items from 2-dimensional array into one array with all items.\n * @param value - The 2-dimensional array with the items.\n * @returns All items retrieved from all inner arrays.\n */\n export function flatten(value: ((T | undefined | null)[] | undefined | null)[]): T[] {\n let result: T[] = [];\n\n if (!hasElements(value)) {\n return result;\n }\n\n for (const arrayLine of value) {\n if (!ObjectExtensions.isNullOrUndefined(arrayLine)) {\n result = result.concat(validValues(arrayLine));\n }\n }\n\n return result;\n }\n\n /**\n * Check if two arrays are equal.\n * @param firstArray - The array with the items.\n * @param secondArray - Another array with the items.\n * @param comparator - The comparator which compares the values and returns true if two objects are equal, false otherwise.\n * @returns True if arrays have the same items, false otherwise.\n */\n export function equals(\n firstArray: T[],\n secondArray: T[],\n comparator?: (valueFromFirstArray: T, valueFromSecondArray: T) => boolean\n ): boolean {\n if (firstArray.length !== secondArray.length) {\n return false;\n }\n\n if (comparator === undefined) {\n return JSON.stringify(firstArray) === JSON.stringify(secondArray);\n }\n\n for (let index = 0; index < firstArray.length; ++index) {\n if (!comparator(firstArray[index], secondArray[index])) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Check if two arrays have the same elements irrespective of the order.\n * @param firstArray - The array with the items.\n * @param secondArray - Another array with the items.\n * @param comparator - The comparator which compares the values and returns true if two objects are equal, false otherwise.\n * @returns True if arrays have the same items, false otherwise.\n */\n export function haveSameItems(\n firstArray: T[],\n secondArray: T[],\n comparator: (valueFromFirstArray: T, valueFromSecondArray: T) => boolean = (valueFromFirstArray: T, valueFromSecondArray: T) =>\n valueFromFirstArray === valueFromSecondArray\n ): boolean {\n if (firstArray.length !== secondArray.length) {\n return false;\n }\n\n for (const item of firstArray) {\n if (!secondArray.some(otherItem => comparator(item, otherItem))) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Calculates a sum of elements in the given array.\n * @param data - List of items.\n * @returns Sum of elements.\n */\n export function calculateSum(data: NonEmptyArray): number {\n let result = data[0];\n for (let index = 1; index < data.length; ++index) {\n result += data[index];\n }\n\n return result;\n }\n\n /**\n * Reverses the elements in the array without modifying the original one.\n * @param array - The array with the items.\n * @returns A new array with reversed order.\n */\n export function reverse(array: T[]): T[] {\n const newArray: T[] = [];\n\n for (let index = array.length - 1; index >= 0; --index) {\n newArray.push(array[index]);\n }\n\n return newArray;\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { ObjectExtensions } from './object-extensions';\n\n/**\n * Namespace which extends enum functionality.\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport namespace EnumExtensions {\n /**\n * @description Returns a list of numeric values and enum names for the specified enum.\n * @param enumClass\n * @param {any} value The enum to examine.\n * @returns {(number | string)[]} An array of numeric values and enum names.\n */\n export function getValues(enumClass: any): (number | string)[] {\n if (ObjectExtensions.isNullOrUndefined(enumClass)) {\n return [];\n }\n\n return Object.keys(enumClass).map(item => enumClass[item]);\n }\n\n /**\n * @description Returns a list of enum names for the specified enum.\n * @param enumClass\n * @param {any} value The enum to examine.\n * @returns {(number | string)[]} An array of string values.\n */\n export function getNames(enumClass: any): string[] {\n return getValues(enumClass).filter(ObjectExtensions.isString);\n }\n\n /**\n * @description Returns a list of numeric values for the specified enum.\n * @param enumClass\n * @param {any} value The enum to examine.\n * @returns {number[]} An array of numeric values.\n */\n export function getNumericValues(enumClass: any): number[] {\n return getValues(enumClass).filter(ObjectExtensions.isNumber);\n }\n\n /**\n * @description Returns a list of enum values for the specified enum.\n * @param enumClass\n * @param {any} value The enum to examine.\n * @returns {number[]} An array of enum values.\n */\n export function getEnumValues(enumClass: any): T[] {\n return getNumericValues(enumClass).map(value => value);\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { ObjectExtensions } from './object-extensions';\n\n/**\n * Namespace which extends string functionality.\n */\nexport namespace StringExtensions {\n /**\n * Checks if string is null, undefined, empty, or whitespace.\n * @param {string | null | undefined} value The string to examine.\n * @returns {boolean} True if it's null, undefined, empty, or whitespace; false otherwise.\n */\n export function isNullOrWhitespace(value: string | null | undefined): boolean {\n return isNullOrEmpty(value) || value!.trim() === '';\n }\n\n /**\n * Checks if string is null, undefined, or empty.\n * @param {string | null | undefined} value The string to examine.\n * @returns {boolean} True if it's null, undefined, empty, or whitespace; false otherwise.\n */\n export function isNullOrEmpty(value: string | null | undefined): boolean {\n if (ObjectExtensions.isNullOrUndefined(value)) {\n return true;\n }\n\n if (!ObjectExtensions.isString(value)) {\n throw new Error('StringExtensions has received a non-string input.');\n }\n\n return value === '';\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/**\n * Namespace which extends Object functionality.\n */\n/* eslint-disable @typescript-eslint/no-explicit-any */\nexport namespace ObjectExtensions {\n /**\n * @description Verifies whether the value is null or undefined.\n * @param {any} value The value to examine.\n * @returns {boolean} True if the value is null or undefined, false otherwise.\n */\n export function isNullOrUndefined(value: any): value is null | undefined {\n return value === null || value === undefined;\n }\n\n /**\n * @description Verifies whether the value is of type string.\n * @param {any} value The value to examine.\n * @returns {boolean} True if the value is a string, false otherwise.\n */\n export function isString(value: any): value is string {\n return typeof value === 'string';\n }\n\n /**\n * @description Verifies whether the value is of type number.\n * @param {any} value The value to examine.\n * @returns {boolean} True if the value is a number, false otherwise.\n */\n export function isNumber(value: any): value is number {\n return typeof value === 'number';\n }\n\n /**\n * Verifies whether the object is a function.\n * @param {any} object The object.\n * @param value\n * @returns {boolean} True if the object is a function, false otherwise.\n */\n export function isFunction(value: any): boolean {\n return typeof value === 'function';\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { IAny, ICreateActionContext, IGeneric } from '@msdyn365-commerce/core';\nimport { QueryResultSettings } from '@msdyn365-commerce/retail-proxy';\n\nimport { QueryResultSettingsProxy } from './QueryResultSettingsProxy';\n\nexport interface ISearchData {\n q: string;\n skip: number;\n top: number;\n itemsPerPage: string;\n maxItems: string;\n channelId: number;\n queryResultSettings: QueryResultSettings;\n}\n\nexport const parseSearchData = (inputData: ICreateActionContext>): ISearchData => {\n // Query is of type 'IDictionary | undefined', so that q and skip are not recognized by tsc\n const {\n requestContext: {\n // @ts-expect-error:2339\n query: { q, top, skip },\n apiSettings: { channelId }\n },\n // @ts-expect-error:2339\n config: { maxItems, itemsPerPage }\n } = inputData;\n const queryResultSettings = QueryResultSettingsProxy.fromInputData(inputData).QueryResultSettings;\n return {\n q,\n skip: (skip && Number(skip)) || 0,\n top: (top && Number(top)) || 50,\n itemsPerPage, // TODO BUGBUG 21667361\n maxItems, // TODO BUGBUG 21667361\n channelId,\n queryResultSettings\n };\n};\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport {\n ProductAvailableQuantity,\n ProductDimensionValueInventoryAvailability,\n ProductInventoryAvailability\n} from '@msdyn365-commerce/retail-proxy';\n\n/**\n * This setting defines the delivery modes supported.\n */\nexport enum DeliveryMode {\n allWareHouses = 0,\n shipping = 1,\n pickup = 2\n}\n\n/**\n * This setting defines the inventory levels supported.\n */\nexport enum InventoryLevels {\n physicalAvailable = 'physicalAvailable',\n totalAvailable = 'totalAvailable',\n threshold = 'inventoryThreshold'\n}\n\n/**\n * Product inventory information class.\n */\nexport interface IProductInventoryInformation {\n ProductAvailableQuantity: ProductAvailableQuantity;\n StockLevelCode?: string;\n StockLevelLabel?: string;\n IsProductAvailable: boolean;\n InventLocationId?: string;\n deliveryType?: DeliveryMode;\n}\n\n/**\n * This setting defines the inventory level values return by the API.\n */\nexport enum InventoryLevelValues {\n outOfStock = 'OOS',\n available = 'AVAIL'\n}\n\n/**\n * Retrieves inventory level code from the dimension based on the app config setting.\n * @param dimensionValuesWithInventory - The dimension info.\n * @param inventoryLevel - App config setting for inventory level.\n * @returns Inventory level code value.\n */\nexport const getInventoryLevelCodeFromDimensionValue = (\n dimensionValuesWithInventory: ProductDimensionValueInventoryAvailability,\n inventoryLevel?: InventoryLevels | undefined\n): InventoryLevelValues | undefined => {\n if (inventoryLevel === InventoryLevels.totalAvailable) {\n return dimensionValuesWithInventory.TotalAvailableInventoryLevelCode as InventoryLevelValues | undefined;\n }\n if (inventoryLevel === InventoryLevels.physicalAvailable) {\n return dimensionValuesWithInventory.PhysicalAvailableInventoryLevelCode as InventoryLevelValues | undefined;\n }\n return undefined;\n};\n\n/**\n * Retrieves inventory level code from the product availability based on the app config setting.\n * @param productAvailability - The product availability info.\n * @param inventoryLevel - App config setting for inventory level.\n * @returns Inventory level code value.\n */\nexport const getInventoryLevelCodeFromProductAvailability = (\n productAvailability: ProductInventoryAvailability,\n inventoryLevel?: InventoryLevels | undefined\n): InventoryLevelValues | undefined => {\n if (inventoryLevel === InventoryLevels.totalAvailable) {\n return productAvailability.TotalAvailableInventoryLevelCode as InventoryLevelValues | undefined;\n }\n if (inventoryLevel === InventoryLevels.physicalAvailable) {\n return productAvailability.PhysicalAvailableInventoryLevelCode as InventoryLevelValues | undefined;\n }\n return undefined;\n};\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { PromiseBodyWrapper } from './base-promise-queue';\nimport { PromiseQueue } from './promise-queue';\n\nexport enum FinitePromiseQueueError {\n InvalidMaxQueueLengthPassed = 'Invalid maxQueueLength value passed to FinitePromiseQueue. maxQueueLength should be more or equal to 2.',\n ProcessWasDiscardedFromTheQueue = 'The process was discarded from FinitePromiseQueue.'\n}\n\n/**\n * Represents a FIFO queue over promises with a limited number of elements waiting for execution.\n * @remark\n * In case the queue reaches the limit,\n * before adding a new element the queue discards the oldest added element which is waiting to be processed.\n * Does not discard elements which are in progress under execution.\n * The discarded element will not be processed and executed.\n * @author Bohdan Yevchenko \n */\nexport class FinitePromiseQueue extends PromiseQueue {\n /**\n * @see constructor\n */\n private readonly _maxQueueLength: number;\n\n /**\n * Initializes the queue with the given limit.\n * @param {number} maxQueueLength\n * Defines the limit of maximum number of elements in the queue.\n * @remarks Includes both the number of elements waiting for the execution\n * and the element processed by the queue at the moment (in case there is some).\n * Value can't be less than 2.\n */\n public constructor(maxQueueLength: number) {\n if (maxQueueLength < 2) {\n throw new Error(FinitePromiseQueueError.InvalidMaxQueueLengthPassed);\n }\n\n super();\n this._maxQueueLength = maxQueueLength;\n }\n\n /**\n * Adds promise to the queue and automatically starts the queue execution.\n * @remarks In case the queue has reached the limit, also discards the oldest added element.\n * @param {PromiseBodyWrapper} promiseBody\n * The body of a function which contains a call to the promise which has to be executed in the queue.\n */\n public async enqueue(promiseBody: PromiseBodyWrapper): Promise {\n let totalElementsCount = this._queue.length;\n\n // If queue hasn't finished processing an element,\n // consider this element as pending.\n if (this._isBusy) {\n ++totalElementsCount;\n }\n\n // Discards the oldest added element from the queue to meet the given limitations.\n // The very first element in the queue is considered as oldest added.\n // Can't discard the element which is under execution as the promise can't be cancelled.\n if (totalElementsCount === this._maxQueueLength) {\n const element = this._queue.shift();\n if (element) {\n element.reject(FinitePromiseQueueError.ProcessWasDiscardedFromTheQueue);\n }\n }\n\n return super.enqueue(promiseBody);\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { IPromiseQueue, PromiseBodyWrapper, PromiseRejectType, PromiseResolveType } from './base-promise-queue';\n\n/**\n * Represents an inner node which is stored in a promise queue.\n * Used internally in the PromiseQueue implementation.\n * @author Bohdan Yevchenko \n */\nclass PromiseQueueElement {\n /**\n * The body of a wrapper-function which contains a call to the promise which has to be executed in the queue.\n */\n public readonly body: PromiseBodyWrapper;\n\n /**\n * Method that resolves the promise after the promise from the body is resolved.\n */\n public readonly resolve: PromiseResolveType;\n\n /**\n * Method that rejects the promise after the promise from the body is rejected.\n */\n public readonly reject: PromiseRejectType;\n\n /**\n * Initializes queue element with the given data.\n * @param {PromiseBodyWrapper} body The body of a wrapper-function which contains a call to the promise which has to be executed in the queue.\n * @param {PromiseResolveType} resolve Method that resolves the promise after the promise from the body is resolved.\n * @param {PromiseRejectType} reject Method that rejects the promise after the promise from the body is rejected.\n */\n public constructor(\n body: PromiseBodyWrapper,\n resolve: PromiseResolveType,\n reject: PromiseRejectType\n ) {\n this.body = body;\n this.resolve = resolve;\n this.reject = reject;\n }\n}\n\n/**\n * Represents a FIFO basic queue over promises.\n * @author Bohdan Yevchenko \n */\nexport class PromiseQueue implements IPromiseQueue {\n /**\n * A list of promises waiting for execution.\n */\n protected readonly _queue: PromiseQueueElement[];\n\n /**\n * Defines whether the queue is processing some element.\n */\n protected _isBusy: boolean;\n\n /**\n * Defines whether the queue can start processing new element.\n */\n private get _canProcess(): boolean {\n return !this._isBusy && this._queue.length > 0;\n }\n\n /**\n * Creates a new instance of PromiseQueue.\n */\n public constructor() {\n this._queue = [];\n this._isBusy = false;\n }\n\n /**\n * Adds promise to the queue and automatically starts the queue execution.\n * @param {PromiseBodyWrapper} promiseBody\n * The body of a function which contains a call to the promise which has to be executed in the queue.\n */\n public async enqueue(promiseBody: PromiseBodyWrapper): Promise {\n return new Promise(async (resolve, reject) => {\n this._queue.push(new PromiseQueueElement(promiseBody, resolve, reject));\n await this._dequeue();\n });\n }\n\n /**\n * If the queue is free, starts processing the first element in the queue and waits until all the elements are processed.\n * Otherwise (if busy or has no elements to process), does nothing.\n */\n private async _dequeue(): Promise {\n // Skip if queue is not able to process any elements.\n if (!this._canProcess) {\n return;\n }\n\n // Lock queue to prevent parallel execution.\n this._isBusy = true;\n\n // Retrieve an element from the waiting queue and start processing.\n const element: PromiseQueueElement = this._queue.shift()!;\n await this._processElement(element);\n\n // Continue executing the subsequent queue elements.\n await this._processNext();\n }\n\n /**\n * Executes the given wrapper over the promise and calls initial resolve/reject correspondingly.\n * @param {PromiseQueueElement} element The queue element which should be processed now.\n */\n private async _processElement(element: PromiseQueueElement): Promise {\n try {\n await element\n .body()\n .then(element.resolve)\n .catch(element.reject);\n } catch (error) {\n element.reject(error);\n }\n }\n\n /**\n * Unlocks the queue and tries to process the next element in the queue.\n */\n private async _processNext(): Promise {\n this._isBusy = false;\n await this._dequeue();\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { v4 as uuidv4 } from 'uuid';\n\n/**\n * Namespace which provides functionality for GUID.\n */\nexport namespace Guid {\n export function generateGuid(): string {\n return uuidv4();\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { Guid as _guid } from './guid';\n\nexport namespace Random {\n export import Guid = _guid;\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/**\n * Regular expressions to validate emails.\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport abstract class EmailRegex {\n /**\n * Represents a HTML5 Validation Regex.\n *\n * A valid email address is a string that matches the email production of the following ABNF, the character set for which is Unicode.\n * This ABNF implements the extensions described in RFC 1123.\n *\n * For more info: https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address.\n */\n public static readonly html5EmailRegex = /^[a-zA-Z0-9.!#$%&'*+=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z])?)+$/;\n\n /**\n * Returns a default regex which should be used for most email validation cases.\n *\n * As of now, the default regex is HTML5 email regex standard.\n * @see EmailRegex.html5EmailRegex - The regex which is set to be default right now.\n *\n * @returns Regular expression for email validation.\n */\n public static get defaultRegex(): RegExp {\n return EmailRegex.html5EmailRegex;\n }\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/**\n * Regular expressions to validate passwords.\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport abstract class PasswordRegex {\n // eslint-disable-next-line max-len\n public static readonly defaultRegex = /^((?=.*[a-z])(?=.*[A-Z])(?=.*\\d)|(?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])|(?=.*[a-z])(?=.*\\d)(?=.*[^A-Za-z0-9])|(?=.*[A-Z])(?=.*\\d)(?=.*[^A-Za-z0-9]))([A-Za-z\\d@#$%^&*\\-_+=[\\]{}|\\\\:',?/`~'();!]|\\.(?!@)){8,16}$/;\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\n/**\n * Regular expressions to validate phone number.\n */\n// eslint-disable-next-line @typescript-eslint/no-extraneous-class\nexport abstract class PhoneRegex {\n public static readonly defaultRegex = '^$|^[- +()]*[0-9][- +()0-9]*$';\n}\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport msdyn365Commerce, {\n IAny,\n ICommerceApiSettings,\n ICoreContext,\n ICreateActionContext,\n IGeneric,\n IRequestContext,\n generateImageUrl as generateImageUrlFromSdk\n} from '@msdyn365-commerce/core';\nimport {\n AsyncResult,\n AttributeValue,\n CartLine,\n ChannelDeliveryOptionConfiguration,\n ChannelInventoryConfiguration,\n CommerceListLine,\n ProductDimension,\n ProductDimensionType,\n ProductSearchResult,\n QueryResultSettings,\n SimpleProduct\n} from '@msdyn365-commerce/retail-proxy';\n\nimport { ProductDetailsCriteria } from '../get-full-products';\nimport { IKeyValuePair } from './data-structures';\nimport { ArrayExtensions, StringExtensions } from './extensions';\nimport { parseSearchData } from './input-data-parser';\nimport { InventoryLevels } from './product-inventory-information';\n\nexport const wrapInResolvedAsyncResult = (input: T | null | undefined): AsyncResult => {\n return >{\n status: 'SUCCESS',\n result: input,\n metadata: {}\n };\n};\n\nexport const wrapInRejectedAsyncResult = (input: T | null | undefined): AsyncResult => {\n return >{\n status: 'FAILED',\n result: input,\n metadata: {}\n };\n};\n\nexport const buildQueryResultSettings = (inputData: ICreateActionContext, IGeneric>): QueryResultSettings => {\n try {\n const searchInputData = parseSearchData(inputData);\n const search = searchInputData.q;\n if (!search) {\n throw new Error('Query string ?q={searchText} is needed for search actions.');\n }\n const top = (searchInputData.maxItems && Number(searchInputData.maxItems)) || searchInputData.top;\n return { Paging: { Top: top, Skip: searchInputData.skip } };\n } catch {\n return {};\n }\n};\n\n/**\n * Utility function to extract the active productId in the following priority:\n * First query param (productId), then UrlToken (itemId), then module config.\n * @param inputData - The Action Input data.\n * @returns Productid or undefined.\n */\nexport const getSelectedProductIdFromActionInput = (inputData: ICreateActionContext>): string | undefined => {\n const context = inputData.requestContext;\n if (context.query?.productId) {\n return context.query.productId;\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- Exsiting code.\n } else if (\n context.urlTokens &&\n inputData.requestContext.urlTokens.itemId &&\n inputData.requestContext.urlTokens.pageType === 'Product'\n ) {\n return context.urlTokens.itemId;\n } else if (inputData && inputData.config && inputData.config.productId) {\n return inputData.config.productId;\n }\n return undefined;\n};\n\n/**\n * Generates a Image URL based on data return from retail server.\n * @param imageUrl The image url returned by Retail Server.\n * @param ctx The request context.\n * @param apiSettings\n */\nexport const generateImageUrl = (imageUrl: string | undefined, apiSettings: ICommerceApiSettings): string | undefined => {\n return generateImageUrlFromSdk(apiSettings, imageUrl);\n};\n\n/**\n * Represents app configuration for dimensions.\n */\nexport interface IDimensionsConfig {\n dimensionsAsSwatchType?: DimensionTypes[];\n dimensionsInProductCard?: DimensionTypes[];\n inventoryLevel?: InventoryLevels;\n dimensionToPreSelectInProductCard?: DimensionTypes;\n enableStockCheck?: boolean;\n warehouseAggregation?: string;\n}\n\n/**\n * Represents app configuration for dimensions.\n */\nexport interface IDimensionsApp {\n config: IDimensionsConfig;\n}\n\n/**\n * Represents product dimension types.\n */\nexport enum DimensionTypes {\n none = 'none',\n color = 'color',\n configuration = 'configuration',\n size = 'size',\n style = 'style'\n}\n\n/**\n * Defines display configuration types.\n */\nexport enum DimensionSwatchDisplayTypes {\n default = 'default',\n productCard = 'productCard'\n}\n\n/**\n * Checks if rendering the particular dimensions is allowed.\n * @param dimensionType - Dimension to be displayed.\n * @param context - Core application context.\n * @param displayType - The swatch location, the component from which it comes from.\n * @returns Updates the state with new product page url.\n */\nexport const checkIfShouldDisplayAsSwatch = (\n dimensionType: DimensionTypes,\n context: ICoreContext,\n displayType: DimensionSwatchDisplayTypes = DimensionSwatchDisplayTypes.default\n): boolean => {\n // Additional checks for the product card since it has a separate config setting.\n if (displayType === DimensionSwatchDisplayTypes.productCard) {\n const dimensionsToDisplayOnProductCard = context.app.config.dimensionsInProductCard;\n if (\n !ArrayExtensions.hasElements(dimensionsToDisplayOnProductCard) ||\n dimensionsToDisplayOnProductCard.includes(DimensionTypes.none) ||\n !dimensionsToDisplayOnProductCard.includes(dimensionType)\n ) {\n return false;\n }\n }\n\n const dimensionsToDisplayAsSwatch = context.app.config.dimensionsAsSwatchType;\n return (\n ArrayExtensions.hasElements(dimensionsToDisplayAsSwatch) &&\n !dimensionsToDisplayAsSwatch.includes(DimensionTypes.none) &&\n dimensionsToDisplayAsSwatch.includes(dimensionType)\n );\n};\n\n/**\n * Generates an image URL for a swatch.\n * @param imageUrl - The image url returned by Retail Server.\n * @param apiSettings - The request context.\n * @returns Full image url.\n */\nexport const generateSwatchImageUrl = (imageUrl: string, apiSettings: ICommerceApiSettings): string => {\n if (imageUrl.startsWith('http')) {\n return imageUrl;\n }\n\n return apiSettings.baseImageUrl + encodeURIComponent(imageUrl);\n};\n\n/**\n * Generates a Image URL for a product based on data return from retail server.\n * @param product The Product returned by Retail Server.\n * @param ctx The request context.\n * @param apiSettings\n */\nexport const generateProductImageUrl = (\n product: SimpleProduct | ProductSearchResult,\n apiSettings: ICommerceApiSettings\n): string | undefined => {\n return generateImageUrl(product.PrimaryImageUrl, apiSettings);\n};\n\n/**\n * Creates a CartLine object from the passed data.\n * @param product The product.\n * @param quantity The quantity.\n * @param catalogId The catalog.\n */\nexport const buildCartLine = (product: SimpleProduct, quantity?: number, catalogId?: number): CartLine => {\n return {\n CatalogId: catalogId || 0,\n Description: product.Description,\n\n // TODO: Investigate this value and what it represents\n EntryMethodTypeValue: 3,\n ItemId: product.ItemId,\n ProductId: product.RecordId,\n Quantity: quantity || 1,\n TrackingId: '',\n UnitOfMeasureSymbol: product.DefaultUnitOfMeasure\n };\n};\n\n/**\n * Creates a CommerceListLine (also know as WishlistLine) object from the passed data.\n * @param productId The RecordId of the Product to be added.\n * @param customerId The account number of the customer.\n * @param wishlistId The Id of the commerce list.\n */\nexport const buildWishlistLine = (productId: number, customerId: string, wishlistId: number): CommerceListLine => {\n return {\n CommerceListId: wishlistId,\n ProductId: productId,\n CustomerId: customerId\n };\n};\n\n/**\n * Utility function to prepare the product details criteria before getting full product:\n * @param inputData The Action Input data\n */\nexport const getProductDetailsCriteriaFromActionInput = (inputData: ICreateActionContext>): ProductDetailsCriteria => {\n if (inputData && inputData.config) {\n return {\n getPrice: !inputData.config.hidePrice,\n getRating: !inputData.config.hideRating\n };\n }\n return {\n getPrice: true,\n getRating: true\n };\n};\n\n/**\n * Transforms search text into the expected 'search terms' format, expected by refiner APIs.\n * @param searchText Free-form text used for searching for products or categories of products.\n */\nexport const ensureSearchTextIsFormedProperly = (searchText: string): string => {\n const prefix = searchText.startsWith(\"'\") ? '' : \"'\";\n const suffix = searchText.endsWith(\"'\") ? '' : \"'\";\n return `${prefix}${searchText}${suffix}`;\n};\n\nexport const ensureSafeSearchText = (searchText: string): string => {\n return searchText.replace(/[^\\d\\sA-Za-z]+/g, '');\n};\n\n/**\n * @deprecated Please use `generateCacheKey` instead.\n */\nexport const buildCacheKey = (base: string, apiSettings: ICommerceApiSettings, locale?: string): string => {\n return `${base}-chanId:${apiSettings.channelId}-catId:${apiSettings.catalogId}${locale ? `-${locale}` : ''}`;\n};\n\n/**\n * Represents a list of keys for general parameters used in the cache key.\n */\nenum DefaultCacheKeyParameterKeys {\n channelIdKey = 'CHANNELID',\n appSettingsCatalogIdKey = 'APPSETTINGSCATALOGID'\n}\n\n/**\n * Generates a key from set of arguments\n * @param apiSettings - Request context API settings.\n * @param entries - Cache key parameters.\n * @returns String which represents the cache key.\n */\nexport const generateCacheKey = (\n apiSettings?: ICommerceApiSettings,\n ...entries: IKeyValuePair[]\n): string => {\n const parsedEntries: IKeyValuePair[] = entries.map(pair => {\n return { key: pair.key.toLocaleUpperCase(), value: pair.value };\n });\n\n const cacheKeyArgumentsKeys = parsedEntries.map(pair => pair.key);\n\n if (apiSettings) {\n if (!cacheKeyArgumentsKeys.includes(DefaultCacheKeyParameterKeys.channelIdKey)) {\n parsedEntries.push({ key: DefaultCacheKeyParameterKeys.channelIdKey, value: apiSettings.channelId });\n }\n\n if (!cacheKeyArgumentsKeys.includes(DefaultCacheKeyParameterKeys.appSettingsCatalogIdKey) && apiSettings.catalogId) {\n parsedEntries.push({ key: DefaultCacheKeyParameterKeys.appSettingsCatalogIdKey, value: apiSettings.catalogId });\n }\n }\n\n return parsedEntries\n .sort((a, b) => a.key.localeCompare(b.key))\n .map(pair => `${pair.key}:{${pair.value}}`)\n .join('-');\n};\n\nexport const buildCacheKeyWithUrlTokens = (base: string, requestContext: IRequestContext): string => {\n const urlTokens = requestContext.urlTokens;\n const defaultCacheKey = buildCacheKey(base, requestContext.apiSettings, requestContext.locale);\n return urlTokens ? `${defaultCacheKey}-${urlTokens.itemId}-${urlTokens.recordId}-${urlTokens.pageType}` : defaultCacheKey;\n};\n\n/**\n * Generates a key from set of arguments as inputs.\n *\n * @param args Argument list of pivots to generate key from.\n * @param handler Handler function for null/undefined values.\n */\n\ntype TKeyTypes = string | number | boolean | null | undefined;\ninterface IGenerateKeyOptions {\n separator?: string;\n handler?(input: null | undefined): string;\n}\nexport const generateKey = (args: TKeyTypes[], options?: IGenerateKeyOptions): string => {\n const { handler, separator }: IGenerateKeyOptions = { ...{ separator: '-', handler: undefined }, ...(options || {}) };\n return args\n .map(arg => {\n if (arg === null || arg === undefined) {\n if (handler) {\n return handler(arg);\n }\n }\n return arg;\n })\n .join(separator);\n};\n\n/**\n * Gets the fall back image url for a variant image.\n * @param itemId Item id of a product.\n * @param apiSettings Api setting from request context.\n */\nexport const getFallbackImageUrl = (\n itemId: string | undefined,\n apiSettings: ICommerceApiSettings,\n isOmniFeatureEnabled?: boolean\n): string | undefined => {\n if (!itemId || isOmniFeatureEnabled) {\n return '';\n }\n\n const parsedItemId = itemId.trim().split(' ')[0];\n\n const productUrl = `Products/${parsedItemId}_000_001.png`;\n return generateImageUrl(productUrl, apiSettings);\n};\n\n/**\n * Converts retail proxy product dimension type to display dimension type.\n * @param productDimensionType - Product dimension type from retail proxy.\n * @returns Local dimension type.\n */\nexport const convertProductDimensionTypeToDimensionTypes = (productDimensionType: ProductDimensionType): DimensionTypes => {\n switch (productDimensionType) {\n case ProductDimensionType.Color:\n return DimensionTypes.color;\n case ProductDimensionType.Configuration:\n return DimensionTypes.configuration;\n case ProductDimensionType.Size:\n return DimensionTypes.size;\n case ProductDimensionType.Style:\n return DimensionTypes.style;\n default:\n return DimensionTypes.none;\n }\n};\n\n/**\n * Converts display dimension type to retail proxy product dimension type.\n * @param dimensionType - Local dimension type.\n * @returns Product dimension type from retail proxy.\n */\nexport const convertDimensionTypeToProductDimensionType = (dimensionType: DimensionTypes): ProductDimensionType => {\n switch (dimensionType) {\n case DimensionTypes.color:\n return ProductDimensionType.Color;\n case DimensionTypes.configuration:\n return ProductDimensionType.Configuration;\n case DimensionTypes.size:\n return ProductDimensionType.Size;\n case DimensionTypes.style:\n return ProductDimensionType.Style;\n default:\n return ProductDimensionType.None;\n }\n};\n\n/**\n * Sets dimensions to url.\n * @param inputUrl - Url to update.\n * @param productDimensions - Dimensions to set.\n */\nexport const setDimensionValuesToQuery = (inputUrl: URL, productDimensions: ProductDimension[]): void => {\n for (const dimension of productDimensions) {\n const dimensionValue = dimension.DimensionValue?.Value;\n if (!StringExtensions.isNullOrWhitespace(dimensionValue)) {\n inputUrl.searchParams.set(convertProductDimensionTypeToDimensionTypes(dimension.DimensionTypeValue), dimensionValue!);\n }\n }\n\n if (msdyn365Commerce.isBrowser) {\n window.history.replaceState(window.history.state, '', inputUrl.toString().replace(inputUrl.host, window.location.host));\n }\n};\n\n/**\n * Retrieves dimension value stored in url.\n * @param urlParameters - Url parameters.\n * @param productDimensionType - The dimension type to retrieve.\n * @returns Product dimension item.\n */\nconst parseDimensionFromUrl = (\n urlParameters: URLSearchParams,\n productDimensionType: ProductDimensionType\n): ProductDimension | undefined => {\n const localDimensionType = convertProductDimensionTypeToDimensionTypes(productDimensionType);\n const value = urlParameters.get(localDimensionType);\n if (!value) {\n return undefined;\n }\n return {\n DimensionTypeValue: productDimensionType,\n DimensionValue: {\n RecordId: 0,\n Value: value\n }\n };\n};\n\n/**\n * Retrieves all dimensions from URL.\n * @param urlParameters - Url parameters.\n * @returns Product dimensions stored in url.\n */\nconst parseDimensionsFromUrl = (urlParameters: URLSearchParams): ProductDimension[] => {\n const dimensionsToParse: ProductDimensionType[] = [\n ProductDimensionType.Color,\n ProductDimensionType.Configuration,\n ProductDimensionType.Size,\n ProductDimensionType.Style\n ];\n const parsedDimensions = dimensionsToParse.map(dimension => parseDimensionFromUrl(urlParameters, dimension));\n return ArrayExtensions.validValues(parsedDimensions);\n};\n\n/**\n * Utility function to extract the dimension values from input url querystring.\n * @param inputUrl - The request url.\n * @returns The selected dimension values.\n */\nexport const getDimensionValuesFromQuery = (inputUrl: URL): ProductDimension[] => {\n const urlWithIgnoredCase = new URL(inputUrl.toString().toLocaleLowerCase());\n const urlParameters = urlWithIgnoredCase.searchParams;\n const dimensions: ProductDimension[] = parseDimensionsFromUrl(urlParameters);\n return dimensions;\n};\n\n/**\n * Get attribute values by channel inventory configuration.\n * @param attributeValues - The attributeValues.\n * @param channelInventoryConfiguration - The channelInventoryConfiguration.\n * @returns The attributeValues filter by channel inventory configuration.\n */\nexport const getAttributeValuesByConfiguration = (\n attributeValues: AttributeValue[] | null,\n channelInventoryConfiguration: ChannelInventoryConfiguration | null\n): AttributeValue[] => {\n if (!attributeValues) {\n return [];\n }\n if (!channelInventoryConfiguration) {\n return attributeValues;\n }\n\n return attributeValues.filter(\n attribute =>\n attribute.RecordId !== channelInventoryConfiguration.InventoryProductAttributeRecordId &&\n attribute.RecordId !== channelInventoryConfiguration.ProductAvailabilitySortableAttributeRecordId\n );\n};\n\n/**\n * Utility function to remove domain querystring parameter from url.\n * @param inputUrl - The request url.\n * @returns The yrl after dropping domain querystring.\n */\nexport const removeDomainQspFromUrl = (inputUrl: string, requestContext: IRequestContext): string => {\n if (requestContext?.features && requestContext.features.remove_domain_qsp) {\n const Url = new URL(inputUrl);\n const urlParams: URLSearchParams = new URLSearchParams(Url.search);\n if (urlParams.has('domain')) {\n urlParams.delete('domain');\n }\n Url.search = urlParams.toString();\n return Url.toString();\n }\n return inputUrl;\n};\n\n/**\n * Utility function to validate catalog Id for B2B user .\n * @param catalogId - The catalog.\n */\nexport const validateCatalogId = (catalogId?: number | undefined) => {\n if (catalogId === -1) {\n throw new Error(\n 'Catalog id is -1. It means no valid catalogs were found for the user. Make sure the user has some valid catalogs assigned.'\n );\n }\n};\n\n/**\n * Utility function to check deliveryMode .\n * @param cartline - CartLine item.\n * @param retailMulitplePickupFeatureState - pickUp feature state, default to false.\n * @param channelDeliveryOptionConfig - Channel Delivery Option Configuration.\n * @param pickupDeliveryModeCode -pickUp delivery mode code string.\n * @returns true id cartline item is pickUp item else false.\n */\nexport const getDeliveryMode = (\n cartLine: CartLine,\n featureSate: boolean = false,\n channelDeliveryOptionConfig?: ChannelDeliveryOptionConfiguration,\n pickupDeliveryMode?: string\n) => {\n if (!featureSate) {\n return cartLine.DeliveryMode === pickupDeliveryMode;\n }\n return (\n cartLine.DeliveryMode ===\n channelDeliveryOptionConfig?.PickupDeliveryModeCodes?.find(deliveryMode => deliveryMode === cartLine.DeliveryMode)\n );\n};\n\n/**\n * Utility function to check if cartline item is pickupitem .\n * @param cartline - CartLine item.\n * @param retailMulitplePickupFeatureState - pickUp feature state.\n * @param channelDeliveryOptionConfig - Channel Delivery Option Configuration.\n * @param pickupDeliveryModeCode -pickUp delivery mode code string.\n * @returns true id cartline item is pickUp item else false.\n */\nexport const isCartLineItemPickUpType = (\n cartline: CartLine,\n retailMulitplePickupFeatureState: boolean = false,\n channelDeliveryOptionConfig?: ChannelDeliveryOptionConfiguration,\n pickupDeliveryModeCode?: string\n): boolean => {\n // check if cartlineitem is pickup item\n if (\n cartline.DeliveryMode &&\n cartline.DeliveryMode !== '' &&\n getDeliveryMode(cartline, retailMulitplePickupFeatureState, channelDeliveryOptionConfig, pickupDeliveryModeCode)\n ) {\n return true;\n }\n return false;\n};\n","/*!\n * Copyright (c) Microsoft Corporation.\n * All rights reserved. See LICENSE in the project root for license information.\n */\n\nimport { IActionContext } from '@msdyn365-commerce/core';\nimport { CartLine } from '@msdyn365-commerce/retail-proxy';\nimport { SimpleProduct } from '@msdyn365-commerce/retail-proxy/dist/Entities/CommerceTypes.g';\n\nimport { ArrayExtensions } from './extensions/array-extensions';\nimport { IProductInventoryInformation } from './product-inventory-information';\n\n/**\n * Cart line inventory validation result interface.\n */\nexport interface ICartLineInventoryValidationResult {\n /**\n * Define whether the cart lines inventory is valid across multiple cart lines.\n */\n readonly isValid: boolean;\n\n /**\n * Defines the list of product id with invalid inventory.\n */\n readonly productIdWithErrors: number[];\n}\n\n/**\n * Validates inventory across cart lines.\n * @param cartLines - The cart lines.\n * @param productAvailabilities - The product availability collection.\n * @param actionContext - The action context.\n * @param products - The products.\n * @param emailDeliveryModeCode - The emailDeliveryModeCode.\n * @returns True if all product quantity are available, false otherwise.\n */\n// eslint-disable-next-line complexity -- existing code.\nexport function validateCartLinesInventory(\n cartLines: CartLine[],\n productAvailabilities: IProductInventoryInformation[],\n actionContext: IActionContext,\n products?: SimpleProduct[],\n emailDeliveryModeCode?: string | undefined\n): ICartLineInventoryValidationResult {\n const cartLineMap = new Map();\n const defaultCartLineQuantity = 1;\n if (!actionContext.requestContext.app.config.enableStockCheck) {\n return {\n isValid: true,\n productIdWithErrors: []\n };\n }\n const productIdWithErrors = [];\n let isValid = true;\n\n if (ArrayExtensions.hasElements(cartLines) && ArrayExtensions.hasElements(productAvailabilities)) {\n // Consolidate products in different cart lines into single entry with the total cart quantity\n for (const cartLine of cartLines) {\n // Skip validation if is an invoice inline.\n if (cartLine.ProductId && !cartLine.IsInvoiceLine && !cartLine.IsGiftCardLine) {\n if (!cartLineMap.has(cartLine.ProductId)) {\n cartLineMap.set(cartLine.ProductId, cartLine.Quantity ?? defaultCartLineQuantity);\n } else {\n const cartLineTotal = cartLineMap.get(cartLine.ProductId) ?? 0;\n cartLineMap.delete(cartLine.ProductId);\n cartLineMap.set(cartLine.ProductId, cartLineTotal + (cartLine.Quantity ?? defaultCartLineQuantity));\n }\n }\n }\n\n // Hashing product availability object by product ID.\n const productAvailabilityMap = new Map();\n for (const productAvailability of productAvailabilities) {\n if (\n productAvailability.ProductAvailableQuantity.ProductId &&\n !productAvailabilityMap.has(productAvailability.ProductAvailableQuantity.ProductId)\n ) {\n productAvailabilityMap.set(productAvailability.ProductAvailableQuantity.ProductId, productAvailability);\n }\n }\n\n // Compare total quantity with the available quantity from the inventory API, also validate that the product is available.\n for (const productId of Array.from(cartLineMap.keys())) {\n const cartLineQty = cartLineMap.get(productId) ?? defaultCartLineQuantity;\n const productAvailability = productAvailabilityMap.get(productId);\n const availableQuantity = productAvailability?.ProductAvailableQuantity.AvailableQuantity ?? undefined;\n\n // If product is non-stocked or cartLine is electronic delivery, then no inventory check\n const cartLine = cartLines.find(line => line.ProductId === productId);\n const cartLineProduct = products?.find(product => product.RecordId === productId);\n let isStockedItem = true;\n if (cartLineProduct) {\n isStockedItem = !!cartLineProduct.Behavior?.IsStockedProduct;\n }\n const isEmailDelivery =\n cartLine?.DeliveryMode && cartLine.DeliveryMode !== '' ? cartLine.DeliveryMode === emailDeliveryModeCode : false;\n const shouldSkipInventoryCheck = !isStockedItem || isEmailDelivery;\n\n // If product is non-stocked or cartLine is electronic delivery, then no inventory check\n if (shouldSkipInventoryCheck) {\n continue;\n }\n if (!productAvailability?.IsProductAvailable || (availableQuantity && cartLineQty > availableQuantity)) {\n productIdWithErrors.push(productId);\n isValid = false;\n }\n }\n }\n return {\n isValid,\n productIdWithErrors\n };\n}\n"],"names":["CategoriesInput","constructor","context","mappedToHierarchy","maxItems","includeRootCategory","getCacheKey","generateCacheKey","this","apiSettings","key","value","sitePath","catalogId","locale","getCacheObjectType","_mappedToHierarchy","dataCacheType","getLocale","channelId","getCatalogId","getFriendlyName","nameTranslations","nameTranslation","length","find","item","Language","toLowerCase","Text","mapCategoryToHierarchy","categoryList","ctx","_rootCategory$Childre","categoryMap","category","localName","NameTranslations","categoryHierarchy","_objectSpread","NeutralizedName","Name","RecordId","rootCategory","Object","values","parentId","ParentCategory","Url","getCategoryUrl","parent","Children","push","createCategoriesHierarchyInput","inputData","topItems","config","topCategories","Number","parseInt","requestContext","async","getCategoryHierarchyAction","input","categories","getCategoryAction","RawCategoriesInput","getCategoryHierarchyActionDataAction","createObservableDataAction","id","action","_context$apiSettings","_requestContext","CategoriesDataActions","callerContext","_inputData$config","QueryResultSettingsProxy","queryResultSettings","fromModuleData","sortingCriteria","undefined","query","top","skip","Paging","Skip","Top","itemsPerPage","Sorting","_config$itemsPerPage","_inputData$requestCon","_inputData$requestCon2","app","platform","defaultPageSizeForAPI","Columns","map","column","ColumnName","IsDescending","join","parameterize","name","arguments","sep","parameterizeFeatureFlags","neutralizedName","candidateName","msdyn365Commerce","platformSettings","enableUrlLocalization","enableUrlEncoding","encodeURIComponent","replace","trim","getCategorySlug","categoryName","Slug","getParameterizeFeatureFlags","getUrlSync","getInvoiceDetailsPageUrlSync","invoiceId","url","includes","substr","indexOf","getProductUrlSync","product","selectedProduct","MasterProductId","getProductPageUrlSync","recordId","Dictionary","_values","_length","_len","entries","Array","_key","forEach","keyValuePair","setValue","removeValue","hasValue","getValue","getValueWithDefaultValue","defaultValue","isEmpty","clear","getValues","getKeys","keys","getKeyValuePairs","Event","_subscribers","subscribe","instance","unsubscribe","instanceId","filter","element","unsubscribeAll","trigger","subscriber","handler","ArrayExtensions","hasElements","ObjectExtensions","isNullOrUndefined","validValues","firstOrDefault","unique","from","Set","all","predicate","flatten","result","arrayLine","concat","equals","firstArray","secondArray","comparator","JSON","stringify","index","haveSameItems","valueFromFirstArray","valueFromSecondArray","some","otherItem","calculateSum","data","reverse","array","newArray","EnumExtensions","StringExtensions","enumClass","getNumericValues","isNumber","getNames","isString","getEnumValues","isNullOrEmpty","Error","isNullOrWhitespace","isFunction","parseSearchData","q","fromInputData","QueryResultSettings","DeliveryMode","InventoryLevels","InventoryLevelValues","getInventoryLevelCodeFromDimensionValue","dimensionValuesWithInventory","inventoryLevel","totalAvailable","TotalAvailableInventoryLevelCode","physicalAvailable","PhysicalAvailableInventoryLevelCode","getInventoryLevelCodeFromProductAvailability","productAvailability","FinitePromiseQueueError","FinitePromiseQueue","PromiseQueue","maxQueueLength","InvalidMaxQueueLengthPassed","super","_maxQueueLength","promiseBody","totalElementsCount","_queue","_isBusy","shift","reject","ProcessWasDiscardedFromTheQueue","enqueue","PromiseQueueElement","body","resolve","Promise","_dequeue","_canProcess","_processElement","_processNext","then","catch","error","Guid","Random","generateGuid","uuidv4","_guid","EmailRegex","html5EmailRegex","PasswordRegex","defaultRegex","PhoneRegex","getSelectedProductIdFromActionInput","_context$query","productId","urlTokens","itemId","pageType","generateImageUrl","imageUrl","generateImageUrlFromSdk","DimensionTypes","DimensionSwatchDisplayTypes","checkIfShouldDisplayAsSwatch","dimensionType","displayType","default","productCard","dimensionsToDisplayOnProductCard","dimensionsInProductCard","none","dimensionsToDisplayAsSwatch","dimensionsAsSwatchType","generateSwatchImageUrl","startsWith","baseImageUrl","generateProductImageUrl","PrimaryImageUrl","buildWishlistLine","customerId","wishlistId","CommerceListId","ProductId","CustomerId","getProductDetailsCriteriaFromActionInput","getPrice","hidePrice","getRating","hideRating","buildCacheKey","base","DefaultCacheKeyParameterKeys","parsedEntries","pair","toLocaleUpperCase","cacheKeyArgumentsKeys","channelIdKey","appSettingsCatalogIdKey","sort","a","b","localeCompare","buildCacheKeyWithUrlTokens","defaultCacheKey","getFallbackImageUrl","isOmniFeatureEnabled","parsedItemId","split","convertProductDimensionTypeToDimensionTypes","productDimensionType","ProductDimensionType","Color","color","Configuration","configuration","Size","size","Style","style","convertDimensionTypeToProductDimensionType","None","setDimensionValuesToQuery","inputUrl","productDimensions","dimension","_dimension$DimensionV","dimensionValue","DimensionValue","Value","searchParams","set","DimensionTypeValue","isBrowser","window","history","replaceState","state","toString","host","location","parseDimensionsFromUrl","urlParameters","parsedDimensions","parseDimensionFromUrl","localDimensionType","get","getDimensionValuesFromQuery","URL","toLocaleLowerCase","getAttributeValuesByConfiguration","attributeValues","channelInventoryConfiguration","attribute","InventoryProductAttributeRecordId","ProductAvailabilitySortableAttributeRecordId","removeDomainQspFromUrl","features","remove_domain_qsp","urlParams","URLSearchParams","search","has","delete","validateCatalogId","getDeliveryMode","cartLine","_channelDeliveryOptio","featureSate","channelDeliveryOptionConfig","pickupDeliveryMode","PickupDeliveryModeCodes","deliveryMode","isCartLineItemPickUpType","cartline","retailMulitplePickupFeatureState","pickupDeliveryModeCode","validateCartLinesInventory","cartLines","productAvailabilities","actionContext","products","emailDeliveryModeCode","cartLineMap","Map","enableStockCheck","isValid","productIdWithErrors","IsInvoiceLine","IsGiftCardLine","_cartLineMap$get","_cartLine$Quantity2","cartLineTotal","Quantity","_cartLine$Quantity","productAvailabilityMap","ProductAvailableQuantity","_cartLineMap$get2","_productAvailability$","cartLineQty","availableQuantity","AvailableQuantity","line","cartLineProduct","isStockedItem","_cartLineProduct$Beha","Behavior","IsStockedProduct","isEmailDelivery","IsProductAvailable"],"sourceRoot":""}