#
tokens: 47548/50000 5/825 files (page 42/61)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 42 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/mcp/node/search-sfra-documentation.docs-only.programmatic.test.js:
--------------------------------------------------------------------------------

```javascript
  1 | import { test, describe, before, after, beforeEach } from 'node:test';
  2 | import { strict as assert } from 'node:assert';
  3 | import { connect } from 'mcp-aegis';
  4 | 
  5 | describe('search_sfra_documentation Tool Programmatic Tests', () => {
  6 |   let client;
  7 | 
  8 |   before(async () => {
  9 |     client = await connect('./aegis.config.docs-only.json');
 10 |   });
 11 | 
 12 |   after(async () => {
 13 |     if (client?.connected) {
 14 |       await client.disconnect();
 15 |     }
 16 |   });
 17 | 
 18 |   beforeEach(() => {
 19 |     // CRITICAL: Clear all buffers to prevent leaking into next tests
 20 |     client.clearAllBuffers();
 21 |   });
 22 | 
 23 |   describe('Valid Search Queries', () => {
 24 |     test('should return structured search results for "render" query', async () => {
 25 |       const result = await client.callTool('search_sfra_documentation', { query: 'render' });
 26 |       
 27 |       assert.equal(result.isError, false, 'Should not be an error');
 28 |       assert.ok(result.content, 'Should have content');
 29 |       assert.equal(result.content.length, 1, 'Should have one content item');
 30 |       assert.equal(result.content[0].type, 'text', 'Content should be text type');
 31 |       
 32 |       // Parse the JSON response
 33 |       const searchResults = JSON.parse(result.content[0].text);
 34 |       assert.ok(Array.isArray(searchResults), 'Results should be an array');
 35 |       assert.ok(searchResults.length > 0, 'Should have search results for "render"');
 36 |       
 37 |       // Validate structure of first result
 38 |       const firstResult = searchResults[0];
 39 |       assert.ok(firstResult.document, 'Should have document field');
 40 |       assert.ok(firstResult.title, 'Should have title field');
 41 |       assert.ok(firstResult.category, 'Should have category field');
 42 |       assert.ok(firstResult.type, 'Should have type field');
 43 |       assert.ok(typeof firstResult.relevanceScore === 'number', 'Should have numeric relevance score');
 44 |       assert.ok(Array.isArray(firstResult.matches), 'Should have matches array');
 45 |     });
 46 | 
 47 |     test('should return results with different document types', async () => {
 48 |       const result = await client.callTool('search_sfra_documentation', { query: 'server' });
 49 |       
 50 |       assert.equal(result.isError, false, 'Should not be an error');
 51 |       
 52 |       const searchResults = JSON.parse(result.content[0].text);
 53 |       assert.ok(searchResults.length > 0, 'Should have results for "server"');
 54 |       
 55 |       // Check that results include various document types
 56 |       const documentTypes = searchResults.map(r => r.type);
 57 |       const uniqueTypes = [...new Set(documentTypes)];
 58 |       assert.ok(uniqueTypes.length > 0, 'Should have at least one document type');
 59 |       
 60 |       // Verify known SFRA types are present (class, module, model)
 61 |       const validTypes = ['class', 'module', 'model'];
 62 |       const hasValidType = searchResults.some(r => validTypes.includes(r.type));
 63 |       assert.ok(hasValidType, 'Should include valid SFRA document types');
 64 |     });
 65 | 
 66 |     test('should include relevance scoring and matches', async () => {
 67 |       const result = await client.callTool('search_sfra_documentation', { query: 'response' });
 68 |       
 69 |       assert.equal(result.isError, false, 'Should not be an error');
 70 |       
 71 |       const searchResults = JSON.parse(result.content[0].text);
 72 |       assert.ok(searchResults.length > 0, 'Should have results for "response"');
 73 |       
 74 |       // Validate relevance scoring
 75 |       for (const searchResult of searchResults) {
 76 |         assert.ok(typeof searchResult.relevanceScore === 'number', 'Each result should have numeric relevance score');
 77 |         assert.ok(searchResult.relevanceScore >= 0, 'Relevance score should be non-negative');
 78 |         
 79 |         // Validate matches structure
 80 |         assert.ok(Array.isArray(searchResult.matches), 'Should have matches array');
 81 |         if (searchResult.matches.length > 0) {
 82 |           const firstMatch = searchResult.matches[0];
 83 |           assert.ok(firstMatch.section, 'Match should have section field');
 84 |           assert.ok(firstMatch.content, 'Match should have content field');
 85 |           assert.ok(typeof firstMatch.lineNumber === 'number', 'Match should have numeric line number');
 86 |         }
 87 |       }
 88 |     });
 89 | 
 90 |     test('should return results ordered by relevance', async () => {
 91 |       const result = await client.callTool('search_sfra_documentation', { query: 'product' });
 92 |       
 93 |       assert.equal(result.isError, false, 'Should not be an error');
 94 |       
 95 |       const searchResults = JSON.parse(result.content[0].text);
 96 |       assert.ok(searchResults.length > 1, 'Should have multiple results to test ordering');
 97 |       
 98 |       // Check that results are ordered by relevance score (descending)
 99 |       for (let i = 1; i < searchResults.length; i++) {
100 |         assert.ok(
101 |           searchResults[i - 1].relevanceScore >= searchResults[i].relevanceScore,
102 |           `Results should be ordered by relevance: ${searchResults[i - 1].relevanceScore} >= ${searchResults[i].relevanceScore}`
103 |         );
104 |       }
105 |     });
106 | 
107 |     test('should categorize documents appropriately', async () => {
108 |       const result = await client.callTool('search_sfra_documentation', { query: 'model' });
109 |       
110 |       assert.equal(result.isError, false, 'Should not be an error');
111 |       
112 |       const searchResults = JSON.parse(result.content[0].text);
113 |       assert.ok(searchResults.length > 0, 'Should have results for "model"');
114 |       
115 |       // Verify categories are valid SFRA categories
116 |       const validCategories = ['core', 'product', 'order', 'customer', 'pricing', 'store', 'other'];
117 |       for (const searchResult of searchResults) {
118 |         assert.ok(
119 |           validCategories.includes(searchResult.category),
120 |           `Category "${searchResult.category}" should be one of: ${validCategories.join(', ')}`
121 |         );
122 |       }
123 |     });
124 | 
125 |     test('should handle special characters in search queries', async () => {
126 |       const result = await client.callTool('search_sfra_documentation', { query: 'dw.util' });
127 |       
128 |       assert.equal(result.isError, false, 'Should not be an error');
129 |       
130 |       const searchResults = JSON.parse(result.content[0].text);
131 |       // Results may be empty or contain matches - both are valid for this query
132 |       assert.ok(Array.isArray(searchResults), 'Should return an array even for special character queries');
133 |     });
134 |   });
135 | 
136 |   describe('Edge Cases and Error Handling', () => {
137 |     test('should return empty array for queries with no matches', async () => {
138 |       const result = await client.callTool('search_sfra_documentation', { query: 'zzznothingfound' });
139 |       
140 |       assert.equal(result.isError, false, 'Should not be an error for no matches');
141 |       assert.equal(result.content[0].text, '[]', 'Should return empty JSON array');
142 |     });
143 | 
144 |     test('should handle empty query with validation error', async () => {
145 |       const result = await client.callTool('search_sfra_documentation', { query: '' });
146 |       
147 |       assert.equal(result.isError, true, 'Should be an error for empty query');
148 |       assert.ok(result.content[0].text.includes('query must be a non-empty string'), 'Should have appropriate error message');
149 |     });
150 | 
151 |     test('should handle missing query parameter', async () => {
152 |       const result = await client.callTool('search_sfra_documentation', {});
153 |       
154 |       assert.equal(result.isError, true, 'Should be an error for missing query');
155 |       assert.ok(result.content[0].text.includes('query must be a non-empty string'), 'Should indicate query is required');
156 |     });
157 | 
158 |     test('should handle whitespace-only query as invalid', async () => {
159 |       const result = await client.callTool('search_sfra_documentation', { query: '   ' });
160 |       
161 |       assert.equal(result.isError, true, 'Should be an error for whitespace-only query');
162 |       assert.ok(result.content[0].text.includes('query must be a non-empty string'), 'Should have appropriate error message');
163 |     });
164 |   });
165 | 
166 | 
167 |   describe('Search Result Quality', () => {
168 |     test('should return relevant results for core SFRA concepts', async () => {
169 |       const coreTerms = ['server', 'request', 'response', 'render'];
170 |       
171 |       for (const term of coreTerms) {
172 |         const result = await client.callTool('search_sfra_documentation', { query: term });
173 |         
174 |         assert.equal(result.isError, false, `Should not be an error for term: ${term}`);
175 |         
176 |         const searchResults = JSON.parse(result.content[0].text);
177 |         assert.ok(searchResults.length > 0, `Should have results for core term: ${term}`);
178 |         
179 |         // Verify that the search term appears in at least one match
180 |         const hasTermInMatches = searchResults.some(sr => 
181 |           sr.matches.some(match => 
182 |             match.content.toLowerCase().includes(term.toLowerCase()) ||
183 |             match.section.toLowerCase().includes(term.toLowerCase())
184 |           )
185 |         );
186 |         assert.ok(hasTermInMatches, `Search results should contain relevant matches for term: ${term}`);
187 |       }
188 |     });
189 | 
190 |     test('should provide useful context in match content', async () => {
191 |       const result = await client.callTool('search_sfra_documentation', { query: 'template' });
192 |       
193 |       assert.equal(result.isError, false, 'Should not be an error');
194 |       
195 |       const searchResults = JSON.parse(result.content[0].text);
196 |       assert.ok(searchResults.length > 0, 'Should have results for "template"');
197 |       
198 |       // Check that matches provide useful context
199 |       for (const searchResult of searchResults) {
200 |         for (const match of searchResult.matches) {
201 |           assert.ok(match.content.length > 10, 'Match content should provide substantial context');
202 |           assert.ok(match.section && match.section.length > 0, 'Match should have meaningful section information');
203 |         }
204 |       }
205 |     });
206 | 
207 |     test('should return appropriate number of results', async () => {
208 |       const result = await client.callTool('search_sfra_documentation', { query: 'product' });
209 |       
210 |       assert.equal(result.isError, false, 'Should not be an error');
211 |       
212 |       const searchResults = JSON.parse(result.content[0].text);
213 |       
214 |       // Should return a reasonable number of results (not too few, not too many)
215 |       assert.ok(searchResults.length >= 1, 'Should have at least 1 result for broad term');
216 |       assert.ok(searchResults.length <= 50, 'Should not return excessive number of results');
217 |     });
218 |   });
219 | 
220 |   describe('Dynamic Validation', () => {
221 |     test('should validate all required fields are present in search results', async () => {
222 |       const result = await client.callTool('search_sfra_documentation', { query: 'price' });
223 |       
224 |       assert.equal(result.isError, false, 'Should not be an error');
225 |       
226 |       const searchResults = JSON.parse(result.content[0].text);
227 |       
228 |       const requiredFields = ['document', 'title', 'category', 'type', 'relevanceScore', 'matches'];
229 |       const requiredMatchFields = ['section', 'content', 'lineNumber'];
230 |       
231 |       for (const searchResult of searchResults) {
232 |         // Validate main result structure
233 |         for (const field of requiredFields) {
234 |           assert.ok(field in searchResult, `Search result should have ${field} field`);
235 |         }
236 |         
237 |         // Validate matches structure
238 |         for (const match of searchResult.matches) {
239 |           for (const field of requiredMatchFields) {
240 |             assert.ok(field in match, `Match should have ${field} field`);
241 |           }
242 |         }
243 |       }
244 |     });
245 |   });
246 | 
247 |   describe('Advanced Search Scenarios', () => {
248 |     test('should handle complex multi-term searches effectively', async () => {
249 |       const complexQueries = [
250 |         'render template isml',
251 |         'request response middleware',
252 |         'product cart pricing',
253 |         'server routing controller'
254 |       ];
255 |       
256 |       for (const query of complexQueries) {
257 |         const result = await client.callTool('search_sfra_documentation', { query });
258 |         
259 |         assert.equal(result.isError, false, `Should handle complex query: "${query}"`);
260 |         
261 |         const searchResults = JSON.parse(result.content[0].text);
262 |         // Complex queries should return results (may be empty but shouldn't error)
263 |         assert.ok(Array.isArray(searchResults), `Should return array for query: "${query}"`);
264 |       }
265 |     });
266 | 
267 |     test('should find specific SFRA document types by search', async () => {
268 |       const documentTypeQueries = [
269 |         { query: 'server', expectedType: 'class' },
270 |         { query: 'render', expectedType: 'module' },
271 |         { query: 'product-full', expectedType: 'model' },
272 |         { query: 'response', expectedType: 'class' }
273 |       ];
274 |       
275 |       for (const { query, expectedType } of documentTypeQueries) {
276 |         const result = await client.callTool('search_sfra_documentation', { query });
277 |         
278 |         assert.equal(result.isError, false, `Should not error for query: "${query}"`);
279 |         
280 |         const searchResults = JSON.parse(result.content[0].text);
281 |         if (searchResults.length > 0) {
282 |           const hasExpectedType = searchResults.some(r => r.type === expectedType);
283 |           assert.ok(hasExpectedType, `Should find ${expectedType} documents for query: "${query}"`);
284 |         }
285 |       }
286 |     });
287 | 
288 |     test('should maintain search result consistency across calls', async () => {
289 |       const query = 'cart';
290 |       const results = [];
291 |       
292 |       // Perform same search multiple times
293 |       for (let i = 0; i < 3; i++) {
294 |         const result = await client.callTool('search_sfra_documentation', { query });
295 |         assert.equal(result.isError, false, `Call ${i + 1} should not error`);
296 |         results.push(JSON.parse(result.content[0].text));
297 |       }
298 |       
299 |       // All results should have same length
300 |       const lengths = results.map(r => r.length);
301 |       const allSameLength = lengths.every(len => len === lengths[0]);
302 |       assert.ok(allSameLength, 'All search calls should return same number of results');
303 |       
304 |       // First result should have same document in all calls
305 |       if (results[0].length > 0) {
306 |         const firstDocuments = results.map(r => r[0].document);
307 |         const allSameFirstDoc = firstDocuments.every(doc => doc === firstDocuments[0]);
308 |         assert.ok(allSameFirstDoc, 'First result should be consistent across calls');
309 |       }
310 |     });
311 | 
312 |     test('should handle category-specific searches', async () => {
313 |       const categoryQueries = [
314 |         { query: 'server request response', expectedCategory: 'core' },
315 |         { query: 'product bundle variant', expectedCategory: 'product' },
316 |         { query: 'cart checkout billing', expectedCategory: 'order' },
317 |         { query: 'customer account profile', expectedCategory: 'customer' }
318 |       ];
319 |       
320 |       for (const { query, expectedCategory } of categoryQueries) {
321 |         const result = await client.callTool('search_sfra_documentation', { query });
322 |         
323 |         assert.equal(result.isError, false, `Should not error for category query: "${query}"`);
324 |         
325 |         const searchResults = JSON.parse(result.content[0].text);
326 |         if (searchResults.length > 0) {
327 |           const hasExpectedCategory = searchResults.some(r => r.category === expectedCategory);
328 |           assert.ok(hasExpectedCategory, `Should find ${expectedCategory} documents for query: "${query}"`);
329 |         }
330 |       }
331 |     });
332 | 
333 |     test('should handle case-insensitive searches correctly', async () => {
334 |       const casePairs = [
335 |         { lower: 'product', upper: 'PRODUCT' },
336 |         { lower: 'render', upper: 'RENDER' },
337 |         { lower: 'server', upper: 'SERVER' }
338 |       ];
339 |       
340 |       for (const { lower, upper } of casePairs) {
341 |         const lowerResult = await client.callTool('search_sfra_documentation', { query: lower });
342 |         const upperResult = await client.callTool('search_sfra_documentation', { query: upper });
343 |         
344 |         assert.equal(lowerResult.isError, false, `Lowercase "${lower}" should not error`);
345 |         assert.equal(upperResult.isError, false, `Uppercase "${upper}" should not error`);
346 |         
347 |         const lowerResults = JSON.parse(lowerResult.content[0].text);
348 |         const upperResults = JSON.parse(upperResult.content[0].text);
349 |         
350 |         // Results should be identical for case variations
351 |         assert.equal(lowerResults.length, upperResults.length, 
352 |           `Case insensitive search should return same number of results for "${lower}" vs "${upper}"`);
353 |       }
354 |     });
355 | 
356 |     test('should provide meaningful search result context', async () => {
357 |       const result = await client.callTool('search_sfra_documentation', { query: 'template' });
358 |       
359 |       assert.equal(result.isError, false, 'Should not be an error');
360 |       
361 |       const searchResults = JSON.parse(result.content[0].text);
362 |       assert.ok(searchResults.length > 0, 'Should have results for "template"');
363 |       
364 |       for (const searchResult of searchResults) {
365 |         // Validate document metadata quality
366 |         assert.ok(searchResult.title.length > 0, 'Title should not be empty');
367 |         assert.ok(searchResult.document.length > 0, 'Document name should not be empty');
368 |         
369 |         // Validate matches provide good context
370 |         for (const match of searchResult.matches) {
371 |           assert.ok(match.content.length > 20, 'Match content should be substantial');
372 |           assert.ok(match.section.length > 0, 'Match section should be specified');
373 |           assert.ok(match.lineNumber > 0, 'Line number should be positive');
374 |           
375 |           // Content should contain search term or related context
376 |           const hasRelevantContent = match.content.toLowerCase().includes('template') ||
377 |                                    match.content.toLowerCase().includes('render') ||
378 |                                    match.content.toLowerCase().includes('view');
379 |           assert.ok(hasRelevantContent, 'Match content should be relevant to search term');
380 |         }
381 |       }
382 |     });
383 |   });
384 | 
385 |   describe('Boundary Condition Testing', () => {
386 |     test('should handle very short queries', async () => {
387 |       const shortQueries = ['a', 'b', 'c', '1', '2'];
388 |       
389 |       for (const query of shortQueries) {
390 |         const result = await client.callTool('search_sfra_documentation', { query });
391 |         
392 |         assert.equal(result.isError, false, `Short query "${query}" should not error`);
393 |         
394 |         const searchResults = JSON.parse(result.content[0].text);
395 |         assert.ok(Array.isArray(searchResults), `Should return array for short query: "${query}"`);
396 |         // Short queries may return many or few results - both are valid
397 |       }
398 |     });
399 | 
400 |     test('should handle queries with special characters', async () => {
401 |       const specialQueries = [
402 |         'dw.util.Collection',
403 |         'product.price',
404 |         'server-response',
405 |         'cart_model',
406 |         'request/response',
407 |         'template.isml'
408 |       ];
409 |       
410 |       for (const query of specialQueries) {
411 |         const result = await client.callTool('search_sfra_documentation', { query });
412 |         
413 |         assert.equal(result.isError, false, `Special character query "${query}" should not error`);
414 |         
415 |         const searchResults = JSON.parse(result.content[0].text);
416 |         assert.ok(Array.isArray(searchResults), `Should return array for special query: "${query}"`);
417 |       }
418 |     });
419 | 
420 |     test('should handle extremely long queries gracefully', async () => {
421 |       const longQuery = 'template rendering isml view data processing controller middleware response request server router navigation menu product catalog pricing cart checkout billing shipping customer account profile management'.repeat(3);
422 |       
423 |       const result = await client.callTool('search_sfra_documentation', { query: longQuery });
424 |       
425 |       assert.equal(result.isError, false, 'Very long query should not error');
426 |       
427 |       const searchResults = JSON.parse(result.content[0].text);
428 |       assert.ok(Array.isArray(searchResults), 'Should return array for very long query');
429 |     });
430 | 
431 |     test('should handle numeric and mixed alphanumeric queries', async () => {
432 |       const numericQueries = ['200', '404', '500', 'v1.2', 'api2', 'html5'];
433 |       
434 |       for (const query of numericQueries) {
435 |         const result = await client.callTool('search_sfra_documentation', { query });
436 |         
437 |         assert.equal(result.isError, false, `Numeric query "${query}" should not error`);
438 |         
439 |         const searchResults = JSON.parse(result.content[0].text);
440 |         assert.ok(Array.isArray(searchResults), `Should return array for numeric query: "${query}"`);
441 |       }
442 |     });
443 |   });
444 | 
445 |   describe('Search Quality and Relevance', () => {
446 |     test('should prioritize exact matches in relevance scoring', async () => {
447 |       const result = await client.callTool('search_sfra_documentation', { query: 'render' });
448 |       
449 |       assert.equal(result.isError, false, 'Should not be an error');
450 |       
451 |       const searchResults = JSON.parse(result.content[0].text);
452 |       assert.ok(searchResults.length > 0, 'Should have results for "render"');
453 |       
454 |       // Find results with "render" in document name vs those without
455 |       const exactMatches = searchResults.filter(r => r.document.toLowerCase().includes('render'));
456 |       const otherMatches = searchResults.filter(r => !r.document.toLowerCase().includes('render'));
457 |       
458 |       if (exactMatches.length > 0 && otherMatches.length > 0) {
459 |         // Exact matches should generally have higher relevance scores
460 |         const avgExactScore = exactMatches.reduce((sum, r) => sum + r.relevanceScore, 0) / exactMatches.length;
461 |         const avgOtherScore = otherMatches.reduce((sum, r) => sum + r.relevanceScore, 0) / otherMatches.length;
462 |         
463 |         assert.ok(avgExactScore >= avgOtherScore, 'Exact matches should have higher average relevance score');
464 |       }
465 |     });
466 | 
467 |     test('should return comprehensive results for broad searches', async () => {
468 |       const broadQueries = ['model', 'data', 'api', 'object'];
469 |       
470 |       for (const query of broadQueries) {
471 |         const result = await client.callTool('search_sfra_documentation', { query });
472 |         
473 |         assert.equal(result.isError, false, `Broad query "${query}" should not error`);
474 |         
475 |         const searchResults = JSON.parse(result.content[0].text);
476 |         
477 |         if (searchResults.length > 0) {
478 |           // Should find multiple document types for broad searches
479 |           const documentTypes = new Set(searchResults.map(r => r.type));
480 |           const categories = new Set(searchResults.map(r => r.category));
481 |           
482 |           // Broad searches should span multiple types/categories
483 |           assert.ok(documentTypes.size >= 1, `Broad query "${query}" should find at least 1 document type`);
484 |           assert.ok(categories.size >= 1, `Broad query "${query}" should find at least 1 category`);
485 |         }
486 |       }
487 |     });
488 | 
489 |     test('should provide specific results for narrow searches', async () => {
490 |       const narrowQueries = ['applyRenderings', 'viewData', 'pageMetaData', 'isJson'];
491 |       
492 |       for (const query of narrowQueries) {
493 |         const result = await client.callTool('search_sfra_documentation', { query });
494 |         
495 |         assert.equal(result.isError, false, `Narrow query "${query}" should not error`);
496 |         
497 |         const searchResults = JSON.parse(result.content[0].text);
498 |         
499 |         // For narrow/specific searches, results should be highly relevant
500 |         for (const searchResult of searchResults) {
501 |           const hasRelevantMatch = searchResult.matches.some(match => 
502 |             match.content.toLowerCase().includes(query.toLowerCase()) ||
503 |             match.section.toLowerCase().includes(query.toLowerCase())
504 |           );
505 |           assert.ok(hasRelevantMatch, `Search result should contain relevant match for specific query: "${query}"`);
506 |         }
507 |       }
508 |     });
509 | 
510 |     test('should handle related term searches effectively', async () => {
511 |       const relatedTermSets = [
512 |         ['cart', 'basket', 'shopping'],
513 |         ['template', 'view', 'render'],
514 |         ['product', 'item', 'catalog'],
515 |         ['customer', 'user', 'account']
516 |       ];
517 |       
518 |       for (const termSet of relatedTermSets) {
519 |         const results = [];
520 |         
521 |         for (const term of termSet) {
522 |           const result = await client.callTool('search_sfra_documentation', { query: term });
523 |           assert.equal(result.isError, false, `Related term "${term}" should not error`);
524 |           results.push(JSON.parse(result.content[0].text));
525 |         }
526 |         
527 |         // Related terms should have some overlap in documents found
528 |         const allDocuments = results.flatMap(r => r.map(doc => doc.document));
529 |         const uniqueDocuments = new Set(allDocuments);
530 |         
531 |         // Should find some documents across related terms
532 |         assert.ok(uniqueDocuments.size > 0, `Related terms ${termSet.join(', ')} should find some documents`);
533 |       }
534 |     });
535 |   });
536 | 
537 |   describe('Stress and Load Testing', () => {
538 |     test('should handle rapid sequential searches efficiently', async () => {
539 |       const queries = ['server', 'request', 'response', 'render', 'model', 'cart', 'product', 'price'];
540 |       
541 |       for (const query of queries) {
542 |         const result = await client.callTool('search_sfra_documentation', { query });
543 |         assert.equal(result.isError, false, `Sequential query "${query}" should not error`);
544 |       }
545 |     });
546 | 
547 |     test('should maintain performance consistency across different query types', async () => {
548 |       const queryTypes = [
549 |         { type: 'short', queries: ['a', 'b', 'c'] },
550 |         { type: 'medium', queries: ['render', 'server', 'model'] },
551 |         { type: 'long', queries: ['template rendering', 'product catalog', 'customer account'] },
552 |         { type: 'complex', queries: ['server request response middleware', 'product cart pricing checkout'] }
553 |       ];
554 |       
555 |       for (const { type, queries } of queryTypes) {
556 |         for (const query of queries) {
557 |           const result = await client.callTool('search_sfra_documentation', { query });
558 |           assert.equal(result.isError, false, `${type} query "${query}" should not error`);
559 |         }
560 |       }
561 |     });
562 |   });
563 | });
564 | 
```

