#
tokens: 49415/50000 10/825 files (page 24/61)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 24 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

--------------------------------------------------------------------------------
/tests/docs-handler.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { DocsToolHandler } from '../src/core/handlers/docs-handler.js';
  2 | import { HandlerContext } from '../src/core/handlers/base-handler.js';
  3 | import { Logger } from '../src/utils/logger.js';
  4 | 
  5 | // Mock the SFCCDocumentationClient
  6 | const mockSFCCDocumentationClient = {
  7 |   getClassDetailsExpanded: jest.fn(),
  8 |   getAvailableClasses: jest.fn(),
  9 |   searchClasses: jest.fn(),
 10 |   searchMethods: jest.fn(),
 11 |   getClassDocumentation: jest.fn(),
 12 | };
 13 | 
 14 | jest.mock('../src/clients/docs-client.js', () => ({
 15 |   SFCCDocumentationClient: jest.fn(() => mockSFCCDocumentationClient),
 16 | }));
 17 | 
 18 | describe('DocsToolHandler', () => {
 19 |   let mockLogger: jest.Mocked<Logger>;
 20 |   let mockDocsClient: typeof mockSFCCDocumentationClient;
 21 |   let context: HandlerContext;
 22 |   let handler: DocsToolHandler;
 23 | 
 24 |   beforeEach(() => {
 25 |     mockLogger = {
 26 |       debug: jest.fn(),
 27 |       log: jest.fn(),
 28 |       error: jest.fn(),
 29 |       timing: jest.fn(),
 30 |       methodEntry: jest.fn(),
 31 |       methodExit: jest.fn(),
 32 |     } as any;
 33 | 
 34 |     // Reset mocks
 35 |     jest.clearAllMocks();
 36 | 
 37 |     // Use the mock client directly
 38 |     mockDocsClient = mockSFCCDocumentationClient;
 39 | 
 40 |     jest.spyOn(Logger, 'getChildLogger').mockReturnValue(mockLogger);
 41 | 
 42 |     context = {
 43 |       logger: mockLogger,
 44 |       config: null as any,
 45 |       capabilities: { canAccessLogs: false, canAccessOCAPI: false },
 46 |     };
 47 | 
 48 |     handler = new DocsToolHandler(context, 'Docs');
 49 |   });
 50 | 
 51 |   afterEach(() => {
 52 |     jest.restoreAllMocks();
 53 |   });
 54 | 
 55 |   // Helper function to initialize handler for tests that need it
 56 |   const initializeHandler = async () => {
 57 |     await (handler as any).initialize();
 58 |   };
 59 | 
 60 |   describe('canHandle', () => {
 61 |     it('should handle docs-related tools', () => {
 62 |       expect(handler.canHandle('get_sfcc_class_info')).toBe(true);
 63 |       expect(handler.canHandle('list_sfcc_classes')).toBe(true);
 64 |       expect(handler.canHandle('search_sfcc_classes')).toBe(true);
 65 |       expect(handler.canHandle('search_sfcc_methods')).toBe(true);
 66 |       expect(handler.canHandle('get_sfcc_class_documentation')).toBe(true);
 67 |     });
 68 | 
 69 |     it('should not handle non-docs tools', () => {
 70 |       expect(handler.canHandle('get_latest_error')).toBe(false);
 71 |       expect(handler.canHandle('unknown_tool')).toBe(false);
 72 |     });
 73 |   });
 74 | 
 75 |   describe('initialization', () => {
 76 |     it('should initialize docs client', async () => {
 77 |       await initializeHandler();
 78 | 
 79 |       const MockedConstructor = jest.requireMock('../src/clients/docs-client.js').SFCCDocumentationClient;
 80 |       expect(MockedConstructor).toHaveBeenCalled();
 81 |       expect(mockLogger.debug).toHaveBeenCalledWith('Documentation client initialized');
 82 |     });
 83 |   });
 84 | 
 85 |   describe('disposal', () => {
 86 |     it('should dispose docs client properly', async () => {
 87 |       await initializeHandler();
 88 |       await (handler as any).dispose();
 89 | 
 90 |       expect(mockLogger.debug).toHaveBeenCalledWith('Documentation client disposed');
 91 |     });
 92 |   });
 93 | 
 94 |   describe('get_sfcc_class_info tool', () => {
 95 |     beforeEach(async () => {
 96 |       await initializeHandler();
 97 |       mockDocsClient.getClassDetailsExpanded.mockResolvedValue({
 98 |         className: 'Product',
 99 |         packageName: 'dw.catalog',
100 |         description: 'Product class description',
101 |         constants: [],
102 |         properties: [
103 |           { name: 'ID', type: 'String', description: 'Product ID' },
104 |           { name: 'name', type: 'String', description: 'Product name' },
105 |         ],
106 |         methods: [
107 |           { name: 'getID', signature: 'getID() : String', description: 'Get product ID' },
108 |           { name: 'getName', signature: 'getName() : String', description: 'Get product name' },
109 |         ],
110 |       });
111 |     });
112 | 
113 |     it('should handle get_sfcc_class_info with className', async () => {
114 |       const args = { className: 'Product', expand: true };
115 |       const result = await handler.handle('get_sfcc_class_info', args, Date.now());
116 | 
117 |       expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', true, {
118 |         includeDescription: true,
119 |         includeConstants: true,
120 |         includeProperties: true,
121 |         includeMethods: true,
122 |         includeInheritance: true,
123 |         search: undefined,
124 |       });
125 |       expect(result.content[0].text).toContain('Product');
126 |       expect(result.content[0].text).toContain('Product class description');
127 |     });
128 | 
129 |     it('should handle get_sfcc_class_info with default expand', async () => {
130 |       const args = { className: 'Customer' };
131 |       await handler.handle('get_sfcc_class_info', args, Date.now());
132 | 
133 |       expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Customer', false, {
134 |         includeDescription: true,
135 |         includeConstants: true,
136 |         includeProperties: true,
137 |         includeMethods: true,
138 |         includeInheritance: true,
139 |         search: undefined,
140 |       });
141 |     });
142 | 
143 |     it('should throw error when className is missing', async () => {
144 |       const result = await handler.handle('get_sfcc_class_info', {}, Date.now());
145 |       expect(result.isError).toBe(true);
146 |       expect(result.content[0].text).toContain('className must be a non-empty string');
147 |     });
148 | 
149 |     it('should handle get_sfcc_class_info with filtering options', async () => {
150 |       const args = {
151 |         className: 'Product',
152 |         includeDescription: false,
153 |         includeConstants: false,
154 |         includeProperties: true,
155 |         includeMethods: false,
156 |         includeInheritance: false,
157 |       };
158 |       const result = await handler.handle('get_sfcc_class_info', args, Date.now());
159 | 
160 |       expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', false, {
161 |         includeDescription: false,
162 |         includeConstants: false,
163 |         includeProperties: true,
164 |         includeMethods: false,
165 |         includeInheritance: false,
166 |         search: undefined,
167 |       });
168 |       expect(result.content[0].text).toContain('Product');
169 |     });
170 | 
171 |     it('should handle get_sfcc_class_info with search parameter', async () => {
172 |       const args = { className: 'Product', search: 'image' };
173 |       const result = await handler.handle('get_sfcc_class_info', args, Date.now());
174 | 
175 |       expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', false, {
176 |         includeDescription: true,
177 |         includeConstants: true,
178 |         includeProperties: true,
179 |         includeMethods: true,
180 |         includeInheritance: true,
181 |         search: 'image',
182 |       });
183 |       expect(result.content[0].text).toContain('Product');
184 |     });
185 | 
186 |     it('should handle get_sfcc_class_info with combined filtering and search', async () => {
187 |       const args = {
188 |         className: 'Product',
189 |         expand: true,
190 |         includeDescription: false,
191 |         includeMethods: true,
192 |         includeProperties: false,
193 |         search: 'price',
194 |       };
195 |       const result = await handler.handle('get_sfcc_class_info', args, Date.now());
196 | 
197 |       expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', true, {
198 |         includeDescription: false,
199 |         includeConstants: true,
200 |         includeProperties: false,
201 |         includeMethods: true,
202 |         includeInheritance: true,
203 |         search: 'price',
204 |       });
205 |       expect(result.content[0].text).toContain('Product');
206 |     });
207 |   });
208 | 
209 |   describe('list_sfcc_classes tool', () => {
210 |     beforeEach(async () => {
211 |       await initializeHandler();
212 |       mockDocsClient.getAvailableClasses.mockResolvedValue([
213 |         'Product', 'Customer', 'Order', 'Catalog',
214 |       ]);
215 |     });
216 | 
217 |     it('should handle list_sfcc_classes', async () => {
218 |       const result = await handler.handle('list_sfcc_classes', {}, Date.now());
219 | 
220 |       expect(mockDocsClient.getAvailableClasses).toHaveBeenCalled();
221 |       expect(result.content[0].text).toContain('Product');
222 |       expect(result.content[0].text).toContain('Customer');
223 |     });
224 |   });
225 | 
226 |   describe('search_sfcc_classes tool', () => {
227 |     beforeEach(async () => {
228 |       await initializeHandler();
229 |       mockDocsClient.searchClasses.mockResolvedValue([
230 |         'Product', 'ProductSearchModel',
231 |       ]);
232 |     });
233 | 
234 |     it('should handle search_sfcc_classes with query', async () => {
235 |       const args = { query: 'product' };
236 |       const result = await handler.handle('search_sfcc_classes', args, Date.now());
237 | 
238 |       expect(mockDocsClient.searchClasses).toHaveBeenCalledWith('product');
239 |       expect(result.content[0].text).toContain('Product');
240 |       expect(result.content[0].text).toContain('ProductSearchModel');
241 |     });
242 | 
243 |     it('should throw error when query is missing', async () => {
244 |       const result = await handler.handle('search_sfcc_classes', {}, Date.now());
245 |       expect(result.isError).toBe(true);
246 |       expect(result.content[0].text).toContain('query must be a non-empty string');
247 |     });
248 | 
249 |     it('should throw error when query is empty', async () => {
250 |       const result = await handler.handle('search_sfcc_classes', { query: '' }, Date.now());
251 |       expect(result.isError).toBe(true);
252 |       expect(result.content[0].text).toContain('query must be a non-empty string');
253 |     });
254 |   });
255 | 
256 |   describe('search_sfcc_methods tool', () => {
257 |     beforeEach(async () => {
258 |       await initializeHandler();
259 |       mockDocsClient.searchMethods.mockResolvedValue([
260 |         {
261 |           className: 'Product',
262 |           method: {
263 |             name: 'getID',
264 |             signature: 'getID() : String',
265 |             description: 'Get product ID',
266 |           },
267 |         },
268 |         {
269 |           className: 'Customer',
270 |           method: {
271 |             name: 'getID',
272 |             signature: 'getID() : String',
273 |             description: 'Get customer ID',
274 |           },
275 |         },
276 |       ]);
277 |     });
278 | 
279 |     it('should handle search_sfcc_methods with methodName', async () => {
280 |       const args = { methodName: 'getID' };
281 |       const result = await handler.handle('search_sfcc_methods', args, Date.now());
282 | 
283 |       expect(mockDocsClient.searchMethods).toHaveBeenCalledWith('getID');
284 |       expect(result.content[0].text).toContain('getID');
285 |       expect(result.content[0].text).toContain('Product');
286 |     });
287 | 
288 |     it('should throw error when methodName is missing', async () => {
289 |       const result = await handler.handle('search_sfcc_methods', {}, Date.now());
290 |       expect(result.isError).toBe(true);
291 |       expect(result.content[0].text).toContain('methodName must be a non-empty string');
292 |     });
293 |   });
294 | 
295 |   describe('get_sfcc_class_documentation tool', () => {
296 |     beforeEach(async () => {
297 |       await initializeHandler();
298 |       mockDocsClient.getClassDocumentation.mockResolvedValue(
299 |         'Detailed documentation for Product class with examples and usage patterns.',
300 |       );
301 |     });
302 | 
303 |     it('should handle get_sfcc_class_documentation with className', async () => {
304 |       const args = { className: 'Product' };
305 |       const result = await handler.handle('get_sfcc_class_documentation', args, Date.now());
306 | 
307 |       expect(mockDocsClient.getClassDocumentation).toHaveBeenCalledWith('Product');
308 |       expect(result.content[0].text).toContain('Detailed documentation');
309 |     });
310 | 
311 |     it('should throw error when className is missing', async () => {
312 |       const result = await handler.handle('get_sfcc_class_documentation', {}, Date.now());
313 |       expect(result.isError).toBe(true);
314 |       expect(result.content[0].text).toContain('className must be a non-empty string');
315 |     });
316 |   });
317 | 
318 |   describe('error handling', () => {
319 |     beforeEach(async () => {
320 |       await initializeHandler();
321 |     });
322 | 
323 |     it('should handle client errors gracefully', async () => {
324 |       mockDocsClient.getClassDetailsExpanded.mockRejectedValue(new Error('Documentation not found'));
325 | 
326 |       const result = await handler.handle('get_sfcc_class_info', { className: 'UnknownClass' }, Date.now());
327 |       expect(result.isError).toBe(true);
328 |       expect(result.content[0].text).toContain('Documentation not found');
329 |     });
330 | 
331 |     it('should throw error for unsupported tools', async () => {
332 |       await expect(handler.handle('unsupported_tool', {}, Date.now()))
333 |         .rejects.toThrow('Unsupported tool');
334 |     });
335 |   });
336 | 
337 |   describe('timing and logging', () => {
338 |     beforeEach(async () => {
339 |       await initializeHandler();
340 |       mockDocsClient.getAvailableClasses.mockResolvedValue(['Product', 'Customer']);
341 |     });
342 | 
343 |     it('should log timing information', async () => {
344 |       const startTime = Date.now();
345 |       await handler.handle('list_sfcc_classes', {}, startTime);
346 | 
347 |       expect(mockLogger.timing).toHaveBeenCalledWith('list_sfcc_classes', startTime);
348 |     });
349 | 
350 |     it('should log execution details', async () => {
351 |       await handler.handle('list_sfcc_classes', {}, Date.now());
352 | 
353 |       expect(mockLogger.debug).toHaveBeenCalledWith(
354 |         'list_sfcc_classes completed successfully',
355 |         expect.any(Object),
356 |       );
357 |     });
358 |   });
359 | });
360 | 
```

--------------------------------------------------------------------------------
/docs/TopLevel/XMLList.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: TopLevel
  2 | 
  3 | # Class XMLList
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - XMLList
  9 | 
 10 | ## Description
 11 | 
 12 | An XMLList object is an ordered collection of properties. A XMLList object represents a XML document, an XML fragment, or an arbitrary collection of XML objects. An individual XML object is the same thing as an XMLList containing only that XML object. All operations available for the XML object are also available for an XMLList object that contains exactly one XML object.
 13 | 
 14 | ## Constructor Summary
 15 | 
 16 | XMLList(value : Object) Creates a new XMLList object using the specified value.
 17 | 
 18 | ## Method Summary
 19 | 
 20 | ### attribute
 21 | 
 22 | **Signature:** `attribute(attributeName : String) : XMLList`
 23 | 
 24 | Returns the attribute associated with this XMLList object that is identified by the specified name.
 25 | 
 26 | ### attributes
 27 | 
 28 | **Signature:** `attributes() : XMLList`
 29 | 
 30 | Returns an XMList of the attributes in this XMLList Object.
 31 | 
 32 | ### child
 33 | 
 34 | **Signature:** `child(propertyName : Object) : XMLList`
 35 | 
 36 | Returns the children of the XMLList object based on the specified property name.
 37 | 
 38 | ### children
 39 | 
 40 | **Signature:** `children() : XMLList`
 41 | 
 42 | Returns an XMLList containing the children of this XMLList object, maintaing the sequence in which they appear.
 43 | 
 44 | ### comments
 45 | 
 46 | **Signature:** `comments() : XMLList`
 47 | 
 48 | Returns the properties of the XMLList object that contain comments.
 49 | 
 50 | ### contains
 51 | 
 52 | **Signature:** `contains(value : XML) : boolean`
 53 | 
 54 | Returns true if this XMLList object contains the specified XML object, false otherwise.
 55 | 
 56 | ### copy
 57 | 
 58 | **Signature:** `copy() : XMLList`
 59 | 
 60 | Returns a deep copy of the this XMLList object.
 61 | 
 62 | ### descendants
 63 | 
 64 | **Signature:** `descendants() : XMLList`
 65 | 
 66 | Calls the descendants() method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order.
 67 | 
 68 | ### descendants
 69 | 
 70 | **Signature:** `descendants(name : String) : XMLList`
 71 | 
 72 | Calls the descendants(name) method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order.
 73 | 
 74 | ### elements
 75 | 
 76 | **Signature:** `elements() : XMLList`
 77 | 
 78 | Calls the elements() method in each XML object in this XMLList object and returns an XMLList containing the results concatenated in order.
 79 | 
 80 | ### elements
 81 | 
 82 | **Signature:** `elements(name : Object) : XMLList`
 83 | 
 84 | Calls the elements(name) method in each of the XML objects in this XMLList object and returns an XMLList containing the results concatenated in order.
 85 | 
 86 | ### hasComplexContent
 87 | 
 88 | **Signature:** `hasComplexContent() : boolean`
 89 | 
 90 | Returns a Boolean value indicating whether this XMLList object contains complex content.
 91 | 
 92 | ### hasOwnProperty
 93 | 
 94 | **Signature:** `hasOwnProperty(prop : String) : boolean`
 95 | 
 96 | Returns a Boolean value indicating whether this object has the property specified by prop.
 97 | 
 98 | ### hasSimpleContent
 99 | 
100 | **Signature:** `hasSimpleContent() : boolean`
101 | 
102 | Returns a Boolean value indicating whether this XML object contains simple content.
103 | 
104 | ### length
105 | 
106 | **Signature:** `length() : Number`
107 | 
108 | Returns the number of children in this XMLList object.
109 | 
110 | ### normalize
111 | 
112 | **Signature:** `normalize() : XMLList`
113 | 
114 | Puts all text nodes in this XMLList, all the XML objects it contains and the descendents of all the XML objects it contains into a normal form by merging adjacent text nodes and eliminating empty text nodes.
115 | 
116 | ### parent
117 | 
118 | **Signature:** `parent() : Object`
119 | 
120 | Returns the parent of the XMLList object or null if the XMLList object does not have a parent.
121 | 
122 | ### processingInstructions
123 | 
124 | **Signature:** `processingInstructions() : XMLList`
125 | 
126 | Calls the processingInstructions() method of each XML object in this XMLList object and returns an XMList containing the results in order.
127 | 
128 | ### processingInstructions
129 | 
130 | **Signature:** `processingInstructions(name : String) : XMLList`
131 | 
132 | Calls the processingInstructions(name) method of each XML object in this XMLList object and returns an XMList containing the results in order.
133 | 
134 | ### propertyIsEnumerable
135 | 
136 | **Signature:** `propertyIsEnumerable(property : String) : boolean`
137 | 
138 | Returns a Boolean indicating whether the specified property will be included in the set of properties iterated over when this XML object is used in a for..in statement.
139 | 
140 | ### text
141 | 
142 | **Signature:** `text() : XMLList`
143 | 
144 | Calls the text() method of each XML object contained in this XMLList object and returns an XMLList containing the results concatenated in order.
145 | 
146 | ### toString
147 | 
148 | **Signature:** `toString() : String`
149 | 
150 | Returns the String representation of this XMLList object.
151 | 
152 | ### toXMLString
153 | 
154 | **Signature:** `toXMLString() : String`
155 | 
156 | Returns an XML-encoded String representation of the XMLList object by calling the toXMLString method on each property contained within this XMLList object.
157 | 
158 | ### valueOf
159 | 
160 | **Signature:** `valueOf() : XMLList`
161 | 
162 | Returns this XMLList object.
163 | 
164 | ## Constructor Detail
165 | 
166 | ## Method Detail
167 | 
168 | ## Method Details
169 | 
170 | ### attribute
171 | 
172 | **Signature:** `attribute(attributeName : String) : XMLList`
173 | 
174 | **Description:** Returns the attribute associated with this XMLList object that is identified by the specified name.
175 | 
176 | **Parameters:**
177 | 
178 | - `attributeName`: the name of the attribute.
179 | 
180 | **Returns:**
181 | 
182 | the value of the attribute as either an XMLList or an empty XMLList
183 | 
184 | ---
185 | 
186 | ### attributes
187 | 
188 | **Signature:** `attributes() : XMLList`
189 | 
190 | **Description:** Returns an XMList of the attributes in this XMLList Object.
191 | 
192 | **Returns:**
193 | 
194 | an XMList of the attributes in this XMLList Object.
195 | 
196 | ---
197 | 
198 | ### child
199 | 
200 | **Signature:** `child(propertyName : Object) : XMLList`
201 | 
202 | **Description:** Returns the children of the XMLList object based on the specified property name.
203 | 
204 | **Parameters:**
205 | 
206 | - `propertyName`: the property name representing the children of this XMLList object.
207 | 
208 | **Returns:**
209 | 
210 | an XMLList of children that match the property name parameter.
211 | 
212 | ---
213 | 
214 | ### children
215 | 
216 | **Signature:** `children() : XMLList`
217 | 
218 | **Description:** Returns an XMLList containing the children of this XMLList object, maintaing the sequence in which they appear.
219 | 
220 | **Returns:**
221 | 
222 | an XMLList containing the children of this XMLList object.
223 | 
224 | ---
225 | 
226 | ### comments
227 | 
228 | **Signature:** `comments() : XMLList`
229 | 
230 | **Description:** Returns the properties of the XMLList object that contain comments.
231 | 
232 | **Returns:**
233 | 
234 | properties of the XMLList object that contain comments.
235 | 
236 | ---
237 | 
238 | ### contains
239 | 
240 | **Signature:** `contains(value : XML) : boolean`
241 | 
242 | **Description:** Returns true if this XMLList object contains the specified XML object, false otherwise.
243 | 
244 | **Parameters:**
245 | 
246 | - `value`: the object to locate in this XMLList object.
247 | 
248 | **Returns:**
249 | 
250 | true if this XMLList object contains the specified XML object, false otherwise.
251 | 
252 | ---
253 | 
254 | ### copy
255 | 
256 | **Signature:** `copy() : XMLList`
257 | 
258 | **Description:** Returns a deep copy of the this XMLList object.
259 | 
260 | **Returns:**
261 | 
262 | the deep copy of the object.
263 | 
264 | ---
265 | 
266 | ### descendants
267 | 
268 | **Signature:** `descendants() : XMLList`
269 | 
270 | **Description:** Calls the descendants() method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order.
271 | 
272 | **Returns:**
273 | 
274 | a list of all descendents of the XML objects in this XMLList object.
275 | 
276 | ---
277 | 
278 | ### descendants
279 | 
280 | **Signature:** `descendants(name : String) : XMLList`
281 | 
282 | **Description:** Calls the descendants(name) method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order.
283 | 
284 | **Parameters:**
285 | 
286 | - `name`: the name of the element to match. To return all descendents, use * as the name parameter.
287 | 
288 | **Returns:**
289 | 
290 | a list of all descendents of the XML objects in this XMLList constrained by the name parameter.
291 | 
292 | ---
293 | 
294 | ### elements
295 | 
296 | **Signature:** `elements() : XMLList`
297 | 
298 | **Description:** Calls the elements() method in each XML object in this XMLList object and returns an XMLList containing the results concatenated in order.
299 | 
300 | ---
301 | 
302 | ### elements
303 | 
304 | **Signature:** `elements(name : Object) : XMLList`
305 | 
306 | **Description:** Calls the elements(name) method in each of the XML objects in this XMLList object and returns an XMLList containing the results concatenated in order. name can be a QName, String, or any other data type that will be converted to a string prior to performing the search for elements of that name. To list all objects use * for the value of name.
307 | 
308 | **Parameters:**
309 | 
310 | - `name`: the name of the elements to return.
311 | 
312 | **Returns:**
313 | 
314 | a list of all elements of the XML objects in this XMLList constrained by the name parameter.
315 | 
316 | ---
317 | 
318 | ### hasComplexContent
319 | 
320 | **Signature:** `hasComplexContent() : boolean`
321 | 
322 | **Description:** Returns a Boolean value indicating whether this XMLList object contains complex content. An XMLList object is considered to contain complex content if it is not empty, contains a single XML item with complex content or contains elements.
323 | 
324 | **Returns:**
325 | 
326 | a Boolean value indicating whether this XMLList object contains complex content.
327 | 
328 | ---
329 | 
330 | ### hasOwnProperty
331 | 
332 | **Signature:** `hasOwnProperty(prop : String) : boolean`
333 | 
334 | **Description:** Returns a Boolean value indicating whether this object has the property specified by prop.
335 | 
336 | **Parameters:**
337 | 
338 | - `prop`: the property to locate.
339 | 
340 | **Returns:**
341 | 
342 | true if the property exists, false otherwise.
343 | 
344 | ---
345 | 
346 | ### hasSimpleContent
347 | 
348 | **Signature:** `hasSimpleContent() : boolean`
349 | 
350 | **Description:** Returns a Boolean value indicating whether this XML object contains simple content. An XMLList object is considered to contain simple content if it is empty, contains a single XML item with simple content or contains no elements.
351 | 
352 | **Returns:**
353 | 
354 | a Boolean value indicating whether this XML object contains simple content.
355 | 
356 | ---
357 | 
358 | ### length
359 | 
360 | **Signature:** `length() : Number`
361 | 
362 | **Description:** Returns the number of children in this XMLList object.
363 | 
364 | **Returns:**
365 | 
366 | the number of children in this XMLList object.
367 | 
368 | ---
369 | 
370 | ### normalize
371 | 
372 | **Signature:** `normalize() : XMLList`
373 | 
374 | **Description:** Puts all text nodes in this XMLList, all the XML objects it contains and the descendents of all the XML objects it contains into a normal form by merging adjacent text nodes and eliminating empty text nodes.
375 | 
376 | **Returns:**
377 | 
378 | the XMLList object containing normailzed objects.
379 | 
380 | ---
381 | 
382 | ### parent
383 | 
384 | **Signature:** `parent() : Object`
385 | 
386 | **Description:** Returns the parent of the XMLList object or null if the XMLList object does not have a parent.
387 | 
388 | **Returns:**
389 | 
390 | the parent of the XMLList object or null if the XMLList object does not have a parent.
391 | 
392 | ---
393 | 
394 | ### processingInstructions
395 | 
396 | **Signature:** `processingInstructions() : XMLList`
397 | 
398 | **Description:** Calls the processingInstructions() method of each XML object in this XMLList object and returns an XMList containing the results in order.
399 | 
400 | **Returns:**
401 | 
402 | an XMLList contaiing the result of calling the processingInstructions() method of each XML object in this XMLList object.
403 | 
404 | ---
405 | 
406 | ### processingInstructions
407 | 
408 | **Signature:** `processingInstructions(name : String) : XMLList`
409 | 
410 | **Description:** Calls the processingInstructions(name) method of each XML object in this XMLList object and returns an XMList containing the results in order.
411 | 
412 | **Parameters:**
413 | 
414 | - `name`: the name representing the processing-instructions you want to retreive.
415 | 
416 | **Returns:**
417 | 
418 | an XMLList containing the result of calling the processingInstructions(name) method of each XML object in this XMLList object.
419 | 
420 | ---
421 | 
422 | ### propertyIsEnumerable
423 | 
424 | **Signature:** `propertyIsEnumerable(property : String) : boolean`
425 | 
426 | **Description:** Returns a Boolean indicating whether the specified property will be included in the set of properties iterated over when this XML object is used in a for..in statement.
427 | 
428 | **Parameters:**
429 | 
430 | - `property`: the property to test.
431 | 
432 | **Returns:**
433 | 
434 | true when the property can be iterated in a for..in statement, false otherwise.
435 | 
436 | ---
437 | 
438 | ### text
439 | 
440 | **Signature:** `text() : XMLList`
441 | 
442 | **Description:** Calls the text() method of each XML object contained in this XMLList object and returns an XMLList containing the results concatenated in order.
443 | 
444 | **Returns:**
445 | 
446 | the concatenated results of calling the text() method of every XML object contained in this XMLList.
447 | 
448 | ---
449 | 
450 | ### toString
451 | 
452 | **Signature:** `toString() : String`
453 | 
454 | **Description:** Returns the String representation of this XMLList object.
455 | 
456 | **Returns:**
457 | 
458 | the String representation of this XMLList object.
459 | 
460 | ---
461 | 
462 | ### toXMLString
463 | 
464 | **Signature:** `toXMLString() : String`
465 | 
466 | **Description:** Returns an XML-encoded String representation of the XMLList object by calling the toXMLString method on each property contained within this XMLList object.
467 | 
468 | **Returns:**
469 | 
470 | an XML-encoded String representation of the XMLList object by calling the toXMLString method on each property contained within this XMLList object.
471 | 
472 | ---
473 | 
474 | ### valueOf
475 | 
476 | **Signature:** `valueOf() : XMLList`
477 | 
478 | **Description:** Returns this XMLList object.
479 | 
480 | **Returns:**
481 | 
482 | this XMLList object.
483 | 
484 | ---
```

