#
tokens: 49773/50000 32/825 files (page 7/61)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 7 of 61. Use http://codebase.md/taurgis/sfcc-dev-mcp?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .DS_Store
├── .github
│   ├── dependabot.yml
│   ├── instructions
│   │   ├── mcp-node-tests.instructions.md
│   │   └── mcp-yml-tests.instructions.md
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   ├── documentation.yml
│   │   ├── feature_request.yml
│   │   └── question.yml
│   ├── PULL_REQUEST_TEMPLATE
│   │   ├── bug_fix.md
│   │   ├── documentation.md
│   │   └── new_tool.md
│   ├── pull_request_template.md
│   └── workflows
│       ├── ci.yml
│       ├── deploy-pages.yml
│       ├── publish.yml
│       └── update-docs.yml
├── .gitignore
├── .husky
│   └── pre-commit
├── aegis.config.docs-only.json
├── aegis.config.json
├── aegis.config.with-dw.json
├── AGENTS.md
├── ai-instructions
│   ├── claude-desktop
│   │   └── claude_custom_instructions.md
│   ├── cursor
│   │   └── .cursor
│   │       └── rules
│   │           ├── debugging-workflows.mdc
│   │           ├── hooks-development.mdc
│   │           ├── isml-templates.mdc
│   │           ├── job-framework.mdc
│   │           ├── performance-optimization.mdc
│   │           ├── scapi-endpoints.mdc
│   │           ├── security-patterns.mdc
│   │           ├── sfcc-development.mdc
│   │           ├── sfra-controllers.mdc
│   │           ├── sfra-models.mdc
│   │           ├── system-objects.mdc
│   │           └── testing-patterns.mdc
│   └── github-copilot
│       └── copilot-instructions.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── docs
│   ├── best-practices
│   │   ├── cartridge_creation.md
│   │   ├── isml_templates.md
│   │   ├── job_framework.md
│   │   ├── localserviceregistry.md
│   │   ├── ocapi_hooks.md
│   │   ├── performance.md
│   │   ├── scapi_custom_endpoint.md
│   │   ├── scapi_hooks.md
│   │   ├── security.md
│   │   ├── sfra_client_side_js.md
│   │   ├── sfra_controllers.md
│   │   ├── sfra_models.md
│   │   └── sfra_scss.md
│   ├── dw_campaign
│   │   ├── ABTest.md
│   │   ├── ABTestMgr.md
│   │   ├── ABTestSegment.md
│   │   ├── AmountDiscount.md
│   │   ├── ApproachingDiscount.md
│   │   ├── BonusChoiceDiscount.md
│   │   ├── BonusDiscount.md
│   │   ├── Campaign.md
│   │   ├── CampaignMgr.md
│   │   ├── CampaignStatusCodes.md
│   │   ├── Coupon.md
│   │   ├── CouponMgr.md
│   │   ├── CouponRedemption.md
│   │   ├── CouponStatusCodes.md
│   │   ├── Discount.md
│   │   ├── DiscountPlan.md
│   │   ├── FixedPriceDiscount.md
│   │   ├── FixedPriceShippingDiscount.md
│   │   ├── FreeDiscount.md
│   │   ├── FreeShippingDiscount.md
│   │   ├── PercentageDiscount.md
│   │   ├── PercentageOptionDiscount.md
│   │   ├── PriceBookPriceDiscount.md
│   │   ├── Promotion.md
│   │   ├── PromotionMgr.md
│   │   ├── PromotionPlan.md
│   │   ├── SlotContent.md
│   │   ├── SourceCodeGroup.md
│   │   ├── SourceCodeInfo.md
│   │   ├── SourceCodeStatusCodes.md
│   │   └── TotalFixedPriceDiscount.md
│   ├── dw_catalog
│   │   ├── Catalog.md
│   │   ├── CatalogMgr.md
│   │   ├── Category.md
│   │   ├── CategoryAssignment.md
│   │   ├── CategoryLink.md
│   │   ├── PriceBook.md
│   │   ├── PriceBookMgr.md
│   │   ├── Product.md
│   │   ├── ProductActiveData.md
│   │   ├── ProductAttributeModel.md
│   │   ├── ProductAvailabilityLevels.md
│   │   ├── ProductAvailabilityModel.md
│   │   ├── ProductInventoryList.md
│   │   ├── ProductInventoryMgr.md
│   │   ├── ProductInventoryRecord.md
│   │   ├── ProductLink.md
│   │   ├── ProductMgr.md
│   │   ├── ProductOption.md
│   │   ├── ProductOptionModel.md
│   │   ├── ProductOptionValue.md
│   │   ├── ProductPriceInfo.md
│   │   ├── ProductPriceModel.md
│   │   ├── ProductPriceTable.md
│   │   ├── ProductSearchHit.md
│   │   ├── ProductSearchModel.md
│   │   ├── ProductSearchRefinementDefinition.md
│   │   ├── ProductSearchRefinements.md
│   │   ├── ProductSearchRefinementValue.md
│   │   ├── ProductVariationAttribute.md
│   │   ├── ProductVariationAttributeValue.md
│   │   ├── ProductVariationModel.md
│   │   ├── Recommendation.md
│   │   ├── SearchModel.md
│   │   ├── SearchRefinementDefinition.md
│   │   ├── SearchRefinements.md
│   │   ├── SearchRefinementValue.md
│   │   ├── SortingOption.md
│   │   ├── SortingRule.md
│   │   ├── Store.md
│   │   ├── StoreGroup.md
│   │   ├── StoreInventoryFilter.md
│   │   ├── StoreInventoryFilterValue.md
│   │   ├── StoreMgr.md
│   │   ├── Variant.md
│   │   └── VariationGroup.md
│   ├── dw_content
│   │   ├── Content.md
│   │   ├── ContentMgr.md
│   │   ├── ContentSearchModel.md
│   │   ├── ContentSearchRefinementDefinition.md
│   │   ├── ContentSearchRefinements.md
│   │   ├── ContentSearchRefinementValue.md
│   │   ├── Folder.md
│   │   ├── Library.md
│   │   ├── MarkupText.md
│   │   └── MediaFile.md
│   ├── dw_crypto
│   │   ├── CertificateRef.md
│   │   ├── CertificateUtils.md
│   │   ├── Cipher.md
│   │   ├── Encoding.md
│   │   ├── JWE.md
│   │   ├── JWEHeader.md
│   │   ├── JWS.md
│   │   ├── JWSHeader.md
│   │   ├── KeyRef.md
│   │   ├── Mac.md
│   │   ├── MessageDigest.md
│   │   ├── SecureRandom.md
│   │   ├── Signature.md
│   │   ├── WeakCipher.md
│   │   ├── WeakMac.md
│   │   ├── WeakMessageDigest.md
│   │   ├── WeakSignature.md
│   │   └── X509Certificate.md
│   ├── dw_customer
│   │   ├── AddressBook.md
│   │   ├── AgentUserMgr.md
│   │   ├── AgentUserStatusCodes.md
│   │   ├── AuthenticationStatus.md
│   │   ├── Credentials.md
│   │   ├── Customer.md
│   │   ├── CustomerActiveData.md
│   │   ├── CustomerAddress.md
│   │   ├── CustomerCDPData.md
│   │   ├── CustomerContextMgr.md
│   │   ├── CustomerGroup.md
│   │   ├── CustomerList.md
│   │   ├── CustomerMgr.md
│   │   ├── CustomerPasswordConstraints.md
│   │   ├── CustomerPaymentInstrument.md
│   │   ├── CustomerStatusCodes.md
│   │   ├── EncryptedObject.md
│   │   ├── ExternalProfile.md
│   │   ├── OrderHistory.md
│   │   ├── ProductList.md
│   │   ├── ProductListItem.md
│   │   ├── ProductListItemPurchase.md
│   │   ├── ProductListMgr.md
│   │   ├── ProductListRegistrant.md
│   │   ├── Profile.md
│   │   └── Wallet.md
│   ├── dw_extensions.applepay
│   │   ├── ApplePayHookResult.md
│   │   └── ApplePayHooks.md
│   ├── dw_extensions.facebook
│   │   ├── FacebookFeedHooks.md
│   │   └── FacebookProduct.md
│   ├── dw_extensions.paymentrequest
│   │   ├── PaymentRequestHookResult.md
│   │   └── PaymentRequestHooks.md
│   ├── dw_extensions.payments
│   │   ├── SalesforceBancontactPaymentDetails.md
│   │   ├── SalesforceCardPaymentDetails.md
│   │   ├── SalesforceEpsPaymentDetails.md
│   │   ├── SalesforceIdealPaymentDetails.md
│   │   ├── SalesforceKlarnaPaymentDetails.md
│   │   ├── SalesforcePaymentDetails.md
│   │   ├── SalesforcePaymentIntent.md
│   │   ├── SalesforcePaymentMethod.md
│   │   ├── SalesforcePaymentRequest.md
│   │   ├── SalesforcePaymentsHooks.md
│   │   ├── SalesforcePaymentsMgr.md
│   │   ├── SalesforcePaymentsSiteConfiguration.md
│   │   ├── SalesforcePayPalOrder.md
│   │   ├── SalesforcePayPalOrderAddress.md
│   │   ├── SalesforcePayPalOrderPayer.md
│   │   ├── SalesforcePayPalPaymentDetails.md
│   │   ├── SalesforceSepaDebitPaymentDetails.md
│   │   └── SalesforceVenmoPaymentDetails.md
│   ├── dw_extensions.pinterest
│   │   ├── PinterestAvailability.md
│   │   ├── PinterestFeedHooks.md
│   │   ├── PinterestOrder.md
│   │   ├── PinterestOrderHooks.md
│   │   └── PinterestProduct.md
│   ├── dw_io
│   │   ├── CSVStreamReader.md
│   │   ├── CSVStreamWriter.md
│   │   ├── File.md
│   │   ├── FileReader.md
│   │   ├── FileWriter.md
│   │   ├── InputStream.md
│   │   ├── OutputStream.md
│   │   ├── PrintWriter.md
│   │   ├── RandomAccessFileReader.md
│   │   ├── Reader.md
│   │   ├── StringWriter.md
│   │   ├── Writer.md
│   │   ├── XMLIndentingStreamWriter.md
│   │   ├── XMLStreamConstants.md
│   │   ├── XMLStreamReader.md
│   │   └── XMLStreamWriter.md
│   ├── dw_job
│   │   ├── JobExecution.md
│   │   └── JobStepExecution.md
│   ├── dw_net
│   │   ├── FTPClient.md
│   │   ├── FTPFileInfo.md
│   │   ├── HTTPClient.md
│   │   ├── HTTPRequestPart.md
│   │   ├── Mail.md
│   │   ├── SFTPClient.md
│   │   ├── SFTPFileInfo.md
│   │   ├── WebDAVClient.md
│   │   └── WebDAVFileInfo.md
│   ├── dw_object
│   │   ├── ActiveData.md
│   │   ├── CustomAttributes.md
│   │   ├── CustomObject.md
│   │   ├── CustomObjectMgr.md
│   │   ├── Extensible.md
│   │   ├── ExtensibleObject.md
│   │   ├── Note.md
│   │   ├── ObjectAttributeDefinition.md
│   │   ├── ObjectAttributeGroup.md
│   │   ├── ObjectAttributeValueDefinition.md
│   │   ├── ObjectTypeDefinition.md
│   │   ├── PersistentObject.md
│   │   ├── SimpleExtensible.md
│   │   └── SystemObjectMgr.md
│   ├── dw_order
│   │   ├── AbstractItem.md
│   │   ├── AbstractItemCtnr.md
│   │   ├── Appeasement.md
│   │   ├── AppeasementItem.md
│   │   ├── Basket.md
│   │   ├── BasketMgr.md
│   │   ├── BonusDiscountLineItem.md
│   │   ├── CouponLineItem.md
│   │   ├── CreateAgentBasketLimitExceededException.md
│   │   ├── CreateBasketFromOrderException.md
│   │   ├── CreateCouponLineItemException.md
│   │   ├── CreateOrderException.md
│   │   ├── CreateTemporaryBasketLimitExceededException.md
│   │   ├── GiftCertificate.md
│   │   ├── GiftCertificateLineItem.md
│   │   ├── GiftCertificateMgr.md
│   │   ├── GiftCertificateStatusCodes.md
│   │   ├── Invoice.md
│   │   ├── InvoiceItem.md
│   │   ├── LineItem.md
│   │   ├── LineItemCtnr.md
│   │   ├── Order.md
│   │   ├── OrderAddress.md
│   │   ├── OrderItem.md
│   │   ├── OrderMgr.md
│   │   ├── OrderPaymentInstrument.md
│   │   ├── OrderProcessStatusCodes.md
│   │   ├── PaymentCard.md
│   │   ├── PaymentInstrument.md
│   │   ├── PaymentMethod.md
│   │   ├── PaymentMgr.md
│   │   ├── PaymentProcessor.md
│   │   ├── PaymentStatusCodes.md
│   │   ├── PaymentTransaction.md
│   │   ├── PriceAdjustment.md
│   │   ├── PriceAdjustmentLimitTypes.md
│   │   ├── ProductLineItem.md
│   │   ├── ProductShippingCost.md
│   │   ├── ProductShippingLineItem.md
│   │   ├── ProductShippingModel.md
│   │   ├── Return.md
│   │   ├── ReturnCase.md
│   │   ├── ReturnCaseItem.md
│   │   ├── ReturnItem.md
│   │   ├── Shipment.md
│   │   ├── ShipmentShippingCost.md
│   │   ├── ShipmentShippingModel.md
│   │   ├── ShippingLineItem.md
│   │   ├── ShippingLocation.md
│   │   ├── ShippingMethod.md
│   │   ├── ShippingMgr.md
│   │   ├── ShippingOrder.md
│   │   ├── ShippingOrderItem.md
│   │   ├── SumItem.md
│   │   ├── TaxGroup.md
│   │   ├── TaxItem.md
│   │   ├── TaxMgr.md
│   │   ├── TrackingInfo.md
│   │   └── TrackingRef.md
│   ├── dw_order.hooks
│   │   ├── CalculateHooks.md
│   │   ├── OrderHooks.md
│   │   ├── PaymentHooks.md
│   │   ├── ReturnHooks.md
│   │   └── ShippingOrderHooks.md
│   ├── dw_rpc
│   │   ├── SOAPUtil.md
│   │   ├── Stub.md
│   │   └── WebReference.md
│   ├── dw_suggest
│   │   ├── BrandSuggestions.md
│   │   ├── CategorySuggestions.md
│   │   ├── ContentSuggestions.md
│   │   ├── CustomSuggestions.md
│   │   ├── ProductSuggestions.md
│   │   ├── SearchPhraseSuggestions.md
│   │   ├── SuggestedCategory.md
│   │   ├── SuggestedContent.md
│   │   ├── SuggestedPhrase.md
│   │   ├── SuggestedProduct.md
│   │   ├── SuggestedTerm.md
│   │   ├── SuggestedTerms.md
│   │   ├── Suggestions.md
│   │   └── SuggestModel.md
│   ├── dw_svc
│   │   ├── FTPService.md
│   │   ├── FTPServiceDefinition.md
│   │   ├── HTTPFormService.md
│   │   ├── HTTPFormServiceDefinition.md
│   │   ├── HTTPService.md
│   │   ├── HTTPServiceDefinition.md
│   │   ├── LocalServiceRegistry.md
│   │   ├── Result.md
│   │   ├── Service.md
│   │   ├── ServiceCallback.md
│   │   ├── ServiceConfig.md
│   │   ├── ServiceCredential.md
│   │   ├── ServiceDefinition.md
│   │   ├── ServiceProfile.md
│   │   ├── ServiceRegistry.md
│   │   ├── SOAPService.md
│   │   └── SOAPServiceDefinition.md
│   ├── dw_system
│   │   ├── AgentUserStatusCodes.md
│   │   ├── Cache.md
│   │   ├── CacheMgr.md
│   │   ├── HookMgr.md
│   │   ├── InternalObject.md
│   │   ├── JobProcessMonitor.md
│   │   ├── Log.md
│   │   ├── Logger.md
│   │   ├── LogNDC.md
│   │   ├── OrganizationPreferences.md
│   │   ├── Pipeline.md
│   │   ├── PipelineDictionary.md
│   │   ├── RemoteInclude.md
│   │   ├── Request.md
│   │   ├── RequestHooks.md
│   │   ├── Response.md
│   │   ├── RESTErrorResponse.md
│   │   ├── RESTResponseMgr.md
│   │   ├── RESTSuccessResponse.md
│   │   ├── SearchStatus.md
│   │   ├── Session.md
│   │   ├── Site.md
│   │   ├── SitePreferences.md
│   │   ├── Status.md
│   │   ├── StatusItem.md
│   │   ├── System.md
│   │   └── Transaction.md
│   ├── dw_util
│   │   ├── ArrayList.md
│   │   ├── Assert.md
│   │   ├── BigInteger.md
│   │   ├── Bytes.md
│   │   ├── Calendar.md
│   │   ├── Collection.md
│   │   ├── Currency.md
│   │   ├── DateUtils.md
│   │   ├── Decimal.md
│   │   ├── FilteringCollection.md
│   │   ├── Geolocation.md
│   │   ├── HashMap.md
│   │   ├── HashSet.md
│   │   ├── Iterator.md
│   │   ├── LinkedHashMap.md
│   │   ├── LinkedHashSet.md
│   │   ├── List.md
│   │   ├── Locale.md
│   │   ├── Map.md
│   │   ├── MapEntry.md
│   │   ├── MappingKey.md
│   │   ├── MappingMgr.md
│   │   ├── PropertyComparator.md
│   │   ├── SecureEncoder.md
│   │   ├── SecureFilter.md
│   │   ├── SeekableIterator.md
│   │   ├── Set.md
│   │   ├── SortedMap.md
│   │   ├── SortedSet.md
│   │   ├── StringUtils.md
│   │   ├── Template.md
│   │   └── UUIDUtils.md
│   ├── dw_value
│   │   ├── EnumValue.md
│   │   ├── MimeEncodedText.md
│   │   ├── Money.md
│   │   └── Quantity.md
│   ├── dw_web
│   │   ├── ClickStream.md
│   │   ├── ClickStreamEntry.md
│   │   ├── Cookie.md
│   │   ├── Cookies.md
│   │   ├── CSRFProtection.md
│   │   ├── Form.md
│   │   ├── FormAction.md
│   │   ├── FormElement.md
│   │   ├── FormElementValidationResult.md
│   │   ├── FormField.md
│   │   ├── FormFieldOption.md
│   │   ├── FormFieldOptions.md
│   │   ├── FormGroup.md
│   │   ├── FormList.md
│   │   ├── FormListItem.md
│   │   ├── Forms.md
│   │   ├── HttpParameter.md
│   │   ├── HttpParameterMap.md
│   │   ├── LoopIterator.md
│   │   ├── PageMetaData.md
│   │   ├── PageMetaTag.md
│   │   ├── PagingModel.md
│   │   ├── Resource.md
│   │   ├── URL.md
│   │   ├── URLAction.md
│   │   ├── URLParameter.md
│   │   ├── URLRedirect.md
│   │   ├── URLRedirectMgr.md
│   │   └── URLUtils.md
│   ├── sfra
│   │   ├── account.md
│   │   ├── address.md
│   │   ├── billing.md
│   │   ├── cart.md
│   │   ├── categories.md
│   │   ├── content.md
│   │   ├── locale.md
│   │   ├── order.md
│   │   ├── payment.md
│   │   ├── price-default.md
│   │   ├── price-range.md
│   │   ├── price-tiered.md
│   │   ├── product-bundle.md
│   │   ├── product-full.md
│   │   ├── product-line-items.md
│   │   ├── product-search.md
│   │   ├── product-tile.md
│   │   ├── querystring.md
│   │   ├── render.md
│   │   ├── request.md
│   │   ├── response.md
│   │   ├── server.md
│   │   ├── shipping.md
│   │   ├── store.md
│   │   ├── stores.md
│   │   └── totals.md
│   └── TopLevel
│       ├── APIException.md
│       ├── arguments.md
│       ├── Array.md
│       ├── ArrayBuffer.md
│       ├── BigInt.md
│       ├── Boolean.md
│       ├── ConversionError.md
│       ├── DataView.md
│       ├── Date.md
│       ├── Error.md
│       ├── ES6Iterator.md
│       ├── EvalError.md
│       ├── Fault.md
│       ├── Float32Array.md
│       ├── Float64Array.md
│       ├── Function.md
│       ├── Generator.md
│       ├── global.md
│       ├── Int16Array.md
│       ├── Int32Array.md
│       ├── Int8Array.md
│       ├── InternalError.md
│       ├── IOError.md
│       ├── Iterable.md
│       ├── Iterator.md
│       ├── JSON.md
│       ├── Map.md
│       ├── Math.md
│       ├── Module.md
│       ├── Namespace.md
│       ├── Number.md
│       ├── Object.md
│       ├── QName.md
│       ├── RangeError.md
│       ├── ReferenceError.md
│       ├── RegExp.md
│       ├── Set.md
│       ├── StopIteration.md
│       ├── String.md
│       ├── Symbol.md
│       ├── SyntaxError.md
│       ├── SystemError.md
│       ├── TypeError.md
│       ├── Uint16Array.md
│       ├── Uint32Array.md
│       ├── Uint8Array.md
│       ├── Uint8ClampedArray.md
│       ├── URIError.md
│       ├── WeakMap.md
│       ├── WeakSet.md
│       ├── XML.md
│       ├── XMLList.md
│       └── XMLStreamError.md
├── docs-site
│   ├── .gitignore
│   ├── App.tsx
│   ├── components
│   │   ├── Badge.tsx
│   │   ├── BreadcrumbSchema.tsx
│   │   ├── CodeBlock.tsx
│   │   ├── Collapsible.tsx
│   │   ├── ConfigBuilder.tsx
│   │   ├── ConfigHero.tsx
│   │   ├── ConfigModeTabs.tsx
│   │   ├── icons.tsx
│   │   ├── Layout.tsx
│   │   ├── LightCodeContainer.tsx
│   │   ├── NewcomerCTA.tsx
│   │   ├── NextStepsStrip.tsx
│   │   ├── OnThisPage.tsx
│   │   ├── Search.tsx
│   │   ├── SEO.tsx
│   │   ├── Sidebar.tsx
│   │   ├── StructuredData.tsx
│   │   ├── ToolCard.tsx
│   │   ├── ToolFilters.tsx
│   │   ├── Typography.tsx
│   │   └── VersionBadge.tsx
│   ├── constants.tsx
│   ├── index.html
│   ├── main.tsx
│   ├── metadata.json
│   ├── package-lock.json
│   ├── package.json
│   ├── pages
│   │   ├── AIInterfacesPage.tsx
│   │   ├── ConfigurationPage.tsx
│   │   ├── DevelopmentPage.tsx
│   │   ├── ExamplesPage.tsx
│   │   ├── FeaturesPage.tsx
│   │   ├── HomePage.tsx
│   │   ├── SecurityPage.tsx
│   │   ├── ToolsPage.tsx
│   │   └── TroubleshootingPage.tsx
│   ├── postcss.config.js
│   ├── public
│   │   ├── .well-known
│   │   │   └── security.txt
│   │   ├── 404.html
│   │   ├── android-chrome-192x192.png
│   │   ├── android-chrome-512x512.png
│   │   ├── apple-touch-icon.png
│   │   ├── explain-product-pricing-methods-no-mcp.png
│   │   ├── explain-product-pricing-methods.png
│   │   ├── favicon-16x16.png
│   │   ├── favicon-32x32.png
│   │   ├── favicon.ico
│   │   ├── llms.txt
│   │   ├── robots.txt
│   │   ├── site.webmanifest
│   │   └── sitemap.xml
│   ├── README.md
│   ├── scripts
│   │   ├── generate-search-index.js
│   │   ├── generate-sitemap.js
│   │   └── search-dev.js
│   ├── src
│   │   └── styles
│   │       ├── input.css
│   │       └── prism-theme.css
│   ├── tailwind.config.js
│   ├── tsconfig.json
│   ├── types.ts
│   ├── utils
│   │   ├── search.ts
│   │   └── toolsData.ts
│   └── vite.config.ts
├── eslint.config.js
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│   └── convert-docs.js
├── SECURITY.md
├── server.json
├── src
│   ├── clients
│   │   ├── base
│   │   │   ├── http-client.ts
│   │   │   ├── oauth-token.ts
│   │   │   └── ocapi-auth-client.ts
│   │   ├── best-practices-client.ts
│   │   ├── cartridge-generation-client.ts
│   │   ├── docs
│   │   │   ├── class-content-parser.ts
│   │   │   ├── class-name-resolver.ts
│   │   │   ├── documentation-scanner.ts
│   │   │   ├── index.ts
│   │   │   └── referenced-types-extractor.ts
│   │   ├── docs-client.ts
│   │   ├── log-client.ts
│   │   ├── logs
│   │   │   ├── index.ts
│   │   │   ├── log-analyzer.ts
│   │   │   ├── log-client.ts
│   │   │   ├── log-constants.ts
│   │   │   ├── log-file-discovery.ts
│   │   │   ├── log-file-reader.ts
│   │   │   ├── log-formatter.ts
│   │   │   ├── log-processor.ts
│   │   │   ├── log-types.ts
│   │   │   └── webdav-client-manager.ts
│   │   ├── ocapi
│   │   │   ├── code-versions-client.ts
│   │   │   ├── site-preferences-client.ts
│   │   │   └── system-objects-client.ts
│   │   ├── ocapi-client.ts
│   │   └── sfra-client.ts
│   ├── config
│   │   ├── configuration-factory.ts
│   │   └── dw-json-loader.ts
│   ├── core
│   │   ├── handlers
│   │   │   ├── abstract-log-tool-handler.ts
│   │   │   ├── base-handler.ts
│   │   │   ├── best-practices-handler.ts
│   │   │   ├── cartridge-handler.ts
│   │   │   ├── client-factory.ts
│   │   │   ├── code-version-handler.ts
│   │   │   ├── docs-handler.ts
│   │   │   ├── job-log-handler.ts
│   │   │   ├── job-log-tool-config.ts
│   │   │   ├── log-handler.ts
│   │   │   ├── log-tool-config.ts
│   │   │   ├── sfra-handler.ts
│   │   │   ├── system-object-handler.ts
│   │   │   └── validation-helpers.ts
│   │   ├── server.ts
│   │   └── tool-definitions.ts
│   ├── index.ts
│   ├── main.ts
│   ├── services
│   │   ├── file-system-service.ts
│   │   ├── index.ts
│   │   └── path-service.ts
│   ├── tool-configs
│   │   ├── best-practices-tool-config.ts
│   │   ├── cartridge-tool-config.ts
│   │   ├── code-version-tool-config.ts
│   │   ├── docs-tool-config.ts
│   │   ├── job-log-tool-config.ts
│   │   ├── log-tool-config.ts
│   │   ├── sfra-tool-config.ts
│   │   └── system-object-tool-config.ts
│   ├── types
│   │   └── types.ts
│   └── utils
│       ├── cache.ts
│       ├── job-log-tool-config.ts
│       ├── job-log-utils.ts
│       ├── log-cache.ts
│       ├── log-tool-config.ts
│       ├── log-tool-constants.ts
│       ├── log-tool-utils.ts
│       ├── logger.ts
│       ├── ocapi-url-builder.ts
│       ├── path-resolver.ts
│       ├── query-builder.ts
│       ├── utils.ts
│       └── validator.ts
├── tests
│   ├── __mocks__
│   │   ├── docs-client.ts
│   │   ├── src
│   │   │   └── clients
│   │   │       └── base
│   │   │           └── http-client.js
│   │   └── webdav.js
│   ├── base-handler.test.ts
│   ├── base-http-client.test.ts
│   ├── best-practices-handler.test.ts
│   ├── cache.test.ts
│   ├── cartridge-handler.test.ts
│   ├── class-content-parser.test.ts
│   ├── class-name-resolver.test.ts
│   ├── client-factory.test.ts
│   ├── code-version-handler.test.ts
│   ├── code-versions-client.test.ts
│   ├── config.test.ts
│   ├── configuration-factory.test.ts
│   ├── docs-handler.test.ts
│   ├── documentation-scanner.test.ts
│   ├── file-system-service.test.ts
│   ├── job-log-handler.test.ts
│   ├── job-log-utils.test.ts
│   ├── log-client.test.ts
│   ├── log-handler.test.ts
│   ├── log-processor.test.ts
│   ├── logger.test.ts
│   ├── mcp
│   │   ├── AGENTS.md
│   │   ├── node
│   │   │   ├── activate-code-version-advanced.full-mode.programmatic.test.js
│   │   │   ├── code-versions.full-mode.programmatic.test.js
│   │   │   ├── generate-cartridge-structure.docs-only.programmatic.test.js
│   │   │   ├── get-available-best-practice-guides.docs-only.programmatic.test.js
│   │   │   ├── get-available-sfra-documents.programmatic.test.js
│   │   │   ├── get-best-practice-guide.docs-only.programmatic.test.js
│   │   │   ├── get-hook-reference.docs-only.programmatic.test.js
│   │   │   ├── get-job-execution-summary.full-mode.programmatic.test.js
│   │   │   ├── get-job-log-entries.full-mode.programmatic.test.js
│   │   │   ├── get-latest-debug.full-mode.programmatic.test.js
│   │   │   ├── get-latest-error.full-mode.programmatic.test.js
│   │   │   ├── get-latest-info.full-mode.programmatic.test.js
│   │   │   ├── get-latest-job-log-files.full-mode.programmatic.test.js
│   │   │   ├── get-latest-warn.full-mode.programmatic.test.js
│   │   │   ├── get-log-file-contents.full-mode.programmatic.test.js
│   │   │   ├── get-sfcc-class-documentation.docs-only.programmatic.test.js
│   │   │   ├── get-sfcc-class-info.docs-only.programmatic.test.js
│   │   │   ├── get-sfra-categories.docs-only.programmatic.test.js
│   │   │   ├── get-sfra-document.programmatic.test.js
│   │   │   ├── get-sfra-documents-by-category.docs-only.programmatic.test.js
│   │   │   ├── get-system-object-definition.full-mode.programmatic.test.js
│   │   │   ├── get-system-object-definitions.docs-only.programmatic.test.js
│   │   │   ├── get-system-object-definitions.full-mode.programmatic.test.js
│   │   │   ├── list-log-files.full-mode.programmatic.test.js
│   │   │   ├── list-sfcc-classes.docs-only.programmatic.test.js
│   │   │   ├── search-best-practices.docs-only.programmatic.test.js
│   │   │   ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js
│   │   │   ├── search-job-logs-by-name.full-mode.programmatic.test.js
│   │   │   ├── search-job-logs.full-mode.programmatic.test.js
│   │   │   ├── search-logs.full-mode.programmatic.test.js
│   │   │   ├── search-sfcc-classes.docs-only.programmatic.test.js
│   │   │   ├── search-sfcc-methods.docs-only.programmatic.test.js
│   │   │   ├── search-sfra-documentation.docs-only.programmatic.test.js
│   │   │   ├── search-site-preferences.full-mode.programmatic.test.js
│   │   │   ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js
│   │   │   ├── search-system-object-attribute-groups.full-mode.programmatic.test.js
│   │   │   ├── summarize-logs.full-mode.programmatic.test.js
│   │   │   ├── tools.docs-only.programmatic.test.js
│   │   │   └── tools.full-mode.programmatic.test.js
│   │   ├── README.md
│   │   ├── test-fixtures
│   │   │   └── dw.json
│   │   └── yaml
│   │       ├── activate-code-version.docs-only.test.mcp.yml
│   │       ├── activate-code-version.full-mode.test.mcp.yml
│   │       ├── get_latest_error.test.mcp.yml
│   │       ├── get-available-best-practice-guides.docs-only.test.mcp.yml
│   │       ├── get-available-best-practice-guides.full-mode.test.mcp.yml
│   │       ├── get-available-sfra-documents.docs-only.test.mcp.yml
│   │       ├── get-available-sfra-documents.full-mode.test.mcp.yml
│   │       ├── get-best-practice-guide.docs-only.test.mcp.yml
│   │       ├── get-best-practice-guide.full-mode.test.mcp.yml
│   │       ├── get-code-versions.docs-only.test.mcp.yml
│   │       ├── get-code-versions.full-mode.test.mcp.yml
│   │       ├── get-hook-reference.docs-only.test.mcp.yml
│   │       ├── get-hook-reference.full-mode.test.mcp.yml
│   │       ├── get-job-execution-summary.full-mode.test.mcp.yml
│   │       ├── get-job-log-entries.full-mode.test.mcp.yml
│   │       ├── get-latest-debug.full-mode.test.mcp.yml
│   │       ├── get-latest-error.full-mode.test.mcp.yml
│   │       ├── get-latest-info.full-mode.test.mcp.yml
│   │       ├── get-latest-job-log-files.full-mode.test.mcp.yml
│   │       ├── get-latest-warn.full-mode.test.mcp.yml
│   │       ├── get-log-file-contents.full-mode.test.mcp.yml
│   │       ├── get-sfcc-class-documentation.docs-only.test.mcp.yml
│   │       ├── get-sfcc-class-documentation.full-mode.test.mcp.yml
│   │       ├── get-sfcc-class-info.docs-only.test.mcp.yml
│   │       ├── get-sfcc-class-info.full-mode.test.mcp.yml
│   │       ├── get-sfra-categories.docs-only.test.mcp.yml
│   │       ├── get-sfra-categories.full-mode.test.mcp.yml
│   │       ├── get-sfra-document.docs-only.test.mcp.yml
│   │       ├── get-sfra-document.full-mode.test.mcp.yml
│   │       ├── get-sfra-documents-by-category.docs-only.test.mcp.yml
│   │       ├── get-sfra-documents-by-category.full-mode.test.mcp.yml
│   │       ├── get-system-object-definition.docs-only.test.mcp.yml
│   │       ├── get-system-object-definition.full-mode.test.mcp.yml
│   │       ├── get-system-object-definitions.docs-only.test.mcp.yml
│   │       ├── get-system-object-definitions.full-mode.test.mcp.yml
│   │       ├── list-log-files.full-mode.test.mcp.yml
│   │       ├── list-sfcc-classes.docs-only.test.mcp.yml
│   │       ├── list-sfcc-classes.full-mode.test.mcp.yml
│   │       ├── search-best-practices.docs-only.test.mcp.yml
│   │       ├── search-best-practices.full-mode.test.mcp.yml
│   │       ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml
│   │       ├── search-custom-object-attribute-definitions.test.mcp.yml
│   │       ├── search-job-logs-by-name.full-mode.test.mcp.yml
│   │       ├── search-job-logs.full-mode.test.mcp.yml
│   │       ├── search-logs.full-mode.test.mcp.yml
│   │       ├── search-sfcc-classes.docs-only.test.mcp.yml
│   │       ├── search-sfcc-classes.full-mode.test.mcp.yml
│   │       ├── search-sfcc-methods.docs-only.test.mcp.yml
│   │       ├── search-sfcc-methods.full-mode.test.mcp.yml
│   │       ├── search-sfra-documentation.docs-only.test.mcp.yml
│   │       ├── search-sfra-documentation.full-mode.test.mcp.yml
│   │       ├── search-site-preferences.docs-only.test.mcp.yml
│   │       ├── search-site-preferences.full-mode.test.mcp.yml
│   │       ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml
│   │       ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml
│   │       ├── search-system-object-attribute-groups.docs-only.test.mcp.yml
│   │       ├── search-system-object-attribute-groups.full-mode.test.mcp.yml
│   │       ├── summarize-logs.full-mode.test.mcp.yml
│   │       ├── tools.docs-only.test.mcp.yml
│   │       └── tools.full-mode.test.mcp.yml
│   ├── oauth-token.test.ts
│   ├── ocapi-auth-client.test.ts
│   ├── ocapi-client.test.ts
│   ├── path-service.test.ts
│   ├── query-builder.test.ts
│   ├── referenced-types-extractor.test.ts
│   ├── servers
│   │   ├── sfcc-mock-server
│   │   │   ├── mock-data
│   │   │   │   └── ocapi
│   │   │   │       ├── code-versions.json
│   │   │   │       ├── custom-object-attributes-customapi.json
│   │   │   │       ├── custom-object-attributes-globalsettings.json
│   │   │   │       ├── custom-object-attributes-versionhistory.json
│   │   │   │       ├── site-preferences-ccv.json
│   │   │   │       ├── site-preferences-fastforward.json
│   │   │   │       ├── site-preferences-sfra.json
│   │   │   │       ├── site-preferences-storefront.json
│   │   │   │       ├── site-preferences-system.json
│   │   │   │       ├── system-object-attribute-groups-campaign.json
│   │   │   │       ├── system-object-attribute-groups-category.json
│   │   │   │       ├── system-object-attribute-groups-order.json
│   │   │   │       ├── system-object-attribute-groups-product.json
│   │   │   │       ├── system-object-attribute-groups-sitepreferences.json
│   │   │   │       ├── system-object-attributes-customeraddress.json
│   │   │   │       ├── system-object-attributes-product-expanded.json
│   │   │   │       ├── system-object-attributes-product.json
│   │   │   │       ├── system-object-definition-category.json
│   │   │   │       ├── system-object-definition-customer.json
│   │   │   │       ├── system-object-definition-customeraddress.json
│   │   │   │       ├── system-object-definition-order.json
│   │   │   │       ├── system-object-definition-product.json
│   │   │   │       ├── system-object-definitions-old.json
│   │   │   │       └── system-object-definitions.json
│   │   │   ├── package-lock.json
│   │   │   ├── package.json
│   │   │   ├── README.md
│   │   │   ├── scripts
│   │   │   │   └── setup-logs.js
│   │   │   ├── server.js
│   │   │   └── src
│   │   │       ├── app.js
│   │   │       ├── config
│   │   │       │   └── server-config.js
│   │   │       ├── middleware
│   │   │       │   ├── auth.js
│   │   │       │   ├── cors.js
│   │   │       │   └── logging.js
│   │   │       ├── routes
│   │   │       │   ├── ocapi
│   │   │       │   │   ├── code-versions-handler.js
│   │   │       │   │   ├── oauth-handler.js
│   │   │       │   │   ├── ocapi-error-utils.js
│   │   │       │   │   ├── ocapi-utils.js
│   │   │       │   │   ├── site-preferences-handler.js
│   │   │       │   │   └── system-objects-handler.js
│   │   │       │   ├── ocapi.js
│   │   │       │   └── webdav.js
│   │   │       └── utils
│   │   │           ├── mock-data-loader.js
│   │   │           └── webdav-xml.js
│   │   └── sfcc-mock-server-manager.ts
│   ├── sfcc-mock-server.test.ts
│   ├── site-preferences-client.test.ts
│   ├── system-objects-client.test.ts
│   ├── utils.test.ts
│   ├── validation-helpers.test.ts
│   └── validator.test.ts
├── tsconfig.json
└── tsconfig.test.json
```

# Files

--------------------------------------------------------------------------------
/src/utils/job-log-tool-config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ToolSpec, LogToolValidators } from './log-tool-utils.js';
 2 | import { ValidationHelpers, CommonValidations } from '../core/handlers/validation-helpers.js';
 3 | import { JobLogToolName, getLimit } from './log-tool-constants.js';
 4 | import { JobLogValidators, JobLogFormatters } from './job-log-utils.js';
 5 | 
 6 | /**
 7 |  * Configuration for job log tools
 8 |  * Maps each tool to its validation, execution, and messaging logic
 9 |  */
10 | export const JOB_LOG_TOOL_CONFIG: Record<JobLogToolName, ToolSpec> = {
11 |   get_latest_job_log_files: {
12 |     defaults: (args) => ({
13 |       limit: getLimit(args.limit as number, 'jobFiles'),
14 |     }),
15 |     validate: (args, toolName) => LogToolValidators.validateLimit(args.limit as number, toolName),
16 |     exec: async (args, client) => client.getLatestJobLogFiles(args.limit as number),
17 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching latest job log files', {
18 |       limit: args.limit as number,
19 |     }),
20 |   },
21 | 
22 |   search_job_logs_by_name: {
23 |     defaults: (args) => ({
24 |       limit: getLimit(args.limit as number, 'jobFiles'),
25 |     }),
26 |     validate: (args, toolName) => {
27 |       ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
28 |       LogToolValidators.validateLimit(args.limit as number, toolName);
29 |     },
30 |     exec: async (args, client) => client.searchJobLogsByName(args.jobName as string, args.limit as number),
31 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs by name', {
32 |       jobName: args.jobName as string,
33 |       limit: args.limit as number,
34 |     }),
35 |   },
36 | 
37 |   get_job_log_entries: {
38 |     defaults: (args) => ({
39 |       level: args.level ?? 'all',
40 |       limit: getLimit(args.limit as number, 'jobEntries'),
41 |     }),
42 |     validate: (args, toolName) => {
43 |       JobLogValidators.validateJobLogLevel(args.level as string, toolName);
44 |       LogToolValidators.validateLimit(args.limit as number, toolName);
45 |     },
46 |     exec: async (args, client) => client.getJobLogEntries(
47 |       args.level as any,
48 |       args.limit as number,
49 |       args.jobName as string,
50 |     ),
51 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching job log entries', {
52 |       level: args.level as string,
53 |       limit: args.limit as number,
54 |       jobName: args.jobName as string,
55 |     }),
56 |   },
57 | 
58 |   search_job_logs: {
59 |     defaults: (args) => ({
60 |       level: args.level ?? 'all',
61 |       limit: getLimit(args.limit as number, 'jobSearch'),
62 |     }),
63 |     validate: (args, toolName) => {
64 |       ValidationHelpers.validateArguments(args, CommonValidations.requiredString('pattern'), toolName);
65 |       JobLogValidators.validateJobLogLevel(args.level as string, toolName);
66 |       LogToolValidators.validateLimit(args.limit as number, toolName);
67 |     },
68 |     exec: async (args, client) => client.searchJobLogs(
69 |       args.pattern as string,
70 |       args.level as any,
71 |       args.limit as number,
72 |       args.jobName as string,
73 |     ),
74 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs', {
75 |       pattern: args.pattern as string,
76 |       level: args.level as string,
77 |       limit: args.limit as number,
78 |       jobName: args.jobName as string,
79 |     }),
80 |   },
81 | 
82 |   get_job_execution_summary: {
83 |     validate: (args, toolName) => {
84 |       ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
85 |     },
86 |     exec: async (args, client) => client.getJobExecutionSummary(args.jobName as string),
87 |     logMessage: (args) => `Getting job execution summary for: ${args.jobName as string}`,
88 |   },
89 | };
90 | 
```