--------------------------------------------------------------------------------
/tests/documentation-scanner.test.ts:
--------------------------------------------------------------------------------

```typescript
  1 | import { DocumentationScanner } from '../src/clients/docs/documentation-scanner.js';
  2 | import { Logger } from '../src/utils/logger.js';
  3 | import fs from 'fs/promises';
  4 | import path from 'path';
  5 | 
  6 | // Mock fs module
  7 | jest.mock('fs/promises');
  8 | jest.mock('path');
  9 | 
 10 | const mockFs = fs as jest.Mocked<typeof fs>;
 11 | const mockPath = path as jest.Mocked<typeof path>;
 12 | 
 13 | describe('DocumentationScanner', () => {
 14 |   let mockLogger: jest.Mocked<Logger>;
 15 |   let scanner: DocumentationScanner;
 16 | 
 17 |   beforeEach(() => {
 18 |     mockLogger = {
 19 |       debug: jest.fn(),
 20 |       log: jest.fn(),
 21 |       error: jest.fn(),
 22 |       timing: jest.fn(),
 23 |       methodEntry: jest.fn(),
 24 |       methodExit: jest.fn(),
 25 |       warn: jest.fn(),
 26 |     } as any;
 27 | 
 28 |     // Setup Logger mock before creating scanner
 29 |     jest.spyOn(Logger, 'getChildLogger').mockReturnValue(mockLogger);
 30 | 
 31 |     // Now create the scanner instance
 32 |     scanner = new DocumentationScanner();
 33 | 
 34 |     // Reset all mocks
 35 |     jest.clearAllMocks();
 36 | 
 37 |     // Setup default path mock behavior
 38 |     mockPath.join.mockImplementation((...segments) => segments.join('/'));
 39 |     mockPath.resolve.mockImplementation((filePath) => `/resolved/${filePath}`);
 40 |   });
 41 | 
 42 |   afterEach(() => {
 43 |     jest.clearAllMocks();
 44 |   });
 45 | 
 46 |   describe('constructor', () => {
 47 |     it('should create logger with correct name', () => {
 48 |       // Re-mock and create a new instance to verify logger creation
 49 |       const loggerSpy = jest.spyOn(Logger, 'getChildLogger').mockReturnValue(mockLogger);
 50 |       new DocumentationScanner();
 51 | 
 52 |       expect(loggerSpy).toHaveBeenCalledWith('DocumentationScanner');
 53 | 
 54 |       loggerSpy.mockRestore();
 55 |     });
 56 |   });
 57 | 
 58 |   describe('scanDocumentation', () => {
 59 |     it('should scan SFCC directories and return class cache', async () => {
 60 |       const mockDirent = (name: string, isDir: boolean = true) => ({
 61 |         name,
 62 |         isDirectory: () => isDir,
 63 |         isFile: () => !isDir,
 64 |         isSymbolicLink: () => false,
 65 |         isBlockDevice: () => false,
 66 |         isCharacterDevice: () => false,
 67 |         isFIFO: () => false,
 68 |         isSocket: () => false,
 69 |       });
 70 | 
 71 |       // Mock readdir for main docs directory
 72 |       mockFs.readdir.mockResolvedValueOnce([
 73 |         mockDirent('dw_catalog'),
 74 |         mockDirent('dw_content'),
 75 |         mockDirent('TopLevel'),
 76 |         mockDirent('best-practices'), // Should be excluded
 77 |         mockDirent('sfra'), // Should be excluded
 78 |         mockDirent('other-dir'), // Should be excluded
 79 |         mockDirent('readme.md', false), // File, should be skipped
 80 |       ] as any);
 81 | 
 82 |       // Mock readdir for package directories in specific order
 83 |       mockFs.readdir
 84 |         .mockResolvedValueOnce([
 85 |           'Product.md',
 86 |           'Category.md',
 87 |           'readme.txt', // non-.md file to be skipped
 88 |         ] as any) // dw_catalog
 89 |         .mockResolvedValueOnce([
 90 |           'ContentMgr.md',
 91 |           'Content.md',
 92 |         ] as any) // dw_content
 93 |         .mockResolvedValueOnce([
 94 |           'String.md',
 95 |           'Number.md',
 96 |         ] as any); // TopLevel
 97 | 
 98 |       // Mock file reading in the expected order based on directory scanning
 99 |       mockFs.readFile
100 |         .mockResolvedValueOnce('# Class Product\n\nProduct documentation content') // dw_catalog/Product.md
101 |         .mockResolvedValueOnce('# Class Category\n\nCategory documentation content') // dw_catalog/Category.md
102 |         .mockResolvedValueOnce('# Class ContentMgr\n\nContentMgr documentation content') // dw_content/ContentMgr.md
103 |         .mockResolvedValueOnce('# Class Content\n\nContent documentation content') // dw_content/Content.md
104 |         .mockResolvedValueOnce('# Class String\n\nString documentation content') // TopLevel/String.md
105 |         .mockResolvedValueOnce('# Class Number\n\nNumber documentation content'); // TopLevel/Number.md
106 | 
107 |       // Mock path validation to ensure all paths are considered valid
108 |       mockPath.resolve.mockImplementation((filePath) => {
109 |         // For the main docs path
110 |         if (filePath === '/docs') {
111 |           return '/resolved/docs';
112 |         }
113 | 
114 |         // For package directories
115 |         if (filePath === '/docs/dw_catalog') {
116 |           return '/resolved/docs/dw_catalog';
117 |         }
118 |         if (filePath === '/docs/dw_content') {
119 |           return '/resolved/docs/dw_content';
120 |         }
121 |         if (filePath === '/docs/TopLevel') {
122 |           return '/resolved/docs/TopLevel';
123 |         }
124 | 
125 |         // For specific files - ensure they're within the package and docs paths
126 |         if (filePath === '/docs/dw_catalog/Product.md') {
127 |           return '/resolved/docs/dw_catalog/Product.md';
128 |         }
129 |         if (filePath === '/docs/dw_catalog/Category.md') {
130 |           return '/resolved/docs/dw_catalog/Category.md';
131 |         }
132 |         if (filePath === '/docs/dw_content/ContentMgr.md') {
133 |           return '/resolved/docs/dw_content/ContentMgr.md';
134 |         }
135 |         if (filePath === '/docs/dw_content/Content.md') {
136 |           return '/resolved/docs/dw_content/Content.md';
137 |         }
138 |         if (filePath === '/docs/TopLevel/String.md') {
139 |           return '/resolved/docs/TopLevel/String.md';
140 |         }
141 |         if (filePath === '/docs/TopLevel/Number.md') {
142 |           return '/resolved/docs/TopLevel/Number.md';
143 |         }
144 | 
145 |         // Default fallback
146 |         return `/resolved${filePath}`;
147 |       });
148 | 
149 |       const result = await scanner.scanDocumentation('/docs');
150 | 
151 |       expect(result).toBeInstanceOf(Map);
152 |       expect(result.size).toBe(6); // Should have 6 .md files total
153 | 
154 |       // Check that SFCC directories were processed
155 |       expect(result.has('dw_catalog.Product')).toBe(true);
156 |       expect(result.has('dw_catalog.Category')).toBe(true);
157 |       expect(result.has('dw_content.ContentMgr')).toBe(true);
158 |       expect(result.has('dw_content.Content')).toBe(true);
159 |       expect(result.has('TopLevel.String')).toBe(true);
160 |       expect(result.has('TopLevel.Number')).toBe(true);
161 | 
162 |       // Verify structure of one cached item
163 |       const productInfo = result.get('dw_catalog.Product');
164 |       expect(productInfo).toEqual({
165 |         className: 'Product',
166 |         packageName: 'dw_catalog',
167 |         filePath: '/docs/dw_catalog/Product.md',
168 |         content: '# Class Product\n\nProduct documentation content',
169 |       });
170 |     });
171 | 
172 |     it('should handle empty docs directory', async () => {
173 |       mockFs.readdir.mockResolvedValueOnce([]);
174 | 
175 |       const result = await scanner.scanDocumentation('/empty-docs');
176 | 
177 |       expect(result).toBeInstanceOf(Map);
178 |       expect(result.size).toBe(0);
179 |     });
180 | 
181 |     it('should skip non-SFCC directories', async () => {
182 |       const mockDirent = (name: string, isDir: boolean = true) => ({
183 |         name,
184 |         isDirectory: () => isDir,
185 |         isFile: () => !isDir,
186 |         isSymbolicLink: () => false,
187 |         isBlockDevice: () => false,
188 |         isCharacterDevice: () => false,
189 |         isFIFO: () => false,
190 |         isSocket: () => false,
191 |       });
192 | 
193 |       mockFs.readdir.mockResolvedValueOnce([
194 |         mockDirent('best-practices'),
195 |         mockDirent('sfra'),
196 |         mockDirent('random-dir'),
197 |         mockDirent('another_dir'),
198 |       ] as any);
199 | 
200 |       const result = await scanner.scanDocumentation('/docs');
201 | 
202 |       expect(result).toBeInstanceOf(Map);
203 |       expect(result.size).toBe(0);
204 |     });
205 | 
206 |     it('should handle directory read errors gracefully', async () => {
207 |       mockFs.readdir.mockRejectedValueOnce(new Error('Permission denied'));
208 | 
209 |       await expect(scanner.scanDocumentation('/forbidden-docs')).rejects.toThrow('Permission denied');
210 |     });
211 |   });
212 | 
213 |   describe('directory classification (isSFCCDirectory)', () => {
214 |     // Test the isSFCCDirectory logic through scanDocumentation behavior
215 |     it('should include dw_ prefixed directories', async () => {
216 |       const mockDirent = (name: string) => ({
217 |         name,
218 |         isDirectory: () => true,
219 |         isFile: () => false,
220 |         isSymbolicLink: () => false,
221 |         isBlockDevice: () => false,
222 |         isCharacterDevice: () => false,
223 |         isFIFO: () => false,
224 |         isSocket: () => false,
225 |       });
226 | 
227 |       mockFs.readdir.mockResolvedValueOnce([
228 |         mockDirent('dw_catalog'),
229 |         mockDirent('dw_content'),
230 |         mockDirent('dw_system'),
231 |         mockDirent('dw_order'),
232 |       ] as any);
233 | 
234 |       mockFs.readdir
235 |         .mockResolvedValueOnce([]) // dw_catalog
236 |         .mockResolvedValueOnce([]) // dw_content
237 |         .mockResolvedValueOnce([]) // dw_system
238 |         .mockResolvedValueOnce([]); // dw_order
239 | 
240 |       await scanner.scanDocumentation('/docs');
241 | 
242 |       // Verify that readdir was called for each dw_ directory
243 |       expect(mockFs.readdir).toHaveBeenCalledTimes(5); // 1 for main + 4 for packages
244 |     });
245 | 
246 |     it('should include TopLevel directory', async () => {
247 |       const mockDirent = (name: string) => ({
248 |         name,
249 |         isDirectory: () => true,
250 |         isFile: () => false,
251 |         isSymbolicLink: () => false,
252 |         isBlockDevice: () => false,
253 |         isCharacterDevice: () => false,
254 |         isFIFO: () => false,
255 |         isSocket: () => false,
256 |       });
257 | 
258 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('TopLevel')] as any);
259 |       mockFs.readdir.mockResolvedValueOnce([]); // TopLevel contents
260 | 
261 |       await scanner.scanDocumentation('/docs');
262 | 
263 |       expect(mockFs.readdir).toHaveBeenCalledTimes(2); // 1 for main + 1 for TopLevel
264 |     });
265 | 
266 |     it('should exclude best-practices directory', async () => {
267 |       const mockDirent = (name: string) => ({
268 |         name,
269 |         isDirectory: () => true,
270 |         isFile: () => false,
271 |         isSymbolicLink: () => false,
272 |         isBlockDevice: () => false,
273 |         isCharacterDevice: () => false,
274 |         isFIFO: () => false,
275 |         isSocket: () => false,
276 |       });
277 | 
278 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('best-practices')] as any);
279 | 
280 |       await scanner.scanDocumentation('/docs');
281 | 
282 |       expect(mockFs.readdir).toHaveBeenCalledTimes(1); // Only main directory
283 |     });
284 | 
285 |     it('should exclude sfra directory', async () => {
286 |       const mockDirent = (name: string) => ({
287 |         name,
288 |         isDirectory: () => true,
289 |         isFile: () => false,
290 |         isSymbolicLink: () => false,
291 |         isBlockDevice: () => false,
292 |         isCharacterDevice: () => false,
293 |         isFIFO: () => false,
294 |         isSocket: () => false,
295 |       });
296 | 
297 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('sfra')] as any);
298 | 
299 |       await scanner.scanDocumentation('/docs');
300 | 
301 |       expect(mockFs.readdir).toHaveBeenCalledTimes(1); // Only main directory
302 |     });
303 |   });
304 | 
305 |   describe('file name validation', () => {
306 |     it('should process valid markdown files', async () => {
307 |       const mockDirent = (name: string) => ({
308 |         name,
309 |         isDirectory: () => true,
310 |         isFile: () => false,
311 |         isSymbolicLink: () => false,
312 |         isBlockDevice: () => false,
313 |         isCharacterDevice: () => false,
314 |         isFIFO: () => false,
315 |         isSocket: () => false,
316 |       });
317 | 
318 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
319 |       mockFs.readdir.mockResolvedValueOnce([
320 |         'Product.md',
321 |         'Valid_File-Name.md',
322 |         'File123.md',
323 |       ] as any);
324 | 
325 |       mockFs.readFile
326 |         .mockResolvedValueOnce('Valid content')
327 |         .mockResolvedValueOnce('Valid content')
328 |         .mockResolvedValueOnce('Valid content');
329 | 
330 |       const result = await scanner.scanDocumentation('/docs');
331 | 
332 |       expect(result.size).toBe(3);
333 |       expect(result.has('dw_catalog.Product')).toBe(true);
334 |       expect(result.has('dw_catalog.Valid_File-Name')).toBe(true);
335 |       expect(result.has('dw_catalog.File123')).toBe(true);
336 |     });
337 | 
338 |     it('should reject files with path traversal sequences', async () => {
339 |       const mockDirent = (name: string) => ({
340 |         name,
341 |         isDirectory: () => true,
342 |         isFile: () => false,
343 |         isSymbolicLink: () => false,
344 |         isBlockDevice: () => false,
345 |         isCharacterDevice: () => false,
346 |         isFIFO: () => false,
347 |         isSocket: () => false,
348 |       });
349 | 
350 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
351 |       mockFs.readdir.mockResolvedValueOnce([
352 |         '../evil.md',
353 |         '..\\evil.md',
354 |         'path/traversal.md',
355 |       ] as any);
356 | 
357 |       const result = await scanner.scanDocumentation('/docs');
358 | 
359 |       expect(result.size).toBe(0);
360 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('path traversal'));
361 |     });
362 | 
363 |     it('should reject files with null bytes', async () => {
364 |       const mockDirent = (name: string) => ({
365 |         name,
366 |         isDirectory: () => true,
367 |         isFile: () => false,
368 |         isSymbolicLink: () => false,
369 |         isBlockDevice: () => false,
370 |         isCharacterDevice: () => false,
371 |         isFIFO: () => false,
372 |         isSocket: () => false,
373 |       });
374 | 
375 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
376 |       mockFs.readdir.mockResolvedValueOnce([
377 |         'evil\0.md',
378 |         'evil\x00.md',
379 |       ] as any);
380 | 
381 |       const result = await scanner.scanDocumentation('/docs');
382 | 
383 |       expect(result.size).toBe(0);
384 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('null bytes'));
385 |     });
386 | 
387 |     it('should reject files with invalid characters', async () => {
388 |       const mockDirent = (name: string) => ({
389 |         name,
390 |         isDirectory: () => true,
391 |         isFile: () => false,
392 |         isSymbolicLink: () => false,
393 |         isBlockDevice: () => false,
394 |         isCharacterDevice: () => false,
395 |         isFIFO: () => false,
396 |         isSocket: () => false,
397 |       });
398 | 
399 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
400 |       mockFs.readdir.mockResolvedValueOnce([
401 |         '[email protected]',
402 |         'file#invalid.md',
403 |         'file$invalid.md',
404 |       ] as any);
405 | 
406 |       const result = await scanner.scanDocumentation('/docs');
407 | 
408 |       expect(result.size).toBe(0);
409 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('invalid characters'));
410 |     });
411 | 
412 |     it('should reject invalid file name types', async () => {
413 |       const mockDirent = (name: string) => ({
414 |         name,
415 |         isDirectory: () => true,
416 |         isFile: () => false,
417 |         isSymbolicLink: () => false,
418 |         isBlockDevice: () => false,
419 |         isCharacterDevice: () => false,
420 |         isFIFO: () => false,
421 |         isSocket: () => false,
422 |       });
423 | 
424 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
425 |       mockFs.readdir.mockResolvedValueOnce(['', null, undefined] as any);
426 | 
427 |       const result = await scanner.scanDocumentation('/docs');
428 | 
429 |       expect(result.size).toBe(0);
430 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('Invalid file name type'));
431 |     });
432 |   });
433 | 
434 |   describe('file path validation', () => {
435 |     it('should validate file paths are within allowed directories', async () => {
436 |       const mockDirent = (name: string) => ({
437 |         name,
438 |         isDirectory: () => true,
439 |         isFile: () => false,
440 |         isSymbolicLink: () => false,
441 |         isBlockDevice: () => false,
442 |         isCharacterDevice: () => false,
443 |         isFIFO: () => false,
444 |         isSocket: () => false,
445 |       });
446 | 
447 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
448 |       mockFs.readdir.mockResolvedValueOnce(['Product.md'] as any);
449 | 
450 |       // Mock path.resolve to simulate path outside allowed directory
451 |       mockPath.resolve.mockImplementation((filePath) => {
452 |         if (filePath.includes('Product.md')) {
453 |           return '/outside/docs/Product.md';
454 |         }
455 |         if (filePath.includes('dw_catalog')) {
456 |           return '/resolved/docs/dw_catalog';
457 |         }
458 |         return '/resolved/docs';
459 |       });
460 | 
461 |       const result = await scanner.scanDocumentation('/docs');
462 | 
463 |       expect(result.size).toBe(0);
464 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('outside allowed directory'));
465 |     });
466 | 
467 |     it('should validate files end with .md extension', async () => {
468 |       const mockDirent = (name: string) => ({
469 |         name,
470 |         isDirectory: () => true,
471 |         isFile: () => false,
472 |         isSymbolicLink: () => false,
473 |         isBlockDevice: () => false,
474 |         isCharacterDevice: () => false,
475 |         isFIFO: () => false,
476 |         isSocket: () => false,
477 |       });
478 | 
479 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
480 |       mockFs.readdir.mockResolvedValueOnce(['Product.md'] as any);
481 | 
482 |       // Mock path.resolve to simulate file without .md extension after resolution
483 |       mockPath.resolve.mockImplementation((filePath) => {
484 |         if (filePath.includes('Product.md')) {
485 |           return '/resolved/docs/dw_catalog/Product.txt';
486 |         }
487 |         if (filePath.includes('dw_catalog')) {
488 |           return '/resolved/docs/dw_catalog';
489 |         }
490 |         return '/resolved/docs';
491 |       });
492 | 
493 |       const result = await scanner.scanDocumentation('/docs');
494 | 
495 |       expect(result.size).toBe(0);
496 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('does not reference a markdown file'));
497 |     });
498 |   });
499 | 
500 |   describe('file content validation', () => {
501 |     it('should reject empty file content', async () => {
502 |       const mockDirent = (name: string) => ({
503 |         name,
504 |         isDirectory: () => true,
505 |         isFile: () => false,
506 |         isSymbolicLink: () => false,
507 |         isBlockDevice: () => false,
508 |         isCharacterDevice: () => false,
509 |         isFIFO: () => false,
510 |         isSocket: () => false,
511 |       });
512 | 
513 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
514 |       mockFs.readdir.mockResolvedValueOnce(['Product.md'] as any);
515 |       mockFs.readFile.mockResolvedValueOnce('   \n\t  \n  '); // Only whitespace
516 | 
517 |       const result = await scanner.scanDocumentation('/docs');
518 | 
519 |       expect(result.size).toBe(0);
520 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('Empty documentation file'));
521 |     });
522 | 
523 |     it('should reject binary content', async () => {
524 |       const mockDirent = (name: string) => ({
525 |         name,
526 |         isDirectory: () => true,
527 |         isFile: () => false,
528 |         isSymbolicLink: () => false,
529 |         isBlockDevice: () => false,
530 |         isCharacterDevice: () => false,
531 |         isFIFO: () => false,
532 |         isSocket: () => false,
533 |       });
534 | 
535 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
536 |       mockFs.readdir.mockResolvedValueOnce(['Product.md'] as any);
537 |       mockFs.readFile.mockResolvedValueOnce('Valid content\0binary data'); // Contains null byte
538 | 
539 |       const result = await scanner.scanDocumentation('/docs');
540 | 
541 |       expect(result.size).toBe(0);
542 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('Binary content detected'));
543 |     });
544 | 
545 |     it('should accept valid file content', async () => {
546 |       const mockDirent = (name: string) => ({
547 |         name,
548 |         isDirectory: () => true,
549 |         isFile: () => false,
550 |         isSymbolicLink: () => false,
551 |         isBlockDevice: () => false,
552 |         isCharacterDevice: () => false,
553 |         isFIFO: () => false,
554 |         isSocket: () => false,
555 |       });
556 | 
557 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
558 |       mockFs.readdir.mockResolvedValueOnce(['Product.md'] as any);
559 |       mockFs.readFile.mockResolvedValueOnce('# Class Product\n\nValid markdown content with special chars: éñ中文');
560 | 
561 |       const result = await scanner.scanDocumentation('/docs');
562 | 
563 |       expect(result.size).toBe(1);
564 |       expect(result.has('dw_catalog.Product')).toBe(true);
565 | 
566 |       const productInfo = result.get('dw_catalog.Product');
567 |       expect(productInfo?.content).toBe('# Class Product\n\nValid markdown content with special chars: éñ中文');
568 |     });
569 |   });
570 | 
571 |   describe('file reading error handling', () => {
572 |     it('should handle file read errors gracefully', async () => {
573 |       const mockDirent = (name: string) => ({
574 |         name,
575 |         isDirectory: () => true,
576 |         isFile: () => false,
577 |         isSymbolicLink: () => false,
578 |         isBlockDevice: () => false,
579 |         isCharacterDevice: () => false,
580 |         isFIFO: () => false,
581 |         isSocket: () => false,
582 |       });
583 | 
584 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
585 |       mockFs.readdir.mockResolvedValueOnce(['Product.md', 'Category.md'] as any);
586 | 
587 |       // First file fails to read, second succeeds
588 |       mockFs.readFile
589 |         .mockRejectedValueOnce(new Error('Permission denied'))
590 |         .mockResolvedValueOnce('# Class Category\n\nValid content');
591 | 
592 |       const result = await scanner.scanDocumentation('/docs');
593 | 
594 |       expect(result.size).toBe(1);
595 |       expect(result.has('dw_catalog.Category')).toBe(true);
596 |       expect(result.has('dw_catalog.Product')).toBe(false);
597 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('Could not read file Product.md'));
598 |     });
599 | 
600 |     it('should handle package directory read errors gracefully', async () => {
601 |       const mockDirent = (name: string) => ({
602 |         name,
603 |         isDirectory: () => true,
604 |         isFile: () => false,
605 |         isSymbolicLink: () => false,
606 |         isBlockDevice: () => false,
607 |         isCharacterDevice: () => false,
608 |         isFIFO: () => false,
609 |         isSocket: () => false,
610 |       });
611 | 
612 |       mockFs.readdir.mockResolvedValueOnce([
613 |         mockDirent('dw_catalog'),
614 |         mockDirent('dw_content'),
615 |       ] as any);
616 | 
617 |       // First package directory fails to read, second succeeds
618 |       mockFs.readdir
619 |         .mockRejectedValueOnce(new Error('Directory not accessible'))
620 |         .mockResolvedValueOnce(['ContentMgr.md'] as any);
621 | 
622 |       mockFs.readFile.mockResolvedValueOnce('# Class ContentMgr\n\nValid content');
623 | 
624 |       const result = await scanner.scanDocumentation('/docs');
625 | 
626 |       expect(result.size).toBe(1);
627 |       expect(result.has('dw_content.ContentMgr')).toBe(true);
628 |       expect(mockLogger.warn).toHaveBeenCalledWith(expect.stringContaining('Could not read package dw_catalog'));
629 |     });
630 |   });
631 | 
632 |   describe('markdown file filtering', () => {
633 |     it('should only process .md files', async () => {
634 |       const mockDirent = (name: string) => ({
635 |         name,
636 |         isDirectory: () => true,
637 |         isFile: () => false,
638 |         isSymbolicLink: () => false,
639 |         isBlockDevice: () => false,
640 |         isCharacterDevice: () => false,
641 |         isFIFO: () => false,
642 |         isSocket: () => false,
643 |       });
644 | 
645 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
646 |       mockFs.readdir.mockResolvedValueOnce([
647 |         'Product.md',
648 |         'readme.txt',
649 |         'documentation.html',
650 |         'Category.md',
651 |         'config.json',
652 |         'index.js',
653 |       ] as any);
654 | 
655 |       mockFs.readFile
656 |         .mockResolvedValueOnce('# Class Product\n\nProduct content')
657 |         .mockResolvedValueOnce('# Class Category\n\nCategory content');
658 | 
659 |       const result = await scanner.scanDocumentation('/docs');
660 | 
661 |       expect(result.size).toBe(2);
662 |       expect(result.has('dw_catalog.Product')).toBe(true);
663 |       expect(result.has('dw_catalog.Category')).toBe(true);
664 | 
665 |       // Verify only .md files were processed
666 |       expect(mockFs.readFile).toHaveBeenCalledTimes(2);
667 |     });
668 |   });
669 | 
670 |   describe('class name extraction', () => {
671 |     it('should extract class names correctly from file names', async () => {
672 |       const mockDirent = (name: string) => ({
673 |         name,
674 |         isDirectory: () => true,
675 |         isFile: () => false,
676 |         isSymbolicLink: () => false,
677 |         isBlockDevice: () => false,
678 |         isCharacterDevice: () => false,
679 |         isFIFO: () => false,
680 |         isSocket: () => false,
681 |       });
682 | 
683 |       mockFs.readdir.mockResolvedValueOnce([mockDirent('dw_catalog')] as any);
684 |       mockFs.readdir.mockResolvedValueOnce(['Product.md', 'Product_Manager.md', 'Product-Utils.md'] as any);
685 | 
686 |       mockFs.readFile
687 |         .mockResolvedValueOnce('Content 1')
688 |         .mockResolvedValueOnce('Content 2')
689 |         .mockResolvedValueOnce('Content 3');
690 | 
691 |       const result = await scanner.scanDocumentation('/docs');
692 | 
693 |       expect(result.size).toBe(3);
694 |       expect(result.has('dw_catalog.Product')).toBe(true);
695 |       expect(result.has('dw_catalog.Product_Manager')).toBe(true);
696 |       expect(result.has('dw_catalog.Product-Utils')).toBe(true);
697 | 
698 |       // Verify class names are extracted correctly
699 |       expect(result.get('dw_catalog.Product')?.className).toBe('Product');
700 |       expect(result.get('dw_catalog.Product_Manager')?.className).toBe('Product_Manager');
701 |       expect(result.get('dw_catalog.Product-Utils')?.className).toBe('Product-Utils');
702 |     });
703 |   });
704 | 
705 |   describe('cache key generation', () => {
706 |     it('should generate correct cache keys', async () => {
707 |       const mockDirent = (name: string) => ({
708 |         name,
709 |         isDirectory: () => true,
710 |         isFile: () => false,
711 |         isSymbolicLink: () => false,
712 |         isBlockDevice: () => false,
713 |         isCharacterDevice: () => false,
714 |         isFIFO: () => false,
715 |         isSocket: () => false,
716 |       });
717 | 
718 |       mockFs.readdir.mockResolvedValueOnce([
719 |         mockDirent('dw_catalog'),
720 |         mockDirent('TopLevel'),
721 |       ] as any);
722 | 
723 |       mockFs.readdir
724 |         .mockResolvedValueOnce(['Product.md'] as any)
725 |         .mockResolvedValueOnce(['String.md'] as any);
726 | 
727 |       mockFs.readFile
728 |         .mockResolvedValueOnce('Product content')
729 |         .mockResolvedValueOnce('String content');
730 | 
731 |       const result = await scanner.scanDocumentation('/docs');
732 | 
733 |       expect(result.size).toBe(2);
734 |       expect(result.has('dw_catalog.Product')).toBe(true);
735 |       expect(result.has('TopLevel.String')).toBe(true);
736 | 
737 |       // Verify full structure of cached items
738 |       const productInfo = result.get('dw_catalog.Product');
739 |       expect(productInfo).toEqual({
740 |         className: 'Product',
741 |         packageName: 'dw_catalog',
742 |         filePath: '/docs/dw_catalog/Product.md',
743 |         content: 'Product content',
744 |       });
745 | 
746 |       const stringInfo = result.get('TopLevel.String');
747 |       expect(stringInfo).toEqual({
748 |         className: 'String',
749 |         packageName: 'TopLevel',
750 |         filePath: '/docs/TopLevel/String.md',
751 |         content: 'String content',
752 |       });
753 |     });
754 |   });
755 | });
756 | 
```