--------------------------------------------------------------------------------
/docs-site/utils/toolsData.ts:
--------------------------------------------------------------------------------

```typescript
  1 | // Centralized metadata for MCP tools. Used by ToolsPage for dynamic rendering.
  2 | // Keeps descriptive, param, and example prompt info in one place for reuse.
  3 | 
  4 | export type ToolMode = 'docs' | 'full' | 'both';
  5 | export interface ToolParam {
  6 |   name: string;
  7 |   required?: boolean;
  8 |   description: string;
  9 | }
 10 | export interface ToolMeta {
 11 |   id: string; // unique id also used as anchor
 12 |   name: string; // tool name as exposed to MCP
 13 |   category: string;
 14 |   mode: ToolMode; // availability
 15 |   description: string;
 16 |   params?: ToolParam[];
 17 |   examples?: string[]; // example AI prompts or usage
 18 |   tags?: string[];
 19 |   popular?: boolean; // mark for quick actions
 20 | }
 21 | 
 22 | // Helper for brevity
 23 | const p = (name: string, description: string, required = true): ToolParam => ({ name, description, required });
 24 | 
 25 | export const TOOL_CATEGORIES = [
 26 |   'Documentation',
 27 |   'Best Practices',
 28 |   'SFRA Docs',
 29 |   'Cartridge Generation',
 30 |   'Log Analysis',
 31 |   'System Objects',
 32 |   'Code Versions'
 33 | ] as const;
 34 | 
 35 | export const tools: ToolMeta[] = [
 36 |   // Documentation (SFCC classes)
 37 |   {
 38 |     id: 'get-sfcc-class-info',
 39 |     name: 'get_sfcc_class_info',
 40 |     category: 'Documentation',
 41 |     mode: 'both',
 42 |     description: 'Detailed information about an SFCC class with filtering and search capabilities: properties, methods, descriptions.',
 43 |     params: [
 44 |       p('className', "SFCC class (e.g. 'Catalog' or 'dw.catalog.Catalog')"), 
 45 |       p('expand', 'Include referenced type details (boolean)', false),
 46 |       p('includeDescription', 'Include class description (boolean, default: true)', false),
 47 |       p('includeConstants', 'Include class constants (boolean, default: true)', false),
 48 |       p('includeProperties', 'Include class properties (boolean, default: true)', false),
 49 |       p('includeMethods', 'Include class methods (boolean, default: true)', false),
 50 |       p('includeInheritance', 'Include inheritance info (boolean, default: true)', false),
 51 |       p('search', 'Filter results by search term (string)', false)
 52 |     ],
 53 |     examples: [
 54 |       'Show methods and properties on dw.catalog.Product',
 55 |       'Show only methods for dw.system.Status class',
 56 |       'Search for "get" methods in dw.catalog.Product',
 57 |       'Show dw.order.Order class without description or constants',
 58 |       'Find "name" related properties and methods in dw.catalog.Product'
 59 |     ],
 60 |     tags: ['api','classes','introspection','filtering','search'],
 61 |     popular: true
 62 |   },
 63 |   { id: 'search-sfcc-classes', name: 'search_sfcc_classes', category: 'Documentation', mode: 'both', description: 'Search SFCC classes by partial name (single word).', params: [p('query', 'Search term (single word)')], examples: ['Find classes related to price','Search for catalog classes'], tags: ['search'], popular: true },
 64 |   { id: 'search-sfcc-methods', name: 'search_sfcc_methods', category: 'Documentation', mode: 'both', description: 'Search methods across all SFCC classes.', params: [p('methodName', 'Method name (single word)')], examples: ['Find get methods on system objects','Search for commit methods'], tags: ['methods','search'] },
 65 |   { id: 'list-sfcc-classes', name: 'list_sfcc_classes', category: 'Documentation', mode: 'both', description: 'List of all available SFCC classes.', examples: ['List all available SFCC classes'] },
 66 |   { id: 'get-sfcc-class-documentation', name: 'get_sfcc_class_documentation', category: 'Documentation', mode: 'both', description: 'Raw markdown documentation for an SFCC class.', params: [p('className','Exact class name')], examples: ['Get raw docs for dw.system.Logger'] },
 67 | 
 68 |   // Best Practices
 69 |   { id: 'get-available-best-practice-guides', name: 'get_available_best_practice_guides', category: 'Best Practices', mode: 'both', description: 'List all best practice guides.', examples: ['List available best practice guides'] },
 70 |   { id: 'get-best-practice-guide', name: 'get_best_practice_guide', category: 'Best Practices', mode: 'both', description: 'Full best practice guide content.', params: [p('guideName','Guide name (cartridge_creation, sfra_client_side_js, sfra_scss, security, performance, etc.)')], examples: ['Open the performance best practice guide'], tags: ['guides'] },
 71 |   { id: 'search-best-practices', name: 'search_best_practices', category: 'Best Practices', mode: 'both', description: 'Search within all best practice guides.', params: [p('query','Search term')], examples: ['Search best practices for caching'], tags: ['search'] },
 72 |   { id: 'get-hook-reference', name: 'get_hook_reference', category: 'Best Practices', mode: 'both', description: 'Hook reference tables for OCAPI or SCAPI.', params: [p('guideName','ocapi_hooks | scapi_hooks')], examples: ['List SCAPI hooks for product'] },
 73 | 
 74 |   // SFRA Docs
 75 |   { id: 'get-available-sfra-documents', name: 'get_available_sfra_documents', category: 'SFRA Docs', mode: 'both', description: 'List all SFRA documents and models.', examples: ['List SFRA docs categories'] },
 76 |   { id: 'get-sfra-document', name: 'get_sfra_document', category: 'SFRA Docs', mode: 'both', description: 'Full SFRA document (server, request, cart, product-full etc.).', params: [p('documentName','SFRA document name')], examples: ['Show the server module SFRA docs'] },
 77 |   { id: 'search-sfra-documentation', name: 'search_sfra_documentation', category: 'SFRA Docs', mode: 'both', description: 'Search across SFRA docs.', params: [p('query','Search term')], examples: ['Search SFRA docs for middleware'], tags: ['search'] },
 78 |   { id: 'get-sfra-categories', name: 'get_sfra_categories', category: 'SFRA Docs', mode: 'both', description: 'List SFRA document categories with counts.' },
 79 |   { id: 'get-sfra-documents-by-category', name: 'get_sfra_documents_by_category', category: 'SFRA Docs', mode: 'both', description: 'Get SFRA documents for a category.', params: [p('category','core|product|order|customer|pricing|store|other')], examples: ['List all order category SFRA docs'] },
 80 | 
 81 |   // Cartridge Generation
 82 |   { id: 'generate-cartridge-structure', name: 'generate_cartridge_structure', category: 'Cartridge Generation', mode: 'both', description: 'Generate cartridge directory structure.', params: [p('cartridgeName','Name of cartridge'), p('targetPath','Target path (optional)', false), p('fullProjectSetup','Include project scaffolding (boolean)', false)], examples: ['Generate cartridge named plugin_demo'], tags: ['scaffold'], popular: true },
 83 | 
 84 |   // Log Analysis (Full Mode)
 85 |   { id: 'get-latest-error', name: 'get_latest_error', category: 'Log Analysis', mode: 'full', description: 'Fetch latest error log entries.', params: [p('date','YYYYMMDD (optional defaults today)', false), p('limit','Number of entries', false)], examples: ['Show last 5 error log entries'], tags: ['logs','errors'], popular: true },
 86 |   { id: 'get-latest-warn', name: 'get_latest_warn', category: 'Log Analysis', mode: 'full', description: 'Fetch latest warn log entries.', params: [p('date','YYYYMMDD', false), p('limit','Entries', false)] },
 87 |   { id: 'get-latest-info', name: 'get_latest_info', category: 'Log Analysis', mode: 'full', description: 'Fetch latest info log entries.', params: [p('date','YYYYMMDD', false), p('limit','Entries', false)] },
 88 |   { id: 'get-latest-debug', name: 'get_latest_debug', category: 'Log Analysis', mode: 'full', description: 'Fetch latest debug log entries.', params: [p('date','YYYYMMDD', false), p('limit','Entries', false)] },
 89 |   { id: 'search-logs', name: 'search_logs', category: 'Log Analysis', mode: 'full', description: 'Search across logs for a pattern.', params: [p('pattern','Search string'), p('date','YYYYMMDD', false), p('limit','Entries', false), p('logLevel','error|warn|info|debug', false)], examples: ['Search logs for OCAPI 500 errors'], tags: ['search'] },
 90 |   { id: 'summarize-logs', name: 'summarize_logs', category: 'Log Analysis', mode: 'full', description: 'High level log activity summary.', params: [p('date','YYYYMMDD', false)], examples: ['Summarize today\'s logs'] },
 91 |   { id: 'list-log-files', name: 'list_log_files', category: 'Log Analysis', mode: 'full', description: 'List available log files with metadata.', examples: ['List available log files'] },
 92 |   { id: 'get-log-file-contents', name: 'get_log_file_contents', category: 'Log Analysis', mode: 'full', description: 'Fetch specific log file contents.', params: [p('filename','File name'), p('maxBytes','Max bytes', false), p('tailOnly','Tail only boolean', false)], examples: ['Show tail of error log'] },
 93 |   { id: 'get-latest-job-log-files', name: 'get_latest_job_log_files', category: 'Log Analysis', mode: 'full', description: 'List latest job log files.', params: [p('limit','Number of files', false)], examples: ['List latest 3 job log files'] },
 94 |   { id: 'get-job-log-entries', name: 'get_job_log_entries', category: 'Log Analysis', mode: 'full', description: 'Get job log entries filtered by level.', params: [p('jobName','Job name', false), p('level','error|warn|info|debug|all', false), p('limit','Entries', false)], examples: ['Get last 10 job log entries'] },
 95 |   { id: 'search-job-logs', name: 'search_job_logs', category: 'Log Analysis', mode: 'full', description: 'Search job logs for pattern.', params: [p('pattern','Search string'), p('jobName','Job name', false), p('limit','Entries', false), p('level','error|warn|info|debug|all', false)], examples: ['Search job logs for timeout'] },
 96 |   { id: 'search-job-logs-by-name', name: 'search_job_logs_by_name', category: 'Log Analysis', mode: 'full', description: 'Find job log files by job name.', params: [p('jobName','Partial job name'), p('limit','Files', false)], examples: ['Find job logs for OrderExport'] },
 97 |   { id: 'get-job-execution-summary', name: 'get_job_execution_summary', category: 'Log Analysis', mode: 'full', description: 'Execution summary for specific job.', params: [p('jobName','Job name')], examples: ['Summarize last execution of DailyFeed job'] },
 98 | 
 99 |   // System Objects
100 |   { id: 'get-system-object-definitions', name: 'get_system_object_definitions', category: 'System Objects', mode: 'full', description: 'All system object definitions with pagination support.', params: [p('start','Start index', false), p('count','Max count', false), p('select','Property selector', false)], examples: ['List system object definitions', 'Get first 10 system objects', 'Get system objects starting from index 5'], tags: ['objects'], popular: true },
101 |   { id: 'get-system-object-definition', name: 'get_system_object_definition', category: 'System Objects', mode: 'full', description: 'Specific system object metadata.', params: [p('objectType','Object type e.g. Product')], examples: ['Get definition for Product object'] },
102 |   { id: 'search-system-object-attribute-definitions', name: 'search_system_object_attribute_definitions', category: 'System Objects', mode: 'full', description: 'Search attributes for a system object.', params: [p('objectType','System object type'), p('searchRequest','Search request body')], examples: ['Search Product attributes for inventory fields'] },
103 |   { id: 'search-system-object-attribute-groups', name: 'search_system_object_attribute_groups', category: 'System Objects', mode: 'full', description: 'Search attribute groups for a system object.', params: [p('objectType','System object type'), p('searchRequest','Search request body')], examples: ['List attribute groups for Product object'] },
104 |   { id: 'search-site-preferences', name: 'search_site_preferences', category: 'System Objects', mode: 'full', description: 'Search site preferences within a group.', params: [p('groupId','Preference group ID'), p('searchRequest','Search request body')], examples: ['Search site preferences in SitePreferencesMarketing group'] },
105 |   { id: 'search-custom-object-attribute-definitions', name: 'search_custom_object_attribute_definitions', category: 'System Objects', mode: 'full', description: 'Search custom object attributes.', params: [p('objectType','Custom object type'), p('searchRequest','Search request body')], examples: ['Search custom object attributes for Global_String'] },
106 | 
107 |   // Code Versions
108 |   { id: 'get-code-versions', name: 'get_code_versions', category: 'Code Versions', mode: 'full', description: 'List all code versions.', examples: ['List available code versions'], popular: true },
109 |   { id: 'activate-code-version', name: 'activate_code_version', category: 'Code Versions', mode: 'full', description: 'Activate a specific code version.', params: [p('codeVersionId','ID of code version')], examples: ['Activate code version int_2025_09'] }
110 | ];
111 | 
112 | export const popularTools = tools.filter(t => t.popular);
113 | export const categoriesWithCounts = TOOL_CATEGORIES.map(cat => ({
114 |   name: cat,
115 |   count: tools.filter(t => t.category === cat).length
116 | }));
117 | 
```