--------------------------------------------------------------------------------
/tests/file-system-service.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { FileSystemService, MockFileSystemService } from '../src/services/file-system-service.js';
  2 | 
  3 | describe('FileSystemService', () => {
  4 |   describe('Production FileSystemService', () => {
  5 |     let service: FileSystemService;
  6 | 
  7 |     beforeEach(() => {
  8 |       service = new FileSystemService();
  9 |     });
 10 | 
 11 |     it('should be instantiable', () => {
 12 |       expect(service).toBeInstanceOf(FileSystemService);
 13 |     });
 14 | 
 15 |     // Note: Testing actual file operations would require integration tests
 16 |     // For unit tests, we mainly test the interface compliance
 17 |   });
 18 | 
 19 |   describe('MockFileSystemService', () => {
 20 |     let mockService: MockFileSystemService;
 21 | 
 22 |     beforeEach(() => {
 23 |       mockService = new MockFileSystemService();
 24 |     });
 25 | 
 26 |     afterEach(() => {
 27 |       mockService.clearMocks();
 28 |     });
 29 | 
 30 |     it('should be instantiable', () => {
 31 |       expect(mockService).toBeInstanceOf(MockFileSystemService);
 32 |     });
 33 | 
 34 |     it('should handle mock files correctly', async () => {
 35 |       const filePath = '/test/file.txt';
 36 |       const content = 'test content';
 37 | 
 38 |       // Initially file should not exist
 39 |       expect(await mockService.exists(filePath)).toBe(false);
 40 | 
 41 |       // Set mock file
 42 |       mockService.setMockFile(filePath, content);
 43 |       expect(await mockService.exists(filePath)).toBe(true);
 44 | 
 45 |       // Read mock file
 46 |       const readContent = await mockService.readFile(filePath);
 47 |       expect(readContent).toBe(content);
 48 |     });
 49 | 
 50 |     it('should handle mock directories correctly', async () => {
 51 |       const dirPath = '/test/dir';
 52 | 
 53 |       // Initially directory should not exist
 54 |       expect(await mockService.exists(dirPath)).toBe(false);
 55 | 
 56 |       // Set mock directory
 57 |       mockService.setMockDirectory(dirPath);
 58 |       expect(await mockService.exists(dirPath)).toBe(true);
 59 |     });
 60 | 
 61 |     it('should create directories through mkdir', async () => {
 62 |       const dirPath = '/test/new-dir';
 63 | 
 64 |       await mockService.mkdir(dirPath, { recursive: true });
 65 |       expect(await mockService.exists(dirPath)).toBe(true);
 66 |     });
 67 | 
 68 |     it('should create files through writeFile', async () => {
 69 |       const filePath = '/test/new-file.txt';
 70 |       const content = 'new content';
 71 | 
 72 |       await mockService.writeFile(filePath, content);
 73 |       expect(await mockService.exists(filePath)).toBe(true);
 74 | 
 75 |       const readContent = await mockService.readFile(filePath);
 76 |       expect(readContent).toBe(content);
 77 |     });
 78 | 
 79 |     it('should throw error when reading non-existent file', async () => {
 80 |       const filePath = '/test/non-existent.txt';
 81 | 
 82 |       await expect(mockService.readFile(filePath)).rejects.toThrow('File not found');
 83 |     });
 84 | 
 85 |     it('should handle access correctly', async () => {
 86 |       const existingPath = '/test/existing';
 87 |       const nonExistentPath = '/test/non-existent';
 88 | 
 89 |       mockService.setMockFile(existingPath, 'content');
 90 | 
 91 |       await expect(mockService.access(existingPath)).resolves.not.toThrow();
 92 |       await expect(mockService.access(nonExistentPath)).rejects.toThrow('Path not accessible');
 93 |     });
 94 | 
 95 |     it('should clear mocks correctly', async () => {
 96 |       const filePath = '/test/file.txt';
 97 |       const dirPath = '/test/dir';
 98 | 
 99 |       mockService.setMockFile(filePath, 'content');
100 |       mockService.setMockDirectory(dirPath);
101 | 
102 |       expect(await mockService.exists(filePath)).toBe(true);
103 |       expect(await mockService.exists(dirPath)).toBe(true);
104 | 
105 |       mockService.clearMocks();
106 | 
107 |       expect(await mockService.exists(filePath)).toBe(false);
108 |       expect(await mockService.exists(dirPath)).toBe(false);
109 |     });
110 |   });
111 | });
112 | 
```

--------------------------------------------------------------------------------
/docs/dw_svc/ServiceRegistry.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.svc
  2 | 
  3 | # Class ServiceRegistry
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.svc.ServiceRegistry
  9 | 
 10 | ## Description
 11 | 
 12 | The ServiceRegistry is responsible for managing Service definitions and their instances. Typical usage involves several steps: The service is defined in the Business Manager and configured with necessary credentials. The service callback is configured once during cartridge initialization: ServiceRegistry.configure("MyFTPService", { mockExec : function(svc:FTPService, params) { return [ { "name": "file1", "timestamp": new Date(2011, 02, 21)}, { "name": "file2", "timestamp": new Date(2012, 02, 21)}, { "name": "file3", "timestamp": new Date(2013, 02, 21)} ]; }, createRequest: function(svc:FTPService, params) { svc.setOperation("list", "/"); }, parseResponse : function(svc:FTPService, listOutput) { var x : Array = []; var resp : Array = listOutput; for(var i = 0; i < resp.length; i++) { var f = resp[i]; x.push( { "name": f['name'], "timestamp": f['timestamp'] } ); } return x; } }); A new service instance is created and called in order to perform the operation: var result : Result = ServiceRegistry.get("MyFTPService").call(); if(result.status == 'OK') { // The result.object is the object returned by the 'after' callback. } else { // Handle the error. See result.error for more information. } See ServiceCallback for all the callback options, and individual ServiceDefinition classes for customization specific to a service type.
 13 | 
 14 | ## Constructor Summary
 15 | 
 16 | ## Method Summary
 17 | 
 18 | ### configure
 19 | 
 20 | **Signature:** `static configure(serviceID : String, configObj : Object) : ServiceDefinition`
 21 | 
 22 | Configure the given serviceId with a callback.
 23 | 
 24 | ### get
 25 | 
 26 | **Signature:** `static get(serviceID : String) : Service`
 27 | 
 28 | Constructs a new instance of the given service.
 29 | 
 30 | ### getDefinition
 31 | 
 32 | **Signature:** `static getDefinition(serviceID : String) : ServiceDefinition`
 33 | 
 34 | Gets a Service Definition.
 35 | 
 36 | ### isConfigured
 37 | 
 38 | **Signature:** `static isConfigured(serviceID : String) : boolean`
 39 | 
 40 | Returns the status of whether the given service has been configured with a callback.
 41 | 
 42 | ## Method Detail
 43 | 
 44 | ## Method Details
 45 | 
 46 | ### configure
 47 | 
 48 | **Signature:** `static configure(serviceID : String, configObj : Object) : ServiceDefinition`
 49 | 
 50 | **Description:** Configure the given serviceId with a callback. If the service is already configured, the given callback will replace any existing one.
 51 | 
 52 | **Parameters:**
 53 | 
 54 | - `serviceID`: Unique Service ID.
 55 | - `configObj`: Configuration callback. See ServiceCallback for a description of available callback methods.
 56 | 
 57 | **Returns:**
 58 | 
 59 | Associated ServiceDefinition, which can be used for further protocol-specific configuration.
 60 | 
 61 | ---
 62 | 
 63 | ### get
 64 | 
 65 | **Signature:** `static get(serviceID : String) : Service`
 66 | 
 67 | **Description:** Constructs a new instance of the given service.
 68 | 
 69 | **Parameters:**
 70 | 
 71 | - `serviceID`: Unique Service ID.
 72 | 
 73 | **Returns:**
 74 | 
 75 | Service instance.
 76 | 
 77 | ---
 78 | 
 79 | ### getDefinition
 80 | 
 81 | **Signature:** `static getDefinition(serviceID : String) : ServiceDefinition`
 82 | 
 83 | **Description:** Gets a Service Definition. This Service Definition is shared across all Service instances returned by get(String).
 84 | 
 85 | **Parameters:**
 86 | 
 87 | - `serviceID`: Unique Service ID.
 88 | 
 89 | **Returns:**
 90 | 
 91 | ServiceDefinition
 92 | 
 93 | ---
 94 | 
 95 | ### isConfigured
 96 | 
 97 | **Signature:** `static isConfigured(serviceID : String) : boolean`
 98 | 
 99 | **Description:** Returns the status of whether the given service has been configured with a callback.
100 | 
101 | **Parameters:**
102 | 
103 | - `serviceID`: Unique Service ID.
104 | 
105 | **Returns:**
106 | 
107 | true if configure has already been called, false otherwise.
108 | 
109 | ---
```

