{"version":3,"sources":["webpack:///../../../src/utilities/utils.ts?fbc0","webpack:///../../../../src/utilities/data-structures/dictionary.ts?bab3","webpack:///../../../../src/utilities/events/event.ts?15a9","webpack:///../../../../src/utilities/regex/email-regex.ts?6a6a","webpack:///../../../../src/utilities/regex/password-regex.ts?456d","webpack:///../../../../src/utilities/regex/phone-regex.ts?9ada","webpack:///../../../src/utilities/input-data-parser.ts?027a","webpack:///../../../src/utilities/QueryResultSettingsProxy.ts?5e44","webpack:///../../src/get-categories-hierarchy.ts?acde","webpack:///../../../src/utilities/product-inventory-information.ts?0ec6","webpack:///../../../../src/utilities/promise-queue/finite-promise-queue.ts?77bf","webpack:///../../../src/utilities/index.ts?5407","webpack:///../../../../src/utilities/extensions/enum-extensions.ts?cf51","webpack:///../../../../src/utilities/extensions/string-extensions.ts?ab9f","webpack:///../../../src/utilities/validate-cartlines-inventory.ts?8b82","webpack:///./node_modules/@msdyn365-commerce-modules/retail-actions/node_modules/uuid/dist/esm-browser/rng.js?b47d","webpack:///./node_modules/@msdyn365-commerce-modules/retail-actions/node_modules/uuid/dist/esm-browser/regex.js?08ba","webpack:///./node_modules/@msdyn365-commerce-modules/retail-actions/node_modules/uuid/dist/esm-browser/stringify.js?6cb1","webpack:///./node_modules/@msdyn365-commerce-modules/retail-actions/node_modules/uuid/dist/esm-browser/validate.js?acea","webpack:///./node_modules/@msdyn365-commerce-modules/retail-actions/node_modules/uuid/dist/esm-browser/v4.js?0101","webpack:///../../../../src/utilities/random/guid.ts?1947","webpack:///../../../../src/utilities/random/index.ts?1f9d","webpack:///../../../../src/utilities/Url-builder/parameterize.ts?f5a5","webpack:///../../../../src/utilities/Url-builder/category-url-builder.ts?e564","webpack:///../../../../src/utilities/Url-builder/invoice-url-builder.ts?d542","webpack:///../../../../src/utilities/Url-builder/product-url-builder.ts?baf1","webpack:///../../../../src/utilities/promise-queue/promise-queue.ts?e362","webpack:///../../../../src/utilities/extensions/object-extensions.ts?6388","webpack:///../../../../src/utilities/promise-queue/index.ts?c43d","webpack:///../../../../src/utilities/extensions/array-extensions.ts?1a2a","webpack:///../../src/get-current-category-hierarchy.ts?d48e","webpack:///../../../../src/utilities/events/index.ts?d3a5","webpack:///../../src/get-categories.ts?8dc6"],"names":["getSelectedProductIdFromActionInput","inputData","context","requestContext","query","productId","urlTokens","itemId","pageType","config","generateImageUrl","imageUrl","apiSettings","generateImageUrlFromSdk","DimensionTypes","DimensionSwatchDisplayTypes","checkIfShouldDisplayAsSwatch","dimensionType","displayType","default","productCard","dimensionsToDisplayOnProductCard","app","dimensionsInProductCard","ArrayExtensions","hasElements","includes","none","dimensionsToDisplayAsSwatch","dimensionsAsSwatchType","generateSwatchImageUrl","startsWith","baseImageUrl","encodeURIComponent","generateProductImageUrl","product","PrimaryImageUrl","buildWishlistLine","customerId","wishlistId","CommerceListId","ProductId","CustomerId","getProductDetailsCriteriaFromActionInput","getPrice","hidePrice","getRating","hideRating","buildCacheKey","base","locale","channelId","catalogId","buildCacheKeyWithUrlTokens","defaultCacheKey","recordId","generateKey","args","options","handler","separator","undefined","map","arg","join","getFallbackImageUrl","parsedItemId","trim","split","productUrl","convertProductDimensionTypeToDimensionTypes","productDimensionType","ProductDimensionType","Color","color","Configuration","configuration","Size","size","Style","style","convertDimensionTypeToProductDimensionType","None","setDimensionValuesToQuery","inputUrl","productDimensions","dimension","searchParams","set","DimensionTypeValue","DimensionValue","Value","window","history","replaceState","state","toString","replace","host","location","parseDimensionsFromUrl","urlParameters","parsedDimensions","localDimensionType","value","get","RecordId","parseDimensionFromUrl","validValues","getDimensionValuesFromQuery","URL","toLocaleLowerCase","getAttributeValuesByConfiguration","attributeValues","channelInventoryConfiguration","filter","attribute","InventoryProductAttributeRecordId","Dictionary","constructor","this","_values","_length","entries","forEach","keyValuePair","setValue","key","removeValue","hasValue","getValue","getValueWithDefaultValue","defaultValue","isEmpty","length","clear","getValues","getKeys","Object","keys","getKeyValuePairs","Event","_subscribers","subscribe","instance","push","unsubscribe","instanceId","element","unsubscribeAll","trigger","subscriber","EmailRegex","html5EmailRegex","PasswordRegex","PhoneRegex","parseSearchData","q","top","skip","maxItems","itemsPerPage","queryResultSettings","QueryResultSettingsProxy","fromInputData","QueryResultSettings","Number","topHint","Paging","Top","skipHint","Skip","sortingHintData","Sorting","Columns","column","ColumnName","IsDescending","sortingHint","fromModuleData","sortingCriteria","parseInt","platform","defaultPageSizeForAPI","CategoriesInput","mappedToHierarchy","getCacheKey","sitePath","getCacheObjectType","_mappedToHierarchy","dataCacheType","getLocale","getCatalogId","mapCategoryToHierarchy","categoryList","ctx","categoryMap","reduce","memo","category","localName","nameTranslations","nameTranslation","find","item","Language","toLowerCase","Text","getFriendlyName","NameTranslations","categoryHierarchy","NeutralizedName","Name","zeroCategory","id","parentId","ParentCategory","Url","getCategoryUrl","parent","Children","createCategoriesHierarchyInput","topItems","topCategories","async","getCategoryHierarchyAction","input","categories","getCategoryAction","RawCategoriesInput","getCategoryHierarchyActionDataAction","createObservableDataAction","action","DeliveryMode","InventoryLevels","InventoryLevelValues","getInventoryLevelCodeFromDimensionValue","dimensionValuesWithInventory","inventoryLevel","totalAvailable","TotalAvailableInventoryLevelCode","physicalAvailable","PhysicalAvailableInventoryLevelCode","getInventoryLevelCodeFromProductAvailability","productAvailability","FinitePromiseQueueError","FinitePromiseQueue","PromiseQueue","maxQueueLength","Error","InvalidMaxQueueLengthPassed","super","_maxQueueLength","promiseBody","totalElementsCount","_queue","_isBusy","shift","reject","ProcessWasDiscardedFromTheQueue","enqueue","EnumExtensions","StringExtensions","enumClass","ObjectExtensions","isNullOrUndefined","getNumericValues","isNumber","isString","isNullOrEmpty","validateCartLinesInventory","cartLines","productAvailabilities","actionContext","products","emailDeliveryModeCode","cartLineMap","Map","enableStockCheck","isValid","productIdWithErrors","cartLine","IsInvoiceLine","has","cartLineTotal","delete","Quantity","productAvailabilityMap","ProductAvailableQuantity","Array","from","cartLineQty","availableQuantity","AvailableQuantity","line","cartLineProduct","isStockedItem","Behavior","IsStockedProduct","isEmailDelivery","IsProductAvailable","getRandomValues","rnds8","Uint8Array","rng","crypto","bind","msCrypto","validate","uuid","REGEX","test","byteToHex","i","substr","stringify","arr","offset","arguments","TypeError","v4","Guid","Random","buf","rnds","random","uuidv4","_guid","parameterize","name","sep","parameterizeFeatureFlags","neutralizedName","candidateName","msdyn365Commerce","platformSettings","enableUrlLocalization","enableUrlEncoding","Slug","getParameterizeFeatureFlags","getCategorySlug","categoryName","getUrlSync","getInvoiceDetailsPageUrlSync","invoiceId","url","indexOf","getProductUrlSync","selectedProduct","MasterProductId","getProductPageUrlSync","PromiseQueueElement","body","resolve","Promise","_dequeue","_canProcess","_processElement","_processNext","then","catch","error","values","Set","predicate","result","arrayLine","concat","firstArray","secondArray","comparator","JSON","index","valueFromFirstArray","valueFromSecondArray","some","otherItem","data","array","newArray","CurrentCategoryHierarchyInput","activeCategoryId","categoryId","activeCategoryParsedId","findCategoryHierarchy","innerCategoryHierarchy","getCurrentCategoryHierarchyAction","fullCategoryHierarchy","getCategoriesHierarchy","reverse","getCurrentCategoryHierarchyActionDataAction","getCategoryActionDataAction","CategoriesDataActions","getCategoriesAsync","callerContext","getPagingFromInputDataOrDefaultValue"],"mappings":"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","file":"static/js/3.92dc65991c2be36baa29.chunk.js","sourcesContent":["/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { generateImageUrl as generateImageUrlFromSdk, IAny, ICommerceApiSettings, ICoreContext,\n ICreateActionContext, IGeneric, IRequestContext } from '@msdyn365-commerce/core';\nimport {\n AsyncResult, AttributeValue, CartLine, ChannelInventoryConfiguration, CommerceListLine, ProductDimension,\n ProductDimensionType, ProductSearchResult, QueryResultSettings, SimpleProduct\n} from '@msdyn365-commerce/retail-proxy';\n\nimport { ProductDetailsCriteria } from '../get-full-products';\nimport { ArrayExtensions } 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 (context.urlTokens && inputData.requestContext.urlTokens.itemId && inputData.requestContext.urlTokens.pageType === 'Product') {\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}\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): boolean => {\n\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 (!ArrayExtensions.hasElements(dimensionsToDisplayOnProductCard) ||\n dimensionsToDisplayOnProductCard.includes(DimensionTypes.none) ||\n !dimensionsToDisplayOnProductCard.includes(dimensionType)) {\n return false;\n }\n }\n\n const dimensionsToDisplayAsSwatch = context.app.config.dimensionsAsSwatchType;\n return ArrayExtensions.hasElements(dimensionsToDisplayAsSwatch) &&\n !dimensionsToDisplayAsSwatch.includes(DimensionTypes.none) &&\n dimensionsToDisplayAsSwatch.includes(dimensionType);\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\nexport const buildCacheKey = (base: string, apiSettings: ICommerceApiSettings, locale?: string): string => {\n return `${base}-chanId:${apiSettings.channelId}-catId:${apiSettings.catalogId}${locale ? `-${locale}` : ''}`;\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 = (itemId: string | undefined, apiSettings: ICommerceApiSettings): string | undefined => {\n if (!itemId) {\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 inputUrl.searchParams.set(\n convertProductDimensionTypeToDimensionTypes(dimension.DimensionTypeValue), dimension.DimensionValue?.Value ?? '');\n }\n\n window.history.replaceState(window.history.state, '', inputUrl.toString().replace(inputUrl.host, window.location.host));\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 = (urlParameters: URLSearchParams, productDimensionType: ProductDimensionType): 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, channelInventoryConfiguration: ChannelInventoryConfiguration | null): AttributeValue[] => {\n if (!attributeValues) {\n return [];\n }\n if (!channelInventoryConfiguration) {\n return attributeValues;\n }\n\n return attributeValues.filter(attribute => attribute.RecordId !== channelInventoryConfiguration.InventoryProductAttributeRecordId);\n};\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\n/**\n * Regular expressions to validate emails.\n */\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-Z0-9])?)*$/; // eslint-disable-line unicorn/better-regex, security/detect-unsafe-regex, require-unicode-regexp, max-len -- HTML 5 Email Validation Regex.\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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\n/**\n * Regular expressions to validate passwords.\n */\nexport abstract class PasswordRegex {\n // eslint-disable-next-line max-len, unicorn/better-regex, require-unicode-regexp -- Default regex from the existing implementation.\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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\n/**\n * Regular expressions to validate phone number.\n */\nexport abstract class PhoneRegex {\n\n public static readonly defaultRegex = '^$|^[- +()]*[0-9][- +()0-9]*$';\n}\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt 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 // @ts-expect-error:2339\n const { requestContext: { query: { q, top, skip }, apiSettings: { channelId } }, config: { maxItems, itemsPerPage } } = 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. All rights reserved.\n * See License.txt 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 * Private constructor, expect instances to be created with the factory method.\n * @param queryResultSettings - Query result setting.\n */\n private constructor(\n queryResultSettings: QueryResultSettings\n ) {\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 = (this.queryResultSettings.Sorting!.Columns || []).map((column: SortColumn) => {\n return `${column.ColumnName}--${column.IsDescending && 'desc' || 'asc'}`;\n }).join(',') || undefined;\n const sortingHint = `sortBy-${sortingHintData}`;\n return `${topHint}|${skipHint}|${sortingHint}`;\n }\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","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { CacheType, createObservableDataAction, getCatalogId, IAction, IActionContext, IActionInput, IAny, ICommerceApiSettings, ICreateActionContext, IGeneric, IRequestContext } 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 { buildCacheKey } 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 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) {\n this._mappedToHierarchy = mappedToHierarchy;\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 = () => buildCacheKey(`${this.channelId}|${this.sitePath}|top-${this.maxItems || 250} | ${this.catalogId}`,\n this.apiSettings, this.locale);\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 = (categoryList: Category[], ctx: IActionContext, locale?: string): CategoryHierarchy[] => {\n if (!categoryList || categoryList.length === 0) {\n return [];\n }\n\n const categoryMap: ICategoryMap = categoryList.reduce((memo: ICategoryMap, category: Category) => {\n const localName = getFriendlyName(locale, category.NameTranslations);\n const categoryHierarchy = { ...category };\n categoryHierarchy.NeutralizedName = category.Name;\n categoryHierarchy.Name = localName || categoryHierarchy.NeutralizedName;\n memo[category.RecordId] = categoryHierarchy;\n return memo;\n }, {});\n\n let zeroCategory = categoryMap[0];\n\n Object.keys(categoryMap).forEach((id: string) => {\n const element = categoryMap[+id];\n const parentId = element.ParentCategory;\n element.Url = getCategoryUrl(element, ctx, categoryMap);\n if (parentId === 0) {\n zeroCategory = element;\n return;\n }\n\n const parent = parentId && categoryMap[parentId];\n if (parent) {\n parent.Children = parent.Children || [];\n parent.Children.push(element);\n }\n });\n\n return (zeroCategory && zeroCategory.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(\n new RawCategoriesInput(ctx.requestContext, false, input.maxItems),\n ctx\n );\n return mapCategoryToHierarchy(categories, ctx, input.getLocale());\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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { ProductAvailableQuantity, ProductDimensionValueInventoryAvailability, ProductInventoryAvailability } 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): InventoryLevelValues | undefined => {\n\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): InventoryLevelValues | undefined => {\n\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. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nexport * from './data-structures';\nexport * from './events';\nexport * from './extensions';\nexport * from './product-inventory-information';\nexport * from './promise-queue';\nexport * from './QueryResultSettingsProxy';\nexport * from './random';\nexport * from './regex';\nexport * from './utils';\nexport * from './validate-cartlines-inventory';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { ObjectExtensions } from './object-extensions';\n\n/**\n * Namespace which extends enum functionality.\n */\nexport namespace EnumExtensions {\n\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","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt 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 /**\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. All rights reserved.\n * See License.txt 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 /**\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 */\nexport function validateCartLinesInventory(\n cartLines: CartLine[],\n productAvailabilities: IProductInventoryInformation[],\n actionContext: IActionContext,\n products?: SimpleProduct[],\n emailDeliveryModeCode?: string | undefined): 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\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) {\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\n if (productAvailability.ProductAvailableQuantity.ProductId &&\n !productAvailabilityMap.has(productAvailability.ProductAvailableQuantity.ProductId)) {\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 = (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","// Unique ID creation requires a high quality random # generator. In the browser we therefore\n// require the crypto API and do not support built-in fallback to lower quality random number\n// generators (like Math.random()).\nvar getRandomValues;\nvar rnds8 = new Uint8Array(16);\nexport default function rng() {\n // lazy load so that environments that need to polyfill have a chance to do so\n if (!getRandomValues) {\n // getRandomValues needs to be invoked in a context where \"this\" is a Crypto implementation. Also,\n // find the complete implementation of crypto (msCrypto) on IE11.\n getRandomValues = typeof crypto !== 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== 'undefined' && typeof msCrypto.getRandomValues === 'function' && msCrypto.getRandomValues.bind(msCrypto);\n\n if (!getRandomValues) {\n throw new Error('crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported');\n }\n }\n\n return getRandomValues(rnds8);\n}","export default /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;","import validate from './validate.js';\n/**\n * Convert array of 16 byte values to UUID string format of the form:\n * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\n */\n\nvar byteToHex = [];\n\nfor (var i = 0; i < 256; ++i) {\n byteToHex.push((i + 0x100).toString(16).substr(1));\n}\n\nfunction stringify(arr) {\n var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n // Note: Be careful editing this code! It's been tuned for performance\n // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434\n var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one\n // of the following:\n // - One or more input array values don't map to a hex octet (leading to\n // \"undefined\" in the uuid)\n // - Invalid input values for the RFC `version` or `variant` fields\n\n if (!validate(uuid)) {\n throw TypeError('Stringified UUID is invalid');\n }\n\n return uuid;\n}\n\nexport default stringify;","import REGEX from './regex.js';\n\nfunction validate(uuid) {\n return typeof uuid === 'string' && REGEX.test(uuid);\n}\n\nexport default validate;","import rng from './rng.js';\nimport stringify from './stringify.js';\n\nfunction v4(options, buf, offset) {\n options = options || {};\n var rnds = options.random || (options.rng || rng)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`\n\n rnds[6] = rnds[6] & 0x0f | 0x40;\n rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided\n\n if (buf) {\n offset = offset || 0;\n\n for (var i = 0; i < 16; ++i) {\n buf[offset + i] = rnds[i];\n }\n\n return buf;\n }\n\n return stringify(rnds);\n}\n\nexport default v4;","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport msdyn365Commerce, { IParameterizeFeatureFlags } from '@msdyn365-commerce/core';\n\nexport function parameterize(name: string = '', sep = '-', parameterizeFeatureFlags: IParameterizeFeatureFlags = {}, neutralizedName?: string) {\n // If neutralizedName flag enabled, we use neutralizedName to construct string\n const candidateName = (msdyn365Commerce.platformSettings && msdyn365Commerce.platformSettings.enableUrlLocalization || parameterizeFeatureFlags.enableUrlLocalization) ? name : 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 (parameterizeFeatureFlags.enableUrlEncoding || msdyn365Commerce.platformSettings && msdyn365Commerce.platformSettings.enableUrlEncoding) {\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(candidateName.toLowerCase().replace(/[\\s!&'()*]+/g, '-').trim().replace(/-+/g, '-').replace(/^-+|-+$/g, ''));\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. All rights reserved.\n * See License.txt 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(category: CategoryHierarchy, categoryMap: ICategoryMap, parameterizeFeatureFlags?: IParameterizeFeatureFlags): 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 = category.Slug || `${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. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt 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. All rights reserved.\n * See License.txt 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.body().then(element.resolve).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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\n/**\n * Namespace which extends Object functionality.\n */\nexport namespace ObjectExtensions {\n\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","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nexport * from './base-promise-queue';\nexport * from './finite-promise-queue';\nexport * from './promise-queue';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt 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 /**\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(firstArray: T[], secondArray: T[], comparator?: (valueFromFirstArray: T, valueFromSecondArray: T) => boolean): 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 // eslint-disable-next-line unicorn/no-for-loop -- Disable as we need to compare by indices.\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[], secondArray: T[],\n comparator: (valueFromFirstArray: T, valueFromSecondArray: T) => boolean = (\n valueFromFirstArray: T, valueFromSecondArray: T) => valueFromFirstArray === valueFromSecondArray): boolean {\n\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. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport {\n createObservableDataAction, IAction, IActionContext,\n IActionInput, IAny, ICreateActionContext, IGeneric, IRequestContext\n} from '@msdyn365-commerce/core';\n\nimport getCategoriesHierarchy, { CategoriesInput } from './get-categories-hierarchy';\nimport { ArrayExtensions } from './utilities';\n\n/**\n * Action Input Class for get-current-category-hierarchy.\n */\nexport class CurrentCategoryHierarchyInput extends CategoriesInput {\n public activeCategoryId: number;\n\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number, activeCategoryId?: number) {\n super(context, mappedToHierarchy, maxItems);\n const defaultActiveCategoryId = 0;\n this.activeCategoryId = activeCategoryId ?? defaultActiveCategoryId;\n }\n\n // @ts-expect-error: Overriding cache object type\n public getCacheObjectType = () => 'CurrentCategoryHierarchy';\n\n public getCacheKey = () => `${this.activeCategoryId}-${this.channelId}`;\n}\n\n/**\n * Creates the input required for the data action.\n * @param inputData\n */\nexport const createCategoriesHierarchyInput = (inputData: ICreateActionContext>): IActionInput => {\n const topItems = inputData.config?.topCategories && Number.parseInt(inputData.config.topCategories, 10);\n let activeCategoryId = inputData.requestContext.urlTokens.pageType === 'Category' ? inputData.requestContext.urlTokens.itemId : undefined;\n activeCategoryId = activeCategoryId ?? inputData.requestContext.query?.categoryId;\n const activeCategoryParsedId = activeCategoryId ? Number.parseInt(activeCategoryId, 10) : undefined;\n\n return new CurrentCategoryHierarchyInput(inputData.requestContext, true, topItems, activeCategoryParsedId);\n};\n\n/**\n * Finds the given category in the list of categories and returns an array with the info on where it's located.\n * @param categories - Categories list to search from.\n * @param categoryId - The category id to find.\n * @returns A list of categories starting from the given category id, ending up the root parent.\n */\nconst findCategoryHierarchy = (categories: CategoryHierarchy[], categoryId: number): CategoryHierarchy[] | null => {\n for (const category of categories) {\n if (category.RecordId === categoryId) {\n return [category];\n }\n\n if (ArrayExtensions.hasElements(category.Children)) {\n const innerCategoryHierarchy = findCategoryHierarchy(category.Children, categoryId);\n if (ArrayExtensions.hasElements(innerCategoryHierarchy)) {\n innerCategoryHierarchy.push(category);\n return innerCategoryHierarchy;\n }\n }\n }\n\n return null;\n};\n\n/**\n * Get the hierarchy of categories that are currently active as a parent -> child array.\n * Return will be as follows: [ParentCategory, Child, SubChild, SubSubChild].\n * @param input\n * @param ctx\n */\nexport async function getCurrentCategoryHierarchyAction(input: CurrentCategoryHierarchyInput, ctx: IActionContext): Promise {\n const fullCategoryHierarchy = await getCategoriesHierarchy(new CategoriesInput(ctx.requestContext, true, input.maxItems), ctx);\n const categoryArray = findCategoryHierarchy(fullCategoryHierarchy, input.activeCategoryId) ?? [];\n const sortedCategoryArray = categoryArray.reverse();\n return sortedCategoryArray;\n}\n\nexport const getCurrentCategoryHierarchyActionDataAction = createObservableDataAction({\n id: '@msdyn365-commerce-modules/retail-actions/get-current-category-hierarchy',\n action: getCurrentCategoryHierarchyAction as IAction,\n input: createCategoriesHierarchyInput\n});\n\nexport default getCurrentCategoryHierarchyActionDataAction;\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nexport * from './event';\nexport * from './event-subscriber';\n","/*--------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * See License.txt in the project root for license information.\n *--------------------------------------------------------------*/\n\nimport { CategoryHierarchy } from '@msdyn365-commerce/commerce-entities';\nimport { CacheType, createObservableDataAction, getCatalogId, IAction, IActionContext,\n IActionInput, IAny, ICreateActionContext, IGeneric, IRequestContext } from '@msdyn365-commerce/core';\nimport { CategoriesDataActions } from '@msdyn365-commerce/retail-proxy';\n\nimport { QueryResultSettingsProxy } from './utilities/QueryResultSettingsProxy';\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 _mappedToHierarchy: boolean;\n\n public constructor(context: IRequestContext, mappedToHierarchy: boolean, maxItems?: number) {\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 => `${this.channelId}|top-${this.maxItems || 250}|${this.catalogId ?? 0}`;\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/**\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 callerContext: ctx,\n queryResultSettings: QueryResultSettingsProxy.getPagingFromInputDataOrDefaultValue(ctx)\n },\n input.channelId, input.catalogId) 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"],"sourceRoot":""}