--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/scripts/setup-logs.js:
--------------------------------------------------------------------------------

```javascript
  1 | const fs = require('fs');
  2 | const path = require('path');
  3 | 
  4 | /**
  5 |  * Setup Script for Mock SFCC Log Files
  6 |  * 
  7 |  * This script creates a realistic directory structure and log files
  8 |  * that mimic the SFCC WebDAV log system for testing purposes.
  9 |  */
 10 | 
 11 | class MockLogGenerator {
 12 |     constructor() {
 13 |         this.baseDir = path.join(__dirname, '../mock-data');
 14 |         this.logsDir = path.join(this.baseDir, 'logs');
 15 |         this.jobsDir = path.join(this.logsDir, 'jobs');
 16 |         
 17 |         // Current date for log file naming
 18 |         this.today = new Date();
 19 |         this.dateString = this.formatDate(this.today);
 20 |         this.timeString = this.formatTime(this.today);
 21 |     }
 22 | 
 23 |     formatDate(date) {
 24 |         const year = date.getFullYear();
 25 |         const month = String(date.getMonth() + 1).padStart(2, '0');
 26 |         const day = String(date.getDate()).padStart(2, '0');
 27 |         return `${year}${month}${day}`;
 28 |     }
 29 | 
 30 |     formatTime(date) {
 31 |         const hours = String(date.getHours()).padStart(2, '0');
 32 |         const minutes = String(date.getMinutes()).padStart(2, '0');
 33 |         const seconds = String(date.getSeconds()).padStart(2, '0');
 34 |         return `${hours}${minutes}${seconds}`;
 35 |     }
 36 | 
 37 |     formatLogTimestamp(date) {
 38 |         // Format like real SFCC logs: [2025-09-14 12:00:00.000 GMT]
 39 |         const year = date.getFullYear();
 40 |         const month = String(date.getMonth() + 1).padStart(2, '0');
 41 |         const day = String(date.getDate()).padStart(2, '0');
 42 |         const hours = String(date.getHours()).padStart(2, '0');
 43 |         const minutes = String(date.getMinutes()).padStart(2, '0');
 44 |         const seconds = String(date.getSeconds()).padStart(2, '0');
 45 |         const milliseconds = String(date.getMilliseconds()).padStart(3, '0');
 46 |         return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`;
 47 |     }
 48 | 
 49 |     ensureDirectoryExists(dirPath) {
 50 |         if (!fs.existsSync(dirPath)) {
 51 |             fs.mkdirSync(dirPath, { recursive: true });
 52 |             console.log(`📁 Created directory: ${dirPath}`);
 53 |         }
 54 |     }
 55 | 
 56 |     generateErrorLogs() {
 57 |         // Create timestamps with specific ordering - oldest first for proper log file structure
 58 |         const baseTime = new Date();
 59 |         const timestamps = [
 60 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest)
 61 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later
 62 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later
 63 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later  
 64 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 5000))  // 5 seconds later (newest)
 65 |         ];
 66 |         
 67 |         const errorEntries = [
 68 |             `[${timestamps[0]} GMT] ERROR PipelineCallServlet|1645761595|Sites-RefArchGlobal-Site|Cart-AddProduct|PipelineCall|nYJXtqnEfz custom [] Custom cartridge error: Unable to connect to external service`,
 69 |             `[${timestamps[1]} GMT] ERROR SystemJobThread|1581553813|sfcc-catalog-import|ImportCatalogStep com.demandware.beehive.core.internal.catalog.CatalogMgr Sites-Site JOB abc123def456 - Product import failed: Invalid category assignment`,
 70 |             `[${timestamps[2]} GMT] ERROR PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|V5YDtxRLpL custom [] Customer profile creation failed: Email already exists`,
 71 |             `[${timestamps[3]} GMT] ERROR PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|Qq38CuNXpX custom [] Payment authorization failed for order ORDER-000001234`,
 72 |             `[${timestamps[4]} GMT] ERROR SystemJobThread|1645761595|sfcc-download-gdpr-einstein-response-files-for-einstein|DownloadGDPRLogFiles com.demandware.component.transaction.cquotient.feed.s3.S3Store Sites-Site JOB bce341cf01 fd3d5c567c091a16392d5b865e 4815298613491841024 - CQ - AWS S3 Configuration Issue: bucketName is missing.`
 73 |         ];
 74 | 
 75 |         const errorContent = errorEntries.join('\n') + '\n';
 76 |         const errorFile = path.join(this.logsDir, `error-blade-${this.dateString}-${this.timeString}.log`);
 77 |         fs.writeFileSync(errorFile, errorContent);
 78 |         console.log(`📄 Created error log: ${errorFile}`);
 79 |     }
 80 | 
 81 |     generateWarnLogs() {
 82 |         // Create timestamps with specific ordering - oldest first for proper log file structure
 83 |         const baseTime = new Date();
 84 |         const timestamps = [
 85 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest)
 86 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later
 87 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later
 88 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later  
 89 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 5000))  // 5 seconds later (newest)
 90 |         ];
 91 |         
 92 |         const warnEntries = [
 93 |             `[${timestamps[0]} GMT] WARN PipelineCallServlet|1645761595|Sites-RefArchGlobal-Site|Product-Show|PipelineCall|AbcDef123G custom [] Product inventory low: SKU-789-XYZ has only 2 units remaining`,
 94 |             `[${timestamps[1]} GMT] WARN PipelineCallServlet|1581553813|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|nYJXtqnEfz custom [] Content asset with ID cookie_hint is offline`,
 95 |             `[${timestamps[2]} GMT] WARN PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|290fx4tnVR custom [] Content asset with ID cookie_hint is offline`,
 96 |             `[${timestamps[3]} GMT] WARN PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|V5YDtxRLpL custom [] Content asset with ID cookie_hint is offline`,
 97 |             `[${timestamps[4]} GMT] WARN PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|Qq38CuNXpX custom [] Content asset with ID cookie_hint is offline`
 98 |         ];
 99 | 