--------------------------------------------------------------------------------
/src/core/handlers/job-log-tool-config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { ToolSpec, LogToolValidators } from '../../utils/log-tool-utils.js';
 2 | import { ValidationHelpers, CommonValidations } from './validation-helpers.js';
 3 | import { JobLogToolName, getLimit } from '../../utils/log-tool-constants.js';
 4 | import { JobLogValidators, JobLogFormatters } from '../../utils/job-log-utils.js';
 5 | 
 6 | /**
 7 |  * Configuration for job log tools
 8 |  * Maps each tool to its validation, execution, and messaging logic
 9 |  */
10 | export const JOB_LOG_TOOL_CONFIG: Record<JobLogToolName, ToolSpec> = {
11 |   get_latest_job_log_files: {
12 |     defaults: (args) => ({
13 |       limit: getLimit(args.limit as number, 'jobFiles'),
14 |     }),
15 |     validate: (args, toolName) => LogToolValidators.validateLimit(args.limit as number, toolName),
16 |     exec: async (args, client) => client.getLatestJobLogFiles(args.limit as number),
17 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching latest job log files', {
18 |       limit: args.limit as number,
19 |     }),
20 |   },
21 | 
22 |   search_job_logs_by_name: {
23 |     defaults: (args) => ({
24 |       limit: getLimit(args.limit as number, 'jobFiles'),
25 |     }),
26 |     validate: (args, toolName) => {
27 |       ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
28 |       LogToolValidators.validateLimit(args.limit as number, toolName);
29 |     },
30 |     exec: async (args, client) => client.searchJobLogsByName(args.jobName as string, args.limit as number),
31 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs by name', {
32 |       jobName: args.jobName as string,
33 |       limit: args.limit as number,
34 |     }),
35 |   },
36 | 
37 |   get_job_log_entries: {
38 |     defaults: (args) => ({
39 |       level: args.level ?? 'all',
40 |       limit: getLimit(args.limit as number, 'jobEntries'),
41 |     }),
42 |     validate: (args, toolName) => {
43 |       JobLogValidators.validateJobLogLevel(args.level as string, toolName);
44 |       LogToolValidators.validateLimit(args.limit as number, toolName);
45 |     },
46 |     exec: async (args, client) => client.getJobLogEntries(
47 |       args.level as any,
48 |       args.limit as number,
49 |       args.jobName as string,
50 |     ),
51 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching job log entries', {
52 |       level: args.level as string,
53 |       limit: args.limit as number,
54 |       jobName: args.jobName as string,
55 |     }),
56 |   },
57 | 
58 |   search_job_logs: {
59 |     defaults: (args) => ({
60 |       level: args.level ?? 'all',
61 |       limit: getLimit(args.limit as number, 'jobSearch'),
62 |     }),
63 |     validate: (args, toolName) => {
64 |       ValidationHelpers.validateArguments(args, CommonValidations.requiredString('pattern'), toolName);
65 |       JobLogValidators.validateJobLogLevel(args.level as string, toolName);
66 |       LogToolValidators.validateLimit(args.limit as number, toolName);
67 |     },
68 |     exec: async (args, client) => client.searchJobLogs(
69 |       args.pattern as string,
70 |       args.level as any,
71 |       args.limit as number,
72 |       args.jobName as string,
73 |     ),
74 |     logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs', {
75 |       pattern: args.pattern as string,
76 |       level: args.level as string,
77 |       limit: args.limit as number,
78 |       jobName: args.jobName as string,
79 |     }),
80 |   },
81 | 
82 |   get_job_execution_summary: {
83 |     validate: (args, toolName) => {
84 |       ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
85 |     },
86 |     exec: async (args, client) => client.getJobExecutionSummary(args.jobName as string),
87 |     logMessage: (args) => `Getting job execution summary for: ${args.jobName as string}`,
88 |   },
89 | };
90 | 
```

--------------------------------------------------------------------------------
/docs-site/scripts/search-dev.js:
--------------------------------------------------------------------------------

```javascript
  1 | #!/usr/bin/env node
  2 | 
  3 | /**
  4 |  * Development utility script for the search index
  5 |  * Provides commands for generation, validation, and testing
  6 |  */
  7 | 
  8 | import { generateSearchIndex, writeSearchIndex } from './generate-search-index.js';
  9 | import fs from 'fs';
 10 | import path from 'path';
 11 | import { fileURLToPath } from 'url';
 12 | 
 13 | const __filename = fileURLToPath(import.meta.url);
 14 | const __dirname = path.dirname(__filename);
 15 | 
 16 | const command = process.argv[2];
 17 | 
 18 | switch (command) {
 19 |   case 'generate':
 20 |     console.log('🔄 Generating search index...');
 21 |     try {
 22 |       const index = generateSearchIndex();
 23 |       writeSearchIndex(index);
 24 |     } catch (error) {
 25 |       console.error('❌ Failed to generate search index:', error.message);
 26 |       process.exit(1);
 27 |     }
 28 |     break;
 29 | 
 30 |   case 'validate':
 31 |     console.log('✅ Validating search index...');
 32 |     try {
 33 |       const indexPath = path.join(__dirname, '../src/generated-search-index.ts');
 34 |       if (!fs.existsSync(indexPath)) {
 35 |         console.error('❌ Search index file not found. Run "generate" first.');
 36 |         process.exit(1);
 37 |       }
 38 | 
 39 |       const stats = fs.statSync(indexPath);
 40 |       const content = fs.readFileSync(indexPath, 'utf-8');
 41 |       const lines = content.split('\n').length;
 42 |       const size = (stats.size / 1024).toFixed(1);
 43 | 
 44 |       // Extract the number of entries
 45 |       const match = content.match(/GENERATED_SEARCH_INDEX: SearchableItem\[\] = \[([\s\S]*)\];/);
 46 |       if (match) {
 47 |         const entriesCount = (match[1].match(/\{/g) || []).length;
 48 |         console.log('📊 Search index statistics:');
 49 |         console.log(`   • File size: ${size} KB`);
 50 |         console.log(`   • Lines: ${lines}`);
 51 |         console.log(`   • Search entries: ${entriesCount}`);
 52 |         console.log(`   • Last modified: ${stats.mtime.toLocaleString()}`);
 53 |         console.log('✅ Search index is valid');
 54 |       } else {
 55 |         throw new Error('Invalid search index format');
 56 |       }
 57 |     } catch (error) {
 58 |       console.error('❌ Search index validation failed:', error.message);
 59 |       process.exit(1);
 60 |     }
 61 |     break;
 62 | 
 63 |   case 'search': {
 64 |     const query = process.argv[3];
 65 |     if (!query) {
 66 |       console.error('❌ Please provide a search query: npm run search-dev search "your query"');
 67 |       process.exit(1);
 68 |     }
 69 | 
 70 |     console.log(`🔍 Testing search for: "${query}"`);
 71 |     try {
 72 |       // Dynamically import and test the search function
 73 |       const { searchDocs } = await import('../utils/search.ts');
 74 |       const results = searchDocs(query);
 75 | 
 76 |       if (results.length === 0) {
 77 |         console.log('📭 No results found');
 78 |       } else {
 79 |         console.log(`📋 Found ${results.length} results:`);
 80 |         results.forEach((result, index) => {
 81 |           console.log(`\n${index + 1}. ${result.heading} (${result.pageTitle})`);
 82 |           console.log(`   Path: ${result.path}`);
 83 |           console.log(`   Score: ${result.score}`);
 84 |           console.log(`   Snippet: ${result.snippet.substring(0, 100)}...`);
 85 |         });
 86 |       }
 87 |     } catch (error) {
 88 |       console.error('❌ Search test failed:', error.message);
 89 |       process.exit(1);
 90 |     }
 91 |     break;
 92 |   }
 93 | 
 94 |   default:
 95 |     console.log(`
 96 | 🔧 Search Index Development Utility
 97 | 
 98 | Usage:
 99 |   node scripts/search-dev.js <command>
100 | 
101 | Commands:
102 |   generate    Generate the search index from React components
103 |   validate    Check if the search index is valid and show statistics
104 |   search      Test search functionality with a query
105 | 
106 | Examples:
107 |   node scripts/search-dev.js generate
108 |   node scripts/search-dev.js validate
109 |   node scripts/search-dev.js search "pattern matching"
110 | `);
111 |     break;
112 | }
113 | 
```

--------------------------------------------------------------------------------
/docs/dw_customer/ExternalProfile.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.customer
  2 | 
  3 | # Class ExternalProfile
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.customer.ExternalProfile
  9 | 
 10 | ## Description
 11 | 
 12 | Represents the credentials of a customer. Since 13.6 it is possible to have customers who are not authenticated through a login and password but through an external authentication provider via the OAuth2 protocol. In such cases, the AuthenticationProviderID will point to an OAuth provider configured in the system and the ExternalID will be the unique identifier of the customer on the Authentication Provider's system. For example, if an authentication provider with ID "Google123" is configured pointing to Google and the customer has a logged in into Google in the past and has created a profile there, Google assigns a unique number identifier to that customer. If the storefront is configured to allow authentication through Google and a new customer logs into the storefront using Google, the AuthenticationProviderID property of his Credentials will contain "Google123" and the ExternalID property will contain whatever unique identifier Google has assigned to him. Note: this class handles sensitive security-related data. Pay special attention to PCI DSS v3. requirements 2, 4, and 12.
 13 | 
 14 | ## Properties
 15 | 
 16 | ### authenticationProviderID
 17 | 
 18 | **Type:** String (Read Only)
 19 | 
 20 | The authentication provider ID.
 21 | 
 22 | ### customer
 23 | 
 24 | **Type:** Customer (Read Only)
 25 | 
 26 | The customer object related to this profile.
 27 | 
 28 | ### email
 29 | 
 30 | **Type:** String
 31 | 
 32 | The customer's email address.
 33 | 
 34 | ### externalID
 35 | 
 36 | **Type:** String (Read Only)
 37 | 
 38 | The external ID.
 39 | 
 40 | ### lastLoginTime
 41 | 
 42 | **Type:** Date (Read Only)
 43 | 
 44 | The last login time of the customer through the external provider
 45 | 
 46 | ## Constructor Summary
 47 | 
 48 | ## Method Summary
 49 | 
 50 | ### getAuthenticationProviderID
 51 | 
 52 | **Signature:** `getAuthenticationProviderID() : String`
 53 | 
 54 | Returns the authentication provider ID.
 55 | 
 56 | ### getCustomer
 57 | 
 58 | **Signature:** `getCustomer() : Customer`
 59 | 
 60 | Returns the customer object related to this profile.
 61 | 
 62 | ### getEmail
 63 | 
 64 | **Signature:** `getEmail() : String`
 65 | 
 66 | Returns the customer's email address.
 67 | 
 68 | ### getExternalID
 69 | 
 70 | **Signature:** `getExternalID() : String`
 71 | 
 72 | Returns the external ID.
 73 | 
 74 | ### getLastLoginTime
 75 | 
 76 | **Signature:** `getLastLoginTime() : Date`
 77 | 
 78 | Returns the last login time of the customer through the external provider
 79 | 
 80 | ### setEmail
 81 | 
 82 | **Signature:** `setEmail(email : String) : void`
 83 | 
 84 | Sets the customer's email address.
 85 | 
 86 | ## Method Detail
 87 | 
 88 | ## Method Details
 89 | 
 90 | ### getAuthenticationProviderID
 91 | 
 92 | **Signature:** `getAuthenticationProviderID() : String`
 93 | 
 94 | **Description:** Returns the authentication provider ID.
 95 | 
 96 | **Returns:**
 97 | 
 98 | the authentication provider ID.
 99 | 
100 | ---
101 | 
102 | ### getCustomer
103 | 
104 | **Signature:** `getCustomer() : Customer`
105 | 
106 | **Description:** Returns the customer object related to this profile.
107 | 
108 | **Returns:**
109 | 
110 | customer object related to profile.
111 | 
112 | ---
113 | 
114 | ### getEmail
115 | 
116 | **Signature:** `getEmail() : String`
117 | 
118 | **Description:** Returns the customer's email address.
119 | 
120 | **Returns:**
121 | 
122 | the customer's email address.
123 | 
124 | ---
125 | 
126 | ### getExternalID
127 | 
128 | **Signature:** `getExternalID() : String`
129 | 
130 | **Description:** Returns the external ID.
131 | 
132 | **Returns:**
133 | 
134 | the external ID.
135 | 
136 | ---
137 | 
138 | ### getLastLoginTime
139 | 
140 | **Signature:** `getLastLoginTime() : Date`
141 | 
142 | **Description:** Returns the last login time of the customer through the external provider
143 | 
144 | **Returns:**
145 | 
146 | the time, when the customer was last logged in through this external provider
147 | 
148 | ---
149 | 
150 | ### setEmail
151 | 
152 | **Signature:** `setEmail(email : String) : void`
153 | 
154 | **Description:** Sets the customer's email address.
155 | 
156 | **Parameters:**
157 | 
158 | - `email`: the customer's email address.
159 | 
160 | ---
```

--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/src/middleware/logging.js:
--------------------------------------------------------------------------------

```javascript
  1 | /**
  2 |  * Logging Middleware
  3 |  * 
  4 |  * Provides request/response logging functionality for debugging and monitoring.
  5 |  * Configurable logging levels and output formatting.
  6 |  */
  7 | 
  8 | /**
  9 |  * Create request logging middleware
 10 |  */
 11 | function createRequestLogger(isDevMode = false) {
 12 |     if (!isDevMode) {
 13 |         // Return no-op middleware in production mode
 14 |         return (req, res, next) => next();
 15 |     }
 16 | 
 17 |     return (req, res, next) => {
 18 |         const timestamp = new Date().toISOString();
 19 |         const method = req.method;
 20 |         const url = req.url;
 21 |         const userAgent = req.headers['user-agent'] || 'Unknown';
 22 |         
 23 |         console.log(`📥 [${timestamp}] ${method} ${url}`, {
 24 |             headers: {
 25 |                 authorization: req.headers.authorization ? '[REDACTED]' : undefined,
 26 |                 'content-type': req.headers['content-type'],
 27 |                 'depth': req.headers.depth,
 28 |                 'range': req.headers.range,
 29 |                 'user-agent': userAgent
 30 |             },
 31 |             query: Object.keys(req.query).length > 0 ? req.query : undefined,
 32 |             body: req.body && Object.keys(req.body).length > 0 ? req.body : undefined
 33 |         });
 34 |         
 35 |         next();
 36 |     };
 37 | }
 38 | 
 39 | /**
 40 |  * Create response logging middleware
 41 |  */
 42 | function createResponseLogger(isDevMode = false) {
 43 |     if (!isDevMode) {
 44 |         // Return no-op middleware in production mode
 45 |         return (req, res, next) => next();
 46 |     }
 47 | 
 48 |     return (req, res, next) => {
 49 |         const originalSend = res.send;
 50 |         const originalJson = res.json;
 51 |         
 52 |         // Override res.send
 53 |         res.send = function(body) {
 54 |             logResponse(req, res, body, 'send');
 55 |             return originalSend.call(this, body);
 56 |         };
 57 |         
 58 |         // Override res.json
 59 |         res.json = function(obj) {
 60 |             logResponse(req, res, obj, 'json');
 61 |             return originalJson.call(this, obj);
 62 |         };
 63 |         
 64 |         next();
 65 |     };
 66 | }
 67 | 
 68 | /**
 69 |  * Log response details
 70 |  */
 71 | function logResponse(req, res, body, type) {
 72 |     const timestamp = new Date().toISOString();
 73 |     const method = req.method;
 74 |     const url = req.url;
 75 |     const statusCode = res.statusCode;
 76 |     
 77 |     let bodyPreview = body;
 78 |     
 79 |     // Truncate large responses for readability
 80 |     if (typeof body === 'string' && body.length > 500) {
 81 |         bodyPreview = body.substring(0, 500) + '... [truncated]';
 82 |     } else if (typeof body === 'object' && body !== null) {
 83 |         const bodyStr = JSON.stringify(body);
 84 |         if (bodyStr.length > 500) {
 85 |             bodyPreview = JSON.stringify(body, null, 2).substring(0, 500) + '... [truncated]';
 86 |         }
 87 |     }
 88 |     
 89 |     console.log(`📤 [${timestamp}] ${method} ${url} -> ${statusCode}`, {
 90 |         headers: {
 91 |             'content-type': res.getHeader('content-type'),
 92 |             'content-length': res.getHeader('content-length'),
 93 |             'content-range': res.getHeader('content-range')
 94 |         },
 95 |         type,
 96 |         body: bodyPreview
 97 |     });
 98 | }
 99 | 
100 | /**
101 |  * Create error logging middleware
102 |  */
103 | function createErrorLogger() {
104 |     return (err, req, res, next) => {
105 |         const timestamp = new Date().toISOString();
106 |         const method = req.method;
107 |         const url = req.url;
108 |         
109 |         console.error(`❌ [${timestamp}] ERROR ${method} ${url}:`, {
110 |             message: err.message,
111 |             stack: err.stack,
112 |             code: err.code
113 |         });
114 |         
115 |         // Don't handle the error, just log it
116 |         next(err);
117 |     };
118 | }
119 | 
120 | module.exports = {
121 |     createRequestLogger,
122 |     createResponseLogger,
123 |     createErrorLogger
124 | };
```

--------------------------------------------------------------------------------
/docs/dw_campaign/CouponMgr.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.campaign
  2 | 
  3 | # Class CouponMgr
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.campaign.CouponMgr
  9 | 
 10 | ## Description
 11 | 
 12 | Manager to access coupons.
 13 | 
 14 | ## Constants
 15 | 
 16 | ### MR_ERROR_INVALID_SITE_ID
 17 | 
 18 | **Type:** String = "MASKREDEMPTIONS_SITE_NOT_FOUND"
 19 | 
 20 | Indicates that an error occurred because a valid data domain cannot be found for given siteID.
 21 | 
 22 | ## Properties
 23 | 
 24 | ### coupons
 25 | 
 26 | **Type:** Collection (Read Only)
 27 | 
 28 | All coupons in the current site in no specific order.
 29 | 
 30 | ## Constructor Summary
 31 | 
 32 | ## Method Summary
 33 | 
 34 | ### getCoupon
 35 | 
 36 | **Signature:** `static getCoupon(couponID : String) : Coupon`
 37 | 
 38 | Returns the coupon with the specified ID.
 39 | 
 40 | ### getCouponByCode
 41 | 
 42 | **Signature:** `static getCouponByCode(couponCode : String) : Coupon`
 43 | 
 44 | Tries to find a coupon for the given coupon code.
 45 | 
 46 | ### getCoupons
 47 | 
 48 | **Signature:** `static getCoupons() : Collection`
 49 | 
 50 | Returns all coupons in the current site in no specific order.
 51 | 
 52 | ### getRedemptions
 53 | 
 54 | **Signature:** `static getRedemptions(couponID : String, couponCode : String) : Collection`
 55 | 
 56 | Returns list of CouponRedemptions for the specified coupon and coupon code, sorted by redemption date descending (i.e.
 57 | 
 58 | ### maskRedemptions
 59 | 
 60 | **Signature:** `static maskRedemptions(siteID : String, email : String) : Status`
 61 | 
 62 | Mask customer email address in coupon redemptions for the given siteID and email address
 63 | 
 64 | ## Method Detail
 65 | 
 66 | ## Method Details
 67 | 
 68 | ### getCoupon
 69 | 
 70 | **Signature:** `static getCoupon(couponID : String) : Coupon`
 71 | 
 72 | **Description:** Returns the coupon with the specified ID.
 73 | 
 74 | **Parameters:**
 75 | 
 76 | - `couponID`: the coupon identifier.
 77 | 
 78 | **Returns:**
 79 | 
 80 | Coupon with specified ID or null
 81 | 
 82 | ---
 83 | 
 84 | ### getCouponByCode
 85 | 
 86 | **Signature:** `static getCouponByCode(couponCode : String) : Coupon`
 87 | 
 88 | **Description:** Tries to find a coupon for the given coupon code. The method first searches for a coupon with a fixed code matching the passed value. If no such fixed coupon is found, it searches for a coupon with a system-generated code matching the passed value. If found, the coupon is returned. Otherwise, the method returns null.
 89 | 
 90 | **Parameters:**
 91 | 
 92 | - `couponCode`: The coupon code to get the coupon for.
 93 | 
 94 | **Returns:**
 95 | 
 96 | The coupon with the matching coupon code or null if no coupon was found.
 97 | 
 98 | ---
 99 | 
100 | ### getCoupons
101 | 
102 | **Signature:** `static getCoupons() : Collection`
103 | 
104 | **Description:** Returns all coupons in the current site in no specific order.
105 | 
106 | **Returns:**
107 | 
108 | Coupons in current site
109 | 
110 | ---
111 | 
112 | ### getRedemptions
113 | 
114 | **Signature:** `static getRedemptions(couponID : String, couponCode : String) : Collection`
115 | 
116 | **Description:** Returns list of CouponRedemptions for the specified coupon and coupon code, sorted by redemption date descending (i.e. last redemption first). Usually, there should only either be 0 or 1 redemption. But if a coupon and code is removed and recreated and re-issued later, there might be multiple such redemption records. Returns an empty list if no redemption record exists in system for the specified coupon and code.
117 | 
118 | **Parameters:**
119 | 
120 | - `couponID`: The coupon id to find redemption for.
121 | - `couponCode`: The coupon code to find redemption for.
122 | 
123 | **Returns:**
124 | 
125 | A sorted list of CouponRedemptions for the specified coupon and coupon code or an empty list if no redemption record exists.
126 | 
127 | ---
128 | 
129 | ### maskRedemptions
130 | 
131 | **Signature:** `static maskRedemptions(siteID : String, email : String) : Status`
132 | 
133 | **Description:** Mask customer email address in coupon redemptions for the given siteID and email address
134 | 
135 | **Parameters:**
136 | 
137 | - `siteID`: the site ID
138 | - `email`: the customer email address
139 | 
140 | **Returns:**
141 | 
142 | The status of the masking result
143 | 
144 | ---
```

--------------------------------------------------------------------------------
/docs/dw_content/ContentMgr.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.content
  2 | 
  3 | # Class ContentMgr
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.content.ContentMgr
  9 | 
 10 | ## Description
 11 | 
 12 | Provides helper methods for getting content assets, library folders and the content library of the current site.
 13 | 
 14 | ## Constants
 15 | 
 16 | ### PRIVATE_LIBRARY
 17 | 
 18 | **Type:** String = "PrivateLibrary"
 19 | 
 20 | The input string to identify that the library is a private site library when invoking getLibrary(String).
 21 | 
 22 | ## Properties
 23 | 
 24 | ### siteLibrary
 25 | 
 26 | **Type:** Library (Read Only)
 27 | 
 28 | The content library of the current site.
 29 | 
 30 | ## Constructor Summary
 31 | 
 32 | ## Method Summary
 33 | 
 34 | ### getContent
 35 | 
 36 | **Signature:** `static getContent(id : String) : Content`
 37 | 
 38 | Returns the content with the corresponding identifier within the current site's site library.
 39 | 
 40 | ### getContent
 41 | 
 42 | **Signature:** `static getContent(library : Library, id : String) : Content`
 43 | 
 44 | Returns the content with the corresponding identifier within the specified library.
 45 | 
 46 | ### getFolder
 47 | 
 48 | **Signature:** `static getFolder(id : String) : Folder`
 49 | 
 50 | Returns the folder identified by the specified id within the current site's site library.
 51 | 
 52 | ### getFolder
 53 | 
 54 | **Signature:** `static getFolder(library : Library, id : String) : Folder`
 55 | 
 56 | Returns the folder identified by the specified id within the specified library.
 57 | 
 58 | ### getLibrary
 59 | 
 60 | **Signature:** `static getLibrary(libraryId : String) : Library`
 61 | 
 62 | Returns the content library specified by the given id.
 63 | 
 64 | ### getSiteLibrary
 65 | 
 66 | **Signature:** `static getSiteLibrary() : Library`
 67 | 
 68 | Returns the content library of the current site.
 69 | 
 70 | ## Method Detail
 71 | 
 72 | ## Method Details
 73 | 
 74 | ### getContent
 75 | 
 76 | **Signature:** `static getContent(id : String) : Content`
 77 | 
 78 | **Description:** Returns the content with the corresponding identifier within the current site's site library.
 79 | 
 80 | **Parameters:**
 81 | 
 82 | - `id`: the ID of the content asset to find.
 83 | 
 84 | **Returns:**
 85 | 
 86 | the content if found, or null if not found.
 87 | 
 88 | ---
 89 | 
 90 | ### getContent
 91 | 
 92 | **Signature:** `static getContent(library : Library, id : String) : Content`
 93 | 
 94 | **Description:** Returns the content with the corresponding identifier within the specified library.
 95 | 
 96 | **Parameters:**
 97 | 
 98 | - `library`: the content library to look for the content in
 99 | - `id`: the ID of the content asset to find.
100 | 
101 | **Returns:**
102 | 
103 | the content if found, or null if not found.
104 | 
105 | ---
106 | 
107 | ### getFolder
108 | 
109 | **Signature:** `static getFolder(id : String) : Folder`
110 | 
111 | **Description:** Returns the folder identified by the specified id within the current site's site library.
112 | 
113 | **Parameters:**
114 | 
115 | - `id`: the ID of the folder to find.
116 | 
117 | **Returns:**
118 | 
119 | the folder, or null if not found.
120 | 
121 | ---
122 | 
123 | ### getFolder
124 | 
125 | **Signature:** `static getFolder(library : Library, id : String) : Folder`
126 | 
127 | **Description:** Returns the folder identified by the specified id within the specified library.
128 | 
129 | **Parameters:**
130 | 
131 | - `library`: the content library to look for the folder in
132 | - `id`: the ID of the folder to find.
133 | 
134 | **Returns:**
135 | 
136 | the folder, or null if not found.
137 | 
138 | ---
139 | 
140 | ### getLibrary
141 | 
142 | **Signature:** `static getLibrary(libraryId : String) : Library`
143 | 
144 | **Description:** Returns the content library specified by the given id. If PRIVATE_LIBRARY is used, then the current site's private library will be returned.
145 | 
146 | **Parameters:**
147 | 
148 | - `libraryId`: the id of the library to return.
149 | 
150 | **Returns:**
151 | 
152 | the library for the passed id. Returns null if there is no content library with that id.
153 | 
154 | ---
155 | 
156 | ### getSiteLibrary
157 | 
158 | **Signature:** `static getSiteLibrary() : Library`
159 | 
160 | **Description:** Returns the content library of the current site.
161 | 
162 | **Returns:**
163 | 
164 | the content library of the current site, or null if there is not content library assigned to the current site.
165 | 
166 | ---
```

--------------------------------------------------------------------------------
/docs/dw_customer/CustomerGroup.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.customer
  2 | 
  3 | # Class CustomerGroup
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.customer.CustomerGroup
 11 | 
 12 | ## Description
 13 | 
 14 | CustomerGroups provide a means to segment customers by various criteria. A merchant can then provide different site experiences (e.g. promotions, prices, sorting rules) to each customer segment. Customer groups can consist of either an explicit list of customers or a business rule that dynamically determines whether a customer is a member. The former type is called "explicit" and the latter type is called "dynamic". Explicit customer group: Consists of an explicit list of customers. Only registered customers can be member of such a group. isRuleBased==false. Dynamic customer group: Memberships are evaluated by a business rule that is attached to the customer group. Registered as well as anonymous customers can be member of such a group. isRuleBased==true. Note: this class might allow access to sensitive personal and private information, depending on how you segment your customers and the names given to your custoemer groups. Pay attention to appropriate legal and regulatory requirements when developing with this data.
 15 | 
 16 | ## Properties
 17 | 
 18 | ### description
 19 | 
 20 | **Type:** String (Read Only)
 21 | 
 22 | Gets the value of the description of the customer group.
 23 | 
 24 | ### ID
 25 | 
 26 | **Type:** String (Read Only)
 27 | 
 28 | The unique ID of the customer group.
 29 | 
 30 | ### ruleBased
 31 | 
 32 | **Type:** boolean (Read Only)
 33 | 
 34 | Returns true if the group determines the membership of customers
 35 |  based on rules. Returns false if the group provides explicit assignement
 36 |  of customers.
 37 | 
 38 | ## Constructor Summary
 39 | 
 40 | ## Method Summary
 41 | 
 42 | ### assignCustomer
 43 | 
 44 | **Signature:** `assignCustomer(customer : Customer) : void`
 45 | 
 46 | Assigns the specified customer to this group.
 47 | 
 48 | ### getDescription
 49 | 
 50 | **Signature:** `getDescription() : String`
 51 | 
 52 | Gets the value of the description of the customer group.
 53 | 
 54 | ### getID
 55 | 
 56 | **Signature:** `getID() : String`
 57 | 
 58 | Returns the unique ID of the customer group.
 59 | 
 60 | ### isRuleBased
 61 | 
 62 | **Signature:** `isRuleBased() : boolean`
 63 | 
 64 | Returns true if the group determines the membership of customers based on rules.
 65 | 
 66 | ### unassignCustomer
 67 | 
 68 | **Signature:** `unassignCustomer(customer : Customer) : void`
 69 | 
 70 | Unassigns the specified customer from this group.
 71 | 
 72 | ## Method Detail
 73 | 
 74 | ## Method Details
 75 | 
 76 | ### assignCustomer
 77 | 
 78 | **Signature:** `assignCustomer(customer : Customer) : void`
 79 | 
 80 | **Description:** Assigns the specified customer to this group. The customer must be registered and the group must not be rule-based.
 81 | 
 82 | **Parameters:**
 83 | 
 84 | - `customer`: Registered customer, must not be null.
 85 | 
 86 | ---
 87 | 
 88 | ### getDescription
 89 | 
 90 | **Signature:** `getDescription() : String`
 91 | 
 92 | **Description:** Gets the value of the description of the customer group.
 93 | 
 94 | **Returns:**
 95 | 
 96 | the description of the customer group
 97 | 
 98 | ---
 99 | 
100 | ### getID
101 | 
102 | **Signature:** `getID() : String`
103 | 
104 | **Description:** Returns the unique ID of the customer group.
105 | 
106 | **Returns:**
107 | 
108 | The unique semantic ID of the customer group.
109 | 
110 | ---
111 | 
112 | ### isRuleBased
113 | 
114 | **Signature:** `isRuleBased() : boolean`
115 | 
116 | **Description:** Returns true if the group determines the membership of customers based on rules. Returns false if the group provides explicit assignement of customers.
117 | 
118 | **Returns:**
119 | 
120 | True, if the customer group is rule based.
121 | 
122 | ---
123 | 
124 | ### unassignCustomer
125 | 
126 | **Signature:** `unassignCustomer(customer : Customer) : void`
127 | 
128 | **Description:** Unassigns the specified customer from this group. The customer must be registered and the group must not be rule-based.
129 | 
130 | **Parameters:**
131 | 
132 | - `customer`: Registered customer, must not be null.
133 | 
134 | ---
```

--------------------------------------------------------------------------------
/src/core/handlers/client-factory.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { HandlerContext } from './base-handler.js';
  2 | import { SFCCLogClient } from '../../clients/log-client.js';
  3 | import { OCAPIClient } from '../../clients/ocapi-client.js';
  4 | import { OCAPICodeVersionsClient } from '../../clients/ocapi/code-versions-client.js';
  5 | import { CartridgeGenerationClient } from '../../clients/cartridge-generation-client.js';
  6 | import { Logger } from '../../utils/logger.js';
  7 | import { IFileSystemService, IPathService, FileSystemService, PathService } from '../../services/index.js';
  8 | 
  9 | /**
 10 |  * Centralized client factory that handles complex initialization logic
 11 |  * and encapsulates the requirements for different client types.
 12 |  */
 13 | export class ClientFactory {
 14 |   private context: HandlerContext;
 15 |   private logger: Logger;
 16 | 
 17 |   constructor(context: HandlerContext, logger: Logger) {
 18 |     this.context = context;
 19 |     this.logger = logger;
 20 |   }
 21 | 
 22 |   /**
 23 |    * Create an SFCC Log Client if log access is available
 24 |    */
 25 |   createLogClient(): SFCCLogClient | null {
 26 |     if (!this.context.capabilities?.canAccessLogs || !this.context.config) {
 27 |       this.logger.debug('Log client not created: missing log access capability or config');
 28 |       return null;
 29 |     }
 30 | 
 31 |     this.logger.debug('Creating SFCC Log Client');
 32 |     return new SFCCLogClient(this.context.config);
 33 |   }
 34 | 
 35 |   /**
 36 |    * Create an OCAPI Client if OCAPI access is available
 37 |    */
 38 |   createOCAPIClient(): OCAPIClient | null {
 39 |     if (!this.hasOCAPICredentials()) {
 40 |       this.logger.debug('OCAPI client not created: missing OCAPI credentials or capability');
 41 |       return null;
 42 |     }
 43 | 
 44 |     this.logger.debug('Creating OCAPI Client');
 45 |     return new OCAPIClient({
 46 |       hostname: this.context.config!.hostname!,
 47 |       clientId: this.context.config!.clientId!,
 48 |       clientSecret: this.context.config!.clientSecret!,
 49 |       version: 'v23_2',
 50 |     });
 51 |   }
 52 | 
 53 |   /**
 54 |    * Create an OCAPI Code Versions Client if OCAPI access is available
 55 |    */
 56 |   createCodeVersionsClient(): OCAPICodeVersionsClient | null {
 57 |     if (!this.hasOCAPICredentials()) {
 58 |       this.logger.debug('Code versions client not created: missing OCAPI credentials or capability');
 59 |       return null;
 60 |     }
 61 | 
 62 |     this.logger.debug('Creating OCAPI Code Versions Client');
 63 |     return new OCAPICodeVersionsClient({
 64 |       hostname: this.context.config!.hostname!,
 65 |       clientId: this.context.config!.clientId!,
 66 |       clientSecret: this.context.config!.clientSecret!,
 67 |       version: 'v23_2',
 68 |     });
 69 |   }
 70 | 
 71 |   /**
 72 |    * Check if OCAPI credentials and capability are available
 73 |    */
 74 |   private hasOCAPICredentials(): boolean {
 75 |     return !!(
 76 |       this.context.capabilities?.canAccessOCAPI &&
 77 |       this.context.config?.hostname &&
 78 |       this.context.config?.clientId &&
 79 |       this.context.config?.clientSecret
 80 |     );
 81 |   }
 82 | 
 83 |   /**
 84 |    * Create a Cartridge Generation Client with injected dependencies
 85 |    */
 86 |   createCartridgeClient(
 87 |     fileSystemService?: IFileSystemService,
 88 |     pathService?: IPathService,
 89 |   ): CartridgeGenerationClient {
 90 |     this.logger.debug('Creating Cartridge Generation Client');
 91 |     return new CartridgeGenerationClient(
 92 |       fileSystemService ?? new FileSystemService(),
 93 |       pathService ?? new PathService(),
 94 |     );
 95 |   }
 96 | 
 97 |   /**
 98 |    * Get the required error message for a client type
 99 |    */
100 |   static getClientRequiredError(clientType: 'OCAPI' | 'Log'): string {
101 |     switch (clientType) {
102 |       case 'OCAPI':
103 |         return 'OCAPI client not configured - ensure credentials are provided in full mode.';
104 |       case 'Log':
105 |         return 'Log client not configured - ensure log access is enabled.';
106 |       default:
107 |         return 'Required client not configured.';
108 |     }
109 |   }
110 | }
111 | 
```

--------------------------------------------------------------------------------
/docs/dw_catalog/ProductOption.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class ProductOption
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.catalog.ProductOption
 11 | 
 12 | ## Description
 13 | 
 14 | Represents a product option.
 15 | 
 16 | ## Properties
 17 | 
 18 | ### defaultValue
 19 | 
 20 | **Type:** ProductOptionValue (Read Only)
 21 | 
 22 | The default value for the product option.
 23 | 
 24 | ### description
 25 | 
 26 | **Type:** String (Read Only)
 27 | 
 28 | The product option's short description in the current locale.
 29 | 
 30 | ### displayName
 31 | 
 32 | **Type:** String (Read Only)
 33 | 
 34 | The product option's display name in the current locale.
 35 | 
 36 | ### htmlName
 37 | 
 38 | **Type:** String (Read Only)
 39 | 
 40 | An HTML representation of the option id.
 41 | 
 42 | ### ID
 43 | 
 44 | **Type:** String (Read Only)
 45 | 
 46 | The product option ID.
 47 | 
 48 | ### image
 49 | 
 50 | **Type:** MediaFile (Read Only)
 51 | 
 52 | The product option's image.
 53 | 
 54 | ### optionValues
 55 | 
 56 | **Type:** Collection (Read Only)
 57 | 
 58 | A collection containing the product option values.
 59 | 
 60 | ## Constructor Summary
 61 | 
 62 | ## Method Summary
 63 | 
 64 | ### getDefaultValue
 65 | 
 66 | **Signature:** `getDefaultValue() : ProductOptionValue`
 67 | 
 68 | Returns the default value for the product option.
 69 | 
 70 | ### getDescription
 71 | 
 72 | **Signature:** `getDescription() : String`
 73 | 
 74 | Returns the product option's short description in the current locale.
 75 | 
 76 | ### getDisplayName
 77 | 
 78 | **Signature:** `getDisplayName() : String`
 79 | 
 80 | Returns the product option's display name in the current locale.
 81 | 
 82 | ### getHtmlName
 83 | 
 84 | **Signature:** `getHtmlName() : String`
 85 | 
 86 | Returns an HTML representation of the option id.
 87 | 
 88 | ### getHtmlName
 89 | 
 90 | **Signature:** `getHtmlName(prefix : String) : String`
 91 | 
 92 | Returns an HTML representation of the option id with the custom prefix.
 93 | 
 94 | ### getID
 95 | 
 96 | **Signature:** `getID() : String`
 97 | 
 98 | Returns the product option ID.
 99 | 
100 | ### getImage
101 | 
102 | **Signature:** `getImage() : MediaFile`
103 | 
104 | Returns the product option's image.
105 | 
106 | ### getOptionValues
107 | 
108 | **Signature:** `getOptionValues() : Collection`
109 | 
110 | Returns a collection containing the product option values.
111 | 
112 | ## Method Detail
113 | 
114 | ## Method Details
115 | 
116 | ### getDefaultValue
117 | 
118 | **Signature:** `getDefaultValue() : ProductOptionValue`
119 | 
120 | **Description:** Returns the default value for the product option.
121 | 
122 | **Returns:**
123 | 
124 | the object for the relation 'defaultValue'
125 | 
126 | ---
127 | 
128 | ### getDescription
129 | 
130 | **Signature:** `getDescription() : String`
131 | 
132 | **Description:** Returns the product option's short description in the current locale.
133 | 
134 | **Returns:**
135 | 
136 | The value of the short description in the current locale, or null if it wasn't found.
137 | 
138 | ---
139 | 
140 | ### getDisplayName
141 | 
142 | **Signature:** `getDisplayName() : String`
143 | 
144 | **Description:** Returns the product option's display name in the current locale.
145 | 
146 | **Returns:**
147 | 
148 | The value of the display name in the current locale, or null if it wasn't found.
149 | 
150 | ---
151 | 
152 | ### getHtmlName
153 | 
154 | **Signature:** `getHtmlName() : String`
155 | 
156 | **Description:** Returns an HTML representation of the option id.
157 | 
158 | **Returns:**
159 | 
160 | an HTML representation of the option id.
161 | 
162 | ---
163 | 
164 | ### getHtmlName
165 | 
166 | **Signature:** `getHtmlName(prefix : String) : String`
167 | 
168 | **Description:** Returns an HTML representation of the option id with the custom prefix.
169 | 
170 | **Parameters:**
171 | 
172 | - `prefix`: a custom prefix for the html name.
173 | 
174 | **Returns:**
175 | 
176 | an HTML representation of the option id.
177 | 
178 | ---
179 | 
180 | ### getID
181 | 
182 | **Signature:** `getID() : String`
183 | 
184 | **Description:** Returns the product option ID.
185 | 
186 | **Returns:**
187 | 
188 | the product option identifier.
189 | 
190 | ---
191 | 
192 | ### getImage
193 | 
194 | **Signature:** `getImage() : MediaFile`
195 | 
196 | **Description:** Returns the product option's image.
197 | 
198 | **Returns:**
199 | 
200 | the product option's image.
201 | 
202 | ---
203 | 
204 | ### getOptionValues
205 | 
206 | **Signature:** `getOptionValues() : Collection`
207 | 
208 | **Description:** Returns a collection containing the product option values.
209 | 
210 | **Returns:**
211 | 
212 | a collection containing the product option values.
213 | 
214 | ---
```

--------------------------------------------------------------------------------
/docs/dw_suggest/SuggestedTerm.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.suggest
  2 | 
  3 | # Class SuggestedTerm
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.suggest.SuggestedTerm
  9 | 
 10 | ## Description
 11 | 
 12 | A single suggested term. Each user input term of the search phrase is being processed separately by the suggestion engine. For each original term, a list of terms will be suggested, either completed terms, corrected terms or even the exact term if it is known to the engine. Each suggested term is represented by a instance of this class. The list of suggested terms belonging to a single original term is represented by a instance of SuggestedTerms class. The suggested term value can either be the completed version of the original term, the corrected version of the original term or exactly the original term.
 13 | 
 14 | ## Properties
 15 | 
 16 | ### additional
 17 | 
 18 | **Type:** boolean (Read Only)
 19 | 
 20 | Returns whether this suggested term is a additional term that has no corresponding term in the original search phrase.
 21 | 
 22 | ### completed
 23 | 
 24 | **Type:** boolean (Read Only)
 25 | 
 26 | Returns whether this suggested term is a auto completed version of the original term.
 27 |  In other words, this method returns true if the original term is a prefix of this suggested term.
 28 | 
 29 | ### corrected
 30 | 
 31 | **Type:** boolean (Read Only)
 32 | 
 33 | Returns whether this suggested term is a corrected version of the original term.
 34 | 
 35 | ### exactMatch
 36 | 
 37 | **Type:** boolean (Read Only)
 38 | 
 39 | Returns whether this suggested term is exactly matching the original term.
 40 | 
 41 | ### value
 42 | 
 43 | **Type:** String (Read Only)
 44 | 
 45 | Returns this suggested term as String value.
 46 | 
 47 | ## Constructor Summary
 48 | 
 49 | ## Method Summary
 50 | 
 51 | ### getValue
 52 | 
 53 | **Signature:** `getValue() : String`
 54 | 
 55 | Returns this suggested term as String value.
 56 | 
 57 | ### isAdditional
 58 | 
 59 | **Signature:** `isAdditional() : boolean`
 60 | 
 61 | Returns whether this suggested term is a additional term that has no corresponding term in the original search phrase.
 62 | 
 63 | ### isCompleted
 64 | 
 65 | **Signature:** `isCompleted() : boolean`
 66 | 
 67 | Returns whether this suggested term is a auto completed version of the original term.
 68 | 
 69 | ### isCorrected
 70 | 
 71 | **Signature:** `isCorrected() : boolean`
 72 | 
 73 | Returns whether this suggested term is a corrected version of the original term.
 74 | 
 75 | ### isExactMatch
 76 | 
 77 | **Signature:** `isExactMatch() : boolean`
 78 | 
 79 | Returns whether this suggested term is exactly matching the original term.
 80 | 
 81 | ## Method Detail
 82 | 
 83 | ## Method Details
 84 | 
 85 | ### getValue
 86 | 
 87 | **Signature:** `getValue() : String`
 88 | 
 89 | **Description:** Returns this suggested term as String value.
 90 | 
 91 | **Returns:**
 92 | 
 93 | the string representation of this suggested term
 94 | 
 95 | ---
 96 | 
 97 | ### isAdditional
 98 | 
 99 | **Signature:** `isAdditional() : boolean`
100 | 
101 | **Description:** Returns whether this suggested term is a additional term that has no corresponding term in the original search phrase.
102 | 
103 | **Returns:**
104 | 
105 | true if this suggested term is a additional term, false otherwise
106 | 
107 | ---
108 | 
109 | ### isCompleted
110 | 
111 | **Signature:** `isCompleted() : boolean`
112 | 
113 | **Description:** Returns whether this suggested term is a auto completed version of the original term. In other words, this method returns true if the original term is a prefix of this suggested term.
114 | 
115 | **Returns:**
116 | 
117 | true if this suggested term is evaluated by auto completion, false otherwise
118 | 
119 | ---
120 | 
121 | ### isCorrected
122 | 
123 | **Signature:** `isCorrected() : boolean`
124 | 
125 | **Description:** Returns whether this suggested term is a corrected version of the original term.
126 | 
127 | **Returns:**
128 | 
129 | true if this suggested term is a corrected version of the original term, false otherwise
130 | 
131 | ---
132 | 
133 | ### isExactMatch
134 | 
135 | **Signature:** `isExactMatch() : boolean`
136 | 
137 | **Description:** Returns whether this suggested term is exactly matching the original term.
138 | 
139 | **Returns:**
140 | 
141 | true if this suggested term exactly matches the original term, false otherwise
142 | 
143 | ---
```

--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/src/utils/webdav-xml.js:
--------------------------------------------------------------------------------

```javascript
  1 | /**
  2 |  * WebDAV XML Response Utilities
  3 |  * 
  4 |  * Handles generation of WebDAV XML responses for PROPFIND and other operations.
  5 |  * Provides clean, reusable functions for XML generation.
  6 |  */
  7 | 
  8 | const path = require('path');
  9 | 
 10 | /**
 11 |  * Generate WebDAV XML response for a single file
 12 |  */
 13 | function generateFileXmlResponse(urlPath, stats) {
 14 |     const filename = path.basename(urlPath);
 15 |     
 16 |     return `<?xml version="1.0" encoding="utf-8"?>
 17 | <D:multistatus xmlns:D="DAV:">
 18 |     <D:response>
 19 |         <D:href>${urlPath}</D:href>
 20 |         <D:propstat>
 21 |             <D:prop>
 22 |                 <D:displayname>${filename}</D:displayname>
 23 |                 <D:getcontentlength>${stats.size}</D:getcontentlength>
 24 |                 <D:getlastmodified>${stats.mtime.toUTCString()}</D:getlastmodified>
 25 |                 <D:resourcetype></D:resourcetype>
 26 |                 <D:getcontenttype>text/plain</D:getcontenttype>
 27 |             </D:prop>
 28 |             <D:status>HTTP/1.1 200 OK</D:status>
 29 |         </D:propstat>
 30 |     </D:response>
 31 | </D:multistatus>`;
 32 | }
 33 | 
 34 | /**
 35 |  * Generate WebDAV XML response for directory listing
 36 |  */
 37 | function generateDirectoryXmlResponse(urlPath, items, stats) {
 38 |     const directoryName = path.basename(urlPath) || 'Logs';
 39 |     
 40 |     // Generate individual item entries
 41 |     const xmlItems = items.map(item => {
 42 |         const isDirectory = item.stats.isDirectory();
 43 |         const itemUrl = urlPath.endsWith('/') ? `${urlPath}${item.name}` : `${urlPath}/${item.name}`;
 44 | 
 45 |         return `
 46 |     <D:response>
 47 |         <D:href>${itemUrl}${isDirectory ? '/' : ''}</D:href>
 48 |         <D:propstat>
 49 |             <D:prop>
 50 |                 <D:displayname>${item.name}</D:displayname>
 51 |                 <D:getcontentlength>${isDirectory ? '' : item.stats.size}</D:getcontentlength>
 52 |                 <D:getlastmodified>${item.stats.mtime.toUTCString()}</D:getlastmodified>
 53 |                 <D:resourcetype>${isDirectory ? '<D:collection/>' : ''}</D:resourcetype>
 54 |                 ${!isDirectory ? '<D:getcontenttype>text/plain</D:getcontenttype>' : ''}
 55 |             </D:prop>
 56 |             <D:status>HTTP/1.1 200 OK</D:status>
 57 |         </D:propstat>
 58 |     </D:response>`;
 59 |     }).join('');
 60 | 
 61 |     return `<?xml version="1.0" encoding="utf-8"?>
 62 | <D:multistatus xmlns:D="DAV:">
 63 |     <D:response>
 64 |         <D:href>${urlPath}</D:href>
 65 |         <D:propstat>
 66 |             <D:prop>
 67 |                 <D:displayname>${directoryName}</D:displayname>
 68 |                 <D:resourcetype><D:collection/></D:resourcetype>
 69 |             </D:prop>
 70 |             <D:status>HTTP/1.1 200 OK</D:status>
 71 |         </D:propstat>
 72 |     </D:response>${xmlItems}
 73 | </D:multistatus>`;
 74 | }
 75 | 
 76 | /**
 77 |  * Generate WebDAV error response
 78 |  */
 79 | function generateErrorXmlResponse(urlPath, statusCode, message) {
 80 |     return `<?xml version="1.0" encoding="utf-8"?>
 81 | <D:multistatus xmlns:D="DAV:">
 82 |     <D:response>
 83 |         <D:href>${urlPath}</D:href>
 84 |         <D:propstat>
 85 |             <D:status>HTTP/1.1 ${statusCode} ${message}</D:status>
 86 |         </D:propstat>
 87 |     </D:response>
 88 | </D:multistatus>`;
 89 | }
 90 | 
 91 | /**
 92 |  * Parse WebDAV depth header
 93 |  */
 94 | function parseDepthHeader(depthHeader) {
 95 |     if (!depthHeader) return 'infinity';
 96 |     
 97 |     const depth = depthHeader.toLowerCase();
 98 |     if (depth === '0') return 0;
 99 |     if (depth === '1') return 1;
100 |     return 'infinity';
101 | }
102 | 
103 | /**
104 |  * Escape XML special characters
105 |  */
106 | function escapeXml(text) {
107 |     return text
108 |         .replace(/&/g, '&amp;')
109 |         .replace(/</g, '&lt;')
110 |         .replace(/>/g, '&gt;')
111 |         .replace(/"/g, '&quot;')
112 |         .replace(/'/g, '&#39;');
113 | }
114 | 
115 | module.exports = {
116 |     generateFileXmlResponse,
117 |     generateDirectoryXmlResponse,
118 |     generateErrorXmlResponse,
119 |     parseDepthHeader,
120 |     escapeXml
121 | };
```

--------------------------------------------------------------------------------
/docs/sfra/store.md:
--------------------------------------------------------------------------------

```markdown
  1 | # SFRA Store Model
  2 | 
  3 | ## Overview
  4 | 
  5 | The Store model represents a physical store location in SFRA applications. It provides store information including location details, contact information, and store hours for store locator functionality and in-store pickup features.
  6 | 
  7 | ## Constructor
  8 | 
  9 | ```javascript
 10 | function store(storeObject)
 11 | ```
 12 | 
 13 | Creates a Store model instance from a store object.
 14 | 
 15 | ### Parameters
 16 | 
 17 | - `storeObject` (dw.catalog.Store) - A Store object from the SFCC API
 18 | 
 19 | ## Properties
 20 | 
 21 | ### ID
 22 | **Type:** string
 23 | 
 24 | Unique identifier for the store.
 25 | 
 26 | ### name
 27 | **Type:** string
 28 | 
 29 | Display name of the store.
 30 | 
 31 | ### address1
 32 | **Type:** string
 33 | 
 34 | Primary address line of the store location.
 35 | 
 36 | ### address2
 37 | **Type:** string
 38 | 
 39 | Secondary address line (suite, building, etc.).
 40 | 
 41 | ### city
 42 | **Type:** string
 43 | 
 44 | City where the store is located.
 45 | 
 46 | ### postalCode
 47 | **Type:** string
 48 | 
 49 | Postal/ZIP code for the store location.
 50 | 
 51 | ### latitude
 52 | **Type:** number
 53 | 
 54 | Latitude coordinate for the store location (used for mapping and distance calculations).
 55 | 
 56 | ### longitude
 57 | **Type:** number
 58 | 
 59 | Longitude coordinate for the store location (used for mapping and distance calculations).
 60 | 
 61 | ### phone
 62 | **Type:** string (optional)
 63 | 
 64 | Store phone number for customer contact.
 65 | 
 66 | ### stateCode
 67 | **Type:** string (optional)
 68 | 
 69 | State or province code for the store location.
 70 | 
 71 | ### countryCode
 72 | **Type:** string (optional)
 73 | 
 74 | Country code for the store location (extracted from countryCode.value).
 75 | 
 76 | ### storeHours
 77 | **Type:** string (optional)
 78 | 
 79 | Store hours information as markup/HTML content for display.
 80 | 
 81 | ## Usage Example
 82 | 
 83 | ```javascript
 84 | var store = require('*/cartridge/models/store');
 85 | var StoreMgr = require('dw/catalog/StoreMgr');
 86 | 
 87 | // Get a specific store
 88 | var storeObject = StoreMgr.getStore('store-001');
 89 | var storeModel = new store(storeObject);
 90 | 
 91 | // Access store properties
 92 | console.log(storeModel.name);          // "Downtown Location"
 93 | console.log(storeModel.address1);      // "123 Main St"
 94 | console.log(storeModel.city);          // "New York"
 95 | console.log(storeModel.phone);         // "555-123-4567"
 96 | 
 97 | // Use coordinates for mapping
 98 | if (storeModel.latitude && storeModel.longitude) {
 99 |     console.log('Location: ' + storeModel.latitude + ', ' + storeModel.longitude);
100 | }
101 | 
102 | // Display store hours
103 | if (storeModel.storeHours) {
104 |     console.log(storeModel.storeHours); // HTML markup for hours display
105 | }
106 | ```
107 | 
108 | ## Coordinate System
109 | 
110 | The model provides geographic coordinates for:
111 | - **Mapping Integration** - Display stores on maps
112 | - **Distance Calculations** - Find nearest stores
113 | - **Location Services** - GPS-based store finding
114 | 
115 | ## Conditional Properties
116 | 
117 | Several properties are only included if they exist in the source store object:
118 | - **phone** - Only included if store has a phone number
119 | - **stateCode** - Only included for locations with state/province
120 | - **countryCode** - Only included if country is specified
121 | - **storeHours** - Only included if store hours are configured
122 | 
123 | ## Store Hours Format
124 | 
125 | Store hours are provided as markup/HTML content, allowing for:
126 | - Rich formatting of hours display
127 | - Multiple day ranges and special hours
128 | - Holiday hours and exceptions
129 | - Custom styling and presentation
130 | 
131 | ## Notes
132 | 
133 | - Handles missing store data gracefully
134 | - Provides essential location information for store locators
135 | - Includes geographic coordinates for mapping functionality
136 | - Supports international stores with flexible address formats
137 | - Store hours support rich HTML formatting
138 | - Null-safe property access for optional fields
139 | 
140 | ## Related Models
141 | 
142 | - **Stores Model** - Collection of store models
143 | - **Product Models** - May include store availability
144 | - **Cart Models** - May include store pickup options
145 | - **Address Models** - Similar address structure
146 | 
```

--------------------------------------------------------------------------------
/docs/dw_campaign/SourceCodeInfo.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.campaign
  2 | 
  3 | # Class SourceCodeInfo
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.campaign.SourceCodeInfo
  9 | 
 10 | ## Description
 11 | 
 12 | Class representing a code (i.e. a "source code") that has been applied to a customer's session. Source codes can qualify customers for different campaigns, promotions, and other site experiences from those that the typical customer sees. Codes are organized into source code groups. Typically, a code is applied to a customer's session automatically by Commerce Cloud Digital when a customer accesses a Digital URL with a well known request parameter in the querystring. A code may also be explicitly applied to a customer session using the SetSourceCode pipelet.
 13 | 
 14 | ## Constants
 15 | 
 16 | ### STATUS_ACTIVE
 17 | 
 18 | **Type:** Number = 2
 19 | 
 20 | The literal source-code is found and currently active.
 21 | 
 22 | ### STATUS_INACTIVE
 23 | 
 24 | **Type:** Number = 1
 25 | 
 26 | The literal source-code is found but not active.
 27 | 
 28 | ### STATUS_INVALID
 29 | 
 30 | **Type:** Number = 0
 31 | 
 32 | The literal source-code is not found in the system.
 33 | 
 34 | ## Properties
 35 | 
 36 | ### code
 37 | 
 38 | **Type:** String (Read Only)
 39 | 
 40 | The literal source-code.
 41 | 
 42 | ### group
 43 | 
 44 | **Type:** SourceCodeGroup (Read Only)
 45 | 
 46 | The associated source-code group.
 47 | 
 48 | ### redirect
 49 | 
 50 | **Type:** URLRedirect (Read Only)
 51 | 
 52 | Retrieves the redirect information from the last processed SourceCodeGroup (active or inactive). If none exists,
 53 |  then the redirect information is retrieved from the source-code preferences, based on the active/inactive status
 54 |  of the SourceCodeGroup. The redirect information is then resolved to the output URL. If the redirect information
 55 |  cannot be resolved to a URL, or there is an error retrieving the preferences, then null is returned.
 56 | 
 57 | ### status
 58 | 
 59 | **Type:** Number (Read Only)
 60 | 
 61 | The status of the source-code.  One of the following:
 62 |  STATUS_INVALID - The source code is not found in the system.
 63 |  STATUS_INACTIVE - The source code is found but not active.
 64 |  STATUS_INACTIVE - The source code is found and active.
 65 | 
 66 | ## Constructor Summary
 67 | 
 68 | ## Method Summary
 69 | 
 70 | ### getCode
 71 | 
 72 | **Signature:** `getCode() : String`
 73 | 
 74 | The literal source-code.
 75 | 
 76 | ### getGroup
 77 | 
 78 | **Signature:** `getGroup() : SourceCodeGroup`
 79 | 
 80 | The associated source-code group.
 81 | 
 82 | ### getRedirect
 83 | 
 84 | **Signature:** `getRedirect() : URLRedirect`
 85 | 
 86 | Retrieves the redirect information from the last processed SourceCodeGroup (active or inactive).
 87 | 
 88 | ### getStatus
 89 | 
 90 | **Signature:** `getStatus() : Number`
 91 | 
 92 | The status of the source-code.
 93 | 
 94 | ## Method Detail
 95 | 
 96 | ## Method Details
 97 | 
 98 | ### getCode
 99 | 
100 | **Signature:** `getCode() : String`
101 | 
102 | **Description:** The literal source-code.
103 | 
104 | **Returns:**
105 | 
106 | the source-code.
107 | 
108 | ---
109 | 
110 | ### getGroup
111 | 
112 | **Signature:** `getGroup() : SourceCodeGroup`
113 | 
114 | **Description:** The associated source-code group.
115 | 
116 | **Returns:**
117 | 
118 | the source-code group.
119 | 
120 | ---
121 | 
122 | ### getRedirect
123 | 
124 | **Signature:** `getRedirect() : URLRedirect`
125 | 
126 | **Description:** Retrieves the redirect information from the last processed SourceCodeGroup (active or inactive). If none exists, then the redirect information is retrieved from the source-code preferences, based on the active/inactive status of the SourceCodeGroup. The redirect information is then resolved to the output URL. If the redirect information cannot be resolved to a URL, or there is an error retrieving the preferences, then null is returned.
127 | 
128 | **Returns:**
129 | 
130 | URLRedirect containing the location and status code, null in case of no redirect was found
131 | 
132 | ---
133 | 
134 | ### getStatus
135 | 
136 | **Signature:** `getStatus() : Number`
137 | 
138 | **Description:** The status of the source-code. One of the following: STATUS_INVALID - The source code is not found in the system. STATUS_INACTIVE - The source code is found but not active. STATUS_INACTIVE - The source code is found and active.
139 | 
140 | **Returns:**
141 | 
142 | the status.
143 | 
144 | ---
```

--------------------------------------------------------------------------------
/docs/dw_util/FilteringCollection.md:
--------------------------------------------------------------------------------

```markdown
 1 | ## Package: dw.util
 2 | 
 3 | # Class FilteringCollection
 4 | 
 5 | ## Inheritance Hierarchy
 6 | 
 7 | - Object
 8 |   - dw.util.Collection
 9 |   - dw.util.FilteringCollection
10 | 
11 | ## Description
12 | 
13 | FilteringCollection is an extension of Collection which provides possibilities to filter the elements to return a new FilteringCollection with a filtered set of elements sort the elements to return a new FilteringCollection with a defined sort order transform the elements to return a new FilteringCollection containing related elements provide a map of the elements against a predefined key Usage - In the current version each FilteringCollection provides a set of predefined qualifier constants which can be passed into the select(Object) method used to filter the elements. Generally qualifiers have the prefix QUALIFIER_. A second method sort(Object) is used to create a new instance with a different element ordering, which takes an orderB< constant. Generally orderBys have the prefix ORDERBY_: examples are ShippingOrder.ORDERBY_ITEMID, ShippingOrder.ORDERBY_ITEMPOSITION, and ORDERBY_REVERSE can be used to provide a FilteringCollection with the reverse ordering. An example with method ShippingOrder.getItems(): var allItems : FilteringCollection = shippingOrder.items; var productItems : FilteringCollection = allItems.select(ShippingOrder.QUALIFIER_PRODUCTITEMS); var serviceItems : FilteringCollection = allItems.select(ShippingOrder.QUALIFIER_SERVICEITEMS); var byPosition : FilteringCollection = productItems.sort(ShippingOrder.ORDERBY_ITEMPOSITION); var revByPosition: FilteringCollection = byPosition.sort(FilteringCollection.ORDERBY_REVERSE); var mapByItemID : Map = allItems.asMap();
14 | 
15 | ## Constants
16 | 
17 | ### ORDERBY_REVERSE
18 | 
19 | **Type:** Object
20 | 
21 | Pass this orderBy with the sort(Object) method to obtain a new FilteringCollection with the reversed sort order. Only use on a FilteringCollection which has been previously sorted.
22 | 
23 | ## Properties
24 | 
25 | ## Constructor Summary
26 | 
27 | ## Method Summary
28 | 
29 | ### asMap
30 | 
31 | **Signature:** `asMap() : Map`
32 | 
33 | Returns a Map containing the elements of this FilteringCollection against a predefined key.
34 | 
35 | ### select
36 | 
37 | **Signature:** `select(qualifier : Object) : FilteringCollection`
38 | 
39 | Select a new FilteringCollection instance by passing a predefined qualifier as an argument to this method.
40 | 
41 | ### sort
42 | 
43 | **Signature:** `sort(orderBy : Object) : FilteringCollection`
44 | 
45 | Select a new FilteringCollection instance by passing a predefined orderBy as an argument to this method.
46 | 
47 | ## Method Detail
48 | 
49 | ## Method Details
50 | 
51 | ### asMap
52 | 
53 | **Signature:** `asMap() : Map`
54 | 
55 | **Description:** Returns a Map containing the elements of this FilteringCollection against a predefined key. The key used is documented in the method returning the FilteringCollection and is typically the ItemID assigned to an element in the collection.
56 | 
57 | **Returns:**
58 | 
59 | a Map containing the elements of this FilteringCollection against a predefined key.
60 | 
61 | ---
62 | 
63 | ### select
64 | 
65 | **Signature:** `select(qualifier : Object) : FilteringCollection`
66 | 
67 | **Description:** Select a new FilteringCollection instance by passing a predefined qualifier as an argument to this method. See FilteringCollection.
68 | 
69 | **Parameters:**
70 | 
71 | - `qualifier`: possible qualifiers are documented in the method returning the FilteringCollection
72 | 
73 | **Returns:**
74 | 
75 | a new FilteringCollection instance
76 | 
77 | ---
78 | 
79 | ### sort
80 | 
81 | **Signature:** `sort(orderBy : Object) : FilteringCollection`
82 | 
83 | **Description:** Select a new FilteringCollection instance by passing a predefined orderBy as an argument to this method. See FilteringCollection.
84 | 
85 | **Parameters:**
86 | 
87 | - `orderBy`: possible orderBys are documented in the method returning the FilteringCollection
88 | 
89 | **Returns:**
90 | 
91 | a new FilteringCollection instance
92 | 
93 | ---
```

--------------------------------------------------------------------------------
/docs/dw_catalog/CategoryAssignment.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class CategoryAssignment
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.catalog.CategoryAssignment
 11 | 
 12 | ## Description
 13 | 
 14 | Represents a category assignment in Commerce Cloud Digital.
 15 | 
 16 | ## Properties
 17 | 
 18 | ### calloutMsg
 19 | 
 20 | **Type:** MarkupText (Read Only)
 21 | 
 22 | The category assignment's callout message in the current locale.
 23 | 
 24 | ### category
 25 | 
 26 | **Type:** Category (Read Only)
 27 | 
 28 | The category to which this category assignment is bound.
 29 | 
 30 | ### image
 31 | 
 32 | **Type:** MediaFile (Read Only)
 33 | 
 34 | The category assignment's image.
 35 | 
 36 | ### longDescription
 37 | 
 38 | **Type:** MarkupText (Read Only)
 39 | 
 40 | The category assignment's long description in the current locale.
 41 | 
 42 | ### name
 43 | 
 44 | **Type:** String (Read Only)
 45 | 
 46 | The name of the category assignment in the current locale.
 47 | 
 48 | ### product
 49 | 
 50 | **Type:** Product (Read Only)
 51 | 
 52 | The product to which this category assignment is bound.
 53 | 
 54 | ### shortDescription
 55 | 
 56 | **Type:** MarkupText (Read Only)
 57 | 
 58 | The category assignment's short description in the current locale.
 59 | 
 60 | ## Constructor Summary
 61 | 
 62 | ## Method Summary
 63 | 
 64 | ### getCalloutMsg
 65 | 
 66 | **Signature:** `getCalloutMsg() : MarkupText`
 67 | 
 68 | Returns the category assignment's callout message in the current locale.
 69 | 
 70 | ### getCategory
 71 | 
 72 | **Signature:** `getCategory() : Category`
 73 | 
 74 | Returns the category to which this category assignment is bound.
 75 | 
 76 | ### getImage
 77 | 
 78 | **Signature:** `getImage() : MediaFile`
 79 | 
 80 | Returns the category assignment's image.
 81 | 
 82 | ### getLongDescription
 83 | 
 84 | **Signature:** `getLongDescription() : MarkupText`
 85 | 
 86 | Returns the category assignment's long description in the current locale.
 87 | 
 88 | ### getName
 89 | 
 90 | **Signature:** `getName() : String`
 91 | 
 92 | Returns the name of the category assignment in the current locale.
 93 | 
 94 | ### getProduct
 95 | 
 96 | **Signature:** `getProduct() : Product`
 97 | 
 98 | Returns the product to which this category assignment is bound.
 99 | 
100 | ### getShortDescription
101 | 
102 | **Signature:** `getShortDescription() : MarkupText`
103 | 
104 | Returns the category assignment's short description in the current locale.
105 | 
106 | ## Method Detail
107 | 
108 | ## Method Details
109 | 
110 | ### getCalloutMsg
111 | 
112 | **Signature:** `getCalloutMsg() : MarkupText`
113 | 
114 | **Description:** Returns the category assignment's callout message in the current locale.
115 | 
116 | **Returns:**
117 | 
118 | the category assignment's callout message in the current locale, or null if it wasn't found.
119 | 
120 | ---
121 | 
122 | ### getCategory
123 | 
124 | **Signature:** `getCategory() : Category`
125 | 
126 | **Description:** Returns the category to which this category assignment is bound.
127 | 
128 | **Returns:**
129 | 
130 | The category to which this category assignment is bound.
131 | 
132 | ---
133 | 
134 | ### getImage
135 | 
136 | **Signature:** `getImage() : MediaFile`
137 | 
138 | **Description:** Returns the category assignment's image.
139 | 
140 | **Returns:**
141 | 
142 | the category assignment's image.
143 | 
144 | ---
145 | 
146 | ### getLongDescription
147 | 
148 | **Signature:** `getLongDescription() : MarkupText`
149 | 
150 | **Description:** Returns the category assignment's long description in the current locale.
151 | 
152 | **Returns:**
153 | 
154 | The category assignment's long description in the current locale, or null if it wasn't found.
155 | 
156 | ---
157 | 
158 | ### getName
159 | 
160 | **Signature:** `getName() : String`
161 | 
162 | **Description:** Returns the name of the category assignment in the current locale.
163 | 
164 | **Returns:**
165 | 
166 | The name of the category assignment for the current locale, or null if it wasn't found.
167 | 
168 | ---
169 | 
170 | ### getProduct
171 | 
172 | **Signature:** `getProduct() : Product`
173 | 
174 | **Description:** Returns the product to which this category assignment is bound.
175 | 
176 | **Returns:**
177 | 
178 | The product to which this category assignment is bound.
179 | 
180 | ---
181 | 
182 | ### getShortDescription
183 | 
184 | **Signature:** `getShortDescription() : MarkupText`
185 | 
186 | **Description:** Returns the category assignment's short description in the current locale.
187 | 
188 | **Returns:**
189 | 
190 | the category assignment's short description in the current locale, or null if it wasn't found.
191 | 
192 | ---
```

--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/src/config/server-config.js:
--------------------------------------------------------------------------------

```javascript
  1 | /**
  2 |  * Server Configuration Management
  3 |  * 
  4 |  * Handles server configuration with sensible defaults and environment overrides.
  5 |  * Follows single responsibility principle for configuration management.
  6 |  */
  7 | 
  8 | class ServerConfig {
  9 |     constructor(options = {}) {
 10 |         // Server basics
 11 |         this.port = options.port || process.env.PORT || 3000;
 12 |         this.host = options.host || process.env.HOST || 'localhost';
 13 |         this.isDevMode = options.dev || process.env.NODE_ENV === 'development' || false;
 14 |         
 15 |         // API versions
 16 |         this.ocapiVersion = options.ocapiVersion || 'v23_2';
 17 |         
 18 |         // Paths
 19 |         this.mockDataPath = options.mockDataPath || require('path').join(__dirname, '../../mock-data');
 20 |         this.webdavBasePath = '/on/demandware.servlet/webdav/Sites';
 21 |         
 22 |         // Authentication - Mock credentials for testing
 23 |         this.validCredentials = {
 24 |             clientId: 'test-client-id',
 25 |             clientSecret: 'test-client-secret',
 26 |             username: 'test-user',
 27 |             password: 'test-password'
 28 |         };
 29 |         
 30 |         // Features toggle
 31 |         this.features = {
 32 |             webdav: options.enableWebdav !== false, // enabled by default
 33 |             ocapi: options.enableOcapi !== false,   // enabled by default
 34 |             cors: options.enableCors !== false,     // enabled by default
 35 |             logging: options.enableLogging !== false, // enabled by default
 36 |             randomErrors: options.enableRandomErrors === true // disabled by default for reliable tests
 37 |         };
 38 |     }
 39 | 
 40 |     /**
 41 |      * Get WebDAV configuration
 42 |      */
 43 |     getWebdavConfig() {
 44 |         return {
 45 |             basePath: this.webdavBasePath,
 46 |             logsPath: require('path').join(this.mockDataPath, 'logs'),
 47 |             enabled: this.features.webdav
 48 |         };
 49 |     }
 50 | 
 51 |     /**
 52 |      * Get OCAPI configuration
 53 |      */
 54 |     getOcapiConfig() {
 55 |         return {
 56 |             version: this.ocapiVersion,
 57 |             basePath: `/s/-/dw/data/${this.ocapiVersion}`,
 58 |             mockDataPath: require('path').join(this.mockDataPath, 'ocapi'),
 59 |             enabled: this.features.ocapi
 60 |         };
 61 |     }
 62 | 
 63 |     /**
 64 |      * Get full server URL
 65 |      */
 66 |     getServerUrl() {
 67 |         return `http://${this.host}:${this.port}`;
 68 |     }
 69 | 
 70 |     /**
 71 |      * Get WebDAV logs URL
 72 |      */
 73 |     getWebdavLogsUrl() {
 74 |         return `${this.getServerUrl()}${this.webdavBasePath}/Logs/`;
 75 |     }
 76 | 
 77 |     /**
 78 |      * Get OCAPI base URL
 79 |      */
 80 |     getOcapiBaseUrl() {
 81 |         return `${this.getServerUrl()}/s/-/dw/data/${this.ocapiVersion}`;
 82 |     }
 83 | 
 84 |     /**
 85 |      * Validate configuration
 86 |      */
 87 |     validate() {
 88 |         const errors = [];
 89 |         
 90 |         if (!this.port || this.port < 1 || this.port > 65535) {
 91 |             errors.push('Invalid port number');
 92 |         }
 93 |         
 94 |         if (!this.host || typeof this.host !== 'string') {
 95 |             errors.push('Invalid host');
 96 |         }
 97 |         
 98 |         if (!this.features.webdav && !this.features.ocapi) {
 99 |             errors.push('At least one feature (WebDAV or OCAPI) must be enabled');
100 |         }
101 |         
102 |         return errors;
103 |     }
104 | 
105 |     /**
106 |      * Get configuration summary for logging
107 |      */
108 |     getSummary() {
109 |         return {
110 |             server: `${this.host}:${this.port}`,
111 |             mode: this.isDevMode ? 'development' : 'production',
112 |             features: Object.entries(this.features)
113 |                 .filter(([_, enabled]) => enabled)
114 |                 .map(([feature, _]) => feature),
115 |             endpoints: {
116 |                 ...(this.features.webdav && { webdav: this.getWebdavLogsUrl() }),
117 |                 ...(this.features.ocapi && { ocapi: this.getOcapiBaseUrl() }),
118 |                 health: `${this.getServerUrl()}/health`
119 |             }
120 |         };
121 |     }
122 | }
123 | 
124 | module.exports = ServerConfig;
```

--------------------------------------------------------------------------------
/docs/dw_system/RemoteInclude.md:
--------------------------------------------------------------------------------

```markdown
 1 | ## Package: dw.system
 2 | 
 3 | # Class RemoteInclude
 4 | 
 5 | ## Inheritance Hierarchy
 6 | 
 7 | - Object
 8 |   - dw.system.RemoteInclude
 9 | 