--------------------------------------------------------------------------------
/docs/dw_extensions.payments/SalesforcePaymentRequest.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.extensions.payments
  2 | 
  3 | # Class SalesforcePaymentRequest
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.extensions.payments.SalesforcePaymentRequest
  9 | 
 10 | ## Description
 11 | 
 12 | Salesforce Payments request for a shopper to make payment. See Salesforce Payments documentation for how to gain access and configure it for use on your sites. A request is required to render payment methods and/or express checkout buttons using <ispayment> or <isbuynow>. You can call methods on the payment request to configure which payment methods and/or express checkout buttons may be presented, and customize their visual presentation. When used with <isbuynow> you must provide the necessary data to prepare the shopper basket to buy the product, and the necessary payment request options for the browser payment app.
 13 | 
 14 | ## Constants
 15 | 
 16 | ### ELEMENT_AFTERPAY_CLEARPAY_MESSAGE
 17 | 
 18 | **Type:** String = "afterpayClearpayMessage"
 19 | 
 20 | Element for the Stripe Afterpay/Clearpay message "afterpayClearpayMessage".
 21 | 
 22 | ### ELEMENT_CARD_CVC
 23 | 
 24 | **Type:** String = "cardCvc"
 25 | 
 26 | Element for the Stripe credit card CVC field "cardCvc".
 27 | 
 28 | ### ELEMENT_CARD_EXPIRY
 29 | 
 30 | **Type:** String = "cardExpiry"
 31 | 
 32 | Element for the Stripe credit card expiration date field "cardExpiry".
 33 | 
 34 | ### ELEMENT_CARD_NUMBER
 35 | 
 36 | **Type:** String = "cardNumber"
 37 | 
 38 | Element for the Stripe credit card number field "cardNumber".
 39 | 
 40 | ### ELEMENT_EPS_BANK
 41 | 
 42 | **Type:** String = "epsBank"
 43 | 
 44 | Element for the Stripe EPS bank selection field "epsBank".
 45 | 
 46 | ### ELEMENT_IBAN
 47 | 
 48 | **Type:** String = "iban"
 49 | 
 50 | Element for the Stripe IBAN field "iban".
 51 | 
 52 | ### ELEMENT_IDEAL_BANK
 53 | 
 54 | **Type:** String = "idealBank"
 55 | 
 56 | Element for the Stripe iDEAL bank selection field "idealBank".
 57 | 
 58 | ### ELEMENT_PAYMENT_REQUEST_BUTTON
 59 | 
 60 | **Type:** String = "paymentRequestButton"
 61 | 
 62 | Element for the Stripe payment request button "paymentRequestButton".
 63 | 
 64 | ### ELEMENT_TYPE_AFTERPAY_CLEARPAY
 65 | 
 66 | **Type:** String = "afterpay_clearpay"
 67 | 
 68 | Element type name for Afterpay.
 69 | 
 70 | ### ELEMENT_TYPE_AFTERPAY_CLEARPAY_MESSAGE
 71 | 
 72 | **Type:** String = "afterpayclearpaymessage"
 73 | 
 74 | Element type name for Afterpay/Clearpay message.
 75 | 
 76 | ### ELEMENT_TYPE_APPLEPAY
 77 | 
 78 | **Type:** String = "applepay"
 79 | 
 80 | Element type name for Apple Pay payment request buttons.
 81 | 
 82 | ### ELEMENT_TYPE_BANCONTACT
 83 | 
 84 | **Type:** String = "bancontact"
 85 | 
 86 | Element type name for Bancontact.
 87 | 
 88 | ### ELEMENT_TYPE_CARD
 89 | 
 90 | **Type:** String = "card"
 91 | 
 92 | Element type name for credit cards.
 93 | 
 94 | ### ELEMENT_TYPE_EPS
 95 | 
 96 | **Type:** String = "eps"
 97 | 
 98 | Element type name for EPS.
 99 | 