100 |         const warnContent = warnEntries.join('\n') + '\n';
101 |         const warnFile = path.join(this.logsDir, `warn-blade-${this.dateString}-${this.timeString}.log`);
102 |         fs.writeFileSync(warnFile, warnContent);
103 |         console.log(`📄 Created warn log: ${warnFile}`);
104 |     }
105 | 
106 |     generateInfoLogs() {
107 |         // Create timestamps with specific ordering - oldest first for proper log file structure
108 |         const baseTime = new Date();
109 |         const timestamps = [
110 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest)
111 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later
112 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later
113 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later  
114 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 5000))  // 5 seconds later (newest)
115 |         ];
116 |         
117 |         const infoEntries = [
118 |             `[${timestamps[0]} GMT] INFO SystemJobThread|1581553813|sfcc-process-orders|ProcessOrdersStep com.demandware.beehive.core.internal.job.JobMgr Sites-Site JOB abc123def456 - Job started: ProcessOrders`,
119 |             `[${timestamps[1]} GMT] INFO PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Account-SubmitRegistration|PipelineCall|V5YDtxRLpL custom [] Customer registration completed: customer.id=123456789`,
120 |             `[${timestamps[2]} GMT] INFO PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Order-Confirm|PipelineCall|AbcDef123G custom [] Order created successfully: ORDER-000001234`,
121 |             `[${timestamps[3]} GMT] INFO SystemJobThread|67038033|sfcc-export-dw-analytics-site-config|ExportDWAnalyticsSiteConfigurationStep Executing step [ExportDWAnalyticsSiteConfigurationStep][5846619] for [Organization]...`,
122 |             `[${timestamps[4]} GMT] INFO SystemJobThread|67038033|sfcc-export-dw-analytics-site-config Executing job [sfcc-export-dw-analytics-site-config][2664334]...`
123 |         ];
124 | 
125 |         const infoContent = infoEntries.join('\n') + '\n';
126 |         const infoFile = path.join(this.logsDir, `info-blade-${this.dateString}-${this.timeString}.log`);
127 |         fs.writeFileSync(infoFile, infoContent);
128 |         console.log(`📄 Created info log: ${infoFile}`);
129 |     }
130 | 
131 |     generateDebugLogs() {
132 |         // Create timestamps with specific ordering - oldest first for proper log file structure
133 |         const baseTime = new Date();
134 |         const timestamps = [
135 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest)
136 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later
137 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later
138 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later  
139 |             this.formatLogTimestamp(new Date(baseTime.getTime() + 5000))  // 5 seconds later (newest)
140 |         ];
141 |         
142 |         const debugEntries = [
143 |             `[${timestamps[0]} GMT] DEBUG PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Account-Show|PipelineCall|290fx4tnVR custom [] Customer session validated: session timeout extended`,
144 |             `[${timestamps[1]} GMT] DEBUG PipelineCallServlet|1645761595|Sites-RefArchGlobal-Site|Cart-Show|PipelineCall|nYJXtqnEfz custom [] Basket calculation: 3 items, subtotal $149.99`,
145 |             `[${timestamps[2]} GMT] DEBUG SystemJobThread|1581553813|sfcc-data-replication|DataReplicationStep com.demandware.beehive.core.internal.system.SystemMgr Sites-Site JOB abc123def456 - Data replication sync started`,
146 |             `[${timestamps[3]} GMT] DEBUG PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Search-Show|PipelineCall|V5YDtxRLpL custom [] Search query executed: 'laptop' returned 45 results`,
147 |             `[${timestamps[4]} GMT] DEBUG PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Product-Show|PipelineCall|AbcDef123G custom [] Product cache hit: SKU ABC-123-XYZ`
148 |         ];
149 | 
150 |         const debugContent = debugEntries.join('\n') + '\n';
151 |         const debugFile = path.join(this.logsDir, `debug-blade-${this.dateString}-${this.timeString}.log`);
152 |         fs.writeFileSync(debugFile, debugContent);
153 |         console.log(`📄 Created debug log: ${debugFile}`);
154 |     }
155 | 
156 |     generateJobLogs() {
157 |         // Create job directories and logs
158 |         const jobs = [
159 |             { 
160 |                 name: 'ProcessOrders', 
161 |                 id: '1234567890',
162 |                 steps: ['ValidateOrdersStep', 'ProcessPaymentsStep', 'UpdateInventoryStep']
163 |             },
164 |             { 
165 |                 name: 'ImportCatalog', 
166 |                 id: '0987654321',
167 |                 steps: ['ValidateCatalogStep', 'ImportProductsStep', 'IndexProductsStep']
168 |             }
169 |         ];
170 | 
171 |         jobs.forEach(job => {
172 |             const jobDir = path.join(this.jobsDir, job.name);
173 |             this.ensureDirectoryExists(jobDir);
174 | 
175 |             const timestamp = this.formatLogTimestamp(new Date());
176 |             
177 |             const jobEntries = [
178 |                 `[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name} Executing job [${job.name}][${job.id}]...`
179 |             ];
180 | 
181 |             // Add step entries
182 |             job.steps.forEach(step => {
183 |                 jobEntries.push(
184 |                     `[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name}|${step} Executing step [${step}] for [Organization]...`,
185 |                     `[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name}|${step} Step [${step}] completed successfully`
186 |                 );
187 |             });
188 | 
189 |             jobEntries.push(`[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name} Execution of job finished with status [OK].`);
190 | 
191 |             const jobContent = jobEntries.join('\n') + '\n';
192 |             const jobFile = path.join(jobDir, `Job-${job.name}-${job.id}.log`);
193 |             fs.writeFileSync(jobFile, jobContent);
194 |             console.log(`📄 Created job log: ${jobFile}`);
195 |         });
196 |     }
197 | 
198 |     run() {
199 |         console.log('🚀 Starting mock log generation...');
200 |         
201 |         // Ensure directories exist
202 |         this.ensureDirectoryExists(this.baseDir);
203 |         this.ensureDirectoryExists(this.logsDir);
204 |         this.ensureDirectoryExists(this.jobsDir);
205 | 
206 |         // Generate all log types
207 |         this.generateErrorLogs();
208 |         this.generateWarnLogs();
209 |         this.generateInfoLogs();
210 |         this.generateDebugLogs();
211 |         this.generateJobLogs();
212 | 
213 |         console.log('✅ Mock log generation completed!');
214 |         console.log(`� Logs created in: ${this.logsDir}`);
215 |     }
216 | }
217 | 
218 | // Run the generator if called directly
219 | if (require.main === module) {
220 |     const generator = new MockLogGenerator();
221 |     generator.run();
222 | }
223 | 
224 | module.exports = MockLogGenerator;
```

--------------------------------------------------------------------------------
/docs/dw_content/MediaFile.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.content
  2 | 
  3 | # Class MediaFile
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.content.MediaFile
  9 | 
 10 | ## Description
 11 | 
 12 | This class represents references to media content (such as images) located within Commerce Cloud Digital or on external systems. Parameter transform: Some methods allow the specification of image transformation parameters. Image transformation is only performed if the Dynamic Imaging Service (DIS) is available for the Commerce Cloud Digital instance, otherwise a standard static content URL is returned. The to-be-transformed image needs to be hosted on Commerce Cloud Digital. Image transformation parameters are specified as JavaScript object literal. They are translated into URL parameters. See Create Image Transformation URLs. Type of transformation Parameters Description Scale an image scaleWidth scaleHeight scaleMode The scaleWidth and scaleHeight parameters are both integers; setting one of these parameters triggers a scaling operation. If both are provided, the one that scales the image less is used to calculate the scale factor. The image is then automatically cropped accord to the second dimension, with a centered position of the cropped area. If the parameter would scale the image larger, only this operation is applied, if the image remains within acceptable pixel dimensions. Note: scaleMode can only be used in combination with scaleHeight and scaleWidth. The scaleMode parameter can be set to cut or fit. The default scaleMode is cut, the behavior of which is explained above. If you specify fit as the scaleMode, the system scales the image into the given box of dimensions while keeping the aspect ratio (possibly resulting in a smaller image in one dimension). Overlay an image imageX imageY imageURI The imageX and imageY parameters are both integers. Valid values for these parameters are 0 or greater. Supported formats are png, jpg, jp2, and gif. The imageURI parameter can be set to the absolute path of the overlaid image. The value of the imageURI parameter must be given in proper URL encoding, and it cannot exceed 400 characters in length. The path may include query string parameters, which supports dynamically generating the overlaid image itself through this service; that is, the overlaid image can itself be a transformed image. If the overlaid image extends over the primary image's boundaries, the overlaid image is cropped so that it fits directly over the primary image. Crop an image cropX cropY cropWidth cropHeight The cropX, cropY, cropWidth, cropHeight parameters are integers. All four parameters must be specified to trigger a cropping operation. Valid values for the cropX and cropY parameters are 0 or greater. If the crop location defined by cropX and cropY is outside the image area, nothing is cropped. Valid values for the cropWidth and cropHeight parameters are 10 or greater. If the cropWidth and cropHeight parameters specify a size that is greater than the original image, the crop area is reduced to the actual image area. If cropWidth and cropHeight are 0 or less, no transformation is applied. Format an image format The format parameter specifies the target format of image. Supported formats are png, jpg, jp2, and gif. If no target format is specified, no format conversion is performed. The attribute value must reference the source image. Source image's format is recognized by the file extension which must be tif, tiff, jpg, jpeg, png, or gif. In the generated URL the file extension of the target format is used in the URL path. This is to make sure the image is loaded from an URL with a matching file extension. The source format is provided as URL parameter. Adjust image compression quality quality The quality parameter specifies a quality setting for jpg and jp2 images, and specifies the compression level for png images. For jpg and jp2 images, you can set values from 1–100 for the highest quality. The default quality is 80. If you're not changing the default quality, you don't need to pass in a value. For png images, the quality setting has no effect on the appearance of the png, since the compression is always lossless. Instead you can use the quality setting to set the zlib compression level and filter-type for PNG images. The tens digit sets the zlib compression level(1-9). The ones digit sets the filter type. If the png setting is not present or set to 0, it uses a default value of 75. If this setting is set to 100, it actually equals the quality setting 90. Adjust Metadata stripping strip The strip parameter specifies if metadata like EXIF and color profiles is stripped from the image during transformation. Valid values for the strip parameter are between true and false. The default is true Change background color bgcolor(color) or bgcolor(color+alpha) The bgcolor parameter specifies the background color for images that support transparency as well as JPEG images when being converted from a format that supports transparency. Optionally, alpha setting for PNG images are also supported. bgcolor expects a 6 digit hexadecimal value of RGB with an optional two hexadecimal characters representing alpha value that determines transparency. FF0000 = Red FF000077 = Red with 50% transparency Alpha values are optional. When the alpha value is omitted, the resulting color is opaque. Alpha values are only valid when the image output format is PNG. Example: The following code var url = product.getImage('thumbnail', 0).getImageURL({scaleWidth: 100, format: 'jpg'}); will produce an image transformation URL like http://<image server host name>/.../on/demandware.static/.../<path to image>/image.jpg?sw=100&sfrm=png.
 13 | 
 14 | ## Properties
 15 | 
 16 | ### absURL
 17 | 
 18 | **Type:** URL (Read Only)
 19 | 
 20 | An absolute URL to the referenced media file. The
 21 |  protocol for the reference is the current protocol of the current
 22 |  HTTP request.
 23 | 
 24 | ### alt
 25 | 
 26 | **Type:** String (Read Only)
 27 | 
 28 | The alternative text assigned to the media file in current
 29 |  requests locale. If no alternative text was assigned or if no defaulting
 30 |  rule was defined, the method returns null.
 31 | 
 32 | ### httpsURL
 33 | 
 34 | **Type:** URL (Read Only)
 35 | 
 36 | An absolute URL to the referenced media file. The
 37 |  protocol is https.
 38 | 
 39 | ### httpURL
 40 | 
 41 | **Type:** URL (Read Only)
 42 | 
 43 | An absolute URL to the referenced media file. The
 44 |  protocol is http.
 45 | 
 46 | ### title
 47 | 
 48 | **Type:** String (Read Only)
 49 | 
 50 | The title assigned to the media file in current requests locale.
 51 |  If no title was assigned or if no defaulting rule was defined, the
 52 |  method returns null.
 53 | 
 54 | ### url
 55 | 
 56 | **Type:** URL (Read Only)
 57 | 
 58 | An URL to the referenced media file. The
 59 |  returned URL is a relative URL.
 60 | 
 61 | ### URL
 62 | 
 63 | **Type:** URL (Read Only)
 64 | 
 65 | An URL to the referenced media file. The
 66 |  returned URL is a relative URL.
 67 | 
 68 | ### viewType
 69 | 
 70 | **Type:** String (Read Only)
 71 | 
 72 | The view type annotation for the media file. The method returns
 73 |  null, if the media file has no view type annotation.
 74 | 
 75 | ## Constructor Summary
 76 | 
 77 | ## Method Summary
 78 | 
 79 | ### getAbsImageURL
 80 | 
 81 | **Signature:** `getAbsImageURL(transform : Object) : URL`
 82 | 
 83 | Returns an URL to the referenced image file.
 84 | 
 85 | ### getAbsURL
 86 | 
 87 | **Signature:** `getAbsURL() : URL`
 88 | 
 89 | Returns an absolute URL to the referenced media file.
 90 | 
 91 | ### getAlt
 92 | 
 93 | **Signature:** `getAlt() : String`
 94 | 
 95 | Returns the alternative text assigned to the media file in current requests locale.
 96 | 
 97 | ### getHttpImageURL
 98 | 
 99 | **Signature:** `getHttpImageURL(transform : Object) : URL`
100 | 
101 | Returns an URL to the referenced image file.
102 | 
103 | ### getHttpsImageURL
104 | 
105 | **Signature:** `getHttpsImageURL(transform : Object) : URL`
106 | 
107 | Returns an URL to the referenced image file.
108 | 
109 | ### getHttpsURL
110 | 
111 | **Signature:** `getHttpsURL() : URL`
112 | 
113 | Returns an absolute URL to the referenced media file.
114 | 
115 | ### getHttpURL
116 | 
117 | **Signature:** `getHttpURL() : URL`
118 | 
119 | Returns an absolute URL to the referenced media file.
120 | 
121 | ### getImageURL
122 | 
123 | **Signature:** `getImageURL(transform : Object) : URL`
124 | 
125 | Returns an URL to the referenced image file.
126 | 
127 | ### getTitle
128 | 
129 | **Signature:** `getTitle() : String`
130 | 
131 | Returns the title assigned to the media file in current requests locale.
132 | 
133 | ### getUrl
134 | 
135 | **Signature:** `getUrl() : URL`
136 | 
137 | Returns an URL to the referenced media file.
138 | 
139 | ### getURL
140 | 
141 | **Signature:** `getURL() : URL`
142 | 
143 | Returns an URL to the referenced media file.
144 | 
145 | ### getViewType
146 | 
147 | **Signature:** `getViewType() : String`
148 | 
149 | Returns the view type annotation for the media file.
150 | 
151 | ## Method Detail
152 | 
153 | ## Method Details
154 | 
155 | ### getAbsImageURL
156 | 
157 | **Signature:** `getAbsImageURL(transform : Object) : URL`
158 | 
159 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. The protocol for the reference is the current protocol of the current HTTP request. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital.
160 | 
161 | **Parameters:**
162 | 
163 | - `transform`: Object with transformation parameters (see class header)
164 | 
165 | **Returns:**
166 | 
167 | an absolute URL to the referenced media file. The protocol for the reference is the current protocol of the current HTTP request. If the referenced media file is hosted externally, an URL to the external file is returned.
168 | 
169 | ---
170 | 
171 | ### getAbsURL
172 | 
173 | **Signature:** `getAbsURL() : URL`
174 | 
175 | **Description:** Returns an absolute URL to the referenced media file. The protocol for the reference is the current protocol of the current HTTP request.
176 | 
177 | **Returns:**
178 | 
179 | an absolute URL to the referenced media file. The protocol for the reference is the current protocol of the current HTTP request.
180 | 
181 | ---
182 | 
183 | ### getAlt
184 | 
185 | **Signature:** `getAlt() : String`
186 | 
187 | **Description:** Returns the alternative text assigned to the media file in current requests locale. If no alternative text was assigned or if no defaulting rule was defined, the method returns null.
188 | 
189 | **Returns:**
190 | 
191 | the alternative text annotated to this media file or null
192 | 
193 | ---
194 | 
195 | ### getHttpImageURL
196 | 
197 | **Signature:** `getHttpImageURL(transform : Object) : URL`
198 | 
199 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. The protocol is http. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital.
200 | 
201 | **Parameters:**
202 | 
203 | - `transform`: Object with transformation parameters (see class header)
204 | 
205 | **Returns:**
206 | 
207 | an absolute URL to the referenced media file. The protocol is http. If the referenced media file is hosted externally, an URL to the external file is returned.
208 | 
209 | ---
210 | 
211 | ### getHttpsImageURL
212 | 
213 | **Signature:** `getHttpsImageURL(transform : Object) : URL`
214 | 
215 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. The protocol is https. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital.
216 | 
217 | **Parameters:**
218 | 
219 | - `transform`: Object with transformation parameters (see class header)
220 | 
221 | **Returns:**
222 | 
223 | an absolute URL to the referenced media file. The protocol is https. If the referenced media file is hosted externally, an URL to the external file is returned.
224 | 
225 | ---
226 | 
227 | ### getHttpsURL
228 | 
229 | **Signature:** `getHttpsURL() : URL`
230 | 
231 | **Description:** Returns an absolute URL to the referenced media file. The protocol is https.
232 | 
233 | **Returns:**
234 | 
235 | an absolute URL to the referenced media file. The protocol is https.
236 | 
237 | ---
238 | 
239 | ### getHttpURL
240 | 
241 | **Signature:** `getHttpURL() : URL`
242 | 
243 | **Description:** Returns an absolute URL to the referenced media file. The protocol is http.
244 | 
245 | **Returns:**
246 | 
247 | an absolute URL to the referenced media file. The protocol is http.
248 | 
249 | ---
250 | 
251 | ### getImageURL
252 | 
253 | **Signature:** `getImageURL(transform : Object) : URL`
254 | 
255 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital.
256 | 
257 | **Parameters:**
258 | 
259 | - `transform`: Object with transformation parameters (see class header)
260 | 
261 | **Returns:**
262 | 
263 | an URL to the referenced media file. The returned URL is a relative URL. If the referenced media file is hosted externally, an URL to the external file is returned.
264 | 
265 | ---
266 | 
267 | ### getTitle
268 | 
269 | **Signature:** `getTitle() : String`
270 | 
271 | **Description:** Returns the title assigned to the media file in current requests locale. If no title was assigned or if no defaulting rule was defined, the method returns null.
272 | 
273 | **Returns:**
274 | 
275 | the title annotated to this media file or null
276 | 
277 | ---
278 | 
279 | ### getUrl
280 | 
281 | **Signature:** `getUrl() : URL`
282 | 
283 | **Description:** Returns an URL to the referenced media file. The returned URL is a relative URL.
284 | 
285 | **Deprecated:**
286 | 
287 | Use getURL() instead.
288 | 
289 | **Returns:**
290 | 
291 | an URL to the referenced media file. The returned URL is a relative URL.
292 | 
293 | ---
294 | 
295 | ### getURL
296 | 
297 | **Signature:** `getURL() : URL`
298 | 
299 | **Description:** Returns an URL to the referenced media file. The returned URL is a relative URL.
300 | 
301 | **Returns:**
302 | 
303 | an URL to the referenced media file. The returned URL is a relative URL.
304 | 
305 | ---
306 | 
307 | ### getViewType
308 | 
309 | **Signature:** `getViewType() : String`
310 | 
311 | **Description:** Returns the view type annotation for the media file. The method returns null, if the media file has no view type annotation.
312 | 
313 | **Returns:**
314 | 
315 | the view type annotated to this media file or null
316 | 
317 | ---
```

--------------------------------------------------------------------------------
/docs/dw_campaign/CampaignMgr.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.campaign
  2 | 
  3 | # Class CampaignMgr
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.campaign.CampaignMgr
  9 | 
 10 | ## Description
 11 | 
 12 | CampaignMgr provides static methods for managing campaign-specific operations such as accessing promotions or updating promotion line items.
 13 | 
 14 | ## Properties
 15 | 
 16 | ### applicablePromotions
 17 | 
 18 | **Type:** Collection (Read Only)
 19 | 
 20 | The enabled promotions of active campaigns applicable for the
 21 |  current customer and source code.
 22 |  
 23 |  Note that this method does not return any coupon-based promotions.
 24 | 
 25 | ## Constructor Summary
 26 | 
 27 | ## Method Summary
 28 | 
 29 | ### applyBonusPromotions
 30 | 
 31 | **Signature:** `static applyBonusPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
 32 | 
 33 | This method has been deprecated and should not be used anymore.
 34 | 
 35 | ### applyOrderPromotions
 36 | 
 37 | **Signature:** `static applyOrderPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
 38 | 
 39 | Applies the applicable order promotions in the specified collection to the specified line item container.
 40 | 
 41 | ### applyProductPromotions
 42 | 
 43 | **Signature:** `static applyProductPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
 44 | 
 45 | Applies all applicable product promotions in the specified collection to the specified line item container.
 46 | 
 47 | ### applyShippingPromotions
 48 | 
 49 | **Signature:** `static applyShippingPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
 50 | 
 51 | Applies all applicable shipping promotions in the specified collection to the specified line item container.
 52 | 
 53 | ### getApplicableConditionalPromotions
 54 | 
 55 | **Signature:** `static getApplicableConditionalPromotions(product : Product) : Collection`
 56 | 
 57 | Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a qualifiying product.
 58 | 
 59 | ### getApplicablePromotions
 60 | 
 61 | **Signature:** `static getApplicablePromotions(product : Product) : Collection`
 62 | 
 63 | Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a discounted product.
 64 | 
 65 | ### getApplicablePromotions
 66 | 
 67 | **Signature:** `static getApplicablePromotions(lineItemCtnr : LineItemCtnr) : Collection`
 68 | 
 69 | Returns the enabled promotions of active campaigns applicable for the current customer, source code and any coupon contained in the specified line item container.
 70 | 
 71 | ### getApplicablePromotions
 72 | 
 73 | **Signature:** `static getApplicablePromotions() : Collection`
 74 | 
 75 | Returns the enabled promotions of active campaigns applicable for the current customer and source code.
 76 | 
 77 | ### getCampaignByID
 78 | 
 79 | **Signature:** `static getCampaignByID(id : String) : Campaign`
 80 | 
 81 | Returns the campaign identified by the specified ID.
 82 | 
 83 | ### getConditionalPromotions
 84 | 
 85 | **Signature:** `static getConditionalPromotions(product : Product) : Collection`
 86 | 
 87 | Returns the enabled promotions of active campaigns for which the specified product is a qualifiying product.
 88 | 
 89 | ### getPromotion
 90 | 
 91 | **Signature:** `static getPromotion(couponCode : String) : Promotion`
 92 | 
 93 | Returns the promotion associated with the specified coupon code.
 94 | 
 95 | ### getPromotionByCouponCode
 96 | 
 97 | **Signature:** `static getPromotionByCouponCode(couponCode : String) : Promotion`
 98 | 
 99 | Returns the promotion associated with the specified coupon code.