10 | ## Description
11 | 
12 | The class represents a remote include value that can be assigned to JSON Object properties. Important notes: Authentication and authorization checks are performed only for the top level request, but NOT for remote include requests. The RestResponseMgr method createScapiRemoteInclude() allows only SCAPI URLs. The RestResponseMgr method createStorefrontControllerRemoteInclude() allows only Controller URLs. Correct rendering of RemoteInclude-containing objects is only performed when processed by dw.system.RESTSuccessResponse.render() method. Please check the provided examples. Example 1. Specify remote include properties. function specifyRemoteIncludeProperties() { var includeValue0 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/0", dw.web.URLParameter("siteId", "TestWapi")); var includeValue1 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/1", dw.web.URLParameter("siteId", "TestWapi")); var greeting = { "hello": "world", "includeProperty0": includeValue0, "includeProperty1": includeValue1 }; dw.system.RESTResponseMgr.createSuccess(greeting).render(); } Example 2. Specify array of remote include properties. function specifyArrayOfRemoteIncludes() { var includeValue0 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/0", dw.web.URLParameter("siteId", "TestWapi")); var includeValue1 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/1", dw.web.URLParameter("siteId", "TestWapi")); var greeting = { "hello": "world", "includeArray": [includeValue0, includeValue1] }; dw.system.RESTResponseMgr.createSuccess(greeting).render(); } Example 3. Storefront controller remote include. function storefrontRemoteInclude() { let remoteInclude = dw.system.RESTResponseMgr.createStorefrontControllerRemoteInclude(new URLAction("Category-Show", "Sites-MyShop-Site", dw.web.URLParameter("cid", "root"))); let json = { status: "JSONOK", include: remoteInclude }; dw.system.RESTResponseMgr.createSuccess(json).render(); } Error handling: SCAPI: In case of 404 response received on included resource, an empty JSON object '{}' will be supplied in final JSON. In case of 201..299, 3xx, 4xx (excluding 404), 5xx response from included resource, final response status will be 500 'Internal Server Error' Controllers: In case of any non 200 response from the included resource an empty string will be included. Note: In case your response format is JSON be aware that this can result in invalid JSON.
13 | 
14 | ## Properties
15 | 
16 | ### url
17 | 
18 | **Type:** String (Read Only)
19 | 
20 | The URL string value specified for the current instance.
21 | 
22 | ### value
23 | 
24 | **Type:** String (Read Only)
25 | 
26 | ## Constructor Summary
27 | 
28 | ## Method Summary
29 | 
30 | ### getUrl
31 | 
32 | **Signature:** `getUrl() : String`
33 | 
34 | Returns the URL string value specified for the current instance.
35 | 
36 | ### toString
37 | 
38 | **Signature:** `toString() : String`
39 | 
40 | Returns the URL string value specified for the current instance, same as getUrl().
41 | 
42 | ### valueOf
43 | 
44 | **Signature:** `valueOf() : Object`
45 | 
46 | Returns the URL string value specified for the current instance, same as getUrl().
47 | 
48 | ## Method Detail
49 | 
50 | ## Method Details
51 | 
52 | ### getUrl
53 | 
54 | **Signature:** `getUrl() : String`
55 | 
56 | **Description:** Returns the URL string value specified for the current instance.
57 | 
58 | ---
59 | 
60 | ### toString
61 | 
62 | **Signature:** `toString() : String`
63 | 
64 | **Description:** Returns the URL string value specified for the current instance, same as getUrl().
65 | 
66 | ---
67 | 
68 | ### valueOf
69 | 
70 | **Signature:** `valueOf() : Object`
71 | 
72 | **Description:** Returns the URL string value specified for the current instance, same as getUrl().
73 | 
74 | ---
```

--------------------------------------------------------------------------------
/docs/sfra/price-tiered.md:
--------------------------------------------------------------------------------

```markdown
  1 | # SFRA Tiered Price Model
  2 | 
  3 | ## Overview
  4 | 
  5 | The Tiered Price model represents quantity-based pricing in SFRA applications, where products have different prices based on the quantity purchased. This enables bulk discounts and volume pricing strategies.
  6 | 
  7 | ## Constructor
  8 | 
  9 | ```javascript
 10 | function TieredPrice(priceTable, useSimplePrice)
 11 | ```
 12 | 
 13 | Creates a Tiered Price model instance with quantity-based pricing tiers.
 14 | 
 15 | ### Parameters
 16 | 
 17 | - `priceTable` (dw.catalog.ProductPriceTable) - Product price table from the API
 18 | - `useSimplePrice` (boolean) - Flag indicating if this is for a product tile (optional)
 19 | 
 20 | ## Properties
 21 | 
 22 | ### type
 23 | **Type:** string
 24 | 
 25 | Always set to 'tiered' to identify this as a tiered price model.
 26 | 
 27 | ### useSimplePrice
 28 | **Type:** boolean
 29 | 
 30 | Flag indicating whether this price is intended for simplified display (e.g., product tiles). Defaults to false.
 31 | 
 32 | ### tiers
 33 | **Type:** Array<Object>
 34 | 
 35 | Array of pricing tier objects, each containing:
 36 | - `quantity` (number) - Minimum quantity for this price tier
 37 | - `price` (DefaultPrice) - Price object for this quantity tier
 38 | 
 39 | ### startingFromPrice
 40 | **Type:** DefaultPrice
 41 | 
 42 | The lowest price available across all tiers, representing the "starting from" price for marketing display. Access the formatted price via `.sales.formatted`.
 43 | 
 44 | ## Tier Structure
 45 | 
 46 | Each tier object in the tiers array contains:
 47 | 
 48 | ### quantity
 49 | Minimum quantity required to qualify for this price tier.
 50 | 
 51 | ### price
 52 | ### price
 53 | Complete DefaultPrice object created with only the sales price for this tier (accessed via `.sales` property).
 54 | 
 55 | ## Usage Example
 56 | 
 57 | ```javascript
 58 | var TieredPrice = require('*/cartridge/models/price/tiered');
 59 | 
 60 | // Get tiered pricing from product
 61 | var product = ProductMgr.getProduct('bulk-product-id');
 62 | var priceTable = product.getPriceModel().getPriceTable();
 63 | 
 64 | var tieredPrice = new TieredPrice(priceTable, false);
 65 | 
 66 | console.log(tieredPrice.type);                    // "tiered"
 67 | console.log('Starting from: ' + tieredPrice.startingFromPrice.sales.formatted);
 68 | 
 69 | // Display all price tiers
 70 | tieredPrice.tiers.forEach(function(tier) {
 71 |     console.log('Buy ' + tier.quantity + '+ for ' + tier.price.sales.formatted + ' each');
 72 | });
 73 | 
 74 | // Example output:
 75 | // Buy 1+ for $10.00 each
 76 | // Buy 5+ for $9.00 each  
 77 | // Buy 10+ for $8.00 each
 78 | ```
 79 | 
 80 | ## Price Calculation Logic
 81 | 
 82 | The model automatically:
 83 | 1. **Processes all quantity breaks** from the price table using `collections.map`
 84 | 2. **Creates DefaultPrice instances** with only sales price for each tier
 85 | 3. **Identifies the lowest price** by comparing `price.sales.value` across all tiers
 86 | 4. **Sets startingFromPrice** to the best available price
 87 | 5. **Maintains tier order** based on quantity requirements
 88 | 6. **Converts quantities** to numeric values using `quantity.getValue()`
 89 | 
 90 | ## Display Modes
 91 | 
 92 | ### Full Pricing (useSimplePrice = false)
 93 | - Shows all pricing tiers
 94 | - Includes complete quantity break information
 95 | - Used on product detail pages
 96 | 
 97 | ### Simple Pricing (useSimplePrice = true)
 98 | - Optimized for product tiles and listings
 99 | - Focuses on starting price and key tiers