100 | ### ELEMENT_TYPE_IDEAL
101 | 
102 | **Type:** String = "ideal"
103 | 
104 | Element type name for iDEAL.
105 | 
106 | ### ELEMENT_TYPE_PAYMENTREQUEST
107 | 
108 | **Type:** String = "paymentrequest"
109 | 
110 | Element type name for other payment request buttons besides Apple Pay, like Google Pay.
111 | 
112 | ### ELEMENT_TYPE_PAYPAL
113 | 
114 | **Type:** String = "paypal"
115 | 
116 | Element type name for PayPal in multi-step checkout.
117 | 
118 | ### ELEMENT_TYPE_PAYPAL_EXPRESS
119 | 
120 | **Type:** String = "paypalexpress"
121 | 
122 | Element type name for PayPal in express checkout.
123 | 
124 | ### ELEMENT_TYPE_PAYPAL_MESSAGE
125 | 
126 | **Type:** String = "paypalmessage"
127 | 
128 | Element type name for the PayPal messages component.
129 | 
130 | ### ELEMENT_TYPE_SEPA_DEBIT
131 | 
132 | **Type:** String = "sepa_debit"
133 | 
134 | Element type name for SEPA debit.
135 | 
136 | ### ELEMENT_TYPE_VENMO
137 | 
138 | **Type:** String = "venmo"
139 | 
140 | Element type name for Venmo in multi-step checkout.
141 | 
142 | ### ELEMENT_TYPE_VENMO_EXPRESS
143 | 
144 | **Type:** String = "venmoexpress"
145 | 
146 | Element type name for Venmo in express checkout.
147 | 
148 | ### PAYPAL_SHIPPING_PREFERENCE_GET_FROM_FILE
149 | 
150 | **Type:** String = "GET_FROM_FILE"
151 | 
152 | PayPal application context shipping_preference value "GET_FROM_FILE", to use the customer-provided shipping address on the PayPal site.
153 | 
154 | ### PAYPAL_SHIPPING_PREFERENCE_NO_SHIPPING
155 | 
156 | **Type:** String = "NO_SHIPPING"
157 | 
158 | PayPal application context shipping_preference value "NO_SHIPPING", to redact the shipping address from the PayPal site. Recommended for digital goods.
159 | 
160 | ### PAYPAL_SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS
161 | 
162 | **Type:** String = "SET_PROVIDED_ADDRESS"
163 | 
164 | PayPal application context shipping_preference value "SET_PROVIDED_ADDRESS", to use the merchant-provided address. The customer cannot change this address on the PayPal site.
165 | 
166 | ### PAYPAL_USER_ACTION_CONTINUE
167 | 
168 | **Type:** String = "CONTINUE"
169 | 
170 | PayPal application context user_action value "CONTINUE". Use this option when the final amount is not known when the checkout flow is initiated and you want to redirect the customer to the merchant page without processing the payment.
171 | 
172 | ### PAYPAL_USER_ACTION_PAY_NOW
173 | 
174 | **Type:** String = "PAY_NOW"
175 | 
176 | PayPal application context user_action value "PAY_NOW". Use this option when the final amount is known when the checkout is initiated and you want to process the payment immediately when the customer clicks Pay Now.
177 | 
178 | ## Properties
179 | 
180 | ### basketData
181 | 
182 | **Type:** Object
183 | 
184 | A JS object containing the data used to prepare the shopper basket when a Buy Now button is tapped.
185 | 
186 | ### billingDetails
187 | 
188 | **Type:** Object
189 | 
190 | A JS object containing the billing details to use when a Stripe PaymentMethod is created.
191 | 
192 | ### cardCaptureAutomatic
193 | 
194 | **Type:** boolean
195 | 
196 | Returns true if the credit card payment should be automatically captured at the time of the sale, or
197 |  false if the credit card payment should be captured later.
198 | 
199 | ### exclude
200 | 
201 | **Type:** Set (Read Only)
202 | 
203 | Returns a set containing the element types to be explicitly excluded from mounted components. See the element
204 |  type constants in this class for the full list of supported element types.
205 |  
206 |  
207 |  Note: if an element type is both explicitly included and excluded, it will not be presented.
208 | 
209 | ### ID
210 | 
211 | **Type:** String (Read Only)
212 | 
213 | The identifier of this payment request.
214 | 
215 | ### include
216 | 
217 | **Type:** Set (Read Only)
218 | 
219 | Returns a set containing the specific element types to include in mounted components. If the set is
220 |  empty then all applicable and enabled element types will be included by default. See the element type constants
221 |  in this class for the full list of supported element types.
222 |  
223 |  
224 |  Note: if an element type is both explicitly included and excluded, it will not be presented.
225 | 
226 | ### selector
227 | 
228 | **Type:** String (Read Only)
229 | 
230 | The DOM element selector where to mount payment methods and/or express checkout buttons.
231 | 
232 | ### setupFutureUsage
233 | 
234 | **Type:** boolean
235 | 
236 | Returns true if the payment method should be always saved for future use off session, or
237 |  false if the payment method should be only saved for future use on session when appropriate.
238 | 
239 | ### statementDescriptor
240 | 
241 | **Type:** String
242 | 
243 | The complete description that appears on your customers' statements for payments made by this request, or
244 |  null if the default statement descriptor for your account will be used.
245 | 
246 | ## Constructor Summary
247 | 
248 | SalesforcePaymentRequest(id : String, selector : String) Constructs a payment request using the given identifiers.
249 | 
250 | ## Method Summary
251 | 
252 | ### addExclude
253 | 
254 | **Signature:** `addExclude(elementType : String) : void`
255 | 
256 | Adds the given element type to explicitly exclude from mounted components.
257 | 
258 | ### addInclude
259 | 
260 | **Signature:** `addInclude(elementType : String) : void`
261 | 
262 | Adds the given element type to include in mounted components.
263 | 
264 | ### calculatePaymentRequestOptions
265 | 
266 | **Signature:** `static calculatePaymentRequestOptions(basket : Basket, options : Object) : Object`
267 | 
268 | Returns a JS object containing the payment request options to use when a Pay Now button is tapped, in the appropriate format for use in client side JavaScript, with data calculated from the given basket.
269 | 
270 | ### format
271 | 
272 | **Signature:** `static format(options : Object) : Object`
273 | 
274 | Returns a JS object containing the payment request options to use when a Buy Now button is tapped, in the appropriate format for use in client side JavaScript.
275 | 
276 | ### getBasketData
277 | 
278 | **Signature:** `getBasketData() : Object`
279 | 
280 | Returns a JS object containing the data used to prepare the shopper basket when a Buy Now button is tapped.
281 | 
282 | ### getBillingDetails
283 | 
284 | **Signature:** `getBillingDetails() : Object`
285 | 
286 | Returns a JS object containing the billing details to use when a Stripe PaymentMethod is created.
287 | 
288 | ### getCardCaptureAutomatic
289 | 
290 | **Signature:** `getCardCaptureAutomatic() : boolean`
291 | 
292 | Returns true if the credit card payment should be automatically captured at the time of the sale, or false if the credit card payment should be captured later.
293 | 
294 | ### getExclude
295 | 
296 | **Signature:** `getExclude() : Set`
297 | 
298 | Returns a set containing the element types to be explicitly excluded from mounted components.
299 | 
300 | ### getID
301 | 
302 | **Signature:** `getID() : String`
303 | 
304 | Returns the identifier of this payment request.
305 | 
306 | ### getInclude
307 | 
308 | **Signature:** `getInclude() : Set`
309 | 
310 | Returns a set containing the specific element types to include in mounted components.
311 | 
312 | ### getSelector
313 | 
314 | **Signature:** `getSelector() : String`
315 | 
316 | Returns the DOM element selector where to mount payment methods and/or express checkout buttons.
317 | 
318 | ### getSetupFutureUsage
319 | 
320 | **Signature:** `getSetupFutureUsage() : boolean`
321 | 
322 | Returns true if the payment method should be always saved for future use off session, or false if the payment method should be only saved for future use on session when appropriate.
323 | 
324 | ### getStatementDescriptor
325 | 
326 | **Signature:** `getStatementDescriptor() : String`
327 | 
328 | Returns the complete description that appears on your customers' statements for payments made by this request, or null if the default statement descriptor for your account will be used.
329 | 
330 | ### setBasketData
331 | 
332 | **Signature:** `setBasketData(basketData : Object) : void`
333 | 
334 | Sets the data used to prepare the shopper basket when a Buy Now button is tapped.
335 | 
336 | ### setBillingDetails
337 | 
338 | **Signature:** `setBillingDetails(billingDetails : Object) : void`
339 | 
340 | Sets the billing details to use when a Stripe PaymentMethod is created.
341 | 
342 | ### setCardCaptureAutomatic
343 | 
344 | **Signature:** `setCardCaptureAutomatic(cardCaptureAutomatic : boolean) : void`
345 | 
346 | Sets if the credit card payment should be automatically captured at the time of the sale.
347 | 
348 | ### setOptions
349 | 
350 | **Signature:** `setOptions(options : Object) : void`
351 | 
352 | Sets the payment request options to use when a Buy Now button is tapped.
353 | 
354 | ### setPayPalButtonsOptions
355 | 
356 | **Signature:** `setPayPalButtonsOptions(options : Object) : void`
357 | 
358 | Sets the the options to pass into the paypal.Buttons call.
359 | 
360 | ### setPayPalShippingPreference
361 | 
362 | **Signature:** `setPayPalShippingPreference(shippingPreference : String) : void`
363 | 
364 | Sets the PayPal order application context shipping_preference value.
365 | 
366 | ### setPayPalUserAction
367 | 
368 | **Signature:** `setPayPalUserAction(userAction : String) : void`
369 | 
370 | Sets the PayPal order application context user_action value.
371 | 
372 | ### setReturnController
373 | 
374 | **Signature:** `setReturnController(returnController : String) : void`
375 | 
376 | Sets the controller to which to redirect when the shopper returns from a 3rd party payment website.
377 | 
378 | ### setSavePaymentMethodEnabled
379 | 
380 | **Signature:** `setSavePaymentMethodEnabled(savePaymentMethodEnabled : boolean) : void`
381 | 
382 | Sets if mounted components may provide a control for the shopper to save their payment method for later use.
383 | 
384 | ### setSetupFutureUsage
385 | 
386 | **Signature:** `setSetupFutureUsage(setupFutureUsage : boolean) : void`
387 | 
388 | Sets if the payment method should be always saved for future use off session.
389 | 
390 | ### setStatementDescriptor
391 | 
392 | **Signature:** `setStatementDescriptor(statementDescriptor : String) : void`
393 | 
394 | Sets the complete description that appears on your customers' statements for payments made by this request.
395 | 
396 | ### setStripeCreateElementOptions
397 | 
398 | **Signature:** `setStripeCreateElementOptions(element : String, options : Object) : void`
399 | 
400 | Sets the the options to pass into the Stripe elements.create call for the given element type.
401 | 
402 | ### setStripeElementsOptions
403 | 
404 | **Signature:** `setStripeElementsOptions(options : Object) : void`
405 | 
406 | Sets the the options to pass into the stripe.elements call.
407 | 
408 | ## Constructor Detail
409 | 
410 | ## Method Detail
411 | 
412 | ## Method Details
413 | 
414 | ### addExclude
415 | 
416 | **Signature:** `addExclude(elementType : String) : void`
417 | 
418 | **Description:** Adds the given element type to explicitly exclude from mounted components. It is not necessary to explicitly exclude element types that are not enabled for the site, or are not applicable for the current shopper and/or their basket. See the element type constants in this class for the full list of supported element types. Note: if an element type is both explicitly included and excluded, it will not be presented.
419 | 
420 | **Parameters:**
421 | 
422 | - `elementType`: element type
423 | 
424 | **See Also:**
425 | 
426 | getExclude()
427 | 
428 | ---
429 | 
430 | ### addInclude
431 | 
432 | **Signature:** `addInclude(elementType : String) : void`
433 | 
434 | **Description:** Adds the given element type to include in mounted components. Call this method to include only a specific list of element types to be presented when applicable and enabled for the site. See the element type constants in this class for the full list of supported element types. Note: if an element type is both explicitly included and excluded, it will not be presented.
435 | 
436 | **Parameters:**
437 | 
438 | - `elementType`: element type
439 | 
440 | **See Also:**
441 | 
442 | getInclude()
443 | 
444 | ---
445 | 
446 | ### calculatePaymentRequestOptions
447 | 
448 | **Signature:** `static calculatePaymentRequestOptions(basket : Basket, options : Object) : Object`
449 | 
450 | **Description:** Returns a JS object containing the payment request options to use when a Pay Now button is tapped, in the appropriate format for use in client side JavaScript, with data calculated from the given basket. This method is provided as a convenience to calculate updated payment request options when the shopper basket has changed. Data in the given options object like total, displayItems, and shippingOptions will be replaced in the returned object by values recalculated from the given basket and applicable shipping methods. The following example shows the resulting output for a basket and sample options. SalesforcePaymentRequest.calculatePaymentRequestOptions(basket, { requestPayerName: true, requestPayerEmail: true, requestPayerPhone: false, requestShipping: true }); returns { currency: 'gbp', total: { label: 'Total', amount: '2644' }, displayItems: [{ label: 'Subtotal', amount: '1919' }, { label: 'Tax', amount: '126' }, { label: 'Ground', amount: '599' }], requestPayerName: true, requestPayerEmail: true, requestPayerPhone: false, requestShipping: true, shippingOptions: [{ id: 'GBP001', label: 'Ground', detail: 'Order received within 7-10 business days', amount: '599' },{ id: 'GBP002', label: 'Express', detail: 'Order received within 2-4 business days', amount: '999' }] }
451 | 
452 | **Parameters:**
453 | 
454 | - `basket`: No Comment In JavaDoc
455 | - `options`: JS object containing payment request options in B2C Commerce API standard format
456 | 
457 | **Returns:**
458 | 
459 | JS object containing equivalent payment request options in Stripe JS API format
460 | 
461 | ---
462 | 
463 | ### format
464 | 
465 | **Signature:** `static format(options : Object) : Object`
466 | 
467 | **Description:** Returns a JS object containing the payment request options to use when a Buy Now button is tapped, in the appropriate format for use in client side JavaScript. This method is provided as a convenience to adjust values in B2C Commerce API standard formats to their equivalents as expected by Stripe JS APIs. The following example shows options set in B2C Commerce API format, and the resulting output. SalesforcePaymentRequest.format({ currency: 'GBP', total: { label: 'Total', amount: '26.44' }, displayItems: [{ label: 'Subtotal', amount: '19.19' }, { label: 'Tax', amount: '1.26' }, { label: 'Ground', amount: '5.99' }], requestPayerPhone: false, shippingOptions: [{ id: 'GBP001', label: 'Ground', detail: 'Order received within 7-10 business days', amount: '5.99' }] }); returns { currency: 'gbp', total: { label: 'Total', amount: '2644' }, displayItems: [{ label: 'Subtotal', amount: '1919' }, { label: 'Tax', amount: '126' }, { label: 'Ground', amount: '599' }], requestPayerPhone: false, shippingOptions: [{ id: 'GBP001', label: 'Ground', detail: 'Order received within 7-10 business days', amount: '599' }] }
468 | 
469 | **Parameters:**
470 | 
471 | - `options`: JS object containing payment request options in B2C Commerce API standard format
472 | 
473 | **Returns:**
474 | 
475 | JS object containing equivalent payment request options in Stripe JS API format
476 | 
477 | ---
478 | 
479 | ### getBasketData
480 | 
481 | **Signature:** `getBasketData() : Object`
482 | 
483 | **Description:** Returns a JS object containing the data used to prepare the shopper basket when a Buy Now button is tapped.
484 | 
485 | **Returns:**
486 | 
487 | JS object containing the basket data
488 | 
489 | **See Also:**
490 | 
491 | setBasketData(Object)
492 | 
493 | ---
494 | 
495 | ### getBillingDetails
496 | 
497 | **Signature:** `getBillingDetails() : Object`
498 | 
499 | **Description:** Returns a JS object containing the billing details to use when a Stripe PaymentMethod is created.
500 | 
501 | **Returns:**
502 | 
503 | JS object containing the billing details
504 | 
505 | **See Also:**
506 | 
507 | setBillingDetails(Object)
508 | 
509 | ---
510 | 
511 | ### getCardCaptureAutomatic
512 | 
513 | **Signature:** `getCardCaptureAutomatic() : boolean`
514 | 
515 | **Description:** Returns true if the credit card payment should be automatically captured at the time of the sale, or false if the credit card payment should be captured later.
516 | 
517 | **Returns:**
518 | 
519 | true if the credit card payment should be automatically captured at the time of the sale, false if the credit card payment should be captured later.
520 | 
521 | ---
522 | 
523 | ### getExclude
524 | 
525 | **Signature:** `getExclude() : Set`
526 | 
527 | **Description:** Returns a set containing the element types to be explicitly excluded from mounted components. See the element type constants in this class for the full list of supported element types. Note: if an element type is both explicitly included and excluded, it will not be presented.
528 | 
529 | **Returns:**
530 | 
531 | set of element types
532 | 
533 | **See Also:**
534 | 
535 | addExclude(String)
536 | 
537 | ---
538 | 
539 | ### getID
540 | 
541 | **Signature:** `getID() : String`
542 | 
543 | **Description:** Returns the identifier of this payment request.
544 | 
545 | **Returns:**
546 | 
547 | payment request identifier
548 | 
549 | ---
550 | 
551 | ### getInclude
552 | 
553 | **Signature:** `getInclude() : Set`
554 | 
555 | **Description:** Returns a set containing the specific element types to include in mounted components. If the set is empty then all applicable and enabled element types will be included by default. See the element type constants in this class for the full list of supported element types. Note: if an element type is both explicitly included and excluded, it will not be presented.
556 | 
557 | **Returns:**
558 | 
559 | set of element types
560 | 
561 | **See Also:**
562 | 
563 | addInclude(String)
564 | 
565 | ---
566 | 
567 | ### getSelector
568 | 
569 | **Signature:** `getSelector() : String`
570 | 
571 | **Description:** Returns the DOM element selector where to mount payment methods and/or express checkout buttons.
572 | 
573 | **Returns:**
574 | 
575 | DOM element selector
576 | 
577 | ---
578 | 
579 | ### getSetupFutureUsage
580 | 
581 | **Signature:** `getSetupFutureUsage() : boolean`
582 | 
583 | **Description:** Returns true if the payment method should be always saved for future use off session, or false if the payment method should be only saved for future use on session when appropriate.
584 | 
585 | **Returns:**
586 | 
587 | true if the payment method should be always saved for future use off session, false if the payment method should be only saved for future use on session when appropriate.
588 | 
589 | ---
590 | 
591 | ### getStatementDescriptor
592 | 
593 | **Signature:** `getStatementDescriptor() : String`
594 | 
595 | **Description:** Returns the complete description that appears on your customers' statements for payments made by this request, or null if the default statement descriptor for your account will be used.
596 | 
597 | **Returns:**
598 | 
599 | statement descriptor for payments made by this request, or null if the account default will be used
600 | 
601 | ---
602 | 
603 | ### setBasketData
604 | 
605 | **Signature:** `setBasketData(basketData : Object) : void`
606 | 
607 | **Description:** Sets the data used to prepare the shopper basket when a Buy Now button is tapped. For convenience this method accepts a JS object to set all of the following properties at once: sku - SKU of the product to add exclusively to the basket (required) quantity - integer quantity of the product, default is 1 shippingMethod - ID of the shipping method to set on the shipment, default is the site default shipping method for the basket currency options - JS array containing one JS object per selected product option, default is no selected options id - product option ID valueId - product option value ID The following example shows how to set all of the supported basket data. request.setBasketData({ sku: 'tv-pdp-6010fdM', quantity: 1, shippingMethod: '001', options: [{ id: 'tvWarranty', valueId: '000' }] });
608 | 
609 | **Parameters:**
610 | 
611 | - `basketData`: JS object containing the basket data
612 | 
613 | **See Also:**
614 | 
615 | getBasketData()
616 | 
617 | ---
618 | 
619 | ### setBillingDetails
620 | 
621 | **Signature:** `setBillingDetails(billingDetails : Object) : void`
622 | 
623 | **Description:** Sets the billing details to use when a Stripe PaymentMethod is created. For convenience this method accepts a JS object to set all details at once. The following example shows how to set details including address. request.setBillingDetails({ address: { city: 'Wien', country: 'AT', line1: 'Opernring 2', postal_code: '1010' }, email: '[email protected]', name: 'Johann Hummel' }); For more information on the available billing details see the Stripe create PaymentMethod API documentation.
624 | 
625 | **Parameters:**
626 | 
627 | - `billingDetails`: JS object containing the billing details
628 | 
629 | ---
630 | 
631 | ### setCardCaptureAutomatic
632 | 
633 | **Signature:** `setCardCaptureAutomatic(cardCaptureAutomatic : boolean) : void`
634 | 
635 | **Description:** Sets if the credit card payment should be automatically captured at the time of the sale.
636 | 
637 | **Parameters:**
638 | 
639 | - `cardCaptureAutomatic`: true if the credit card payment should be automatically captured at the time of the sale, or false if the credit card payment should be captured later.
640 | 
641 | ---
642 | 
643 | ### setOptions
644 | 
645 | **Signature:** `setOptions(options : Object) : void`
646 | 
647 | **Description:** Sets the payment request options to use when a Buy Now button is tapped. For convenience this method accepts a JS object to set all options at once. The following example shows how to set options including currency, labels, and amounts, in B2C Commerce API format. request.setOptions({ currency: 'GBP', total: { label: 'Total', amount: '26.44' }, displayItems: [{ label: 'Subtotal', amount: '19.19' }, { label: 'Tax', amount: '1.26' }, { label: 'Ground', amount: '5.99' }], requestPayerPhone: false, shippingOptions: [{ id: 'GBP001', label: 'Ground', detail: 'Order received within 7-10 business days', amount: '5.99' }] }); The total option must match the total that will result from preparing the shopper basket using the data provided to setBasketData(Object) in this request. The id of each JS object in the shippingOptions array must equal the ID of the corresponding site shipping method that the shopper may select in the browser payment app. For more information on the available payment request options see the Stripe Payment Request object API documentation. Note: The Stripe Payment Request country option will be set automatically to the country of the Salesforce Payments account associated with the Commerce Cloud instance and is not included here.
648 | 
649 | **Parameters:**
650 | 
651 | - `options`: JS object containing the payment request options
652 | 
653 | ---
654 | 
655 | ### setPayPalButtonsOptions
656 | 
657 | **Signature:** `setPayPalButtonsOptions(options : Object) : void`
658 | 
659 | **Description:** Sets the the options to pass into the paypal.Buttons call. For more information see the PayPal Buttons API documentation.
660 | 
661 | **Parameters:**
662 | 
663 | - `options`: JS object containing the options
664 | 
665 | ---
666 | 
667 | ### setPayPalShippingPreference
668 | 
669 | **Signature:** `setPayPalShippingPreference(shippingPreference : String) : void`
670 | 
671 | **Description:** Sets the PayPal order application context shipping_preference value. For more information see the PayPal Orders API documentation.
672 | 
673 | **Parameters:**
674 | 
675 | - `shippingPreference`: constant indicating the shipping preference
676 | 
677 | **See Also:**
678 | 
679 | PAYPAL_SHIPPING_PREFERENCE_GET_FROM_FILE
680 | PAYPAL_SHIPPING_PREFERENCE_NO_SHIPPING
681 | PAYPAL_SHIPPING_PREFERENCE_SET_PROVIDED_ADDRESS
682 | 
683 | ---
684 | 
685 | ### setPayPalUserAction
686 | 
687 | **Signature:** `setPayPalUserAction(userAction : String) : void`
688 | 
689 | **Description:** Sets the PayPal order application context user_action value. For more information see the PayPal Orders API documentation.
690 | 
691 | **Parameters:**
692 | 
693 | - `userAction`: constant indicating the user action
694 | 
695 | **See Also:**
696 | 
697 | PAYPAL_USER_ACTION_CONTINUE
698 | PAYPAL_USER_ACTION_PAY_NOW
699 | 
700 | ---
701 | 
702 | ### setReturnController
703 | 
704 | **Signature:** `setReturnController(returnController : String) : void`
705 | 
706 | **Description:** Sets the controller to which to redirect when the shopper returns from a 3rd party payment website. Default is the controller for the current page.
707 | 
708 | **Parameters:**
709 | 
710 | - `returnController`: return controller, such as "Cart-Show"
711 | 
712 | ---
713 | 
714 | ### setSavePaymentMethodEnabled
715 | 
716 | **Signature:** `setSavePaymentMethodEnabled(savePaymentMethodEnabled : boolean) : void`
717 | 
718 | **Description:** Sets if mounted components may provide a control for the shopper to save their payment method for later use. When set to false no control will be provided. When set to true a control may be provided, if applicable for the shopper and presented payment method, but is not guaranteed.
719 | 
720 | **Parameters:**
721 | 
722 | - `savePaymentMethodEnabled`: if mounted components may provide a control for the shopper to save their payment method
723 | 
724 | ---
725 | 
726 | ### setSetupFutureUsage
727 | 
728 | **Signature:** `setSetupFutureUsage(setupFutureUsage : boolean) : void`
729 | 
730 | **Description:** Sets if the payment method should be always saved for future use off session.
731 | 
732 | **Parameters:**
733 | 
734 | - `setupFutureUsage`: true if the payment method should be always saved for future use off session, or false if the payment method should be only saved for future use on session when appropriate.
735 | 
736 | ---
737 | 
738 | ### setStatementDescriptor
739 | 
740 | **Signature:** `setStatementDescriptor(statementDescriptor : String) : void`
741 | 
742 | **Description:** Sets the complete description that appears on your customers' statements for payments made by this request. Set this to null to use the default statement descriptor for your account.
743 | 
744 | **Parameters:**
745 | 
746 | - `statementDescriptor`: statement descriptor for payments made by this request, or null to use the account default
747 | 
748 | ---
749 | 
750 | ### setStripeCreateElementOptions
751 | 
752 | **Signature:** `setStripeCreateElementOptions(element : String, options : Object) : void`
753 | 
754 | **Description:** Sets the the options to pass into the Stripe elements.create call for the given element type. For more information see the Stripe Elements API documentation.
755 | 
756 | **Parameters:**
757 | 
758 | - `element`: name of the Stripe element whose creation to configure
759 | - `options`: JS object containing the options
760 | 
761 | **See Also:**
762 | 
763 | ELEMENT_AFTERPAY_CLEARPAY_MESSAGE
764 | ELEMENT_CARD_CVC
765 | ELEMENT_CARD_EXPIRY
766 | ELEMENT_CARD_NUMBER
767 | ELEMENT_EPS_BANK
768 | ELEMENT_IBAN
769 | ELEMENT_IDEAL_BANK
770 | ELEMENT_PAYMENT_REQUEST_BUTTON
771 | 
772 | ---
773 | 
774 | ### setStripeElementsOptions
775 | 
776 | **Signature:** `setStripeElementsOptions(options : Object) : void`
777 | 
778 | **Description:** Sets the the options to pass into the stripe.elements call. For more information see the Stripe Elements API documentation.
779 | 
780 | **Parameters:**
781 | 
782 | - `options`: JS object containing the options
783 | 
784 | ---
```

--------------------------------------------------------------------------------
/docs/dw_catalog/Variant.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: dw.catalog
  2 | 
  3 | # Class Variant
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - dw.object.PersistentObject
  9 |   - dw.object.ExtensibleObject
 10 |     - dw.catalog.Product
 11 |       - dw.catalog.Variant
 12 | 
 13 | ## Description
 14 | 
 15 | Represents a variant of a product variation. If the variant does not define an own value, the value is retrieved by fallback from variation groups (sorted by their position) or the variation master.
 16 | 
 17 | ## Properties
 18 | 
 19 | ### allProductLinks
 20 | 
 21 | **Type:** Collection (Read Only)
 22 | 
 23 | All product links of the product variant. 
 24 | 
 25 |  If the variant does not define any product links, the product links are retrieved
 26 |  from the assigned variation groups, sorted by their position.
 27 | 
 28 |  If none of the variation groups define any product links, the product links are
 29 |  retrieved from the master product.
 30 | 
 31 | ### brand
 32 | 
 33 | **Type:** String (Read Only)
 34 | 
 35 | The brand of the product variant. 
 36 | 
 37 |  If the variant does not define an own value for 'brand', the value is retrieved
 38 |  from the assigned variation groups, sorted by their position.
 39 | 
 40 |  If none of the variation groups define a value for 'brand', the value of
 41 |  the master product is returned.
 42 | 
 43 | ### classificationCategory
 44 | 
 45 | **Type:** Category (Read Only)
 46 | 
 47 | The classification category of the product variant. 
 48 | 
 49 |  Please note that the classification category is always inherited
 50 |  from the master and cannot be overridden by the variant.
 51 | 
 52 | ### custom
 53 | 
 54 | **Type:** CustomAttributes (Read Only)
 55 | 
 56 | The custom attributes of the variant. 
 57 | 
 58 |  Custom attributes are inherited from the master product and can
 59 |  be overridden by the variant.
 60 | 
 61 | ### EAN
 62 | 
 63 | **Type:** String (Read Only)
 64 | 
 65 | The EAN of the product variant. 
 66 | 
 67 |  If the variant does not define an own value for 'EAN', the value is retrieved
 68 |  from the assigned variation groups, sorted by their position.
 69 | 
 70 |  If none of the variation groups define a value for 'EAN', the value of
 71 |  the master product is returned.
 72 | 
 73 | ### image
 74 | 
 75 | **Type:** MediaFile (Read Only)
 76 | 
 77 | The image of the product variant. 
 78 | 
 79 |  If the variant does not define an own value for 'image', the value is retrieved
 80 |  from the assigned variation groups, sorted by their position.
 81 | 
 82 |  If none of the variation groups define a value for 'image', the value of
 83 |  the master product is returned.
 84 | 
 85 | ### longDescription
 86 | 
 87 | **Type:** MarkupText (Read Only)
 88 | 
 89 | The long description of the product variant. 
 90 | 
 91 |  If the variant does not define an own value for 'longDescription', the value is retrieved
 92 |  from the assigned variation groups, sorted by their position.
 93 | 
 94 |  If none of the variation groups define a value for 'longDescription', the value of
 95 |  the master product is returned.
 96 | 
 97 | ### manufacturerName
 98 | 
 99 | **Type:** String (Read Only)
100 | 
101 | The manufacturer name of the product variant. 
102 | 
103 |  If the variant does not define an own value for 'manufacturerName', the value is retrieved
104 |  from the assigned variation groups, sorted by their position.
105 | 
106 |  If none of the variation groups define a value for 'manufacturerName', the value of
107 |  the master product is returned.
108 | 
109 | ### manufacturerSKU
110 | 
111 | **Type:** String (Read Only)
112 | 
113 | The manufacturer sku of the product variant. 
114 | 
115 |  If the variant does not define an own value for 'manufacturerSKU', the value is retrieved
116 |  from the assigned variation groups, sorted by their position.
117 | 
118 |  If none of the variation groups define a value for 'manufacturerSKU', the value of
119 |  the master product is returned.
120 | 
121 | ### masterProduct
122 | 
123 | **Type:** Product (Read Only)
124 | 
125 | The ProductMaster for this mastered product.
126 | 
127 | ### name
128 | 
129 | **Type:** String (Read Only)
130 | 
131 | The name of the product variant. 
132 | 
133 |  If the variant does not define an own value for 'name', the value is retrieved
134 |  from the assigned variation groups, sorted by their position.
135 | 
136 |  If none of the variation groups define a value for 'name', the value of
137 |  the master product is returned.
138 | 
139 | ### onlineFrom
140 | 
141 | **Type:** Date (Read Only)
142 | 
143 | The onlineFrom date of the product variant. 
144 | 
145 |  If the variant does not define an own value for 'onlineFrom', the value is retrieved
146 |  from the assigned variation groups, sorted by their position.
147 | 
148 |  If none of the variation groups define a value for 'onlineFrom', the value of
149 |  the master product is returned.
150 | 
151 | ### onlineTo
152 | 
153 | **Type:** Date (Read Only)
154 | 
155 | The onlineTo date of the product variant. 
156 | 
157 |  If the variant does not define an own value for 'onlineTo', the value is retrieved
158 |  from the assigned variation groups, sorted by their position.
159 | 
160 |  If none of the variation groups define a value for 'onlineTo', the value of
161 |  the master product is returned.
162 | 
163 | ### optionProduct
164 | 
165 | **Type:** boolean (Read Only)
166 | 
167 | Returns 'true' if the variant has any options, otherwise 'false'.
168 |  Method also returns 'true' if the variant has not any options,
169 |  but the related variation groups (sorted by position) or
170 |  master product has options.
171 | 
172 | ### pageDescription
173 | 
174 | **Type:** String (Read Only)
175 | 
176 | The pageDescription of the product variant. 
177 | 
178 |  If the variant does not define an own value for 'pageDescription', the value is retrieved
179 |  from the assigned variation groups, sorted by their position.
180 | 
181 |  If none of the variation groups define a value for 'pageDescription', the value of
182 |  the master product is returned.
183 | 
184 | ### pageKeywords
185 | 
186 | **Type:** String (Read Only)
187 | 
188 | The pageKeywords of the product variant. 
189 | 
190 |  If the variant does not define an own value for 'pageKeywords', the value is retrieved
191 |  from the assigned variation groups, sorted by their position.
192 | 
193 |  If none of the variation groups define a value for 'pageKeywords', the value of
194 |  the master product is returned.
195 | 
196 | ### pageTitle
197 | 
198 | **Type:** String (Read Only)
199 | 
200 | The pageTitle of the product variant. 
201 | 
202 |  If the variant does not define an own value for 'pageTitle', the value is retrieved
203 |  from the assigned variation groups, sorted by their position.
204 | 
205 |  If none of the variation groups define a value for 'pageTitle', the value of
206 |  the master product is returned.
207 | 
208 | ### pageURL
209 | 
210 | **Type:** String (Read Only)
211 | 
212 | The pageURL of the product variant. 
213 | 
214 |  If the variant does not define an own value for 'pageURL', the value is retrieved
215 |  from the assigned variation groups, sorted by their position.
216 | 
217 |  If none of the variation groups define a value for 'pageURL', the value of
218 |  the master product is returned.
219 | 
220 | ### productLinks
221 | 
222 | **Type:** Collection (Read Only)
223 | 
224 | All product links of the product variant for which the target
225 |  product is assigned to the current site catalog. 
226 | 
227 |  If the variant does not define any product links, the product links are retrieved
228 |  from the assigned variation groups, sorted by their position
229 | 
230 |  If none of the variation groups define any product links, the product links are retrieved
231 |  from the master product.
232 | 
233 | ### shortDescription
234 | 
235 | **Type:** MarkupText (Read Only)
236 | 
237 | The short description of the product variant. 
238 | 
239 |  If the variant does not define an own value for 'shortDescription', the value is retrieved
240 |  from the assigned variation groups, sorted by their position.
241 | 
242 |  If none of the variation groups define a value for 'shortDescription', the value of
243 |  the master product is returned.
244 | 
245 | ### taxClassID
246 | 
247 | **Type:** String (Read Only)
248 | 
249 | The tax class id of the product variant. 
250 | 
251 |  If the variant does not define an own value for 'taxClassID', the value is retrieved
252 |  from the assigned variation groups, sorted by their position.
253 | 
254 |  If none of the variation groups define a value for 'taxClassID', the value of
255 |  the master product is returned.
256 | 
257 | ### template
258 | 
259 | **Type:** String (Read Only)
260 | 
261 | The rendering template name of the product variant. 
262 | 
263 |  If the variant does not define an own value for 'template', the value is retrieved
264 |  from the assigned variation groups, sorted by their position.
265 | 
266 |  If none of the variation groups define a value for 'template', the value of
267 |  the master product is returned.
268 | 
269 | ### thumbnail
270 | 
271 | **Type:** MediaFile (Read Only)
272 | 
273 | The thumbnail image of the product variant. 
274 | 
275 |  If the variant does not define an own value for 'thumbnail', the value is retrieved
276 |  from the assigned variation groups, sorted by their position.
277 | 
278 |  If none of the variation groups define a value for 'thumbnail', the value of
279 |  the master product is returned.
280 | 
281 | ### unit
282 | 
283 | **Type:** String (Read Only)
284 | 
285 | The sales unit of the product variant as defined by the
286 |  master product. 
287 | 
288 |  If the variant does not define an own value for 'unit', the value is retrieved
289 |  from the assigned variation groups, sorted by their position.
290 | 
291 |  If none of the variation groups define a value for 'unit', the value of
292 |  the master product is returned.
293 | 
294 | ### unitQuantity
295 | 
296 | **Type:** Quantity (Read Only)
297 | 
298 | The unitQuantity of the product variant as defined by the
299 |  master product. 
300 | 
301 |  If the variant does not define an own value for 'unitQuantity', the value is retrieved
302 |  from the assigned variation groups, sorted by their position.
303 | 
304 |  If none of the variation groups define a value for 'unitQuantity', the value of
305 |  the master product is returned.
306 | 
307 | ### UPC
308 | 
309 | **Type:** String (Read Only)
310 | 
311 | The UPC of the product variant. 
312 | 
313 |  If the variant does not define an own value for 'UPC', the value is retrieved
314 |  from the assigned variation groups, sorted by their position.
315 | 
316 |  If none of the variation groups define a value for 'UPC', the value of
317 |  the master product is returned.
318 | 
319 | ## Constructor Summary
320 | 
321 | ## Method Summary
322 | 
323 | ### getAllProductLinks
324 | 
325 | **Signature:** `getAllProductLinks() : Collection`
326 | 
327 | Returns all product links of the product variant.
328 | 
329 | ### getAllProductLinks
330 | 
331 | **Signature:** `getAllProductLinks(type : Number) : Collection`
332 | 
333 | Returns all product links of the specified type of the product variant.
334 | 
335 | ### getBrand
336 | 
337 | **Signature:** `getBrand() : String`
338 | 
339 | Returns the brand of the product variant.
340 | 
341 | ### getClassificationCategory
342 | 
343 | **Signature:** `getClassificationCategory() : Category`
344 | 
345 | Returns the classification category of the product variant.
346 | 
347 | ### getCustom
348 | 
349 | **Signature:** `getCustom() : CustomAttributes`
350 | 
351 | Returns the custom attributes of the variant.
352 | 
353 | ### getEAN
354 | 
355 | **Signature:** `getEAN() : String`
356 | 
357 | Returns the EAN of the product variant.
358 | 
359 | ### getImage
360 | 
361 | **Signature:** `getImage() : MediaFile`
362 | 
363 | Returns the image of the product variant.
364 | 
365 | ### getLongDescription
366 | 
367 | **Signature:** `getLongDescription() : MarkupText`
368 | 
369 | Returns the long description of the product variant.
370 | 
371 | ### getManufacturerName
372 | 
373 | **Signature:** `getManufacturerName() : String`
374 | 
375 | Returns the manufacturer name of the product variant.
376 | 
377 | ### getManufacturerSKU
378 | 
379 | **Signature:** `getManufacturerSKU() : String`
380 | 
381 | Returns the manufacturer sku of the product variant.
382 | 
383 | ### getMasterProduct
384 | 
385 | **Signature:** `getMasterProduct() : Product`
386 | 
387 | Returns the ProductMaster for this mastered product.
388 | 
389 | ### getName
390 | 
391 | **Signature:** `getName() : String`
392 | 
393 | Returns the name of the product variant.
394 | 
395 | ### getOnlineFrom
396 | 
397 | **Signature:** `getOnlineFrom() : Date`
398 | 
399 | Returns the onlineFrom date of the product variant.
400 | 
401 | ### getOnlineTo
402 | 
403 | **Signature:** `getOnlineTo() : Date`
404 | 
405 | Returns the onlineTo date of the product variant.
406 | 
407 | ### getPageDescription
408 | 
409 | **Signature:** `getPageDescription() : String`
410 | 
411 | Returns the pageDescription of the product variant.
412 | 
413 | ### getPageKeywords
414 | 
415 | **Signature:** `getPageKeywords() : String`
416 | 
417 | Returns the pageKeywords of the product variant.
418 | 
419 | ### getPageTitle
420 | 
421 | **Signature:** `getPageTitle() : String`
422 | 
423 | Returns the pageTitle of the product variant.
424 | 
425 | ### getPageURL
426 | 
427 | **Signature:** `getPageURL() : String`
428 | 
429 | Returns the pageURL of the product variant.
430 | 
431 | ### getProductLinks
432 | 
433 | **Signature:** `getProductLinks() : Collection`
434 | 
435 | Returns all product links of the product variant for which the target product is assigned to the current site catalog.
436 | 
437 | ### getProductLinks
438 | 
439 | **Signature:** `getProductLinks(type : Number) : Collection`
440 | 
441 | Returns all product links of the specified type of the product variant for which the target product is assigned to the current site catalog.
442 | 
443 | ### getRecommendations
444 | 
445 | **Signature:** `getRecommendations(type : Number) : Collection`
446 | 
447 | Retrieve the sorted collection of recommendations of the specified type for this product variant.
448 | 
449 | ### getShortDescription
450 | 
451 | **Signature:** `getShortDescription() : MarkupText`
452 | 
453 | Returns the short description of the product variant.
454 | 
455 | ### getTaxClassID
456 | 
457 | **Signature:** `getTaxClassID() : String`
458 | 
459 | Returns the tax class id of the product variant.
460 | 
461 | ### getTemplate
462 | 
463 | **Signature:** `getTemplate() : String`
464 | 
465 | Returns the rendering template name of the product variant.
466 | 
467 | ### getThumbnail
468 | 
469 | **Signature:** `getThumbnail() : MediaFile`
470 | 
471 | Returns the thumbnail image of the product variant.
472 | 
473 | ### getUnit
474 | 
475 | **Signature:** `getUnit() : String`
476 | 
477 | Returns the sales unit of the product variant as defined by the master product.
478 | 
479 | ### getUnitQuantity
480 | 
481 | **Signature:** `getUnitQuantity() : Quantity`
482 | 
483 | Returns the unitQuantity of the product variant as defined by the master product.
484 | 
485 | ### getUPC
486 | 
487 | **Signature:** `getUPC() : String`
488 | 
489 | Returns the UPC of the product variant.
490 | 
491 | ### isOptionProduct
492 | 
493 | **Signature:** `isOptionProduct() : boolean`
494 | 
495 | Returns 'true' if the variant has any options, otherwise 'false'.
496 | 
497 | ## Method Detail
498 | 
499 | ## Method Details
500 | 
501 | ### getAllProductLinks
502 | 
503 | **Signature:** `getAllProductLinks() : Collection`
504 | 
505 | **Description:** Returns all product links of the product variant. If the variant does not define any product links, the product links are retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define any product links, the product links are retrieved from the master product.
506 | 
507 | **Returns:**
508 | 
509 | All product links of the variant, variation group or master
510 | 
511 | ---
512 | 
513 | ### getAllProductLinks
514 | 
515 | **Signature:** `getAllProductLinks(type : Number) : Collection`
516 | 
517 | **Description:** Returns all product links of the specified type of the product variant. If the variant does not define any product links of the specified type, the product links are retrieved for the specified type from the assigned variation groups, sorted by their position. If none of the variation groups define any product links of the specified type, the product links are retrieved for the specified type from the master product.
518 | 
519 | **Parameters:**
520 | 
521 | - `type`: Type of the product link
522 | 
523 | **Returns:**
524 | 
525 | Product links of specified type of the variant, variation group or master
526 | 
527 | ---
528 | 
529 | ### getBrand
530 | 
531 | **Signature:** `getBrand() : String`
532 | 
533 | **Description:** Returns the brand of the product variant. If the variant does not define an own value for 'brand', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'brand', the value of the master product is returned.
534 | 
535 | **Returns:**
536 | 
537 | The brand of the variant, variation group or master
538 | 
539 | ---
540 | 
541 | ### getClassificationCategory
542 | 
543 | **Signature:** `getClassificationCategory() : Category`
544 | 
545 | **Description:** Returns the classification category of the product variant. Please note that the classification category is always inherited from the master and cannot be overridden by the variant.
546 | 
547 | **Returns:**
548 | 
549 | The classification category as defined for the master product of the variant
550 | 
551 | ---
552 | 
553 | ### getCustom
554 | 
555 | **Signature:** `getCustom() : CustomAttributes`
556 | 
557 | **Description:** Returns the custom attributes of the variant. Custom attributes are inherited from the master product and can be overridden by the variant.
558 | 
559 | **Returns:**
560 | 
561 | the custom attributes of the variant.
562 | 
563 | ---
564 | 
565 | ### getEAN
566 | 
567 | **Signature:** `getEAN() : String`
568 | 
569 | **Description:** Returns the EAN of the product variant. If the variant does not define an own value for 'EAN', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'EAN', the value of the master product is returned.
570 | 
571 | **Returns:**
572 | 
573 | The EAN of the variant, variation group or master
574 | 
575 | ---
576 | 
577 | ### getImage
578 | 
579 | **Signature:** `getImage() : MediaFile`
580 | 
581 | **Description:** Returns the image of the product variant. If the variant does not define an own value for 'image', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'image', the value of the master product is returned.
582 | 
583 | **Returns:**
584 | 
585 | The image of the variant, variation group or master
586 | 
587 | ---
588 | 
589 | ### getLongDescription
590 | 
591 | **Signature:** `getLongDescription() : MarkupText`
592 | 
593 | **Description:** Returns the long description of the product variant. If the variant does not define an own value for 'longDescription', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'longDescription', the value of the master product is returned.
594 | 
595 | **Returns:**
596 | 
597 | The long description of the variant, variation group or master
598 | 
599 | ---
600 | 
601 | ### getManufacturerName
602 | 
603 | **Signature:** `getManufacturerName() : String`
604 | 
605 | **Description:** Returns the manufacturer name of the product variant. If the variant does not define an own value for 'manufacturerName', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'manufacturerName', the value of the master product is returned.
606 | 
607 | **Returns:**
608 | 
609 | The manufacturer name of the variant, variation group or master
610 | 
611 | ---
612 | 
613 | ### getManufacturerSKU
614 | 
615 | **Signature:** `getManufacturerSKU() : String`
616 | 
617 | **Description:** Returns the manufacturer sku of the product variant. If the variant does not define an own value for 'manufacturerSKU', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'manufacturerSKU', the value of the master product is returned.
618 | 
619 | **Returns:**
620 | 
621 | The manufacturer sku of the variant, variation group or master
622 | 
623 | ---
624 | 
625 | ### getMasterProduct
626 | 
627 | **Signature:** `getMasterProduct() : Product`
628 | 
629 | **Description:** Returns the ProductMaster for this mastered product.
630 | 
631 | **Returns:**
632 | 
633 | the ProductMaster of this mastered product
634 | 
635 | ---
636 | 
637 | ### getName
638 | 
639 | **Signature:** `getName() : String`
640 | 
641 | **Description:** Returns the name of the product variant. If the variant does not define an own value for 'name', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'name', the value of the master product is returned.
642 | 
643 | **Returns:**
644 | 
645 | The name of the variant, variation group or master
646 | 
647 | ---
648 | 
649 | ### getOnlineFrom
650 | 
651 | **Signature:** `getOnlineFrom() : Date`
652 | 
653 | **Description:** Returns the onlineFrom date of the product variant. If the variant does not define an own value for 'onlineFrom', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'onlineFrom', the value of the master product is returned.
654 | 
655 | **Returns:**
656 | 
657 | The onlineFrom date of the variant, variation group or master
658 | 
659 | ---
660 | 
661 | ### getOnlineTo
662 | 
663 | **Signature:** `getOnlineTo() : Date`
664 | 
665 | **Description:** Returns the onlineTo date of the product variant. If the variant does not define an own value for 'onlineTo', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'onlineTo', the value of the master product is returned.
666 | 
667 | **Returns:**
668 | 
669 | The onlineTo date of the variant, variation group or master
670 | 
671 | ---
672 | 
673 | ### getPageDescription
674 | 
675 | **Signature:** `getPageDescription() : String`
676 | 
677 | **Description:** Returns the pageDescription of the product variant. If the variant does not define an own value for 'pageDescription', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'pageDescription', the value of the master product is returned.
678 | 
679 | **Returns:**
680 | 
681 | The pageDescription of the variant, variation group or master
682 | 
683 | ---
684 | 
685 | ### getPageKeywords
686 | 
687 | **Signature:** `getPageKeywords() : String`
688 | 
689 | **Description:** Returns the pageKeywords of the product variant. If the variant does not define an own value for 'pageKeywords', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'pageKeywords', the value of the master product is returned.
690 | 
691 | **Returns:**
692 | 
693 | The pageKeywords of the variant, variation group or master
694 | 
695 | ---
696 | 
697 | ### getPageTitle
698 | 
699 | **Signature:** `getPageTitle() : String`
700 | 
701 | **Description:** Returns the pageTitle of the product variant. If the variant does not define an own value for 'pageTitle', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'pageTitle', the value of the master product is returned.
702 | 
703 | **Returns:**
704 | 
705 | The pageTitle of the variant, variation group or master
706 | 
707 | ---
708 | 
709 | ### getPageURL
710 | 
711 | **Signature:** `getPageURL() : String`
712 | 
713 | **Description:** Returns the pageURL of the product variant. If the variant does not define an own value for 'pageURL', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'pageURL', the value of the master product is returned.
714 | 
715 | **Returns:**
716 | 
717 | The pageURL of the variant, variation group or master
718 | 
719 | ---
720 | 
721 | ### getProductLinks
722 | 
723 | **Signature:** `getProductLinks() : Collection`
724 | 
725 | **Description:** Returns all product links of the product variant for which the target product is assigned to the current site catalog. If the variant does not define any product links, the product links are retrieved from the assigned variation groups, sorted by their position If none of the variation groups define any product links, the product links are retrieved from the master product.
726 | 
727 | **Returns:**
728 | 
729 | Product links of the variant, variation group or master
730 | 
731 | ---
732 | 
733 | ### getProductLinks
734 | 
735 | **Signature:** `getProductLinks(type : Number) : Collection`
736 | 
737 | **Description:** Returns all product links of the specified type of the product variant for which the target product is assigned to the current site catalog. If the variant does not define any product links of the specified type, the product links are retrieved for the specified type from the assigned variation groups, sorted by their position If none of the variation groups define any product links of the specified type, the product links are retrieved for the specified type from the master product.
738 | 
739 | **Parameters:**
740 | 
741 | - `type`: Type of the product link
742 | 
743 | **Returns:**
744 | 
745 | Product links of specified type of the variant, variation group or master
746 | 
747 | ---
748 | 
749 | ### getRecommendations
750 | 
751 | **Signature:** `getRecommendations(type : Number) : Collection`
752 | 
753 | **Description:** Retrieve the sorted collection of recommendations of the specified type for this product variant. The types (cross-sell, up-sell, etc) are enumerated in the dw.catalog.Recommendation class. Only recommendations which are stored in the current site catalog are returned. Furthermore, a recommendation is only returned if the target of the recommendation is assigned to the current site catalog. If the variant does not define any recommendations, recommendations are retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define any recommendations, the recommendations of the master are returned.
754 | 
755 | **Parameters:**
756 | 
757 | - `type`: the recommendation type
758 | 
759 | **Returns:**
760 | 
761 | the sorted collection, never null but possibly empty.
762 | 
763 | ---
764 | 
765 | ### getShortDescription
766 | 
767 | **Signature:** `getShortDescription() : MarkupText`
768 | 
769 | **Description:** Returns the short description of the product variant. If the variant does not define an own value for 'shortDescription', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'shortDescription', the value of the master product is returned.
770 | 
771 | **Returns:**
772 | 
773 | The short description of the variant, variation group or master
774 | 
775 | ---
776 | 
777 | ### getTaxClassID
778 | 
779 | **Signature:** `getTaxClassID() : String`
780 | 
781 | **Description:** Returns the tax class id of the product variant. If the variant does not define an own value for 'taxClassID', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'taxClassID', the value of the master product is returned.
782 | 
783 | **Returns:**
784 | 
785 | The tax class id of the variant, variation group or master
786 | 
787 | ---
788 | 
789 | ### getTemplate
790 | 
791 | **Signature:** `getTemplate() : String`
792 | 
793 | **Description:** Returns the rendering template name of the product variant. If the variant does not define an own value for 'template', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'template', the value of the master product is returned.
794 | 
795 | **Returns:**
796 | 
797 | The rendering template name of the variant, variation group or master
798 | 
799 | ---
800 | 
801 | ### getThumbnail
802 | 
803 | **Signature:** `getThumbnail() : MediaFile`
804 | 
805 | **Description:** Returns the thumbnail image of the product variant. If the variant does not define an own value for 'thumbnail', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'thumbnail', the value of the master product is returned.
806 | 
807 | **Returns:**
808 | 
809 | The thumbnail image of the variant, variation group or master
810 | 
811 | ---
812 | 
813 | ### getUnit
814 | 
815 | **Signature:** `getUnit() : String`
816 | 
817 | **Description:** Returns the sales unit of the product variant as defined by the master product. If the variant does not define an own value for 'unit', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'unit', the value of the master product is returned.
818 | 
819 | **Returns:**
820 | 
821 | The sales unit of the variant, variation group or master
822 | 
823 | ---
824 | 
825 | ### getUnitQuantity
826 | 
827 | **Signature:** `getUnitQuantity() : Quantity`
828 | 
829 | **Description:** Returns the unitQuantity of the product variant as defined by the master product. If the variant does not define an own value for 'unitQuantity', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'unitQuantity', the value of the master product is returned.
830 | 
831 | **Returns:**
832 | 
833 | The unitQuantity of the variant, variation group or master
834 | 
835 | ---
836 | 
837 | ### getUPC
838 | 
839 | **Signature:** `getUPC() : String`
840 | 
841 | **Description:** Returns the UPC of the product variant. If the variant does not define an own value for 'UPC', the value is retrieved from the assigned variation groups, sorted by their position. If none of the variation groups define a value for 'UPC', the value of the master product is returned.
842 | 
843 | **Returns:**
844 | 
845 | The UPC of the variant, variation group or master
846 | 
847 | ---
848 | 
849 | ### isOptionProduct
850 | 
851 | **Signature:** `isOptionProduct() : boolean`
852 | 
853 | **Description:** Returns 'true' if the variant has any options, otherwise 'false'. Method also returns 'true' if the variant has not any options, but the related variation groups (sorted by position) or master product has options.
854 | 
855 | **Returns:**
856 | 
857 | true if the variant has any options, false otherwise.
858 | 
859 | ---
```