100 | 
101 | ### getPromotionByID
102 | 
103 | **Signature:** `static getPromotionByID(id : String) : Promotion`
104 | 
105 | Returns the promotion identified by the specified ID.
106 | 
107 | ### getPromotions
108 | 
109 | **Signature:** `static getPromotions(product : Product) : Collection`
110 | 
111 | Returns the enabled promotions of active campaigns for which the specified product is a discounted product.
112 | 
113 | ## Method Detail
114 | 
115 | ## Method Details
116 | 
117 | ### applyBonusPromotions
118 | 
119 | **Signature:** `static applyBonusPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
120 | 
121 | **Description:** This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. The method does nothing, since bonus promotions are applied as product or order promotions using methods applyProductPromotions(LineItemCtnr, Collection) and applyOrderPromotions(LineItemCtnr, Collection). The method returns 'true' if any the line item container contains any bonus product line items, and otherwise false.
122 | 
123 | **Deprecated:**
124 | 
125 | Use PromotionMgr instead.
126 | 
127 | **Parameters:**
128 | 
129 | - `lineItemCtnr`: Basket or order
130 | - `promotions`: Parameter not used, can be null
131 | 
132 | **Returns:**
133 | 
134 | True if line item container contains bonus product line items, else false
135 | 
136 | ---
137 | 
138 | ### applyOrderPromotions
139 | 
140 | **Signature:** `static applyOrderPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
141 | 
142 | **Description:** Applies the applicable order promotions in the specified collection to the specified line item container. This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. Note that the method does also apply any bonus discounts defined as order promotions (see also applyBonusPromotions(LineItemCtnr, Collection)).
143 | 
144 | **Deprecated:**
145 | 
146 | Use PromotionMgr
147 | 
148 | **Parameters:**
149 | 
150 | - `lineItemCtnr`: basket or order
151 | - `promotions`: list of all promotions to be applied
152 | 
153 | **Returns:**
154 | 
155 | true if changes were made to the line item container, false otherwise.
156 | 
157 | ---
158 | 
159 | ### applyProductPromotions
160 | 
161 | **Signature:** `static applyProductPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
162 | 
163 | **Description:** Applies all applicable product promotions in the specified collection to the specified line item container. This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. Note that the method does also apply any bonus discounts defined as product promotions (see also applyBonusPromotions(LineItemCtnr, Collection)).
164 | 
165 | **Deprecated:**
166 | 
167 | Use PromotionMgr
168 | 
169 | **Parameters:**
170 | 
171 | - `lineItemCtnr`: basket or order
172 | - `promotions`: list of all promotions to be applied
173 | 
174 | **Returns:**
175 | 
176 | true if changes were made to the line item container, false otherwise.
177 | 
178 | ---
179 | 
180 | ### applyShippingPromotions
181 | 
182 | **Signature:** `static applyShippingPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean`
183 | 
184 | **Description:** Applies all applicable shipping promotions in the specified collection to the specified line item container. This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers.
185 | 
186 | **Deprecated:**
187 | 
188 | Use PromotionMgr
189 | 
190 | **Parameters:**
191 | 
192 | - `lineItemCtnr`: basket or order
193 | - `promotions`: list of all promotions to be applied
194 | 
195 | **Returns:**
196 | 
197 | true if changes were made to the line item container, false otherwise.
198 | 
199 | ---
200 | 
201 | ### getApplicableConditionalPromotions
202 | 
203 | **Signature:** `static getApplicableConditionalPromotions(product : Product) : Collection`
204 | 
205 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a qualifiying product. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getApplicableConditionalPromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product.
206 | 
207 | **Deprecated:**
208 | 
209 | Use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product)
210 | 
211 | **Parameters:**
212 | 
213 | - `product`: Qualifying product
214 | 
215 | **Returns:**
216 | 
217 | List of active promotions
218 | 
219 | ---
220 | 
221 | ### getApplicablePromotions
222 | 
223 | **Signature:** `static getApplicablePromotions(product : Product) : Collection`
224 | 
225 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a discounted product. Note that this method does not return any coupon-based promotions. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getApplicablePromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product.
226 | 
227 | **Deprecated:**
228 | 
229 | Use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product)
230 | 
231 | **Parameters:**
232 | 
233 | - `product`: The product whose promotions are returned.
234 | 
235 | **Returns:**
236 | 
237 | A list of promotions
238 | 
239 | ---
240 | 
241 | ### getApplicablePromotions
242 | 
243 | **Signature:** `static getApplicablePromotions(lineItemCtnr : LineItemCtnr) : Collection`
244 | 
245 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer, source code and any coupon contained in the specified line item container. Note that although the method has been deprecated, no replacement method is provided.
246 | 
247 | **Deprecated:**
248 | 
249 | There is no replacement for this method.
250 | 
251 | **Parameters:**
252 | 
253 | - `lineItemCtnr`: the basket or order
254 | 
255 | **Returns:**
256 | 
257 | list of all applicable promotion for the given basket or order
258 | 
259 | ---
260 | 
261 | ### getApplicablePromotions
262 | 
263 | **Signature:** `static getApplicablePromotions() : Collection`
264 | 
265 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer and source code. Note that this method does not return any coupon-based promotions.
266 | 
267 | **Deprecated:**
268 | 
269 | Use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getPromotions()
270 | 
271 | **Returns:**
272 | 
273 | List of active promotions
274 | 
275 | ---
276 | 
277 | ### getCampaignByID
278 | 
279 | **Signature:** `static getCampaignByID(id : String) : Campaign`
280 | 
281 | **Description:** Returns the campaign identified by the specified ID.
282 | 
283 | **Deprecated:**
284 | 
285 | Use PromotionMgr.getCampaign(String)
286 | 
287 | **Parameters:**
288 | 
289 | - `id`: Campaign ID
290 | 
291 | **Returns:**
292 | 
293 | Campaign or null if not found
294 | 
295 | ---
296 | 
297 | ### getConditionalPromotions
298 | 
299 | **Signature:** `static getConditionalPromotions(product : Product) : Collection`
300 | 
301 | **Description:** Returns the enabled promotions of active campaigns for which the specified product is a qualifiying product. Note that the method also returns coupon-based promotions. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getConditionalPromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product.
302 | 
303 | **Deprecated:**
304 | 
305 | Use PromotionMgr.getActivePromotions() and PromotionPlan.getProductPromotions(Product)
306 | 
307 | **Parameters:**
308 | 
309 | - `product`: The product whose conditional promotions are returned.
310 | 
311 | **Returns:**
312 | 
313 | A list of promotions
314 | 
315 | ---
316 | 
317 | ### getPromotion
318 | 
319 | **Signature:** `static getPromotion(couponCode : String) : Promotion`
320 | 
321 | **Description:** Returns the promotion associated with the specified coupon code.
322 | 
323 | **Deprecated:**
324 | 
325 | Coupons are now related to multiple promotions. Method returns the first promotion associated with the coupon code in case of multiple assigned promotions.
326 | 
327 | **Parameters:**
328 | 
329 | - `couponCode`: The coupon code used to lookup the promotion
330 | 
331 | **Returns:**
332 | 
333 | The resolved promotion object or null if none was found
334 | 
335 | ---
336 | 
337 | ### getPromotionByCouponCode
338 | 
339 | **Signature:** `static getPromotionByCouponCode(couponCode : String) : Promotion`
340 | 
341 | **Description:** Returns the promotion associated with the specified coupon code.
342 | 
343 | **Deprecated:**
344 | 
345 | Coupons are now related to multiple promotions. Method returns the first promotion associated with the coupon in case of multiple assigned promotions
346 | 
347 | **Parameters:**
348 | 
349 | - `couponCode`: Coupon code
350 | 
351 | **Returns:**
352 | 
353 | The associated promotion or null
354 | 
355 | ---
356 | 
357 | ### getPromotionByID
358 | 
359 | **Signature:** `static getPromotionByID(id : String) : Promotion`
360 | 
361 | **Description:** Returns the promotion identified by the specified ID.
362 | 
363 | **Deprecated:**
364 | 
365 | Use PromotionMgr.getPromotion(String)
366 | 
367 | **Parameters:**
368 | 
369 | - `id`: Promotion ID
370 | 
371 | **Returns:**
372 | 
373 | Promotion or null if not found
374 | 
375 | ---
376 | 
377 | ### getPromotions
378 | 
379 | **Signature:** `static getPromotions(product : Product) : Collection`
380 | 
381 | **Description:** Returns the enabled promotions of active campaigns for which the specified product is a discounted product. Note that method does only return promotions based on customer groups or source codes. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getPromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product.
382 | 
383 | **Deprecated:**
384 | 
385 | Use PromotionMgr.getActivePromotions() and PromotionPlan.getProductPromotions(Product)
386 | 
387 | **Parameters:**
388 | 
389 | - `product`: Discounted product
390 | 
391 | **Returns:**
392 | 
393 | List of promotions
394 | 
395 | ---
```