100 | - Simplified display for grid views
101 | 
102 | ## Notes
103 | 
104 | - Automatically calculates the best "starting from" price by comparing sales values
105 | - Each tier DefaultPrice is created with only sales price (access via `.sales` property)
106 | - Uses `collections.map` utility to process price table quantities
107 | - Supports unlimited number of quantity tiers
108 | - Each tier uses DefaultPrice for consistent formatting
109 | - Useful for B2B and bulk purchasing scenarios
110 | - Type property enables template conditional logic
111 | - `useSimplePrice` defaults to `false` if not provided
112 | 
113 | ## Related Models
114 | 
115 | - **DefaultPrice Model** - Used for individual tier pricing
116 | - **RangePrice Model** - Alternative pricing model for price ranges
117 | - **Product Models** - Use tiered prices for bulk products
118 | 
```

--------------------------------------------------------------------------------
/docs/sfra/cart.md:
--------------------------------------------------------------------------------

```markdown
  1 | # SFRA Cart Model
  2 | 
  3 | ## Overview
  4 | 
  5 | The Cart model represents the current customer's shopping basket in SFRA applications. It provides comprehensive cart functionality including product line items, shipping methods, totals, discounts, and cart actions.
  6 | 
  7 | ## Constructor
  8 | 
  9 | ```javascript
 10 | function CartModel(basket)
 11 | ```
 12 | 
 13 | Creates a Cart model instance from a basket object.
 14 | 
 15 | ### Parameters
 16 | 
 17 | - `basket` (dw.order.Basket) - Current user's basket
 18 | 
 19 | ## Properties
 20 | 
 21 | ### items
 22 | **Type:** Array<Object>
 23 | 
 24 | Array of product line items in the cart. Each item contains product information, quantity, pricing, and other details.
 25 | 
 26 | ### numItems
 27 | **Type:** number
 28 | 
 29 | Total number of items (quantity) in the cart.
 30 | 
 31 | ### totals
 32 | **Type:** TotalsModel
 33 | 
 34 | Totals model containing cart pricing information including subtotals, taxes, shipping costs, and grand total.
 35 | 
 36 | ### shipments
 37 | **Type:** Array<Object>
 38 | 
 39 | Array of shipment objects, each containing:
 40 | - `shippingMethods` - Available shipping methods for the shipment
 41 | - `selectedShippingMethod` - ID of the currently selected shipping method
 42 | 
 43 | ### numOfShipments
 44 | **Type:** number
 45 | 
 46 | Number of shipments in the cart.
 47 | 
 48 | ### hasBonusProduct
 49 | **Type:** boolean
 50 | 
 51 | Indicates whether the cart contains any bonus products from promotions.
 52 | 
 53 | ### actionUrls
 54 | **Type:** Object
 55 | 
 56 | Object containing URLs for cart actions:
 57 | - `removeProductLineItemUrl` - URL to remove product line items
 58 | - `updateQuantityUrl` - URL to update item quantities
 59 | - `selectShippingUrl` - URL to select shipping methods
 60 | - `submitCouponCodeUrl` - URL to add coupon codes
 61 | - `removeCouponLineItem` - URL to remove coupon line items
 62 | 
 63 | ### approachingDiscounts
 64 | **Type:** Array<Object>
 65 | 
 66 | Array of approaching discount objects, each containing:
 67 | - `discountMsg` - Message describing the approaching discount
 68 | 
 69 | ### valid
 70 | **Type:** boolean
 71 | 
 72 | Indicates whether the basket is valid based on validation hooks.
 73 | 
 74 | ### resources
 75 | **Type:** Object
 76 | 
 77 | Object containing localized resource strings:
 78 | - `numberOfItems` - Formatted message showing number of items in cart
 79 | - `minicartCountOfItems` - Formatted message for minicart count
 80 | - `emptyCartMsg` - Message displayed when cart is empty
 81 | 
 82 | ## Helper Functions
 83 | 
 84 | ### getApproachingDiscounts(basket, discountPlan)
 85 | Generates an object of approaching discounts based on current basket and discount plan.
 86 | 
 87 | **Parameters:**
 88 | - `basket` (dw.order.Basket) - Current user's basket
 89 | - `discountPlan` (dw.campaign.DiscountPlan) - Set of applicable discounts
 90 | 
 91 | **Returns:** Object - Object containing approaching discount information
 92 | 
 93 | ### getCartActionUrls()
 94 | Generates an object of URLs used for cart actions.
 95 | 
 96 | **Returns:** Object - Object containing cart action URLs in string format
 97 | 
 98 | ## Usage Example
 99 | 