--------------------------------------------------------------------------------
/docs/TopLevel/XML.md:
--------------------------------------------------------------------------------

```markdown
  1 | ## Package: TopLevel
  2 | 
  3 | # Class XML
  4 | 
  5 | ## Inheritance Hierarchy
  6 | 
  7 | - Object
  8 |   - XML
  9 | 
 10 | ## Description
 11 | 
 12 | The XML object contains functions and properties for working with XML instances. The XML object implements the powerful XML-handling standards defined in the ECMA-357 specification (known as "E4X"). Use the toXMLString() method to return a string representation of the XML object regardless of whether the XML object has simple content or complex content. Do not create large XML objects in memory to avoid out-of-memory conditions. When dealing with XML streams use XMLStreamReader and XMLStreamWriter. The following example shows how: var id : String = "p42"; var pname : String = "a product"; // use E4X syntax var product : XML = <product id={id}> <name>{pname}</name> <shortdesc></shortdesc> </product>; product.shortdesc = "a fine product"; product.longdesc = "this is a fine product"; var xmlString = product.toXMLString(); fileWriter.write(xmlString); The code above will write the following to file: <product id="p42"> <name>a product</name> <shortdesc>a fine product</shortdesc> <longdesc>this is a fine product</longdesc> </product> Do not create large XML objects in memory to avoid out-of-memory conditions. When dealing with XML streams use XMLStreamReader and XMLStreamWriter.
 13 | 
 14 | ## Properties
 15 | 
 16 | ## Constructor Summary
 17 | 
 18 | XML() Creates a new XML object.
 19 | 
 20 | XML(value : Object) Creates a new XML object.
 21 | 
 22 | ## Method Summary
 23 | 
 24 | ### addNamespace
 25 | 
 26 | **Signature:** `addNamespace(ns : Object) : XML`
 27 | 
 28 | Adds a namespace to the set of in-scope namespaces for the XML object.
 29 | 
 30 | ### appendChild
 31 | 
 32 | **Signature:** `appendChild(child : Object) : XML`
 33 | 
 34 | Appends the specified child to the end of the object's properties.
 35 | 
 36 | ### attribute
 37 | 
 38 | **Signature:** `attribute(attributeName : String) : XMLList`
 39 | 
 40 | Returns the attribute associated with this XML object that is identified by the specified name.
 41 | 
 42 | ### attributes
 43 | 
 44 | **Signature:** `attributes() : XMLList`
 45 | 
 46 | Returns an XMList of the attributes in this XML Object.
 47 | 
 48 | ### child
 49 | 
 50 | **Signature:** `child(propertyName : Object) : XMLList`
 51 | 
 52 | Returns the children of the XML object based on the specified property name.
 53 | 
 54 | ### childIndex
 55 | 
 56 | **Signature:** `childIndex() : Number`
 57 | 
 58 | Identifies the zero-based index of this XML object within the context of its parent, or -1 if this object has no parent.
 59 | 
 60 | ### children
 61 | 
 62 | **Signature:** `children() : XMLList`
 63 | 
 64 | Returns an XMLList containing the children of this XML object, maintaing the sequence in which they appear.
 65 | 
 66 | ### comments
 67 | 
 68 | **Signature:** `comments() : XMLList`
 69 | 
 70 | Returns the properties of the XML object that contain comments.
 71 | 
 72 | ### contains
 73 | 
 74 | **Signature:** `contains(value : XML) : boolean`
 75 | 
 76 | Returns true if this XML object contains the specified XML object, false otherwise.
 77 | 
 78 | ### copy
 79 | 
 80 | **Signature:** `copy() : XML`
 81 | 
 82 | Returns a copy of the this XML object including duplicate copies of the entire tree of nodes.
 83 | 
 84 | ### defaultSettings
 85 | 
 86 | **Signature:** `static defaultSettings() : Object`
 87 | 
 88 | Returns a new Object with the following properties set to the default values: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting.
 89 | 
 90 | ### descendants
 91 | 
 92 | **Signature:** `descendants() : XMLList`
 93 | 
 94 | Returns all descendents of the XML object.
 95 | 
 96 | ### descendants
 97 | 
 98 | **Signature:** `descendants(name : String) : XMLList`
 99 | 
100 | Returns all descendents of the XML object that have the specified name parameter.
101 | 
102 | ### elements
103 | 
104 | **Signature:** `elements() : XMLList`
105 | 
106 | Returns a list of all of the elements of the XML object.
107 | 
108 | ### elements
109 | 
110 | **Signature:** `elements(name : Object) : XMLList`
111 | 
112 | Returns a list of the elements of the XML object using the specified name to constrain the list.
113 | 
114 | ### hasComplexContent
115 | 
116 | **Signature:** `hasComplexContent() : boolean`
117 | 
118 | Returns a Boolean value indicating whether this XML object contains complex content.
119 | 
120 | ### hasOwnProperty
121 | 
122 | **Signature:** `hasOwnProperty(prop : String) : boolean`
123 | 
124 | Returns a Boolean value indicating whether this object has the property specified by prop.
125 | 
126 | ### hasSimpleContent
127 | 
128 | **Signature:** `hasSimpleContent() : boolean`
129 | 
130 | Returns a Boolean value indicating whether this XML object contains simple content.
131 | 
132 | ### inScopeNamespaces
133 | 
134 | **Signature:** `inScopeNamespaces() : Array`
135 | 
136 | Returns an Array of Namespace objects representing the namespaces in scope for this XML object in the context of its parent.
137 | 
138 | ### insertChildAfter
139 | 
140 | **Signature:** `insertChildAfter(child1 : Object, child2 : Object) : XML`
141 | 
142 | Inserts the specified child2 after the specified child1 in this XML object and returns this XML object.
143 | 
144 | ### insertChildBefore
145 | 
146 | **Signature:** `insertChildBefore(child1 : Object, child2 : Object) : XML`
147 | 
148 | Inserts the specified child2 before the specified child1 in this XML object and returns this XML object.
149 | 
150 | ### length
151 | 
152 | **Signature:** `length() : Number`
153 | 
154 | Returns a value of 1 for XML objects.
155 | 
156 | ### localName
157 | 
158 | **Signature:** `localName() : Object`
159 | 
160 | Returns the local name portion of the qualified name of the XML object.
161 | 
162 | ### name
163 | 
164 | **Signature:** `name() : Object`
165 | 
166 | Returns the qualified name for the XML object.
167 | 
168 | ### namespace
169 | 
170 | **Signature:** `namespace() : Object`
171 | 
172 | Returns the namespace associated with the qualified name of this XML object.
173 | 
174 | ### namespace
175 | 
176 | **Signature:** `namespace(prefix : String) : Object`
177 | 
178 | Returns the namespace that matches the specified prefix and that is in scope for the XML object.
179 | 
180 | ### namespaceDeclarations
181 | 
182 | **Signature:** `namespaceDeclarations() : Array`
183 | 
184 | Returns an Array of namespace declarations associated with the XML Obnject in the context of its parent.
185 | 
186 | ### nodeKind
187 | 
188 | **Signature:** `nodeKind() : String`
189 | 
190 | Returns the type of the XML object, such as text, comment, processing-instruction, or attribute.
191 | 
192 | ### normalize
193 | 
194 | **Signature:** `normalize() : XML`
195 | 
196 | Merges adjacent text nodes and eliminates and eliminates empty text nodes for this XML object and all its descendents.
197 | 
198 | ### parent
199 | 
200 | **Signature:** `parent() : Object`
201 | 
202 | Returns the parent of the XML object or null if the XML object does not have a parent.
203 | 
204 | ### prependChild
205 | 
206 | **Signature:** `prependChild(value : Object) : XML`
207 | 
208 | Inserts the specified child into this XML object prior to its existing XML properties and then returns this XML object.
209 | 
210 | ### processingInstructions
211 | 
212 | **Signature:** `processingInstructions() : XMLList`
213 | 
214 | Returns an XMLList containing all the children of this XML object that are processing-instructions.
215 | 
216 | ### processingInstructions
217 | 
218 | **Signature:** `processingInstructions(name : String) : XMLList`
219 | 
220 | Returns an XMLList containing all the children of this XML object that are processing-instructions with the specified name.
221 | 
222 | ### propertyIsEnumerable
223 | 
224 | **Signature:** `propertyIsEnumerable(property : String) : boolean`
225 | 
226 | 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.
227 | 
228 | ### removeNamespace
229 | 
230 | **Signature:** `removeNamespace(ns : Namespace) : XML`
231 | 
232 | Removes the specified namespace from the in scope namespaces of this object and all its descendents, then returns a copy of this XML object.
233 | 
234 | ### replace
235 | 
236 | **Signature:** `replace(propertyName : String, value : Object) : XML`
237 | 
238 | Replaces the XML properties of this XML object specified by propertyName with value and returns this updated XML object.
239 | 
240 | ### setChildren
241 | 
242 | **Signature:** `setChildren(value : Object) : XML`
243 | 
244 | Replaces the XML properties of this XML object with a new set of XML properties from value.
245 | 
246 | ### setLocalName
247 | 
248 | **Signature:** `setLocalName(name : String) : void`
249 | 
250 | Replaces the local name of this XML object with a string constructed from the specified name.
251 | 
252 | ### setName
253 | 
254 | **Signature:** `setName(name : String) : void`
255 | 
256 | Replaces the name of this XML object with a QName or AttributeName constructed from the specified name.
257 | 
258 | ### setNamespace
259 | 
260 | **Signature:** `setNamespace(ns : Namespace) : void`
261 | 
262 | Replaces the namespace associated with the name of this XML object with the specified namespace.
263 | 
264 | ### setSettings
265 | 
266 | **Signature:** `static setSettings() : void`
267 | 
268 | Restores the default settings for the following XML properties: XML.ignoreComments = true XML.ignoreProcessingInstructions = true XML.ignoreWhitespace = true XML.prettyIndent = 2 XML.prettyPrinting = true
269 | 
270 | ### setSettings
271 | 
272 | **Signature:** `static setSettings(settings : Object) : void`
273 | 
274 | Updates the collection of global XML properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyPrinting, prettyIndent, and prettyPrinting.
275 | 
276 | ### settings
277 | 
278 | **Signature:** `static settings() : Object`
279 | 
280 | Returns the collection of global XML properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyPrinting, prettyIndent, and prettyPrinting.
281 | 
282 | ### text
283 | 
284 | **Signature:** `text() : XMLList`
285 | 
286 | Returns an XMLList containing all XML properties of this XML object that represent XML text nodes.
287 | 
288 | ### toString
289 | 
290 | **Signature:** `toString() : String`
291 | 
292 | Returns the String representation of the XML object.
293 | 
294 | ### toXMLString
295 | 
296 | **Signature:** `toXMLString() : String`
297 | 
298 | Returns a XML-encoded String representation of the XML object, including tag and attributed delimiters.
299 | 
300 | ### valueOf
301 | 
302 | **Signature:** `valueOf() : XML`
303 | 
304 | Returns this XML object.
305 | 
306 | ## Constructor Detail
307 | 
308 | ## Method Detail
309 | 
310 | ## Method Details
311 | 
312 | ### addNamespace
313 | 
314 | **Signature:** `addNamespace(ns : Object) : XML`
315 | 
316 | **Description:** Adds a namespace to the set of in-scope namespaces for the XML object. If the namespace already exists in the in-scope namespaces for the XML object, then the prefix of the existing namespace is set to undefined. If ns is a Namespace instance, it is used directly. However, if ns is a QName instance, the input parameter's URI is used to create a new namespace. If ns is not a Namespace or QName instance, ns is converted to a String and a namespace is created from the String.
317 | 
318 | **Parameters:**
319 | 
320 | - `ns`: the namespace to add to the XML object.
321 | 
322 | **Returns:**
323 | 
324 | a new XML object, with the namespace added.
325 | 
326 | ---
327 | 
328 | ### appendChild
329 | 
330 | **Signature:** `appendChild(child : Object) : XML`
331 | 
332 | **Description:** Appends the specified child to the end of the object's properties. child should be a XML object, an XMLList object or any other data type that will then be converted to a String.
333 | 
334 | **Parameters:**
335 | 
336 | - `child`: the object to append to this XML object.
337 | 
338 | **Returns:**
339 | 
340 | the XML object with the child appended.
341 | 
342 | ---
343 | 
344 | ### attribute
345 | 
346 | **Signature:** `attribute(attributeName : String) : XMLList`
347 | 
348 | **Description:** Returns the attribute associated with this XML object that is identified by the specified name.
349 | 
350 | **Parameters:**
351 | 
352 | - `attributeName`: the name of the attribute.
353 | 
354 | **Returns:**
355 | 
356 | the value of the attribute as either an XMLList or an empty XMLList
357 | 
358 | ---
359 | 
360 | ### attributes
361 | 
362 | **Signature:** `attributes() : XMLList`
363 | 
364 | **Description:** Returns an XMList of the attributes in this XML Object.
365 | 
366 | **Returns:**
367 | 
368 | an XMList of the attributes in this XML Object.
369 | 
370 | ---
371 | 
372 | ### child
373 | 
374 | **Signature:** `child(propertyName : Object) : XMLList`
375 | 
376 | **Description:** Returns the children of the XML object based on the specified property name.
377 | 
378 | **Parameters:**
379 | 
380 | - `propertyName`: the property name representing the children of this XML object.
381 | 
382 | **Returns:**
383 | 
384 | an XMLList of children that match the property name parameter.
385 | 
386 | ---
387 | 
388 | ### childIndex
389 | 
390 | **Signature:** `childIndex() : Number`
391 | 
392 | **Description:** Identifies the zero-based index of this XML object within the context of its parent, or -1 if this object has no parent.
393 | 
394 | **Returns:**
395 | 
396 | the index of this XML object in the context of its parent, or -1 if this object has no parent.
397 | 
398 | ---
399 | 
400 | ### children
401 | 
402 | **Signature:** `children() : XMLList`
403 | 
404 | **Description:** Returns an XMLList containing the children of this XML object, maintaing the sequence in which they appear.
405 | 
406 | **Returns:**
407 | 
408 | an XMLList containing the children of this XML object.
409 | 
410 | ---
411 | 
412 | ### comments
413 | 
414 | **Signature:** `comments() : XMLList`
415 | 
416 | **Description:** Returns the properties of the XML object that contain comments.
417 | 
418 | **Returns:**
419 | 
420 | properties of the XML object that contain comments.
421 | 
422 | ---
423 | 
424 | ### contains
425 | 
426 | **Signature:** `contains(value : XML) : boolean`
427 | 
428 | **Description:** Returns true if this XML object contains the specified XML object, false otherwise.
429 | 
430 | **Parameters:**
431 | 
432 | - `value`: the object to locate in this XML object.
433 | 
434 | **Returns:**
435 | 
436 | true if this XML object contains the specified XML object, false otherwise.
437 | 
438 | ---
439 | 
440 | ### copy
441 | 
442 | **Signature:** `copy() : XML`
443 | 
444 | **Description:** Returns a copy of the this XML object including duplicate copies of the entire tree of nodes. The copied XML object has no parent.
445 | 
446 | **Returns:**
447 | 
448 | the copy of the object.
449 | 
450 | ---
451 | 
452 | ### defaultSettings
453 | 
454 | **Signature:** `static defaultSettings() : Object`
455 | 
456 | **Description:** Returns a new Object with the following properties set to the default values: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting. The default values are as follows: ignoreComments = true ignoreProcessingInstructions = true ignoreWhitespace = true prettyIndent = 2 prettyPrinting = true Be aware that this method does not apply the settings to an existing instance of an XML object. Instead, this method returns an Object containing the default settings.
457 | 
458 | **Returns:**
459 | 
460 | an Object with properties set to the default settings.
461 | 
462 | ---
463 | 
464 | ### descendants
465 | 
466 | **Signature:** `descendants() : XMLList`
467 | 
468 | **Description:** Returns all descendents of the XML object.
469 | 
470 | **Returns:**
471 | 
472 | a list of all descendents of the XML object.
473 | 
474 | ---
475 | 
476 | ### descendants
477 | 
478 | **Signature:** `descendants(name : String) : XMLList`
479 | 
480 | **Description:** Returns all descendents of the XML object that have the specified name parameter. To return all descendents, use * as the name parameter.
481 | 
482 | **Parameters:**
483 | 
484 | - `name`: the name of the element to match. To return all descendents, use * as the name parameter.
485 | 
486 | **Returns:**
487 | 
488 | a list of all descendents constrained by the name parameter.
489 | 
490 | ---
491 | 
492 | ### elements
493 | 
494 | **Signature:** `elements() : XMLList`
495 | 
496 | **Description:** Returns a list of all of the elements of the XML object.
497 | 
498 | ---
499 | 
500 | ### elements
501 | 
502 | **Signature:** `elements(name : Object) : XMLList`
503 | 
504 | **Description:** Returns a list of the elements of the XML object using the specified name to constrain the list. 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.
505 | 
506 | **Parameters:**
507 | 
508 | - `name`: the name of the elements to return or an * to return all elements.
509 | 
510 | **Returns:**
511 | 
512 | a list of the elements of the XML object using the specified name to constrain the list.
513 | 
514 | ---
515 | 
516 | ### hasComplexContent
517 | 
518 | **Signature:** `hasComplexContent() : boolean`
519 | 
520 | **Description:** Returns a Boolean value indicating whether this XML object contains complex content. An XML object is considered to contain complex content if it represents an XML element that has child elements. XML objects representing attributes, comments, processing instructions and text nodes do not have complex content. The existence of attributes, comments, processing instructions and text nodes within an XML object is not significant in determining if it has complex content.
521 | 
522 | **Returns:**
523 | 
524 | a Boolean value indicating whether this XML object contains complex content.
525 | 
526 | ---
527 | 
528 | ### hasOwnProperty
529 | 
530 | **Signature:** `hasOwnProperty(prop : String) : boolean`
531 | 
532 | **Description:** Returns a Boolean value indicating whether this object has the property specified by prop.
533 | 
534 | **Parameters:**
535 | 
536 | - `prop`: the property to locate.
537 | 
538 | **Returns:**
539 | 
540 | true if the property exists, false otherwise.
541 | 
542 | ---
543 | 
544 | ### hasSimpleContent
545 | 
546 | **Signature:** `hasSimpleContent() : boolean`
547 | 
548 | **Description:** Returns a Boolean value indicating whether this XML object contains simple content. An XML object is considered to contain simple content if it represents a text node, represents an attribute node or if it represents an XML element that has no child elements. XML objects representing comments and processing instructions do not have simple content. The existence of attributes, comments, processing instructions and text nodes within an XML object is not significant in determining if it has simple content.
549 | 
550 | **Returns:**
551 | 
552 | a Boolean value indicating whether this XML object contains simple content.
553 | 
554 | ---
555 | 
556 | ### inScopeNamespaces
557 | 
558 | **Signature:** `inScopeNamespaces() : Array`
559 | 
560 | **Description:** Returns an Array of Namespace objects representing the namespaces in scope for this XML object in the context of its parent. If the parent of this XML object is modified, the associated namespace declarations may change. The set of namespaces returned by this method may be a super set of the namespaces used by this value
561 | 
562 | **Returns:**
563 | 
564 | an Array of Namespace objects representing the namespaces in scope for this XML object in the context of its parent.
565 | 
566 | ---
567 | 
568 | ### insertChildAfter
569 | 
570 | **Signature:** `insertChildAfter(child1 : Object, child2 : Object) : XML`
571 | 
572 | **Description:** Inserts the specified child2 after the specified child1 in this XML object and returns this XML object. If child1 is null, inserts child2 before all children of this XML object. If child1 does not exist in this XML object, it returns without modifying this XML object.
573 | 
574 | **Parameters:**
575 | 
576 | - `child1`: the child after which child2 is inserted.
577 | - `child2`: the child to insert into this XML object.
578 | 
579 | **Returns:**
580 | 
581 | the updated XML object.
582 | 
583 | ---
584 | 
585 | ### insertChildBefore
586 | 
587 | **Signature:** `insertChildBefore(child1 : Object, child2 : Object) : XML`
588 | 
589 | **Description:** Inserts the specified child2 before the specified child1 in this XML object and returns this XML object. If child1 is null, inserts child2 after all children of this XML object. If child1 does not exist in this XML object, it returns without modifying this XML object.
590 | 
591 | **Parameters:**
592 | 
593 | - `child1`: the child before which child2 is inserted.
594 | - `child2`: the child to insert into this XML object.
595 | 
596 | **Returns:**
597 | 
598 | the updated XML object.
599 | 
600 | ---
601 | 
602 | ### length
603 | 
604 | **Signature:** `length() : Number`
605 | 
606 | **Description:** Returns a value of 1 for XML objects.
607 | 
608 | **Returns:**
609 | 
610 | the value of 1.
611 | 
612 | ---
613 | 
614 | ### localName
615 | 
616 | **Signature:** `localName() : Object`
617 | 
618 | **Description:** Returns the local name portion of the qualified name of the XML object.
619 | 
620 | **Returns:**
621 | 
622 | the local name as either a String or null.
623 | 
624 | ---
625 | 
626 | ### name
627 | 
628 | **Signature:** `name() : Object`
629 | 
630 | **Description:** Returns the qualified name for the XML object.
631 | 
632 | **Returns:**
633 | 
634 | the qualified name as either a QName or null.
635 | 
636 | ---
637 | 
638 | ### namespace
639 | 
640 | **Signature:** `namespace() : Object`
641 | 
642 | **Description:** Returns the namespace associated with the qualified name of this XML object.
643 | 
644 | **Returns:**
645 | 
646 | the namespace associated with the qualified name of this XML object.
647 | 
648 | ---
649 | 
650 | ### namespace
651 | 
652 | **Signature:** `namespace(prefix : String) : Object`
653 | 
654 | **Description:** Returns the namespace that matches the specified prefix and that is in scope for the XML object. if there is no such namespace, the method returns undefined.
655 | 
656 | **Parameters:**
657 | 
658 | - `prefix`: the prefix to use when attempting to locate a namespace.
659 | 
660 | **Returns:**
661 | 
662 | the namespace that matches the specified prefix and that is in scope for the XML object. If specified namespace does not exist, the method returns undefined.
663 | 
664 | ---
665 | 
666 | ### namespaceDeclarations
667 | 
668 | **Signature:** `namespaceDeclarations() : Array`
669 | 
670 | **Description:** Returns an Array of namespace declarations associated with the XML Obnject in the context of its parent.
671 | 
672 | **Returns:**
673 | 
674 | an Array of namespace declarations associated with the XML Obnject in the context of its parent.
675 | 
676 | ---
677 | 
678 | ### nodeKind
679 | 
680 | **Signature:** `nodeKind() : String`
681 | 
682 | **Description:** Returns the type of the XML object, such as text, comment, processing-instruction, or attribute.
683 | 
684 | **Returns:**
685 | 
686 | the type of the XML object.
687 | 
688 | ---
689 | 
690 | ### normalize
691 | 
692 | **Signature:** `normalize() : XML`
693 | 
694 | **Description:** Merges adjacent text nodes and eliminates and eliminates empty text nodes for this XML object and all its descendents.
695 | 
696 | **Returns:**
697 | 
698 | the normalized XML object.
699 | 
700 | ---
701 | 
702 | ### parent
703 | 
704 | **Signature:** `parent() : Object`
705 | 
706 | **Description:** Returns the parent of the XML object or null if the XML object does not have a parent.
707 | 
708 | **Returns:**
709 | 
710 | the parent of the XML object of null if the XML object does not have a parent.
711 | 
712 | ---
713 | 
714 | ### prependChild
715 | 
716 | **Signature:** `prependChild(value : Object) : XML`
717 | 
718 | **Description:** Inserts the specified child into this XML object prior to its existing XML properties and then returns this XML object.
719 | 
720 | **Parameters:**
721 | 
722 | - `value`: the child to prepend to this XML object.
723 | 
724 | **Returns:**
725 | 
726 | the XML object updated with the prepended child.
727 | 
728 | ---
729 | 
730 | ### processingInstructions
731 | 
732 | **Signature:** `processingInstructions() : XMLList`
733 | 
734 | **Description:** Returns an XMLList containing all the children of this XML object that are processing-instructions.
735 | 
736 | **Returns:**
737 | 
738 | an XMLList containing all the children of this XML object that are processing-instructions.
739 | 
740 | ---
741 | 
742 | ### processingInstructions
743 | 
744 | **Signature:** `processingInstructions(name : String) : XMLList`
745 | 
746 | **Description:** Returns an XMLList containing all the children of this XML object that are processing-instructions with the specified name. If you use * for the name, all processing-instructions are returned.
747 | 
748 | **Parameters:**
749 | 
750 | - `name`: the name representing the processing-instructions you want to retreive.
751 | 
752 | **Returns:**
753 | 
754 | an XMLList containing all the children of this XML object that are processing-instructions with the specified name.
755 | 
756 | ---
757 | 
758 | ### propertyIsEnumerable
759 | 
760 | **Signature:** `propertyIsEnumerable(property : String) : boolean`
761 | 
762 | **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.
763 | 
764 | **Parameters:**
765 | 
766 | - `property`: the property to test.
767 | 
768 | **Returns:**
769 | 
770 | true when the property can be iterated in a for..in statement, false otherwise.
771 | 
772 | ---
773 | 
774 | ### removeNamespace
775 | 
776 | **Signature:** `removeNamespace(ns : Namespace) : XML`
777 | 
778 | **Description:** Removes the specified namespace from the in scope namespaces of this object and all its descendents, then returns a copy of this XML object. This method will not remove a namespace from an object when it is referenced by that object's QName or the ONames of that object's attributes.
779 | 
780 | **Parameters:**
781 | 
782 | - `ns`: the namespace to remove.
783 | 
784 | **Returns:**
785 | 
786 | a copy of this XML object with the namespace removed.
787 | 
788 | ---
789 | 
790 | ### replace
791 | 
792 | **Signature:** `replace(propertyName : String, value : Object) : XML`
793 | 
794 | **Description:** Replaces the XML properties of this XML object specified by propertyName with value and returns this updated XML object. If this XML object contains no properties that match propertyName, the replace method returns without modifying this XML object. The propertyName parameter may be a numeric property name, an unqualified name for a set of XML elements, a qualified name for a set of XML elements or the properties wildcard *. When the propertyName parameter is an unqualified name, it identifies XML elements in the default namespace. The value parameter may be an XML object, XMLList object or any value that may be converted to a String.
795 | 
796 | **Parameters:**
797 | 
798 | - `propertyName`: a numeric property name, an unqualified name for a set of XML elements, a qualified name for a set of XML elements or the properties wildcard *.
799 | - `value`: an XML object, XMLList object or any value that may be converted to a String.
800 | 
801 | **Returns:**
802 | 
803 | the updated XML object.
804 | 
805 | ---
806 | 
807 | ### setChildren
808 | 
809 | **Signature:** `setChildren(value : Object) : XML`
810 | 
811 | **Description:** Replaces the XML properties of this XML object with a new set of XML properties from value.
812 | 
813 | **Parameters:**
814 | 
815 | - `value`: a single XML object or an XMLList.
816 | 
817 | **Returns:**
818 | 
819 | the updated XML object.
820 | 
821 | ---
822 | 
823 | ### setLocalName
824 | 
825 | **Signature:** `setLocalName(name : String) : void`
826 | 
827 | **Description:** Replaces the local name of this XML object with a string constructed from the specified name.
828 | 
829 | **Parameters:**
830 | 
831 | - `name`: the new local name.
832 | 
833 | ---
834 | 
835 | ### setName
836 | 
837 | **Signature:** `setName(name : String) : void`
838 | 
839 | **Description:** Replaces the name of this XML object with a QName or AttributeName constructed from the specified name.
840 | 
841 | **Parameters:**
842 | 
843 | - `name`: the new name of this XML object.
844 | 
845 | ---
846 | 
847 | ### setNamespace
848 | 
849 | **Signature:** `setNamespace(ns : Namespace) : void`
850 | 
851 | **Description:** Replaces the namespace associated with the name of this XML object with the specified namespace.
852 | 
853 | **Parameters:**
854 | 
855 | - `ns`: the namespace to associated with the name of thix XML object.
856 | 
857 | ---
858 | 
859 | ### setSettings
860 | 
861 | **Signature:** `static setSettings() : void`
862 | 
863 | **Description:** Restores the default settings for the following XML properties: XML.ignoreComments = true XML.ignoreProcessingInstructions = true XML.ignoreWhitespace = true XML.prettyIndent = 2 XML.prettyPrinting = true
864 | 
865 | ---
866 | 
867 | ### setSettings
868 | 
869 | **Signature:** `static setSettings(settings : Object) : void`
870 | 
871 | **Description:** Updates the collection of global XML properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyPrinting, prettyIndent, and prettyPrinting.
872 | 
873 | **Parameters:**
874 | 
875 | - `settings`: an object with each of the following properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting.
876 | 
877 | ---
878 | 
879 | ### settings
880 | 
881 | **Signature:** `static settings() : Object`
882 | 
883 | **Description:** Returns the collection of global XML properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyPrinting, prettyIndent, and prettyPrinting.
884 | 
885 | **Returns:**
886 | 
887 | an object with each of the following properties: ignoreComments, ignoreProcessingInstructions, ignoreWhitespace, prettyIndent, and prettyPrinting.
888 | 
889 | ---
890 | 
891 | ### text
892 | 
893 | **Signature:** `text() : XMLList`
894 | 
895 | **Description:** Returns an XMLList containing all XML properties of this XML object that represent XML text nodes.
896 | 
897 | **Returns:**
898 | 
899 | an XMLList containing all XML properties of this XML object that represent XML text nodes.
900 | 
901 | ---
902 | 
903 | ### toString
904 | 
905 | **Signature:** `toString() : String`
906 | 
907 | **Description:** Returns the String representation of the XML object. If the object contains simple content, this method returns a String with tag, attributes, and namespace declarations removed. However, if the object contains complex content, this method returns an XML encoded String representing the entire XML object. If you want to return the entire XML object regardless of content complexity, use the toXMLString() method.
908 | 
909 | **Returns:**
910 | 
911 | the String representation of the XML object.
912 | 
913 | ---
914 | 
915 | ### toXMLString
916 | 
917 | **Signature:** `toXMLString() : String`
918 | 
919 | **Description:** Returns a XML-encoded String representation of the XML object, including tag and attributed delimiters.
920 | 
921 | **Returns:**
922 | 
923 | the string representation of the XML object.
924 | 
925 | ---
926 | 
927 | ### valueOf
928 | 
929 | **Signature:** `valueOf() : XML`
930 | 
931 | **Description:** Returns this XML object.
932 | 
933 | **Returns:**
934 | 
935 | this XML object.
936 | 
937 | ---
```
Page 42/61FirstPrevNextLast