--------------------------------------------------------------------------------
/docs/dw_value/Money.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.value
  2 | 
  3 | # Class Money
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.value.Money
  9 | 
 10 | ## Description
 11 | 
 12 | Represents money in Commerce Cloud Digital.
 13 | 
 14 | ## Constants
 15 | 
 16 | ### NOT_AVAILABLE
 17 | 
 18 | **Type:** Money
 19 | 
 20 | Represents that there is no money available.
 21 | 
 22 | ## Properties
 23 | 
 24 | ### available
 25 | 
 26 | **Type:** boolean (Read Only)
 27 | 
 28 | Identifies if the instance contains settings for value and currency.
 29 | 
 30 | ### currencyCode
 31 | 
 32 | **Type:** String (Read Only)
 33 | 
 34 | The ISO 4217 currency mnemonic (such as 'USD', 'EUR') of the currency the
 35 |  money value relates to.
 36 | 
 37 |  Note a money instance may also describe a price that is 'not available'.
 38 |  In this case the value of this attribute is N/A.
 39 | 
 40 | ### decimalValue
 41 | 
 42 | **Type:** Decimal (Read Only)
 43 | 
 44 | The money as Decimal, null is returned when the money is not available.
 45 | 
 46 | ### value
 47 | 
 48 | **Type:** Number (Read Only)
 49 | 
 50 | The value of the money instance.
 51 | 
 52 | ### valueOrNull
 53 | 
 54 | **Type:** Number (Read Only)
 55 | 
 56 | Return the value of the money instance or null if the
 57 |  Money instance is NOT_AVAILABLE.
 58 | 
 59 | ## Constructor Summary
 60 | 
 61 | Money(value : Number, currencyCode : String) Constructs a new money instance with the specified amount for the specified currency.
 62 | 
 63 | ## Method Summary
 64 | 
 65 | ### add
 66 | 
 67 | **Signature:** `add(value : Money) : Money`
 68 | 
 69 | Returns a Money instance by adding the specified Money object to the current object.
 70 | 
 71 | ### addPercent
 72 | 
 73 | **Signature:** `addPercent(percent : Number) : Money`
 74 | 
 75 | Adds a certain percentage to the money object.
 76 | 
 77 | ### addRate
 78 | 
 79 | **Signature:** `addRate(value : Number) : Money`
 80 | 
 81 | Adds a rate (e.g.
 82 | 
 83 | ### compareTo
 84 | 
 85 | **Signature:** `compareTo(other : Money) : Number`
 86 | 
 87 | Compares two Money values.
 88 | 
 89 | ### divide
 90 | 
 91 | **Signature:** `divide(divisor : Number) : Money`
 92 | 
 93 | Divide Money object by specified divisor.
 94 | 
 95 | ### equals
 96 | 
 97 | **Signature:** `equals(other : Object) : boolean`
 98 | 
 99 | Compares two money values whether they are equivalent.
100 | 
101 | ### getCurrencyCode
102 | 
103 | **Signature:** `getCurrencyCode() : String`
104 | 
105 | Returns the ISO 4217 currency mnemonic (such as 'USD', 'EUR') of the currency the money value relates to.
106 | 
107 | ### getDecimalValue
108 | 
109 | **Signature:** `getDecimalValue() : Decimal`
110 | 
111 | Returns the money as Decimal, null is returned when the money is not available.
112 | 
113 | ### getValue
114 | 
115 | **Signature:** `getValue() : Number`
116 | 
117 | Returns the value of the money instance.
118 | 
119 | ### getValueOrNull
120 | 
121 | **Signature:** `getValueOrNull() : Number`
122 | 
123 | Return the value of the money instance or null if the Money instance is NOT_AVAILABLE.
124 | 
125 | ### hashCode
126 | 
127 | **Signature:** `hashCode() : Number`
128 | 
129 | Calculates the hash code for a money;
130 | 
131 | ### isAvailable
132 | 
133 | **Signature:** `isAvailable() : boolean`
134 | 
135 | Identifies if the instance contains settings for value and currency.
136 | 
137 | ### isOfSameCurrency
138 | 
139 | **Signature:** `isOfSameCurrency(value : Money) : boolean`
140 | 
141 | Identifies if two Money value have the same currency.
142 | 
143 | ### multiply
144 | 
145 | **Signature:** `multiply(factor : Number) : Money`
146 | 
147 | Multiply Money object by specified factor.
148 | 
149 | ### multiply
150 | 
151 | **Signature:** `multiply(quantity : Quantity) : Money`
152 | 
153 | Multiplies the Money object with the given quantity.
154 | 
155 | ### newMoney
156 | 
157 | **Signature:** `newMoney(value : Decimal) : Money`
158 | 
159 | Method returns a new instance of Money with the same currency but different value.
160 | 
161 | ### percentLessThan
162 | 
163 | **Signature:** `percentLessThan(value : Money) : Number`
164 | 
165 | Convenience method.
166 | 
167 | ### percentOf
168 | 
169 | **Signature:** `percentOf(value : Money) : Number`
170 | 
171 | Convenience method.
172 | 
173 | ### prorate
174 | 
175 | **Signature:** `static prorate(dist : Money, values : Money...) : Money[]`
176 | 
177 | Prorates the specified values using the specified discount.
178 | 
179 | ### subtract
180 | 
181 | **Signature:** `subtract(value : Money) : Money`
182 | 
183 | Returns a new Money instance by substracting the specified Money object from the current object.
184 | 
185 | ### subtractPercent
186 | 
187 | **Signature:** `subtractPercent(percent : Number) : Money`
188 | 
189 | Subtracts a certain percentage from the money object.
190 | 
191 | ### subtractRate
192 | 
193 | **Signature:** `subtractRate(value : Number) : Money`
194 | 
195 | Subtracts a rate (e.g.
196 | 
197 | ### toFormattedString
198 | 
199 | **Signature:** `toFormattedString() : String`
200 | 
201 | Returns a string representation of Money according to the regional settings configured for current request locale, for example '$59.00' or 'USD 59.00'.
202 | 
203 | ### toNumberString
204 | 
205 | **Signature:** `toNumberString() : String`
206 | 
207 | Returns a string representation for the numeric value of this money.
208 | 
209 | ### toString
210 | 
211 | **Signature:** `toString() : String`
212 | 
213 | Returns a string representation of this Money object.
214 | 
215 | ### valueOf
216 | 
217 | **Signature:** `valueOf() : Object`
218 | 
219 | According to the ECMA spec returns the "natural" primitve value.
220 | 
221 | ## Constructor Detail
222 | 
223 | ## Method Detail
224 | 
225 | ## Method Details
226 | 
227 | ### add
228 | 
229 | **Signature:** `add(value : Money) : Money`
230 | 
231 | **Description:** Returns a Money instance by adding the specified Money object to the current object. Only objects representing the same currency can be added. If one of the Money values is N/A, the result is N/A.
232 | 
233 | **Parameters:**
234 | 
235 | - `value`: the Money object to add to this Money instance.
236 | 
237 | **Returns:**
238 | 
239 | the Money object representing the sum of the operands.
240 | 
241 | ---
242 | 
243 | ### addPercent
244 | 
245 | **Signature:** `addPercent(percent : Number) : Money`
246 | 
247 | **Description:** Adds a certain percentage to the money object. The percent value is given as true percent value, so for example 10 represent 10%. If this Money is N/A the result is also N/A.
248 | 
249 | **Parameters:**
250 | 
251 | - `percent`: the percent value
252 | 
253 | **Returns:**
254 | 
255 | new Money object with the result of the calculation
256 | 
257 | ---
258 | 
259 | ### addRate
260 | 
261 | **Signature:** `addRate(value : Number) : Money`
262 | 
263 | **Description:** Adds a rate (e.g. 0.05) to the money object. This is typically for example to add a tax rate.
264 | 
265 | **Parameters:**
266 | 
267 | - `value`: the rate to add.
268 | 
269 | **Returns:**
270 | 
271 | a new Money object with rate added.
272 | 
273 | ---
274 | 
275 | ### compareTo
276 | 
277 | **Signature:** `compareTo(other : Money) : Number`
278 | 
279 | **Description:** Compares two Money values. An exception is thrown if the two Money values are of different currency. If one of the Money values represents the N/A value it is treated as 0.0.
280 | 
281 | **Parameters:**
282 | 
283 | - `other`: the money instance to comare against this money instance.
284 | 
285 | **Returns:**
286 | 
287 | the comparison of 0 if the money instances are equal or non-0 if they are different.
288 | 
289 | ---
290 | 
291 | ### divide
292 | 
293 | **Signature:** `divide(divisor : Number) : Money`
294 | 
295 | **Description:** Divide Money object by specified divisor. If this Money is N/A the result is also N/A.
296 | 
297 | **Parameters:**
298 | 
299 | - `divisor`: the divisor.
300 | 
301 | **Returns:**
302 | 
303 | Money object representing division result
304 | 
305 | ---
306 | 
307 | ### equals
308 | 
309 | **Signature:** `equals(other : Object) : boolean`
310 | 
311 | **Description:** Compares two money values whether they are equivalent.
312 | 
313 | **Parameters:**
314 | 
315 | - `other`: the object to compare against this money instance.
316 | 
317 | **Returns:**
318 | 
319 | true if equal, false otherwise.
320 | 
321 | ---
322 | 
323 | ### getCurrencyCode
324 | 
325 | **Signature:** `getCurrencyCode() : String`
326 | 
327 | **Description:** Returns the ISO 4217 currency mnemonic (such as 'USD', 'EUR') of the currency the money value relates to. Note a money instance may also describe a price that is 'not available'. In this case the value of this attribute is N/A.
328 | 
329 | **Returns:**
330 | 
331 | the value of the currency code.
332 | 
333 | ---
334 | 
335 | ### getDecimalValue
336 | 
337 | **Signature:** `getDecimalValue() : Decimal`
338 | 
339 | **Description:** Returns the money as Decimal, null is returned when the money is not available.
340 | 
341 | **Returns:**
342 | 
343 | the money as Decimal
344 | 
345 | ---
346 | 
347 | ### getValue
348 | 
349 | **Signature:** `getValue() : Number`
350 | 
351 | **Description:** Returns the value of the money instance.
352 | 
353 | **Returns:**
354 | 
355 | the value of the money instance.
356 | 
357 | **See Also:**
358 | 
359 | getDecimalValue()
360 | 
361 | ---
362 | 
363 | ### getValueOrNull
364 | 
365 | **Signature:** `getValueOrNull() : Number`
366 | 
367 | **Description:** Return the value of the money instance or null if the Money instance is NOT_AVAILABLE.
368 | 
369 | **Returns:**
370 | 
371 | Value of money instance or null.
372 | 
373 | ---
374 | 
375 | ### hashCode
376 | 
377 | **Signature:** `hashCode() : Number`
378 | 
379 | **Description:** Calculates the hash code for a money;
380 | 
381 | ---
382 | 
383 | ### isAvailable
384 | 
385 | **Signature:** `isAvailable() : boolean`
386 | 
387 | **Description:** Identifies if the instance contains settings for value and currency.
388 | 
389 | **Returns:**
390 | 
391 | true if the instance is initialized with value and currency, false if the state is 'not available'.
392 | 
393 | ---
394 | 
395 | ### isOfSameCurrency
396 | 
397 | **Signature:** `isOfSameCurrency(value : Money) : boolean`
398 | 
399 | **Description:** Identifies if two Money value have the same currency.
400 | 
401 | **Parameters:**
402 | 
403 | - `value`: the Money value passed to be tested
404 | 
405 | **Returns:**
406 | 
407 | true if both instances have the same currency, false otherwise.
408 | 
409 | ---
410 | 
411 | ### multiply
412 | 
413 | **Signature:** `multiply(factor : Number) : Money`
414 | 
415 | **Description:** Multiply Money object by specified factor. If this Money is N/A the result is also N/A.
416 | 
417 | **Parameters:**
418 | 
419 | - `factor`: multiplication factor
420 | 
421 | **Returns:**
422 | 
423 | Money object representing multiplication result.
424 | 
425 | ---
426 | 
427 | ### multiply
428 | 
429 | **Signature:** `multiply(quantity : Quantity) : Money`
430 | 
431 | **Description:** Multiplies the Money object with the given quantity. If this Money is N/A the result is also N/A.
432 | 
433 | **Parameters:**
434 | 
435 | - `quantity`: the quantity to multiply the value by
436 | 
437 | **Returns:**
438 | 
439 | a new Money representing the multiplication result.
440 | 
441 | ---
442 | 
443 | ### newMoney
444 | 
445 | **Signature:** `newMoney(value : Decimal) : Money`
446 | 
447 | **Description:** Method returns a new instance of Money with the same currency but different value. An N/A instance is returned if value is null.
448 | 
449 | **Parameters:**
450 | 
451 | - `value`: as a decimal
452 | 
453 | **Returns:**
454 | 
455 | new Money instance with same currency
456 | 
457 | ---
458 | 
459 | ### percentLessThan
460 | 
461 | **Signature:** `percentLessThan(value : Money) : Number`
462 | 
463 | **Description:** Convenience method. Calculates and returns the percentage off this price represents in relation to the passed base price. The result is generally equal to 100.0 - this.percentOf(value). For example, if this value is $30 and the passed value is $50, then the return value will be 40.0, representing a 40% discount. This method will return null if the compare value is null, this value or the compare value is unavailable, or the compare value equals 0.0.
464 | 
465 | **Parameters:**
466 | 
467 | - `value`: The price to compare to this price
468 | 
469 | **Returns:**
470 | 
471 | The percentage discount this price represents in relation to the passed base price.
472 | 
473 | **See Also:**
474 | 
475 | percentOf(Money)
476 | 
477 | **Throws:**
478 | 
479 | IllegalArgumentException - If the currencies are not comparable.
480 | 
481 | ---
482 | 
483 | ### percentOf
484 | 
485 | **Signature:** `percentOf(value : Money) : Number`
486 | 
487 | **Description:** Convenience method. Calculates and returns the percentage of the passed value this price represents. For example, if this value is $30 and the passed value is $50, then the return value will be 60.0 (i.e. 60%). This method will return null if the compare value is null, this value or the compare value is unavailable, or the compare value equals 0.0.
488 | 
489 | **Parameters:**
490 | 
491 | - `value`: The price to compare to this price
492 | 
493 | **Returns:**
494 | 
495 | The percentage of the compare price this price represents, or null.
496 | 
497 | **Throws:**
498 | 
499 | IllegalArgumentException - If the currencies are not comparable.
500 | 
501 | ---
502 | 
503 | ### prorate
504 | 
505 | **Signature:** `static prorate(dist : Money, values : Money...) : Money[]`
506 | 
507 | **Description:** Prorates the specified values using the specified discount.
508 | 
509 | **Parameters:**
510 | 
511 | - `dist`: the proration discount.
512 | - `values`: the values to prorate.
513 | 
514 | **Returns:**
515 | 
516 | the prorated values.
517 | 
518 | ---
519 | 
520 | ### subtract
521 | 
522 | **Signature:** `subtract(value : Money) : Money`
523 | 
524 | **Description:** Returns a new Money instance by substracting the specified Money object from the current object. Only objects representing the same currency can be subtracted. If one of the Money values is N/A, the result is N/A.
525 | 
526 | **Parameters:**
527 | 
528 | - `value`: the Money object to subtract
529 | 
530 | **Returns:**
531 | 
532 | the Money object representing the result of subtraction.
533 | 
534 | ---
535 | 
536 | ### subtractPercent
537 | 
538 | **Signature:** `subtractPercent(percent : Number) : Money`
539 | 
540 | **Description:** Subtracts a certain percentage from the money object. The percent value is given as true percent value, so for example 10 represent 10%. If this Money is N/A the result is also N/A.
541 | 
542 | **Parameters:**
543 | 
544 | - `percent`: the percent value
545 | 
546 | **Returns:**
547 | 
548 | new Money object with the result of the calculation
549 | 
550 | ---
551 | 
552 | ### subtractRate
553 | 
554 | **Signature:** `subtractRate(value : Number) : Money`
555 | 
556 | **Description:** Subtracts a rate (e.g. 0.05) from the money object. This is typically for example to subtract a tax rates.
557 | 
558 | **Parameters:**
559 | 
560 | - `value`: the rate to subtract.
561 | 
562 | **Returns:**
563 | 
564 | a new Money object with rate subtracted.
565 | 
566 | ---
567 | 
568 | ### toFormattedString
569 | 
570 | **Signature:** `toFormattedString() : String`
571 | 
572 | **Description:** Returns a string representation of Money according to the regional settings configured for current request locale, for example '$59.00' or 'USD 59.00'.
573 | 
574 | **Returns:**
575 | 
576 | The formatted String representation of the passed money. In case of an error the string 'N/A' is returned.
577 | 
578 | ---
579 | 
580 | ### toNumberString
581 | 
582 | **Signature:** `toNumberString() : String`
583 | 
584 | **Description:** Returns a string representation for the numeric value of this money. The number is formatted with the decimal symbols of the platforms default locale.
585 | 
586 | **Returns:**
587 | 
588 | a string representation for the numeric value of this money.
589 | 
590 | ---
591 | 
592 | ### toString
593 | 
594 | **Signature:** `toString() : String`
595 | 
596 | **Description:** Returns a string representation of this Money object.
597 | 
598 | **Returns:**
599 | 
600 | a string representation of this Money object.
601 | 
602 | ---
603 | 
604 | ### valueOf
605 | 
606 | **Signature:** `valueOf() : Object`
607 | 
608 | **Description:** According to the ECMA spec returns the "natural" primitve value. Here the value portion of the Money is returned.
609 | 
610 | ---
```

--------------------------------------------------------------------------------
/docs/dw_customer/CustomerAddress.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.customer
  2 | 
  3 | # Class CustomerAddress
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.customer.CustomerAddress
 11 | 
 12 | ## Description
 13 | 
 14 | The Address class represents a customer's address. Note: this class allows access to sensitive personal and private information. Pay attention to appropriate legal and regulatory requirements.
 15 | 
 16 | ## Properties
 17 | 
 18 | ### address1
 19 | 
 20 | **Type:** String
 21 | 
 22 | The customer's first address.
 23 | 
 24 | ### address2
 25 | 
 26 | **Type:** String
 27 | 
 28 | The customer's second address value.
 29 | 
 30 | ### city
 31 | 
 32 | **Type:** String
 33 | 
 34 | The customer's city.
 35 | 
 36 | ### companyName
 37 | 
 38 | **Type:** String
 39 | 
 40 | The customer's company name.
 41 | 
 42 | ### countryCode
 43 | 
 44 | **Type:** EnumValue
 45 | 
 46 | The customer's country code. Commerce Cloud Digital supports two-character
 47 |  country codes per ISO 3166-1 alpha-2. See
 48 |  http://www.iso.org/iso/country_codes/iso_3166-faqs/iso_3166_faqs_general.htm
 49 |  for additional information.
 50 | 
 51 | ### firstName
 52 | 
 53 | **Type:** String
 54 | 
 55 | The customer's first name.
 56 | 
 57 | ### fullName
 58 | 
 59 | **Type:** String (Read Only)
 60 | 
 61 | A concatenation of the customer's first, middle,
 62 |  and last names and its suffix.
 63 | 
 64 | ### ID
 65 | 
 66 | **Type:** String
 67 | 
 68 | The name of the address.
 69 | 
 70 | ### jobTitle
 71 | 
 72 | **Type:** String
 73 | 
 74 | The customer's job title.
 75 | 
 76 | ### lastName
 77 | 
 78 | **Type:** String
 79 | 
 80 | The customer's last name.
 81 | 
 82 | ### phone
 83 | 
 84 | **Type:** String
 85 | 
 86 | The customer's phone number.
 87 | 
 88 | ### postalCode
 89 | 
 90 | **Type:** String
 91 | 
 92 | The customer's postal code.
 93 | 
 94 | ### postBox
 95 | 
 96 | **Type:** String
 97 | 
 98 | The customer's post box.
 99 | 
100 | ### salutation
101 | 
102 | **Type:** String
103 | 
104 | The customer's salutation.
105 | 
106 | ### secondName
107 | 
108 | **Type:** String
109 | 
110 | The customer's second name.
111 | 
112 | ### stateCode
113 | 
114 | **Type:** String
115 | 
116 | The customer's state.
117 | 
118 | ### suffix
119 | 
120 | **Type:** String
121 | 
122 | The customer's suffix.
123 | 
124 | ### suite
125 | 
126 | **Type:** String
127 | 
128 | The customer's suite.
129 | 
130 | ### title
131 | 
132 | **Type:** String
133 | 
134 | The customer's title.
135 | 
136 | ## Constructor Summary
137 | 
138 | ## Method Summary
139 | 
140 | ### getAddress1
141 | 
142 | **Signature:** `getAddress1() : String`
143 | 
144 | Returns the customer's first address.
145 | 
146 | ### getAddress2
147 | 
148 | **Signature:** `getAddress2() : String`
149 | 
150 | Returns the customer's second address value.
151 | 
152 | ### getCity
153 | 
154 | **Signature:** `getCity() : String`
155 | 
156 | Returns the customer's city.
157 | 
158 | ### getCompanyName
159 | 
160 | **Signature:** `getCompanyName() : String`
161 | 
162 | Returns the customer's company name.
163 | 
164 | ### getCountryCode
165 | 
166 | **Signature:** `getCountryCode() : EnumValue`
167 | 
168 | Returns the customer's country code.
169 | 
170 | ### getFirstName
171 | 
172 | **Signature:** `getFirstName() : String`
173 | 
174 | Returns the customer's first name.
175 | 
176 | ### getFullName
177 | 
178 | **Signature:** `getFullName() : String`
179 | 
180 | Returns a concatenation of the customer's first, middle, and last names and its suffix.
181 | 
182 | ### getID
183 | 
184 | **Signature:** `getID() : String`
185 | 
186 | Returns the name of the address.
187 | 
188 | ### getJobTitle
189 | 
190 | **Signature:** `getJobTitle() : String`
191 | 
192 | Returns the customer's job title.
193 | 
194 | ### getLastName
195 | 
196 | **Signature:** `getLastName() : String`
197 | 
198 | Returns the customer's last name.
199 | 
200 | ### getPhone
201 | 
202 | **Signature:** `getPhone() : String`
203 | 
204 | Returns the customer's phone number.
205 | 
206 | ### getPostalCode
207 | 
208 | **Signature:** `getPostalCode() : String`
209 | 
210 | Returns the customer's postal code.
211 | 
212 | ### getPostBox
213 | 
214 | **Signature:** `getPostBox() : String`
215 | 
216 | Returns the customer's post box.
217 | 
218 | ### getSalutation
219 | 
220 | **Signature:** `getSalutation() : String`
221 | 
222 | Returns the customer's salutation.
223 | 
224 | ### getSecondName
225 | 
226 | **Signature:** `getSecondName() : String`
227 | 
228 | Returns the customer's second name.
229 | 
230 | ### getStateCode
231 | 
232 | **Signature:** `getStateCode() : String`
233 | 
234 | Returns the customer's state.
235 | 
236 | ### getSuffix
237 | 
238 | **Signature:** `getSuffix() : String`
239 | 
240 | Returns the customer's suffix.
241 | 
242 | ### getSuite
243 | 
244 | **Signature:** `getSuite() : String`
245 | 
246 | Returns the customer's suite.
247 | 
248 | ### getTitle
249 | 
250 | **Signature:** `getTitle() : String`
251 | 
252 | Returns the customer's title.
253 | 
254 | ### isEquivalentAddress
255 | 
256 | **Signature:** `isEquivalentAddress(address : Object) : boolean`
257 | 
258 | Returns true if the specified address is equivalent to this address.
259 | 
260 | ### setAddress1
261 | 
262 | **Signature:** `setAddress1(value : String) : void`
263 | 
264 | Sets the value of the customer's first address.
265 | 
266 | ### setAddress2
267 | 
268 | **Signature:** `setAddress2(value : String) : void`
269 | 
270 | Sets the customer's second address value.
271 | 
272 | ### setCity
273 | 
274 | **Signature:** `setCity(city : String) : void`
275 | 
276 | Sets the customer's city.
277 | 
278 | ### setCompanyName
279 | 
280 | **Signature:** `setCompanyName(companyName : String) : void`
281 | 
282 | Sets the customer's company name.
283 | 
284 | ### setCountryCode
285 | 
286 | **Signature:** `setCountryCode(countryCode : String) : void`
287 | 
288 | Sets the customer's country code.
289 | 
290 | ### setFirstName
291 | 
292 | **Signature:** `setFirstName(firstName : String) : void`
293 | 
294 | Sets the customer's first name.
295 | 
296 | ### setID
297 | 
298 | **Signature:** `setID(value : String) : void`
299 | 
300 | Sets the address name.
301 | 
302 | ### setJobTitle
303 | 
304 | **Signature:** `setJobTitle(jobTitle : String) : void`
305 | 
306 | Sets the customer's job title.
307 | 
308 | ### setLastName
309 | 
310 | **Signature:** `setLastName(lastName : String) : void`
311 | 
312 | Sets the customer's last name.
313 | 
314 | ### setPhone
315 | 
316 | **Signature:** `setPhone(phoneNumber : String) : void`
317 | 
318 | Sets the customer's phone number.
319 | 
320 | ### setPostalCode
321 | 
322 | **Signature:** `setPostalCode(postalCode : String) : void`
323 | 
324 | Sets the customer's postal code.
325 | 
326 | ### setPostBox
327 | 
328 | **Signature:** `setPostBox(postBox : String) : void`
329 | 
330 | Sets the customer's post box.
331 | 
332 | ### setSaluation
333 | 
334 | **Signature:** `setSaluation(value : String) : void`
335 | 
336 | Sets the customer's salutation.
337 | 
338 | ### setSalutation
339 | 
340 | **Signature:** `setSalutation(value : String) : void`
341 | 
342 | Sets the customer's salutation.
343 | 
344 | ### setSecondName
345 | 
346 | **Signature:** `setSecondName(secondName : String) : void`
347 | 
348 | Sets the customer's second name.
349 | 
350 | ### setStateCode
351 | 
352 | **Signature:** `setStateCode(state : String) : void`
353 | 
354 | Sets the customer's state.
355 | 
356 | ### setSuffix
357 | 
358 | **Signature:** `setSuffix(suffix : String) : void`
359 | 
360 | Sets the customer's suffix.
361 | 
362 | ### setSuite
363 | 
364 | **Signature:** `setSuite(value : String) : void`
365 | 
366 | Sets the customer's suite.
367 | 
368 | ### setTitle
369 | 
370 | **Signature:** `setTitle(title : String) : void`
371 | 
372 | Sets the customer's title.
373 | 
374 | ## Method Detail
375 | 
376 | ## Method Details
377 | 
378 | ### getAddress1
379 | 
380 | **Signature:** `getAddress1() : String`
381 | 
382 | **Description:** Returns the customer's first address.
383 | 
384 | **Returns:**
385 | 
386 | the first address value.
387 | 
388 | ---
389 | 
390 | ### getAddress2
391 | 
392 | **Signature:** `getAddress2() : String`
393 | 
394 | **Description:** Returns the customer's second address value.
395 | 
396 | **Returns:**
397 | 
398 | the value of the second address.
399 | 
400 | ---
401 | 
402 | ### getCity
403 | 
404 | **Signature:** `getCity() : String`
405 | 
406 | **Description:** Returns the customer's city.
407 | 
408 | **Returns:**
409 | 
410 | the customer's city.
411 | 
412 | ---
413 | 
414 | ### getCompanyName
415 | 
416 | **Signature:** `getCompanyName() : String`
417 | 
418 | **Description:** Returns the customer's company name.
419 | 
420 | **Returns:**
421 | 
422 | the company name.
423 | 
424 | ---
425 | 
426 | ### getCountryCode
427 | 
428 | **Signature:** `getCountryCode() : EnumValue`
429 | 
430 | **Description:** Returns the customer's country code. Commerce Cloud Digital supports two-character country codes per ISO 3166-1 alpha-2. See http://www.iso.org/iso/country_codes/iso_3166-faqs/iso_3166_faqs_general.htm for additional information.
431 | 
432 | **Returns:**
433 | 
434 | the two-digit country code.
435 | 
436 | ---
437 | 
438 | ### getFirstName
439 | 
440 | **Signature:** `getFirstName() : String`
441 | 
442 | **Description:** Returns the customer's first name.
443 | 
444 | **Returns:**
445 | 
446 | the customer first name.
447 | 
448 | ---
449 | 
450 | ### getFullName
451 | 
452 | **Signature:** `getFullName() : String`
453 | 
454 | **Description:** Returns a concatenation of the customer's first, middle, and last names and its suffix.
455 | 
456 | **Returns:**
457 | 
458 | a concatenation of the customer's first, middle, and last names and its suffix.
459 | 
460 | ---
461 | 
462 | ### getID
463 | 
464 | **Signature:** `getID() : String`
465 | 
466 | **Description:** Returns the name of the address.
467 | 
468 | **Returns:**
469 | 
470 | the address name.
471 | 
472 | ---
473 | 
474 | ### getJobTitle
475 | 
476 | **Signature:** `getJobTitle() : String`
477 | 
478 | **Description:** Returns the customer's job title.
479 | 
480 | **Returns:**
481 | 
482 | the job title.
483 | 
484 | ---
485 | 
486 | ### getLastName
487 | 
488 | **Signature:** `getLastName() : String`
489 | 
490 | **Description:** Returns the customer's last name.
491 | 
492 | **Returns:**
493 | 
494 | the last name.
495 | 
496 | ---
497 | 
498 | ### getPhone
499 | 
500 | **Signature:** `getPhone() : String`
501 | 
502 | **Description:** Returns the customer's phone number.
503 | 
504 | **Returns:**
505 | 
506 | the phone number.
507 | 
508 | ---
509 | 
510 | ### getPostalCode
511 | 
512 | **Signature:** `getPostalCode() : String`
513 | 
514 | **Description:** Returns the customer's postal code.
515 | 
516 | **Returns:**
517 | 
518 | the postal code.
519 | 
520 | ---
521 | 
522 | ### getPostBox
523 | 
524 | **Signature:** `getPostBox() : String`
525 | 
526 | **Description:** Returns the customer's post box.
527 | 
528 | **Returns:**
529 | 
530 | the post box.
531 | 
532 | ---
533 | 
534 | ### getSalutation
535 | 
536 | **Signature:** `getSalutation() : String`
537 | 
538 | **Description:** Returns the customer's salutation.
539 | 
540 | **Returns:**
541 | 
542 | the salutation.
543 | 
544 | ---
545 | 
546 | ### getSecondName
547 | 
548 | **Signature:** `getSecondName() : String`
549 | 
550 | **Description:** Returns the customer's second name.
551 | 
552 | **Returns:**
553 | 
554 | the second name.
555 | 
556 | ---
557 | 
558 | ### getStateCode
559 | 
560 | **Signature:** `getStateCode() : String`
561 | 
562 | **Description:** Returns the customer's state.
563 | 
564 | **Returns:**
565 | 
566 | the state.
567 | 
568 | ---
569 | 
570 | ### getSuffix
571 | 
572 | **Signature:** `getSuffix() : String`
573 | 
574 | **Description:** Returns the customer's suffix.
575 | 
576 | **Returns:**
577 | 
578 | the suffix.
579 | 
580 | ---
581 | 
582 | ### getSuite
583 | 
584 | **Signature:** `getSuite() : String`
585 | 
586 | **Description:** Returns the customer's suite.
587 | 
588 | **Returns:**
589 | 
590 | the suite.
591 | 
592 | ---
593 | 
594 | ### getTitle
595 | 
596 | **Signature:** `getTitle() : String`
597 | 
598 | **Description:** Returns the customer's title.
599 | 
600 | **Returns:**
601 | 
602 | the title.
603 | 
604 | ---
605 | 
606 | ### isEquivalentAddress
607 | 
608 | **Signature:** `isEquivalentAddress(address : Object) : boolean`
609 | 
610 | **Description:** Returns true if the specified address is equivalent to this address. An equivalent address is an address whose core attributes contain the same values. The core attributes are: address1 address2 city companyName countryCode firstName lastName postalCode postBox stateCode
611 | 
612 | **Parameters:**
613 | 
614 | - `address`: the address to test.
615 | 
616 | **Returns:**
617 | 
618 | true if the specified address is equivalent to this address, false otherwise.
619 | 
620 | ---
621 | 
622 | ### setAddress1
623 | 
624 | **Signature:** `setAddress1(value : String) : void`
625 | 
626 | **Description:** Sets the value of the customer's first address.
627 | 
628 | **Parameters:**
629 | 
630 | - `value`: The value to set.
631 | 
632 | ---
633 | 
634 | ### setAddress2
635 | 
636 | **Signature:** `setAddress2(value : String) : void`
637 | 
638 | **Description:** Sets the customer's second address value.
639 | 
640 | **Parameters:**
641 | 
642 | - `value`: The value to set.
643 | 
644 | ---
645 | 
646 | ### setCity
647 | 
648 | **Signature:** `setCity(city : String) : void`
649 | 
650 | **Description:** Sets the customer's city.
651 | 
652 | **Parameters:**
653 | 
654 | - `city`: the customer's city to set.
655 | 
656 | ---
657 | 
658 | ### setCompanyName
659 | 
660 | **Signature:** `setCompanyName(companyName : String) : void`
661 | 
662 | **Description:** Sets the customer's company name.
663 | 
664 | **Parameters:**
665 | 
666 | - `companyName`: the name of the company.
667 | 
668 | ---
669 | 
670 | ### setCountryCode
671 | 
672 | **Signature:** `setCountryCode(countryCode : String) : void`
673 | 
674 | **Description:** Sets the customer's country code. Commerce Cloud Digital supports two-character country codes per ISO 3166-1 alpha-2. See http://www.iso.org/iso/country_codes/iso_3166-faqs/iso_3166_faqs_general.htm for additional information.
675 | 
676 | **Parameters:**
677 | 
678 | - `countryCode`: the country code, must be no more than 2 characters or will be truncated.
679 | 
680 | ---
681 | 
682 | ### setFirstName
683 | 
684 | **Signature:** `setFirstName(firstName : String) : void`
685 | 
686 | **Description:** Sets the customer's first name.
687 | 
688 | **Parameters:**
689 | 
690 | - `firstName`: the customer's first name to set.
691 | 
692 | ---
693 | 
694 | ### setID
695 | 
696 | **Signature:** `setID(value : String) : void`
697 | 
698 | **Description:** Sets the address name.
699 | 
700 | **Parameters:**
701 | 
702 | - `value`: the name to use.
703 | 
704 | ---
705 | 
706 | ### setJobTitle
707 | 
708 | **Signature:** `setJobTitle(jobTitle : String) : void`
709 | 
710 | **Description:** Sets the customer's job title.
711 | 
712 | **Parameters:**
713 | 
714 | - `jobTitle`: The jobTitle to set.
715 | 
716 | ---
717 | 
718 | ### setLastName
719 | 
720 | **Signature:** `setLastName(lastName : String) : void`
721 | 
722 | **Description:** Sets the customer's last name.
723 | 
724 | **Parameters:**
725 | 
726 | - `lastName`: The last name to set.
727 | 
728 | ---
729 | 
730 | ### setPhone
731 | 
732 | **Signature:** `setPhone(phoneNumber : String) : void`
733 | 
734 | **Description:** Sets the customer's phone number. The length is restricted to 32 characters.
735 | 
736 | **Parameters:**
737 | 
738 | - `phoneNumber`: The phone number to set.
739 | 
740 | ---
741 | 
742 | ### setPostalCode
743 | 
744 | **Signature:** `setPostalCode(postalCode : String) : void`
745 | 
746 | **Description:** Sets the customer's postal code.
747 | 
748 | **Parameters:**
749 | 
750 | - `postalCode`: The postal code to set.
751 | 
752 | ---
753 | 
754 | ### setPostBox
755 | 
756 | **Signature:** `setPostBox(postBox : String) : void`
757 | 
758 | **Description:** Sets the customer's post box.
759 | 
760 | **Parameters:**
761 | 
762 | - `postBox`: The post box to set.
763 | 
764 | ---
765 | 
766 | ### setSaluation
767 | 
768 | **Signature:** `setSaluation(value : String) : void`
769 | 
770 | **Description:** Sets the customer's salutation.
771 | 
772 | **Deprecated:**
773 | 
774 | Use setSalutation(String)
775 | 
776 | **Parameters:**
777 | 
778 | - `value`: the salutation.
779 | 
780 | ---
781 | 
782 | ### setSalutation
783 | 
784 | **Signature:** `setSalutation(value : String) : void`
785 | 
786 | **Description:** Sets the customer's salutation.
787 | 
788 | **Parameters:**
789 | 
790 | - `value`: the salutation.
791 | 
792 | ---
793 | 
794 | ### setSecondName
795 | 
796 | **Signature:** `setSecondName(secondName : String) : void`
797 | 
798 | **Description:** Sets the customer's second name.
799 | 
800 | **Parameters:**
801 | 
802 | - `secondName`: The second name to set.
803 | 
804 | ---
805 | 
806 | ### setStateCode
807 | 
808 | **Signature:** `setStateCode(state : String) : void`
809 | 
810 | **Description:** Sets the customer's state.
811 | 
812 | **Parameters:**
813 | 
814 | - `state`: The state to set.
815 | 
816 | ---
817 | 
818 | ### setSuffix
819 | 
820 | **Signature:** `setSuffix(suffix : String) : void`
821 | 
822 | **Description:** Sets the customer's suffix.
823 | 
824 | **Parameters:**
825 | 
826 | - `suffix`: The suffix to set.
827 | 
828 | ---
829 | 
830 | ### setSuite
831 | 
832 | **Signature:** `setSuite(value : String) : void`
833 | 
834 | **Description:** Sets the customer's suite. The length is restricted to 32 characters.
835 | 
836 | **Parameters:**
837 | 
838 | - `value`: the suite to set.
839 | 
840 | ---
841 | 
842 | ### setTitle
843 | 
844 | **Signature:** `setTitle(title : String) : void`
845 | 
846 | **Description:** Sets the customer's title.
847 | 
848 | **Parameters:**
849 | 
850 | - `title`: The title to set.
851 | 
852 | ---
```

--------------------------------------------------------------------------------
/docs/dw_catalog/ProductAttributeModel.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class ProductAttributeModel
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.catalog.ProductAttributeModel
  9 | 
 10 | ## Description
 11 | 
 12 | Class representing the complete attribute model for products in the system. An instance of this class provides methods to access the attribute definitions and groups for the system object type 'Product' and perhaps additional information depending on how the instance is obtained. A ProductAttributeModel can be obtained in one of three ways: ProductAttributeModel(): When the no-arg constructor is used the model represents: the attribute groups of the system object type 'Product' (i.e. the global product attribute groups) and their bound attributes Category.getProductAttributeModel(): When the attribute model for a Category is retrieved, the model represents: the global product attribute groups product attribute groups of the calling category product attribute groups of any parent categories of the calling category Product.getAttributeModel(): When the attribute model for a Product is retrieved, the model represents: the global product attribute groups product attribute groups of the product's classification category product attribute groups of any parent categories of the product's classification category In this case, the model additionally provides access to the attribute values of the product. If the product lacks a classification category, then only the global product attribute group is considered by the model. The ProductAttributeModel provides a generic way to display the attribute values of a product on a product detail page organized into appropriate visual groups. This is typically done as follows: On the product detail page, call Product.getAttributeModel() to get the attribute model for the product. Call getVisibleAttributeGroups() to get the groups that are appropriate for this product and all other products assigned to the same classification category. Iterate the groups, and display each as a "group" in the UI. Call getVisibleAttributeDefinitions(ObjectAttributeGroup) for each group. Iterate and display the attribute names using ObjectAttributeDefinition.getDisplayName(). For each attribute, get the product's display value(s) for that attribute, using getDisplayValue(). This might require custom display logic based on the type of attribute (strings, dates, multi-value attributes, etc).
 13 | 
 14 | ## Properties
 15 | 
 16 | ### attributeGroups
 17 | 
 18 | **Type:** Collection (Read Only)
 19 | 
 20 | A sorted collection of attribute groups of this model. The groups
 21 |  returned depends on how this model is constructed and what it represents.
 22 |  (See class-level documentation for details).
 23 |  
 24 |  The collection of returned groups is sorted first by scope and secondly
 25 |  by explicit sort order. Global groups always appear before
 26 |  category-specific groups in the list. Groups of parent categories always
 27 |  appear before groups belonging to subcategories. At each scope, groups
 28 |  have an explicit sort order which can be managed within the Business
 29 |  Manager.
 30 |  
 31 |  When there are multiple attribute groups with the same ID, the following
 32 |  rules apply:
 33 | 
 34 |  
 35 |  If this model represents the global product attribute group only
 36 |  (e.g. the no-arg constructor was used), duplicates cannot occur since
 37 |  only one group can be defined with a given ID at that scope.
 38 |  If this model is associated with specific categories (e.g. it is
 39 |  constructed from a product with a classification category), then a
 40 |  category product attribute group might have the same ID as a global
 41 |  product attribute group. In this case, the category group overrides the
 42 |  global one.
 43 |  If a category and one of its ancestor categories both define a
 44 |  product attribute group with the same ID, the sub-category group
 45 |  overrides the parent group.
 46 |  
 47 | 
 48 |  As a result of these rules, this method will never return two attribute
 49 |  groups with the same ID.
 50 | 
 51 | ### orderRequiredAttributeDefinitions
 52 | 
 53 | **Type:** Collection (Read Only)
 54 | 
 55 | An unsorted collection of attribute definitions marked as
 56 |  order-required. Order-required attributes are usually copied into order
 57 |  line items.
 58 |  
 59 |  The returned attribute definitions are sorted according to the explicit
 60 |  sort order defined for the attributes in the group. This is managed by
 61 |  merchant in the Business Manager.
 62 | 
 63 | ### visibleAttributeGroups
 64 | 
 65 | **Type:** Collection (Read Only)
 66 | 
 67 | A sorted collection of visible attribute groups of this model.
 68 |  This method is similar to getAttributeGroups() but only includes
 69 |  attribute groups containing at least one attribute definition that is
 70 |  visible. See
 71 |  getVisibleAttributeDefinitions(ObjectAttributeGroup).
 72 | 
 73 | ## Constructor Summary
 74 | 
 75 | ProductAttributeModel() Constructs a product attribute model that is not based on a product nor a category.
 76 | 
 77 | ## Method Summary
 78 | 
 79 | ### getAttributeDefinition
 80 | 
 81 | **Signature:** `getAttributeDefinition(id : String) : ObjectAttributeDefinition`
 82 | 
 83 | Returns the attribute definition with the given id from the product attribute model.
 84 | 
 85 | ### getAttributeDefinitions
 86 | 
 87 | **Signature:** `getAttributeDefinitions(group : ObjectAttributeGroup) : Collection`
 88 | 
 89 | Returns a sorted collection of attribute definitions for the given attribute group.
 90 | 
 91 | ### getAttributeGroup
 92 | 
 93 | **Signature:** `getAttributeGroup(id : String) : ObjectAttributeGroup`
 94 | 
 95 | Returns the attribute group with the given id from the product attribute model.
 96 | 
 97 | ### getAttributeGroups
 98 | 
 99 | **Signature:** `getAttributeGroups() : Collection`
100 | 
101 | Returns a sorted collection of attribute groups of this model.
102 | 
103 | ### getDisplayValue
104 | 
105 | **Signature:** `getDisplayValue(definition : ObjectAttributeDefinition) : Object`
106 | 
107 | Returns the value that the underlying product defines for the given attribute definition in the current locale.
108 | 
109 | ### getOrderRequiredAttributeDefinitions
110 | 
111 | **Signature:** `getOrderRequiredAttributeDefinitions() : Collection`
112 | 
113 | Returns an unsorted collection of attribute definitions marked as order-required.
114 | 
115 | ### getValue
116 | 
117 | **Signature:** `getValue(definition : ObjectAttributeDefinition) : Object`
118 | 
119 | Returns the attribute value for the specified attribute definition.
120 | 
121 | ### getVisibleAttributeDefinitions
122 | 
123 | **Signature:** `getVisibleAttributeDefinitions(group : ObjectAttributeGroup) : Collection`
124 | 
125 | Returns a sorted collection of all visible attribute definitions for the given attribute group.
126 | 
127 | ### getVisibleAttributeGroups
128 | 
129 | **Signature:** `getVisibleAttributeGroups() : Collection`
130 | 
131 | Returns a sorted collection of visible attribute groups of this model.
132 | 
133 | ## Constructor Detail
134 | 
135 | ## Method Detail
136 | 
137 | ## Method Details
138 | 
139 | ### getAttributeDefinition
140 | 
141 | **Signature:** `getAttributeDefinition(id : String) : ObjectAttributeDefinition`
142 | 
143 | **Description:** Returns the attribute definition with the given id from the product attribute model. If attribute definition does not exist, null is returned.
144 | 
145 | **Parameters:**
146 | 
147 | - `id`: the identifier of the attribute definition.
148 | 
149 | **Returns:**
150 | 
151 | attribute definition or null if not exist
152 | 
153 | ---
154 | 
155 | ### getAttributeDefinitions
156 | 
157 | **Signature:** `getAttributeDefinitions(group : ObjectAttributeGroup) : Collection`
158 | 
159 | **Description:** Returns a sorted collection of attribute definitions for the given attribute group. If no attribute definition exist for the group, an empty collection is returned. The returned attribute definitions are sorted according to the explicit sort order defined for the attributes in the group. This is managed by merchant in the Business Manager.
160 | 
161 | **Parameters:**
162 | 
163 | - `group`: the group whose attribute definitions are returned.
164 | 
165 | **Returns:**
166 | 
167 | a sorted collection of ObjectAttributeDefinition instances.
168 | 
169 | ---
170 | 
171 | ### getAttributeGroup
172 | 
173 | **Signature:** `getAttributeGroup(id : String) : ObjectAttributeGroup`
174 | 
175 | **Description:** Returns the attribute group with the given id from the product attribute model. If attribute group does not exist, null is returned.
176 | 
177 | **Parameters:**
178 | 
179 | - `id`: the attribute group identifier.
180 | 
181 | **Returns:**
182 | 
183 | the attribute group or null if not exist
184 | 
185 | ---
186 | 
187 | ### getAttributeGroups
188 | 
189 | **Signature:** `getAttributeGroups() : Collection`
190 | 
191 | **Description:** Returns a sorted collection of attribute groups of this model. The groups returned depends on how this model is constructed and what it represents. (See class-level documentation for details). The collection of returned groups is sorted first by scope and secondly by explicit sort order. Global groups always appear before category-specific groups in the list. Groups of parent categories always appear before groups belonging to subcategories. At each scope, groups have an explicit sort order which can be managed within the Business Manager. When there are multiple attribute groups with the same ID, the following rules apply: If this model represents the global product attribute group only (e.g. the no-arg constructor was used), duplicates cannot occur since only one group can be defined with a given ID at that scope. If this model is associated with specific categories (e.g. it is constructed from a product with a classification category), then a category product attribute group might have the same ID as a global product attribute group. In this case, the category group overrides the global one. If a category and one of its ancestor categories both define a product attribute group with the same ID, the sub-category group overrides the parent group. As a result of these rules, this method will never return two attribute groups with the same ID.
192 | 
193 | **Returns:**
194 | 
195 | collection of all attribute groups.
196 | 
197 | ---
198 | 
199 | ### getDisplayValue
200 | 
201 | **Signature:** `getDisplayValue(definition : ObjectAttributeDefinition) : Object`
202 | 
203 | **Description:** Returns the value that the underlying product defines for the given attribute definition in the current locale. In case the attribute definition defines localized attribute values, the product's value is used as an id to find the localized display value. In case of an Image attribute this method returns a MediaFile instance. In previous versions this method returned a String with the image path. In case of an HTML attribute this method returns a MarkupText instance. In previous versions this method returned a String with the HTML source.
204 | 
205 | **API Versioned:**
206 | 
207 | From version 10.6. In prior versions this method returned a String with the image path or a String with the HTML source
208 | 
209 | **Parameters:**
210 | 
211 | - `definition`: the definition to use.
212 | 
213 | **Returns:**
214 | 
215 | The localized product attribute display value.
216 | 
217 | ---
218 | 
219 | ### getOrderRequiredAttributeDefinitions
220 | 
221 | **Signature:** `getOrderRequiredAttributeDefinitions() : Collection`
222 | 
223 | **Description:** Returns an unsorted collection of attribute definitions marked as order-required. Order-required attributes are usually copied into order line items. The returned attribute definitions are sorted according to the explicit sort order defined for the attributes in the group. This is managed by merchant in the Business Manager.
224 | 
225 | **Returns:**
226 | 
227 | a collection of order-required ObjectAttributeDefinition instances.
228 | 
229 | ---
230 | 
231 | ### getValue
232 | 
233 | **Signature:** `getValue(definition : ObjectAttributeDefinition) : Object`
234 | 
235 | **Description:** Returns the attribute value for the specified attribute definition. If the product does not define a value, null is returned. Note: this method may only be used where the attribute model was created for a specific product; otherwise it will always return null. If the attribute is localized, the value for the current session locale is returned. In case of an Image attribute this method returns a MediaFile instance. In previous versions this method returned a String with the image path. In case of an HTML attribute this method returns a MarkupText instance. In previous versions this method returned a String with the HTML source.
236 | 
237 | **API Versioned:**
238 | 
239 | From version 10.6. In prior versions this method returned a String with the image path or a String with the HTML source.
240 | 
241 | **Parameters:**
242 | 
243 | - `definition`: the attribute definition to use when locating and returning the value.
244 | 
245 | **Returns:**
246 | 
247 | value the value associated with the object attribute definition.
248 | 
249 | ---
250 | 
251 | ### getVisibleAttributeDefinitions
252 | 
253 | **Signature:** `getVisibleAttributeDefinitions(group : ObjectAttributeGroup) : Collection`
254 | 
255 | **Description:** Returns a sorted collection of all visible attribute definitions for the given attribute group. If no visible attribute definition exist for the group, an empty collection is returned. An attribute definition is considered visible if is marked as visible. If the product attribute model is created for a specific product, the product must also define a value for the attribute definition; else the attribute definition is considered as invisible. The returned attribute definitions are sorted according to the explicit sort order defined for the attributes in the group. This is managed by merchant in the Business Manager.
256 | 
257 | **Parameters:**
258 | 
259 | - `group`: the group whose visible attribute definitions are returned.
260 | 
261 | **Returns:**
262 | 
263 | a sorted collection of visible ObjectAttributeDefinition instances.
264 | 
265 | ---
266 | 
267 | ### getVisibleAttributeGroups
268 | 
269 | **Signature:** `getVisibleAttributeGroups() : Collection`
270 | 
271 | **Description:** Returns a sorted collection of visible attribute groups of this model. This method is similar to getAttributeGroups() but only includes attribute groups containing at least one attribute definition that is visible. See getVisibleAttributeDefinitions(ObjectAttributeGroup).
272 | 
273 | **Returns:**
274 | 
275 | sorted collection of visible ObjectAttributeGroup instances.
276 | 
277 | ---
```

--------------------------------------------------------------------------------
/tests/mcp/yaml/get-sfra-document.docs-only.test.mcp.yml:
--------------------------------------------------------------------------------

```yaml
  1 | description: "Test get_sfra_document tool for retrieving SFRA documentation"
  2 | tests:
  3 |   # Smoke test - ensure tool is available and accessible
  4 |   - it: "should be available in tools list"
  5 |     request:
  6 |       jsonrpc: "2.0"
  7 |       id: "list-sfra-document-tool"
  8 |       method: "tools/list"
  9 |       params: {}
 10 |     expect:
 11 |       response:
 12 |         jsonrpc: "2.0"
 13 |         id: "list-sfra-document-tool"
 14 |         result:
 15 |           tools:
 16 |             match:arrayContains:name:get_sfra_document
 17 |       stderr: "toBeEmpty"
 18 | 
 19 |   # Valid document tests - Core SFRA classes
 20 |   - it: "should retrieve server document successfully"
 21 |     request:
 22 |       jsonrpc: "2.0"
 23 |       id: "get-server-doc"
 24 |       method: "tools/call"
 25 |       params:
 26 |         name: "get_sfra_document"
 27 |         arguments:
 28 |           documentName: "server"
 29 |     expect:
 30 |       response:
 31 |         jsonrpc: "2.0"
 32 |         id: "get-server-doc"
 33 |         result:
 34 |           content:
 35 |             - type: "text"
 36 |               text: "match:contains:Class Server"
 37 |           isError: false
 38 |       performance:
 39 |         maxResponseTime: "2000ms"
 40 |       stderr: "toBeEmpty"
 41 | 
 42 |   - it: "should retrieve request document successfully"
 43 |     request:
 44 |       jsonrpc: "2.0"
 45 |       id: "get-request-doc"
 46 |       method: "tools/call"
 47 |       params:
 48 |         name: "get_sfra_document"
 49 |         arguments:
 50 |           documentName: "request"
 51 |     expect:
 52 |       response:
 53 |         jsonrpc: "2.0"
 54 |         id: "get-request-doc"
 55 |         result:
 56 |           content:
 57 |             - type: "text"
 58 |               text: "match:contains:Class Request"
 59 |           isError: false
 60 |       performance:
 61 |         maxResponseTime: "2000ms"
 62 |       stderr: "toBeEmpty"
 63 | 
 64 |   - it: "should retrieve response document successfully"
 65 |     request:
 66 |       jsonrpc: "2.0"
 67 |       id: "get-response-doc"
 68 |       method: "tools/call"
 69 |       params:
 70 |         name: "get_sfra_document"
 71 |         arguments:
 72 |           documentName: "response"
 73 |     expect:
 74 |       response:
 75 |         jsonrpc: "2.0"
 76 |         id: "get-response-doc"
 77 |         result:
 78 |           content:
 79 |             - type: "text"
 80 |               text: "match:contains:Class Response"
 81 |           isError: false
 82 |       performance:
 83 |         maxResponseTime: "2000ms"
 84 |       stderr: "toBeEmpty"
 85 | 
 86 |   - it: "should retrieve querystring document successfully"
 87 |     request:
 88 |       jsonrpc: "2.0"
 89 |       id: "get-querystring-doc"
 90 |       method: "tools/call"
 91 |       params:
 92 |         name: "get_sfra_document"
 93 |         arguments:
 94 |           documentName: "querystring"
 95 |     expect:
 96 |       response:
 97 |         jsonrpc: "2.0"
 98 |         id: "get-querystring-doc"
 99 |         result:
100 |           content:
101 |             - type: "text"
102 |               text: "match:contains:QueryString"
103 |           isError: false
104 |       performance:
105 |         maxResponseTime: "2000ms"
106 |       stderr: "toBeEmpty"
107 | 
108 |   - it: "should retrieve render document successfully"
109 |     request:
110 |       jsonrpc: "2.0"
111 |       id: "get-render-doc"
112 |       method: "tools/call"
113 |       params:
114 |         name: "get_sfra_document"
115 |         arguments:
116 |           documentName: "render"
117 |     expect:
118 |       response:
119 |         jsonrpc: "2.0"
120 |         id: "get-render-doc"
121 |         result:
122 |           content:
123 |             - type: "text"
124 |               text: "match:contains:render"
125 |           isError: false
126 |       performance:
127 |         maxResponseTime: "2000ms"
128 |       stderr: "toBeEmpty"
129 | 
130 |   # Product model tests
131 |   - it: "should retrieve product-full document successfully"
132 |     request:
133 |       jsonrpc: "2.0"
134 |       id: "get-product-full-doc"
135 |       method: "tools/call"
136 |       params:
137 |         name: "get_sfra_document"
138 |         arguments:
139 |           documentName: "product-full"
140 |     expect:
141 |       response:
142 |         jsonrpc: "2.0"
143 |         id: "get-product-full-doc"
144 |         result:
145 |           content:
146 |             - type: "text"
147 |               text: "match:contains:product"
148 |           isError: false
149 |       performance:
150 |         maxResponseTime: "2000ms"
151 |       stderr: "toBeEmpty"
152 | 
153 |   - it: "should retrieve cart document successfully"
154 |     request:
155 |       jsonrpc: "2.0"
156 |       id: "get-cart-doc"
157 |       method: "tools/call"
158 |       params:
159 |         name: "get_sfra_document"
160 |         arguments:
161 |           documentName: "cart"
162 |     expect:
163 |       response:
164 |         jsonrpc: "2.0"
165 |         id: "get-cart-doc"
166 |         result:
167 |           content:
168 |             - type: "text"
169 |               text: "match:contains:cart"
170 |           isError: false
171 |       performance:
172 |         maxResponseTime: "2000ms"
173 |       stderr: "toBeEmpty"
174 | 
175 |   # Customer model tests
176 |   - it: "should retrieve account document successfully"
177 |     request:
178 |       jsonrpc: "2.0"
179 |       id: "get-account-doc"
180 |       method: "tools/call"
181 |       params:
182 |         name: "get_sfra_document"
183 |         arguments:
184 |           documentName: "account"
185 |     expect:
186 |       response:
187 |         jsonrpc: "2.0"
188 |         id: "get-account-doc"
189 |         result:
190 |           content:
191 |             - type: "text"
192 |               text: "match:contains:account"
193 |           isError: false
194 |       performance:
195 |         maxResponseTime: "2000ms"
196 |       stderr: "toBeEmpty"
197 | 
198 |   # Response format validation tests
199 |   - it: "should return properly structured JSON content"
200 |     request:
201 |       jsonrpc: "2.0"
202 |       id: "validate-server-structure"
203 |       method: "tools/call"
204 |       params:
205 |         name: "get_sfra_document"
206 |         arguments:
207 |           documentName: "server"
208 |     expect:
209 |       response:
210 |         jsonrpc: "2.0"
211 |         id: "validate-server-structure"
212 |         result:
213 |           content:
214 |             - type: "text"
215 |               text: "match:regex:\\{[\\s\\S]*title[\\s\\S]*sections[\\s\\S]*content[\\s\\S]*\\}"
216 |           isError: false
217 |       stderr: "toBeEmpty"
218 | 
219 |   - it: "should include document metadata"
220 |     request:
221 |       jsonrpc: "2.0"
222 |       id: "validate-metadata"
223 |       method: "tools/call"
224 |       params:
225 |         name: "get_sfra_document"
226 |         arguments:
227 |           documentName: "server"
228 |     expect:
229 |       response:
230 |         jsonrpc: "2.0"
231 |         id: "validate-metadata"
232 |         result:
233 |           content:
234 |             - type: "text"
235 |               text: "match:regex:[\\s\\S]*type[\\s\\S]*category[\\s\\S]*filename[\\s\\S]*lastModified[\\s\\S]*"
236 |           isError: false
237 |       stderr: "toBeEmpty"
238 | 
239 |   - it: "should include sections array"
240 |     request:
241 |       jsonrpc: "2.0"
242 |       id: "validate-sections"
243 |       method: "tools/call"
244 |       params:
245 |         name: "get_sfra_document"
246 |         arguments:
247 |           documentName: "server"
248 |     expect:
249 |       response:
250 |         jsonrpc: "2.0"
251 |         id: "validate-sections"
252 |         result:
253 |           content:
254 |             - type: "text"
255 |               text: "match:regex:[\\s\\S]*sections[\\s\\S]*\\[[\\s\\S]*\\][\\s\\S]*"
256 |           isError: false
257 |       stderr: "toBeEmpty"
258 | 
259 |   - it: "should include comprehensive content"
260 |     request:
261 |       jsonrpc: "2.0"
262 |       id: "validate-content-detail"
263 |       method: "tools/call"
264 |       params:
265 |         name: "get_sfra_document"
266 |         arguments:
267 |           documentName: "server"
268 |     expect:
269 |       response:
270 |         jsonrpc: "2.0"
271 |         id: "validate-content-detail"
272 |         result:
273 |           content:
274 |             - type: "text"
275 |               text: "match:regex:[\\s\\S]*Description[\\s\\S]*Method Summary[\\s\\S]*Method Detail[\\s\\S]*"
276 |           isError: false
277 |       stderr: "toBeEmpty"
278 | 
279 |   # Error handling tests
280 |   - it: "should handle nonexistent document gracefully"
281 |     request:
282 |       jsonrpc: "2.0"
283 |       id: "error-nonexistent"
284 |       method: "tools/call"
285 |       params:
286 |         name: "get_sfra_document"
287 |         arguments:
288 |           documentName: "nonexistent-document"
289 |     expect:
290 |       response:
291 |         jsonrpc: "2.0"
292 |         id: "error-nonexistent"
293 |         result:
294 |           content:
295 |             - type: "text"
296 |               text: "match:contains:not found"
297 |           isError: true
298 |       stderr: "toBeEmpty"
299 | 
300 |   - it: "should handle empty document name"
301 |     request:
302 |       jsonrpc: "2.0"
303 |       id: "error-empty-name"
304 |       method: "tools/call"
305 |       params:
306 |         name: "get_sfra_document"
307 |         arguments:
308 |           documentName: ""
309 |     expect:
310 |       response:
311 |         jsonrpc: "2.0"
312 |         id: "error-empty-name"
313 |         result:
314 |           content:
315 |             - type: "text"
316 |               text: "match:regex:(Error|not found|invalid)"
317 |           isError: true
318 |       stderr: "toBeEmpty"
319 | 
320 |   - it: "should handle invalid document name characters"
321 |     request:
322 |       jsonrpc: "2.0"
323 |       id: "error-invalid-chars"
324 |       method: "tools/call"
325 |       params:
326 |         name: "get_sfra_document"
327 |         arguments:
328 |           documentName: "invalid/document/name"
329 |     expect:
330 |       response:
331 |         jsonrpc: "2.0"
332 |         id: "error-invalid-chars"
333 |         result:
334 |           content:
335 |             - type: "text"
336 |               text: "match:regex:(Error|not found|invalid)"
337 |           isError: true
338 |       stderr: "toBeEmpty"
339 | 
340 |   - it: "should handle missing documentName parameter"
341 |     request:
342 |       jsonrpc: "2.0"
343 |       id: "error-missing-param"
344 |       method: "tools/call"
345 |       params:
346 |         name: "get_sfra_document"
347 |         arguments: {}
348 |     expect:
349 |       response:
350 |         jsonrpc: "2.0"
351 |         id: "error-missing-param"
352 |         result:
353 |           content:
354 |             - type: "text"
355 |               text: "match:regex:(Error|required|missing|documentName|non-empty string)"
356 |           isError: true
357 |       stderr: "toBeEmpty"
358 | 
359 |   # Case sensitivity tests - it appears the tool is case-insensitive
360 |   - it: "should handle case variations for document names"
361 |     request:
362 |       jsonrpc: "2.0"
363 |       id: "case-insensitive-upper"
364 |       method: "tools/call"
365 |       params:
366 |         name: "get_sfra_document"
367 |         arguments:
368 |           documentName: "SERVER"
369 |     expect:
370 |       response:
371 |         jsonrpc: "2.0"
372 |         id: "case-insensitive-upper"
373 |         result:
374 |           content:
375 |             - type: "text"
376 |               text: "match:contains:Class Server"
377 |           isError: false
378 |       stderr: "toBeEmpty"
379 | 
380 |   - it: "should handle mixed case document names"
381 |     request:
382 |       jsonrpc: "2.0"
383 |       id: "case-insensitive-mixed"
384 |       method: "tools/call"
385 |       params:
386 |         name: "get_sfra_document"
387 |         arguments:
388 |           documentName: "Server"
389 |     expect:
390 |       response:
391 |         jsonrpc: "2.0"
392 |         id: "case-insensitive-mixed"
393 |         result:
394 |           content:
395 |             - type: "text"
396 |               text: "match:contains:Class Server"
397 |           isError: false
398 |       stderr: "toBeEmpty"
399 | 
400 |   # Content quality tests
401 |   - it: "should provide meaningful content for server document"
402 |     request:
403 |       jsonrpc: "2.0"
404 |       id: "content-quality-server"
405 |       method: "tools/call"
406 |       params:
407 |         name: "get_sfra_document"
408 |         arguments:
409 |           documentName: "server"
410 |     expect:
411 |       response:
412 |         jsonrpc: "2.0"
413 |         id: "content-quality-server"
414 |         result:
415 |           content:
416 |             - type: "text"
417 |               text: "match:regex:[\\s\\S]*middleware[\\s\\S]*routing[\\s\\S]*HTTP[\\s\\S]*"
418 |           isError: false
419 |       stderr: "toBeEmpty"
420 | 
421 |   - it: "should provide meaningful content for request document"
422 |     request:
423 |       jsonrpc: "2.0"
424 |       id: "content-quality-request"
425 |       method: "tools/call"
426 |       params:
427 |         name: "get_sfra_document"
428 |         arguments:
429 |           documentName: "request"
430 |     expect:
431 |       response:
432 |         jsonrpc: "2.0"
433 |         id: "content-quality-request"
434 |         result:
435 |           content:
436 |             - type: "text"
437 |               text: "match:regex:[\\s\\S]*HTTP[\\s\\S]*session[\\s\\S]*customer[\\s\\S]*"
438 |           isError: false
439 |       stderr: "toBeEmpty"
440 | 
441 |   # Additional model document tests
442 |   - it: "should retrieve billing document successfully"
443 |     request:
444 |       jsonrpc: "2.0"
445 |       id: "get-billing-doc"
446 |       method: "tools/call"
447 |       params:
448 |         name: "get_sfra_document"
449 |         arguments:
450 |           documentName: "billing"
451 |     expect:
452 |       response:
453 |         jsonrpc: "2.0"
454 |         id: "get-billing-doc"
455 |         result:
456 |           content:
457 |             - type: "text"
458 |               text: "match:contains:billing"
459 |           isError: false
460 |       performance:
461 |         maxResponseTime: "2000ms"
462 |       stderr: "toBeEmpty"
463 | 
464 |   - it: "should retrieve shipping document successfully"
465 |     request:
466 |       jsonrpc: "2.0"
467 |       id: "get-shipping-doc"
468 |       method: "tools/call"
469 |       params:
470 |         name: "get_sfra_document"
471 |         arguments:
472 |           documentName: "shipping"
473 |     expect:
474 |       response:
475 |         jsonrpc: "2.0"
476 |         id: "get-shipping-doc"
477 |         result:
478 |           content:
479 |             - type: "text"
480 |               text: "match:contains:shipping"
481 |           isError: false
482 |       performance:
483 |         maxResponseTime: "2000ms"
484 |       stderr: "toBeEmpty"
485 | 
486 |   # Edge case tests
487 |   - it: "should handle document names with hyphens"
488 |     request:
489 |       jsonrpc: "2.0"
490 |       id: "hyphen-document"
491 |       method: "tools/call"
492 |       params:
493 |         name: "get_sfra_document"
494 |         arguments:
495 |           documentName: "product-full"
496 |     expect:
497 |       response:
498 |         jsonrpc: "2.0"
499 |         id: "hyphen-document"
500 |         result:
501 |           content:
502 |             - type: "text"
503 |               text: "match:type:string"
504 |           isError: false
505 |       stderr: "toBeEmpty"
506 | 
507 |   - it: "should handle very long nonexistent document names"
508 |     request:
509 |       jsonrpc: "2.0"
510 |       id: "long-nonexistent"
511 |       method: "tools/call"
512 |       params:
513 |         name: "get_sfra_document"
514 |         arguments:
515 |           documentName: "this-is-a-very-long-document-name-that-definitely-does-not-exist-anywhere"
516 |     expect:
517 |       response:
518 |         jsonrpc: "2.0"
519 |         id: "long-nonexistent"
520 |         result:
521 |           content:
522 |             - type: "text"
523 |               text: "match:regex:(Error|not found)"
524 |           isError: true
525 |       stderr: "toBeEmpty"
526 | 
```
Page 24/61FirstPrevNextLast