100 | ```javascript
101 | var CartModel = require('*/cartridge/models/cart');
102 | var BasketMgr = require('dw/order/BasketMgr');
103 | 
104 | var currentBasket = BasketMgr.getCurrentBasket();
105 | var cart = new CartModel(currentBasket);
106 | 
107 | // Access cart properties
108 | console.log(cart.numItems);
109 | console.log(cart.totals.grandTotal);
110 | console.log(cart.actionUrls.updateQuantityUrl);
111 | 
112 | // Check if cart has items
113 | if (cart.items && cart.items.length > 0) {
114 |     // Process cart items
115 |     cart.items.forEach(function(item) {
116 |         console.log(item.productName);
117 |     });
118 | }
119 | ```
120 | 
121 | ## Notes
122 | 
123 | - If basket is null, the cart will have empty items array and numItems of 0
124 | - The model automatically calculates shipping methods for each shipment
125 | - Bonus products from promotions are tracked separately
126 | - Cart validation is performed using hooks
127 | - All action URLs are generated dynamically using URLUtils
128 | 
129 | ## Related Models
130 | 
131 | - **TotalsModel** - Used for cart pricing calculations
132 | - **ProductLineItemsModel** - Used for product line item formatting
133 | - **Shipping Models** - Used for shipping method information
134 | - **Address Model** - Used for shipping addresses
135 | 
```

--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------

```javascript
  1 | import js from '@eslint/js';
  2 | import tseslint from 'typescript-eslint';
  3 | 
  4 | export default tseslint.config(
  5 |   // Base recommended configs
  6 |   js.configs.recommended,
  7 |   ...tseslint.configs.recommended,
  8 | 
  9 |   // Global settings
 10 |   {
 11 |     languageOptions: {
 12 |       ecmaVersion: 2022,
 13 |       sourceType: 'module',
 14 |       globals: {
 15 |         console: 'readonly',
 16 |         process: 'readonly',
 17 |         Buffer: 'readonly',
 18 |         __dirname: 'readonly',
 19 |         __filename: 'readonly',
 20 |       },
 21 |     },
 22 |   },
 23 | 
 24 |   // TypeScript files
 25 |   {
 26 |     files: ['**/*.ts', '**/*.tsx'],
 27 |     languageOptions: {
 28 |       parser: tseslint.parser,
 29 |       parserOptions: {
 30 |         project: ['./tsconfig.json', './tsconfig.test.json'],
 31 |         tsconfigRootDir: import.meta.dirname,
 32 |       },
 33 |     },
 34 |     rules: {
 35 |       // TypeScript specific rules
 36 |       '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
 37 |       '@typescript-eslint/no-explicit-any': 'off',
 38 |       '@typescript-eslint/explicit-function-return-type': 'off',
 39 |       '@typescript-eslint/explicit-module-boundary-types': 'off',
 40 |       '@typescript-eslint/no-non-null-assertion': 'off',
 41 |       '@typescript-eslint/prefer-nullish-coalescing': 'error',
 42 |       '@typescript-eslint/prefer-optional-chain': 'error',
 43 |       '@typescript-eslint/no-empty-object-type': 'off',
 44 | 
 45 |       // General code quality rules
 46 |       'no-console': 'off',
 47 |       'prefer-const': 'error',
 48 |       'no-var': 'error',
 49 |       'object-shorthand': 'error',
 50 |       'prefer-arrow-callback': 'error',
 51 |       'prefer-template': 'error',
 52 |       'no-trailing-spaces': 'error',
 53 |       'eol-last': 'error',
 54 |       'comma-dangle': ['error', 'always-multiline'],
 55 |       'quotes': ['error', 'single', { avoidEscape: true }],
 56 |       'semi': ['error', 'always'],
 57 | 
 58 |       // Basic formatting rules
 59 |       'indent': ['error', 2, { SwitchCase: 1 }],
 60 |       'linebreak-style': ['error', 'unix'],
 61 |       'max-len': ['error', { code: 120, ignoreUrls: true, ignoreStrings: true, ignoreTemplateLiterals: true }],
 62 |       'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1 }],
 63 |       'object-curly-spacing': ['error', 'always'],
 64 |       'array-bracket-spacing': ['error', 'never'],
 65 |       'key-spacing': ['error', { beforeColon: false, afterColon: true }],
 66 |       'comma-spacing': ['error', { before: false, after: true }],
 67 |       'space-before-blocks': ['error', 'always'],
 68 |       'space-infix-ops': 'error',
 69 |       'brace-style': ['error', '1tbs', { allowSingleLine: true }],
 70 |       'curly': ['error', 'all'],
 71 |     },
 72 |   },
 73 | 
 74 |   // Test files
 75 |   {
 76 |     files: ['**/*.test.ts', '**/*.spec.ts', 'tests/**/*.ts'],
 77 |     languageOptions: {
 78 |       globals: {
 79 |         jest: 'readonly',
 80 |         describe: 'readonly',
 81 |         it: 'readonly',
 82 |         expect: 'readonly',
 83 |         beforeEach: 'readonly',
 84 |         afterEach: 'readonly',
 85 |         beforeAll: 'readonly',
 86 |         afterAll: 'readonly',
 87 |       },
 88 |     },
 89 |     rules: {
 90 |       '@typescript-eslint/no-explicit-any': 'off',
 91 |       '@typescript-eslint/no-non-null-assertion': 'off',
 92 |     },
 93 |   },
 94 | 
 95 |   // Script files
 96 |   {
 97 |     files: ['scripts/**/*.js'],
 98 |     languageOptions: {
 99 |       sourceType: 'module',
100 |       globals: {
101 |         console: 'readonly',
102 |         process: 'readonly',
103 |         Buffer: 'readonly',
104 |         __dirname: 'readonly',
105 |         __filename: 'readonly',
106 |       },
107 |     },
108 |   },
109 | 
110 |   // Mock files (CommonJS format)
111 |   {
112 |     files: ['**/__mocks__/**/*.js'],
113 |     languageOptions: {
114 |       sourceType: 'script',
115 |       globals: {
116 |         module: 'writable',
117 |         exports: 'writable',
118 |         jest: 'readonly',
119 |       },
120 |     },
121 |   },
122 | 
123 |   // Ignore patterns
124 |   {
125 |     ignores: [
126 |       'tmp/**',
127 |       'dist/**',
128 |       'node_modules/**',
129 |       'coverage/**',
130 |       'docs-site/**',
131 |       'docs-site-old/**',
132 |       '*.config.js',
133 |       'jest.config.js',
134 |       'tests/servers/**',
135 |     ],
136 |   },
137 | );
138 | 
```

--------------------------------------------------------------------------------
/docs/dw_crypto/X509Certificate.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.crypto
  2 | 
  3 | # Class X509Certificate
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.crypto.CertificateRef
  9 |   - dw.crypto.X509Certificate
 10 | 
 11 | ## Description
 12 | 
 13 | Represents an X.509 public key certificate as defined in RFC 5280. It provides access to the standard fields of an X.509 certificate including version, serial number, validity period, distinguished names, and signature algorithm.
 14 | 
 15 | ## Properties
 16 | 
 17 | ### issuerDN
 18 | 
 19 | **Type:** String (Read Only)
 20 | 
 21 | The X.500 distinguished name of the entity that signed this certificate.
 22 | 
 23 | ### notAfter
 24 | 
 25 | **Type:** Date (Read Only)
 26 | 
 27 | The end date of the certificate validity period.
 28 | 
 29 | ### notBefore
 30 | 
 31 | **Type:** Date (Read Only)
 32 | 
 33 | The start date of the certificate validity period.
 34 | 
 35 | ### serialNumber
 36 | 
 37 | **Type:** String (Read Only)
 38 | 
 39 | The certificate serial number in string format. The serial number is a unique positive integer assigned
 40 |  by the CA to each certificate.
 41 | 
 42 | ### sigAlgName
 43 | 
 44 | **Type:** String (Read Only)
 45 | 
 46 | The algorithm used to sign this certificate. The name follows the format defined in RFC 5280 (e.g.,
 47 |  "SHA256withRSA", "SHA384withECDSA").
 48 | 
 49 | ### subjectDN
 50 | 
 51 | **Type:** String (Read Only)
 52 | 
 53 | The X.500 distinguished name of the entity this certificate belongs to.
 54 | 
 55 | ### version
 56 | 
 57 | **Type:** Number (Read Only)
 58 | 
 59 | The X.509 certificate version number.
 60 | 
 61 | ## Constructor Summary
 62 | 
 63 | ## Method Summary
 64 | 
 65 | ### getIssuerDN
 66 | 
 67 | **Signature:** `getIssuerDN() : String`
 68 | 
 69 | Returns the X.500 distinguished name of the entity that signed this certificate.
 70 | 
 71 | ### getNotAfter
 72 | 
 73 | **Signature:** `getNotAfter() : Date`
 74 | 
 75 | Returns the end date of the certificate validity period.
 76 | 
 77 | ### getNotBefore
 78 | 
 79 | **Signature:** `getNotBefore() : Date`
 80 | 
 81 | Returns the start date of the certificate validity period.
 82 | 
 83 | ### getSerialNumber
 84 | 
 85 | **Signature:** `getSerialNumber() : String`
 86 | 
 87 | Returns the certificate serial number in string format.
 88 | 
 89 | ### getSigAlgName
 90 | 
 91 | **Signature:** `getSigAlgName() : String`
 92 | 
 93 | Returns the algorithm used to sign this certificate.
 94 | 
 95 | ### getSubjectDN
 96 | 
 97 | **Signature:** `getSubjectDN() : String`
 98 | 
 99 | Returns the X.500 distinguished name of the entity this certificate belongs to.
100 | 
101 | ### getVersion
102 | 
103 | **Signature:** `getVersion() : Number`
104 | 
105 | Returns the X.509 certificate version number.
106 | 
107 | ## Method Detail
108 | 
109 | ## Method Details
110 | 
111 | ### getIssuerDN
112 | 
113 | **Signature:** `getIssuerDN() : String`
114 | 
115 | **Description:** Returns the X.500 distinguished name of the entity that signed this certificate.
116 | 
117 | **Returns:**
118 | 
119 | the issuer's X.500 distinguished name
120 | 
121 | ---
122 | 
123 | ### getNotAfter
124 | 
125 | **Signature:** `getNotAfter() : Date`
126 | 
127 | **Description:** Returns the end date of the certificate validity period.
128 | 
129 | **Returns:**
130 | 
131 | the date after which this certificate is not valid
132 | 
133 | ---
134 | 
135 | ### getNotBefore
136 | 
137 | **Signature:** `getNotBefore() : Date`
138 | 
139 | **Description:** Returns the start date of the certificate validity period.
140 | 
141 | **Returns:**
142 | 
143 | the date before which this certificate is not valid
144 | 
145 | ---
146 | 
147 | ### getSerialNumber
148 | 
149 | **Signature:** `getSerialNumber() : String`
150 | 
151 | **Description:** Returns the certificate serial number in string format. The serial number is a unique positive integer assigned by the CA to each certificate.
152 | 
153 | **Returns:**
154 | 
155 | the certificate serial number as a string
156 | 
157 | ---
158 | 
159 | ### getSigAlgName
160 | 
161 | **Signature:** `getSigAlgName() : String`
162 | 
163 | **Description:** Returns the algorithm used to sign this certificate. The name follows the format defined in RFC 5280 (e.g., "SHA256withRSA", "SHA384withECDSA").
164 | 
165 | **Returns:**
166 | 
167 | the signature algorithm name
168 | 
169 | ---
170 | 
171 | ### getSubjectDN
172 | 
173 | **Signature:** `getSubjectDN() : String`
174 | 
175 | **Description:** Returns the X.500 distinguished name of the entity this certificate belongs to.
176 | 
177 | **Returns:**
178 | 
179 | the subject's X.500 distinguished name
180 | 
181 | ---
182 | 
183 | ### getVersion
184 | 
185 | **Signature:** `getVersion() : Number`
186 | 
187 | **Description:** Returns the X.509 certificate version number.
188 | 
189 | **Returns:**
190 | 
191 | certificate version (typically 1, 2, or 3)
192 | 
193 | ---
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------

```yaml
  1 | name: 🐛 Bug Report
  2 | description: Report a bug or unexpected behavior in the SFCC Development MCP Server
  3 | title: "[Bug]: "
  4 | labels: ["bug", "needs-triage"]
  5 | assignees: []
  6 | body:
  7 |   - type: markdown
  8 |     attributes:
  9 |       value: |
 10 |         Thanks for taking the time to report a bug! Please fill out the information below to help us investigate and fix the issue.
 11 | 
 12 |   - type: checkboxes
 13 |     id: terms
 14 |     attributes:
 15 |       label: Pre-flight Checklist
 16 |       description: Please confirm you have completed these steps before submitting the bug report.
 17 |       options:
 18 |         - label: I have searched existing issues to ensure this bug hasn't been reported already
 19 |           required: true
 20 |         - label: I have read the documentation and troubleshooting guide
 21 |           required: true
 22 |         - label: I am using a supported Node.js version (18+)
 23 |           required: true
 24 | 
 25 |   - type: dropdown
 26 |     id: operating-mode
 27 |     attributes:
 28 |       label: Operating Mode
 29 |       description: Which mode were you using when the bug occurred?
 30 |       options:
 31 |         - Documentation-only mode
 32 |         - Full mode (with SFCC credentials)
 33 |         - Not sure
 34 |     validations:
 35 |       required: true
 36 | 
 37 |   - type: textarea
 38 |     id: bug-description
 39 |     attributes:
 40 |       label: Bug Description
 41 |       description: A clear and concise description of what the bug is.
 42 |       placeholder: Describe what happened and what you expected to happen instead.
 43 |     validations:
 44 |       required: true
 45 | 
 46 |   - type: textarea
 47 |     id: reproduction-steps
 48 |     attributes:
 49 |       label: Steps to Reproduce
 50 |       description: Detailed steps to reproduce the behavior.
 51 |       placeholder: |
 52 |         1. Start the MCP server with...
 53 |         2. Call the tool...
 54 |         3. Observe the error...
 55 |     validations:
 56 |       required: true
 57 | 
 58 |   - type: textarea
 59 |     id: expected-behavior
 60 |     attributes:
 61 |       label: Expected Behavior
 62 |       description: What you expected to happen.
 63 |     validations:
 64 |       required: true
 65 | 
 66 |   - type: textarea
 67 |     id: actual-behavior
 68 |     attributes:
 69 |       label: Actual Behavior
 70 |       description: What actually happened, including any error messages.
 71 |     validations:
 72 |       required: true
 73 | 
 74 |   - type: textarea
 75 |     id: environment
 76 |     attributes:
 77 |       label: Environment Information
 78 |       description: Information about your environment
 79 |       value: |
 80 |         - OS: [e.g., macOS 14.1, Windows 11, Ubuntu 22.04]
 81 |         - Node.js version: [run `node --version`]
 82 |         - NPM/Yarn version: [run `npm --version` or `yarn --version`]
 83 |         - SFCC Dev MCP version: [check package.json version]
 84 |         - MCP Client: [e.g., Claude Desktop, Custom implementation]
 85 |     validations:
 86 |       required: true
 87 | 
 88 |   - type: textarea
 89 |     id: logs
 90 |     attributes:
 91 |       label: Relevant Logs
 92 |       description: Any relevant log output or error messages
 93 |       render: shell
 94 |       placeholder: Paste any relevant logs here (please remove any sensitive information like credentials)
 95 | 
 96 |   - type: textarea
 97 |     id: configuration
 98 |     attributes:
 99 |       label: Configuration (Sanitized)
100 |       description: Your configuration (with sensitive information removed)
101 |       render: json
102 |       placeholder: |
103 |         {
104 |           "hostname": "your-instance.demandware.net",
105 |           "clientId": "[REDACTED]",
106 |           "version": "v21_3"
107 |         }
108 | 
109 |   - type: dropdown
110 |     id: affected-tools
111 |     attributes:
112 |       label: Affected Tools
113 |       description: Which MCP tools are affected by this bug?
114 |       multiple: true
115 |       options:
116 |         - SFCC Class Documentation Tools
117 |         - Best Practices Guide Tools
118 |         - Log Analysis Tools
119 |         - System Object Tools
120 |         - Authentication/OAuth
121 |         - Configuration Loading
122 |         - All Tools
123 |         - Not sure
124 | 
125 |   - type: textarea
126 |     id: additional-context
127 |     attributes:
128 |       label: Additional Context
129 |       description: Any other context, screenshots, or information that might be helpful.
130 | 
```

--------------------------------------------------------------------------------
/docs-site/scripts/generate-sitemap.js:
--------------------------------------------------------------------------------

```javascript
  1 | #!/usr/bin/env node
  2 | 
  3 | /**
  4 |  * Sitemap Generator for SFCC Development MCP Server Documentation
  5 |  *
  6 |  * This script generates an XML sitemap for the SFCC Development MCP Server documentation site.
  7 |  * Run this whenever you add new pages or want to update the sitemap.
  8 |  *
  9 |  * Usage: node scripts/generate-sitemap.js
 10 |  */
 11 | 
 12 | import fs from 'fs';
 13 | import path from 'path';
 14 | import { fileURLToPath } from 'url';
 15 | 
 16 | const __filename = fileURLToPath(import.meta.url);
 17 | const __dirname = path.dirname(__filename);
 18 | 
 19 | const baseUrl = 'https://sfcc-mcp-dev.rhino-inquisitor.com';
 20 | const currentDate = new Date().toISOString().split('T')[0];
 21 | 
 22 | // Define all pages with their priorities and change frequencies
 23 | const pages = [
 24 |   {
 25 |     path: '/',
 26 |     priority: '1.0',
 27 |     changefreq: 'weekly',
 28 |     description: 'SFCC Development MCP Server Homepage',
 29 |   },
 30 |   {
 31 |     path: '/configuration/',
 32 |     priority: '0.9',
 33 |     changefreq: 'monthly',
 34 |     description: 'Configuration Guide',
 35 |   },
 36 |   {
 37 |     path: '/ai-interfaces/',
 38 |     priority: '0.8',
 39 |     changefreq: 'monthly',
 40 |     description: 'AI Interface Setup Guide',
 41 |   },
 42 |   {
 43 |     path: '/features/',
 44 |     priority: '0.8',
 45 |     changefreq: 'monthly',
 46 |     description: 'Features Overview',
 47 |   },
 48 |   {
 49 |     path: '/tools/',
 50 |     priority: '0.8',
 51 |     changefreq: 'monthly',
 52 |     description: 'Available Tools',
 53 |   },
 54 |   {
 55 |     path: '/examples/',
 56 |     priority: '0.8',
 57 |     changefreq: 'monthly',
 58 |     description: 'Examples and Use Cases',
 59 |   },
 60 |   {
 61 |     path: '/security/',
 62 |     priority: '0.7',
 63 |     changefreq: 'monthly',
 64 |     description: 'Security Guidelines',
 65 |   },
 66 |   {
 67 |     path: '/development/',
 68 |     priority: '0.6',
 69 |     changefreq: 'monthly',
 70 |     description: 'Development Guide',
 71 |   },
 72 |   {
 73 |     path: '/troubleshooting/',
 74 |     priority: '0.7',
 75 |     changefreq: 'monthly',
 76 |     description: 'Troubleshooting Guide',
 77 |   },
 78 | ];
 79 | 
 80 | function generateSitemap() {
 81 |   const header = `<?xml version="1.0" encoding="UTF-8"?>
 82 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
 83 |         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 84 |         xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
 85 |         http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">`;
 86 | 
 87 |   const footer = `
 88 | </urlset>`;
 89 | 
 90 |   const urls = pages.map(page => {
 91 |     // For SSG routing, URLs should point to clean paths without hash fragments
 92 |     const url = page.path === '/' ? baseUrl : `${baseUrl}${page.path}`;
 93 |     return `    
 94 |     <!-- ${page.description} -->
 95 |     <url>
 96 |         <loc>${url}</loc>
 97 |         <lastmod>${currentDate}</lastmod>
 98 |         <changefreq>${page.changefreq}</changefreq>
 99 |         <priority>${page.priority}</priority>
100 |     </url>`;
101 |   }).join('');
102 | 
103 |   return header + urls + footer;
104 | }
105 | 
106 | function generateRobotsTxt() {
107 |   return `User-agent: *
108 | Allow: /
109 | 
110 | # Sitemap
111 | Sitemap: ${baseUrl}/sitemap.xml
112 | 
113 | # Crawl-delay for respectful crawling
114 | Crawl-delay: 1
115 | 
116 | # Allow all common search engines
117 | User-agent: Googlebot
118 | Allow: /
119 | 
120 | User-agent: Bingbot
121 | Allow: /
122 | 
123 | User-agent: Slurp
124 | Allow: /
125 | 
126 | User-agent: DuckDuckBot
127 | Allow: /
128 | 
129 | # Block certain paths if needed
130 | # Disallow: /temp/
131 | # Disallow: /private/`;
132 | }
133 | 
134 | // Generate files
135 | const sitemap = generateSitemap();
136 | const robots = generateRobotsTxt();
137 | 
138 | // Write files
139 | const publicDir = path.join(__dirname, '..', 'public');
140 | if (!fs.existsSync(publicDir)) {
141 |   fs.mkdirSync(publicDir, { recursive: true });
142 | }
143 | 
144 | fs.writeFileSync(path.join(publicDir, 'sitemap.xml'), sitemap);
145 | fs.writeFileSync(path.join(publicDir, 'robots.txt'), robots);
146 | 
147 | console.log('✅ Sitemap and robots.txt generated successfully!');
148 | console.log(`📄 Generated ${pages.length} URLs in sitemap.xml`);
149 | console.log('🤖 Updated robots.txt with sitemap reference');
150 | console.log(`📅 Last modified: ${currentDate}`);
151 | 
152 | // Also log the pages for verification
153 | console.log('\n📋 Pages included in sitemap:');
154 | pages.forEach(page => {
155 |   console.log(`   ${page.path} (Priority: ${page.priority}, ${page.changefreq})`);
156 | });
157 | 
```

--------------------------------------------------------------------------------
/docs/dw_catalog/Catalog.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class Catalog
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.catalog.Catalog
 11 | 
 12 | ## Description
 13 | 
 14 | Represents a Commerce Cloud Digital Catalog. Catalogs are containers of products and other product-related information and can be shared between sites. Every product in the system is contained in (or "owned by") exactly one catalog. Every site has a single "site catalog" which defines the products that are available to purchase on that site. The static method CatalogMgr.getSiteCatalog() returns the site catalog for the current site. Catalogs are organized into a tree of categories with a single top-level root category. Products are assigned to categories within catalogs. They can be assigned to categories in their owning catalog, or other catalogs. They can be assigned to multiple categories within the same catalog. Products that are not assigned to any categories are considered "uncategorized." A product has a single "classification category" in some catalog, and one "primary category" per catalog. The classification category defines the attribute set of the product. The primary category is used as standard presentation context within that catalog in the storefront. While Commerce Cloud Digital does not currently distinguish different catalog types, it is common practice to have two general types of catalog: "Product catalogs" typically contain detailed product information and are frequently generated from some backend PIM system. "Site Catalogs" define the category structure of the storefront and contain primarily the assignments of these categories to the products defined in the product catalogs. The site catalog is assigned to the site. In addition to products and categories, catalogs contain recommendations, shared variation attributes which can be used by multiple master products, and shared product options which can be used by multiple option products.
 15 | 
 16 | ## Properties
 17 | 
 18 | ### description
 19 | 
 20 | **Type:** String (Read Only)
 21 | 
 22 | The value of the localized extensible object attribute
 23 |  "shortDescription" for the current locale.
 24 | 
 25 | ### displayName
 26 | 
 27 | **Type:** String (Read Only)
 28 | 
 29 | The value of the localized extensible object attribute
 30 |  "displayName" for the current locale.
 31 | 
 32 | ### ID
 33 | 
 34 | **Type:** String (Read Only)
 35 | 
 36 | The value of attribute 'id'.
 37 | 
 38 | ### root
 39 | 
 40 | **Type:** Category (Read Only)
 41 | 
 42 | The object for the relation 'root'.
 43 | 
 44 | ## Constructor Summary
 45 | 
 46 | ## Method Summary
 47 | 
 48 | ### getDescription
 49 | 
 50 | **Signature:** `getDescription() : String`
 51 | 
 52 | Returns the value of the localized extensible object attribute "shortDescription" for the current locale.
 53 | 
 54 | ### getDisplayName
 55 | 
 56 | **Signature:** `getDisplayName() : String`
 57 | 
 58 | Returns the value of the localized extensible object attribute "displayName" for the current locale.
 59 | 
 60 | ### getID
 61 | 
 62 | **Signature:** `getID() : String`
 63 | 
 64 | Returns the value of attribute 'id'.
 65 | 
 66 | ### getRoot
 67 | 
 68 | **Signature:** `getRoot() : Category`
 69 | 
 70 | Returns the object for the relation 'root'.
 71 | 
 72 | ## Method Detail
 73 | 
 74 | ## Method Details
 75 | 
 76 | ### getDescription
 77 | 
 78 | **Signature:** `getDescription() : String`
 79 | 
 80 | **Description:** Returns the value of the localized extensible object attribute "shortDescription" for the current locale.
 81 | 
 82 | **Returns:**
 83 | 
 84 | The value of the attribute for the current locale, or null if it wasn't found.
 85 | 
 86 | ---
 87 | 
 88 | ### getDisplayName
 89 | 
 90 | **Signature:** `getDisplayName() : String`
 91 | 
 92 | **Description:** Returns the value of the localized extensible object attribute "displayName" for the current locale.
 93 | 
 94 | **Returns:**
 95 | 
 96 | The value of the attribute for the current locale, or null if it wasn't found.
 97 | 
 98 | ---
 99 | 
100 | ### getID
101 | 
102 | **Signature:** `getID() : String`
103 | 
104 | **Description:** Returns the value of attribute 'id'.
105 | 
106 | **Returns:**
107 | 
108 | the value of the attribute 'id'
109 | 
110 | ---
111 | 
112 | ### getRoot
113 | 
114 | **Signature:** `getRoot() : Category`
115 | 
116 | **Description:** Returns the object for the relation 'root'.
117 | 
118 | **Returns:**
119 | 
120 | the object for the relation 'root'.
121 | 
122 | ---
```

--------------------------------------------------------------------------------
/docs/dw_catalog/ProductMgr.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class ProductMgr
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.catalog.ProductMgr
  9 | 
 10 | ## Description
 11 | 
 12 | Provides helper methods for getting products based on Product ID or Catalog.
 13 | 
 14 | ## Constructor Summary
 15 | 
 16 | ## Method Summary
 17 | 
 18 | ### getProduct
 19 | 
 20 | **Signature:** `static getProduct(productID : String) : Product`
 21 | 
 22 | Returns the product with the specified id.
 23 | 
 24 | ### queryAllSiteProducts
 25 | 
 26 | **Signature:** `static queryAllSiteProducts() : SeekableIterator`
 27 | 
 28 | Returns all products assigned to the current site.
 29 | 
 30 | ### queryAllSiteProductsSorted
 31 | 
 32 | **Signature:** `static queryAllSiteProductsSorted() : SeekableIterator`
 33 | 
 34 | Returns all products assigned to the current site.
 35 | 
 36 | ### queryProductsInCatalog
 37 | 
 38 | **Signature:** `static queryProductsInCatalog(catalog : Catalog) : SeekableIterator`
 39 | 
 40 | Returns all products assigned to the the specified catalog, where assignment has the same meaning as it does for queryAllSiteProducts().
 41 | 
 42 | ### queryProductsInCatalogSorted
 43 | 
 44 | **Signature:** `static queryProductsInCatalogSorted(catalog : Catalog) : SeekableIterator`
 45 | 
 46 | Returns all products assigned to the the specified catalog.
 47 | 
 48 | ## Method Detail
 49 | 
 50 | ## Method Details
 51 | 
 52 | ### getProduct
 53 | 
 54 | **Signature:** `static getProduct(productID : String) : Product`
 55 | 
 56 | **Description:** Returns the product with the specified id.
 57 | 
 58 | **Parameters:**
 59 | 
 60 | - `productID`: the product identifier.
 61 | 
 62 | **Returns:**
 63 | 
 64 | Product for specified id or null
 65 | 
 66 | ---
 67 | 
 68 | ### queryAllSiteProducts
 69 | 
 70 | **Signature:** `static queryAllSiteProducts() : SeekableIterator`
 71 | 
 72 | **Description:** Returns all products assigned to the current site. A product is assigned to a site if it is assigned to at least one category of the site catalog or it is a variant and it's master product is assigned to the current site It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
 73 | 
 74 | **Returns:**
 75 | 
 76 | Iterator of all site products
 77 | 
 78 | **See Also:**
 79 | 
 80 | SeekableIterator.close()
 81 | 
 82 | ---
 83 | 
 84 | ### queryAllSiteProductsSorted
 85 | 
 86 | **Signature:** `static queryAllSiteProductsSorted() : SeekableIterator`
 87 | 
 88 | **Description:** Returns all products assigned to the current site. Works like queryAllSiteProducts(), but additionally sorts the result set by product ID. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
 89 | 
 90 | **Returns:**
 91 | 
 92 | Iterator of all site products sorted by product ID.
 93 | 
 94 | **See Also:**
 95 | 
 96 | SeekableIterator.close()
 97 | 
 98 | ---
 99 | 
100 | ### queryProductsInCatalog
101 | 
102 | **Signature:** `static queryProductsInCatalog(catalog : Catalog) : SeekableIterator`
103 | 
104 | **Description:** Returns all products assigned to the the specified catalog, where assignment has the same meaning as it does for queryAllSiteProducts(). It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
105 | 
106 | **Parameters:**
107 | 
108 | - `catalog`: The catalog whose assigned products should be returned.
109 | 
110 | **Returns:**
111 | 
112 | Iterator of all products assigned to specified catalog.
113 | 
114 | **See Also:**
115 | 
116 | SeekableIterator.close()
117 | 
118 | ---
119 | 
120 | ### queryProductsInCatalogSorted
121 | 
122 | **Signature:** `static queryProductsInCatalogSorted(catalog : Catalog) : SeekableIterator`
123 | 
124 | **Description:** Returns all products assigned to the the specified catalog. Works like queryProductsInCatalog(), but additionally sorts the result set by product ID. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
125 | 
126 | **Parameters:**
127 | 
128 | - `catalog`: The catalog whose assigned products should be returned.
129 | 
130 | **Returns:**
131 | 
132 | Iterator of all products assigned to specified catalog sorted by product ID.
133 | 
134 | **See Also:**
135 | 
136 | SeekableIterator.close()
137 | 
138 | ---
```

--------------------------------------------------------------------------------
/docs/dw_catalog/CatalogMgr.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class CatalogMgr
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.catalog.CatalogMgr
  9 | 
 10 | ## Description
 11 | 
 12 | Provides helper methods for getting categories.
 13 | 
 14 | ## Properties
 15 | 
 16 | ### siteCatalog
 17 | 
 18 | **Type:** Catalog (Read Only)
 19 | 
 20 | The catalog of the current site or null if no catalog is assigned to the site.
 21 | 
 22 | ### sortingOptions
 23 | 
 24 | **Type:** List (Read Only)
 25 | 
 26 | A list containing the sorting options configured for this site.
 27 | 
 28 | ### sortingRules
 29 | 
 30 | **Type:** Collection (Read Only)
 31 | 
 32 | A collection containing all of the sorting rules for this site, including global sorting rules.
 33 | 
 34 | ## Constructor Summary
 35 | 
 36 | ## Method Summary
 37 | 
 38 | ### getCatalog
 39 | 
 40 | **Signature:** `static getCatalog(id : String) : Catalog`
 41 | 
 42 | Returns the catalog identified by the specified catalog id.
 43 | 
 44 | ### getCategory
 45 | 
 46 | **Signature:** `static getCategory(id : String) : Category`
 47 | 
 48 | Returns the category of the site catalog identified by the specified category id.
 49 | 
 50 | ### getSiteCatalog
 51 | 
 52 | **Signature:** `static getSiteCatalog() : Catalog`
 53 | 
 54 | Returns the catalog of the current site or null if no catalog is assigned to the site.
 55 | 
 56 | ### getSortingOption
 57 | 
 58 | **Signature:** `static getSortingOption(id : String) : SortingOption`
 59 | 
 60 | Returns the sorting option with the given ID for this site, or null if there is no such option.
 61 | 
 62 | ### getSortingOptions
 63 | 
 64 | **Signature:** `static getSortingOptions() : List`
 65 | 
 66 | Returns a list containing the sorting options configured for this site.
 67 | 
 68 | ### getSortingRule
 69 | 
 70 | **Signature:** `static getSortingRule(id : String) : SortingRule`
 71 | 
 72 | Returns the sorting rule with the given ID for this site, or null if there is no such rule.
 73 | 
 74 | ### getSortingRules
 75 | 
 76 | **Signature:** `static getSortingRules() : Collection`
 77 | 
 78 | Returns a collection containing all of the sorting rules for this site, including global sorting rules.
 79 | 
 80 | ## Method Detail
 81 | 
 82 | ## Method Details
 83 | 
 84 | ### getCatalog
 85 | 
 86 | **Signature:** `static getCatalog(id : String) : Catalog`
 87 | 
 88 | **Description:** Returns the catalog identified by the specified catalog id. Returns null if no catalog with the specified id exists in the current organization context.
 89 | 
 90 | **Parameters:**
 91 | 
 92 | - `id`: Catalog id
 93 | 
 94 | **Returns:**
 95 | 
 96 | the catalog or null.
 97 | 
 98 | ---
 99 | 
100 | ### getCategory
101 | 
102 | **Signature:** `static getCategory(id : String) : Category`
103 | 
104 | **Description:** Returns the category of the site catalog identified by the specified category id. Returns null if no site catalog is defined, or no category with the specified id is found in the site catalog.
105 | 
106 | **Parameters:**
107 | 
108 | - `id`: the category identifier.
109 | 
110 | **Returns:**
111 | 
112 | the category of the site catalog identified by the specified category id or null if no site catalog is found.
113 | 
114 | ---
115 | 
116 | ### getSiteCatalog
117 | 
118 | **Signature:** `static getSiteCatalog() : Catalog`
119 | 
120 | **Description:** Returns the catalog of the current site or null if no catalog is assigned to the site.
121 | 
122 | **Returns:**
123 | 
124 | the catalog of the current site or null.
125 | 
126 | ---
127 | 
128 | ### getSortingOption
129 | 
130 | **Signature:** `static getSortingOption(id : String) : SortingOption`
131 | 
132 | **Description:** Returns the sorting option with the given ID for this site, or null if there is no such option.
133 | 
134 | **Parameters:**
135 | 
136 | - `id`: the ID of the sorting option
137 | 
138 | **Returns:**
139 | 
140 | a SortingOption or null.
141 | 
142 | ---
143 | 
144 | ### getSortingOptions
145 | 
146 | **Signature:** `static getSortingOptions() : List`
147 | 
148 | **Description:** Returns a list containing the sorting options configured for this site.
149 | 
150 | **Returns:**
151 | 
152 | a list of SortingOption objects
153 | 
154 | ---
155 | 
156 | ### getSortingRule
157 | 
158 | **Signature:** `static getSortingRule(id : String) : SortingRule`
159 | 
160 | **Description:** Returns the sorting rule with the given ID for this site, or null if there is no such rule.
161 | 
162 | **Parameters:**
163 | 
164 | - `id`: the ID of the sorting rule
165 | 
166 | **Returns:**
167 | 
168 | a SortingRule or null.
169 | 
170 | ---
171 | 
172 | ### getSortingRules
173 | 
174 | **Signature:** `static getSortingRules() : Collection`
175 | 
176 | **Description:** Returns a collection containing all of the sorting rules for this site, including global sorting rules.
177 | 
178 | **Returns:**
179 | 
180 | a collection of SortingRule objects
181 | 
182 | ---
```

--------------------------------------------------------------------------------
/docs/dw_util/SortedSet.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.util
  2 | 
  3 | # Class SortedSet
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.util.Collection
  9 |   - dw.util.Set
 10 |     - dw.util.SortedSet
 11 | 
 12 | ## Description
 13 | 
 14 | A set that further guarantees that its iterator will traverse the set in ascending element order, sorted according to the natural ordering of its elements (only supported for Number, String, Date, Money and Quantity), or by a comparator provided at sorted set creation time.
 15 | 
 16 | ## Constructor Summary
 17 | 
 18 | SortedSet() Constructor to create a new SortedSet.
 19 | 
 20 | SortedSet(comparator : Object) Constructor to create a new SortedSet.
 21 | 
 22 | SortedSet(collection : Collection) Constructor for a new SortedSet.
 23 | 
 24 | ## Method Summary
 25 | 
 26 | ### clone
 27 | 
 28 | **Signature:** `clone() : SortedSet`
 29 | 
 30 | Returns a shallow copy of this set.
 31 | 
 32 | ### first
 33 | 
 34 | **Signature:** `first() : Object`
 35 | 
 36 | Returns the first (lowest) element currently in this sorted set.
 37 | 
 38 | ### headSet
 39 | 
 40 | **Signature:** `headSet(key : Object) : SortedSet`
 41 | 
 42 | Returns a view of the portion of this sorted set whose elements are strictly less than toElement.
 43 | 
 44 | ### last
 45 | 
 46 | **Signature:** `last() : Object`
 47 | 
 48 | Returns the last (highest) element currently in this sorted set.
 49 | 
 50 | ### subSet
 51 | 
 52 | **Signature:** `subSet(from : Object, to : Object) : SortedSet`
 53 | 
 54 | Returns a view of the portion of this sorted set whose elements range from fromElement, inclusive, to toElement, exclusive.
 55 | 
 56 | ### tailSet
 57 | 
 58 | **Signature:** `tailSet(key : Object) : SortedSet`
 59 | 
 60 | Returns a view of the portion of this sorted set whose elements are greater than or equal to fromElement.
 61 | 
 62 | ## Constructor Detail
 63 | 
 64 | ## Method Detail
 65 | 
 66 | ## Method Details
 67 | 
 68 | ### clone
 69 | 
 70 | **Signature:** `clone() : SortedSet`
 71 | 
 72 | **Description:** Returns a shallow copy of this set.
 73 | 
 74 | **Returns:**
 75 | 
 76 | a shallow copy of this set.
 77 | 
 78 | ---
 79 | 
 80 | ### first
 81 | 
 82 | **Signature:** `first() : Object`
 83 | 
 84 | **Description:** Returns the first (lowest) element currently in this sorted set.
 85 | 
 86 | **Returns:**
 87 | 
 88 | the first (lowest) element currently in this sorted set.
 89 | 
 90 | ---
 91 | 
 92 | ### headSet
 93 | 
 94 | **Signature:** `headSet(key : Object) : SortedSet`
 95 | 
 96 | **Description:** Returns a view of the portion of this sorted set whose elements are strictly less than toElement. The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations.
 97 | 
 98 | **Parameters:**
 99 | 
100 | - `key`: high endpoint (exclusive) of the headSet.
101 | 
102 | **Returns:**
103 | 
104 | a view of the specified initial range of this sorted set.
105 | 
106 | ---
107 | 
108 | ### last
109 | 
110 | **Signature:** `last() : Object`
111 | 
112 | **Description:** Returns the last (highest) element currently in this sorted set.
113 | 
114 | **Returns:**
115 | 
116 | the last (highest) element currently in this sorted set.
117 | 
118 | ---
119 | 
120 | ### subSet
121 | 
122 | **Signature:** `subSet(from : Object, to : Object) : SortedSet`
123 | 
124 | **Description:** Returns a view of the portion of this sorted set whose elements range from fromElement, inclusive, to toElement, exclusive. (If fromElement and toElement are equal, the returned sorted set is empty.) The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations that this sorted set supports.
125 | 
126 | **Parameters:**
127 | 
128 | - `from`: low endpoint (inclusive) of the subSet.
129 | - `to`: high endpoint (exclusive) of the subSet.
130 | 
131 | **Returns:**
132 | 
133 | a view of the specified range within this sorted set.
134 | 
135 | ---
136 | 
137 | ### tailSet
138 | 
139 | **Signature:** `tailSet(key : Object) : SortedSet`
140 | 
141 | **Description:** Returns a view of the portion of this sorted set whose elements are greater than or equal to fromElement. The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations.
142 | 
143 | **Parameters:**
144 | 
145 | - `key`: low endpoint (inclusive) of the tailSet.
146 | 
147 | **Returns:**
148 | 
149 | a view of the specified final range of this sorted set.
150 | 
151 | ---
```

--------------------------------------------------------------------------------
/docs/dw_catalog/PriceBook.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class PriceBook
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.catalog.PriceBook
 11 | 
 12 | ## Description
 13 | 
 14 | Represents a price book.
 15 | 
 16 | ## Properties
 17 | 
 18 | ### currencyCode
 19 | 
 20 | **Type:** String (Read Only)
 21 | 
 22 | The currency code of the price book.
 23 | 
 24 | ### description
 25 | 
 26 | **Type:** String (Read Only)
 27 | 
 28 | The description of the price book.
 29 | 
 30 | ### displayName
 31 | 
 32 | **Type:** String (Read Only)
 33 | 
 34 | The display name of the price book.
 35 | 
 36 | ### ID
 37 | 
 38 | **Type:** String (Read Only)
 39 | 
 40 | The ID of the price book.
 41 | 
 42 | ### online
 43 | 
 44 | **Type:** boolean (Read Only)
 45 | 
 46 | The online status of the price book. The online status
 47 |  is calculated from the online status flag and the onlineFrom
 48 |  onlineTo dates defined for the price book.
 49 | 
 50 | ### onlineFlag
 51 | 
 52 | **Type:** boolean (Read Only)
 53 | 
 54 | The online status flag of the price book.
 55 | 
 56 | ### onlineFrom
 57 | 
 58 | **Type:** Date (Read Only)
 59 | 
 60 | The date from which the price book is online or valid.
 61 | 
 62 | ### onlineTo
 63 | 
 64 | **Type:** Date (Read Only)
 65 | 
 66 | The date until which the price book is online or valid.
 67 | 
 68 | ### parentPriceBook
 69 | 
 70 | **Type:** PriceBook (Read Only)
 71 | 
 72 | The parent price book.
 73 | 
 74 | ## Constructor Summary
 75 | 
 76 | ## Method Summary
 77 | 
 78 | ### getCurrencyCode
 79 | 
 80 | **Signature:** `getCurrencyCode() : String`
 81 | 
 82 | Returns the currency code of the price book.
 83 | 
 84 | ### getDescription
 85 | 
 86 | **Signature:** `getDescription() : String`
 87 | 
 88 | Returns the description of the price book.
 89 | 
 90 | ### getDisplayName
 91 | 
 92 | **Signature:** `getDisplayName() : String`
 93 | 
 94 | Returns the display name of the price book.
 95 | 
 96 | ### getID
 97 | 
 98 | **Signature:** `getID() : String`
 99 | 
100 | Returns the ID of the price book.
101 | 
102 | ### getOnlineFlag
103 | 
104 | **Signature:** `getOnlineFlag() : boolean`
105 | 
106 | Returns the online status flag of the price book.
107 | 
108 | ### getOnlineFrom
109 | 
110 | **Signature:** `getOnlineFrom() : Date`
111 | 
112 | Returns the date from which the price book is online or valid.
113 | 
114 | ### getOnlineTo
115 | 
116 | **Signature:** `getOnlineTo() : Date`
117 | 
118 | Returns the date until which the price book is online or valid.
119 | 
120 | ### getParentPriceBook
121 | 
122 | **Signature:** `getParentPriceBook() : PriceBook`
123 | 
124 | Returns the parent price book.
125 | 
126 | ### isOnline
127 | 
128 | **Signature:** `isOnline() : boolean`
129 | 
130 | Returns the online status of the price book.
131 | 
132 | ## Method Detail
133 | 
134 | ## Method Details
135 | 
136 | ### getCurrencyCode
137 | 
138 | **Signature:** `getCurrencyCode() : String`
139 | 
140 | **Description:** Returns the currency code of the price book.
141 | 
142 | **Returns:**
143 | 
144 | Currency code of the price book
145 | 
146 | ---
147 | 
148 | ### getDescription
149 | 
150 | **Signature:** `getDescription() : String`
151 | 
152 | **Description:** Returns the description of the price book.
153 | 
154 | **Returns:**
155 | 
156 | Currency code of the price book
157 | 
158 | ---
159 | 
160 | ### getDisplayName
161 | 
162 | **Signature:** `getDisplayName() : String`
163 | 
164 | **Description:** Returns the display name of the price book.
165 | 
166 | **Returns:**
167 | 
168 | Display name of the price book
169 | 
170 | ---
171 | 
172 | ### getID
173 | 
174 | **Signature:** `getID() : String`
175 | 
176 | **Description:** Returns the ID of the price book.
177 | 
178 | **Returns:**
179 | 
180 | ID of the price book
181 | 
182 | ---
183 | 
184 | ### getOnlineFlag
185 | 
186 | **Signature:** `getOnlineFlag() : boolean`
187 | 
188 | **Description:** Returns the online status flag of the price book.
189 | 
190 | **Returns:**
191 | 
192 | the online status flag of the price book.
193 | 
194 | ---
195 | 
196 | ### getOnlineFrom
197 | 
198 | **Signature:** `getOnlineFrom() : Date`
199 | 
200 | **Description:** Returns the date from which the price book is online or valid.
201 | 
202 | **Returns:**
203 | 
204 | the date from which the price book is online or valid.
205 | 
206 | ---
207 | 
208 | ### getOnlineTo
209 | 
210 | **Signature:** `getOnlineTo() : Date`
211 | 
212 | **Description:** Returns the date until which the price book is online or valid.
213 | 
214 | **Returns:**
215 | 
216 | the date until which the price book is online or valid.
217 | 
218 | ---
219 | 
220 | ### getParentPriceBook
221 | 
222 | **Signature:** `getParentPriceBook() : PriceBook`
223 | 
224 | **Description:** Returns the parent price book.
225 | 
226 | **Returns:**
227 | 
228 | Parent price book
229 | 
230 | ---
231 | 
232 | ### isOnline
233 | 
234 | **Signature:** `isOnline() : boolean`
235 | 
236 | **Description:** Returns the online status of the price book. The online status is calculated from the online status flag and the onlineFrom onlineTo dates defined for the price book.
237 | 
238 | **Returns:**
239 | 
240 | The online status of the price book.
241 | 
242 | ---
```

--------------------------------------------------------------------------------
/docs/dw_system/Cache.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.system
  2 | 
  3 | # Class Cache
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.system.Cache
  9 | 
 10 | ## Description
 11 | 
 12 | The Cache class represents a custom cache. A cache stores data over multiple requests. Each cartridge can define its own caches for different business requirements. To limit the visibility of cache entries by scope, for example, by site, catalog, or external system, include the scope reference when constructing the key. For example: var cache = CacheMgr.getCache( 'SiteConfigurations' ); cache.get( Site.current.ID + "config", function loadSiteConfiguration() {return loadCfg( Site.current );} ); Do not build the cache key using personal user data, since the key might be visible in log messages. There is never a guarantee that a stored object can be retrieved from the cache. The storage allocated for entries is limited and clearing or invalidation might occur at any time. To maintain the cache size limits, the cache evicts entries that are less likely to be used again. For example, the cache might evict an entry because it hasn't been used recently or very often. Cache entries aren't synchronized between different application servers. The cache returns immutable copies of the original objects put into the cache. Lists are converted to arrays during this process. Only JavaScript primitive values and tree-like object structures can be stored as entries. Object structures can consist of arrays, lists, and basic JavaScript objects. Script API classes are not supported, except List and its subclasses. null can be stored as a value. undefined can't be stored. See CacheMgr for details about how to configure a custom cache.
 13 | 
 14 | ## Constructor Summary
 15 | 
 16 | ## Method Summary
 17 | 
 18 | ### get
 19 | 
 20 | **Signature:** `get(key : String, loader : Function) : Object`
 21 | 
 22 | Returns the value associated with key in this cache, or invokes the loader function to generate the entry if there is no entry found.
 23 | 
 24 | ### get
 25 | 
 26 | **Signature:** `get(key : String) : Object`
 27 | 
 28 | Returns the value associated with key in this cache.
 29 | 
 30 | ### invalidate
 31 | 
 32 | **Signature:** `invalidate(key : String) : void`
 33 | 
 34 | Removes the cache entry for key (if one exists) manually before the cache's eviction strategy goes into effect.
 35 | 
 36 | ### put
 37 | 
 38 | **Signature:** `put(key : String, value : Object) : void`
 39 | 
 40 | Stores the specified entry directly into the cache, replacing any previously cached entry for key if one exists.
 41 | 
 42 | ## Method Detail
 43 | 
 44 | ## Method Details
 45 | 
 46 | ### get
 47 | 
 48 | **Signature:** `get(key : String, loader : Function) : Object`
 49 | 
 50 | **Description:** Returns the value associated with key in this cache, or invokes the loader function to generate the entry if there is no entry found. The generated entry is stored for future retrieval. If the loader function returns undefined, this value is not stored in the cache.
 51 | 
 52 | **Parameters:**
 53 | 
 54 | - `key`: The cache key.
 55 | - `loader`: The loader function that is called if no value is stored in the cache.
 56 | 
 57 | **Returns:**
 58 | 
 59 | The value found in the cache or the value returned from the loader function call.
 60 | 
 61 | ---
 62 | 
 63 | ### get
 64 | 
 65 | **Signature:** `get(key : String) : Object`
 66 | 
 67 | **Description:** Returns the value associated with key in this cache. If there is no entry in the cache then undefined is returned.
 68 | 
 69 | **Parameters:**
 70 | 
 71 | - `key`: The cache key.
 72 | 
 73 | **Returns:**
 74 | 
 75 | The stored value or undefined if no value is found in the cache.
 76 | 
 77 | ---
 78 | 
 79 | ### invalidate
 80 | 
 81 | **Signature:** `invalidate(key : String) : void`
 82 | 
 83 | **Description:** Removes the cache entry for key (if one exists) manually before the cache's eviction strategy goes into effect.
 84 | 
 85 | **Parameters:**
 86 | 
 87 | - `key`: The cache key.
 88 | 
 89 | ---
 90 | 
 91 | ### put
 92 | 
 93 | **Signature:** `put(key : String, value : Object) : void`
 94 | 
 95 | **Description:** Stores the specified entry directly into the cache, replacing any previously cached entry for key if one exists. Storing undefined as value has the same effect as calling invalidate(String) for that key.
 96 | 
 97 | **Parameters:**
 98 | 
 99 | - `key`: The cache key.
100 | - `value`: The value to be store in the cache.
101 | 
102 | ---
```
Page 7/61FirstPrevNextLast