This is page 24 of 61. Use http://codebase.md/taurgis/sfcc-dev-mcp?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .DS_Store ├── .github │ ├── dependabot.yml │ ├── instructions │ │ ├── mcp-node-tests.instructions.md │ │ └── mcp-yml-tests.instructions.md │ ├── ISSUE_TEMPLATE │ │ ├── bug_report.yml │ │ ├── config.yml │ │ ├── documentation.yml │ │ ├── feature_request.yml │ │ └── question.yml │ ├── PULL_REQUEST_TEMPLATE │ │ ├── bug_fix.md │ │ ├── documentation.md │ │ └── new_tool.md │ ├── pull_request_template.md │ └── workflows │ ├── ci.yml │ ├── deploy-pages.yml │ ├── publish.yml │ └── update-docs.yml ├── .gitignore ├── .husky │ └── pre-commit ├── aegis.config.docs-only.json ├── aegis.config.json ├── aegis.config.with-dw.json ├── AGENTS.md ├── ai-instructions │ ├── claude-desktop │ │ └── claude_custom_instructions.md │ ├── cursor │ │ └── .cursor │ │ └── rules │ │ ├── debugging-workflows.mdc │ │ ├── hooks-development.mdc │ │ ├── isml-templates.mdc │ │ ├── job-framework.mdc │ │ ├── performance-optimization.mdc │ │ ├── scapi-endpoints.mdc │ │ ├── security-patterns.mdc │ │ ├── sfcc-development.mdc │ │ ├── sfra-controllers.mdc │ │ ├── sfra-models.mdc │ │ ├── system-objects.mdc │ │ └── testing-patterns.mdc │ └── github-copilot │ └── copilot-instructions.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── docs │ ├── best-practices │ │ ├── cartridge_creation.md │ │ ├── isml_templates.md │ │ ├── job_framework.md │ │ ├── localserviceregistry.md │ │ ├── ocapi_hooks.md │ │ ├── performance.md │ │ ├── scapi_custom_endpoint.md │ │ ├── scapi_hooks.md │ │ ├── security.md │ │ ├── sfra_client_side_js.md │ │ ├── sfra_controllers.md │ │ ├── sfra_models.md │ │ └── sfra_scss.md │ ├── dw_campaign │ │ ├── ABTest.md │ │ ├── ABTestMgr.md │ │ ├── ABTestSegment.md │ │ ├── AmountDiscount.md │ │ ├── ApproachingDiscount.md │ │ ├── BonusChoiceDiscount.md │ │ ├── BonusDiscount.md │ │ ├── Campaign.md │ │ ├── CampaignMgr.md │ │ ├── CampaignStatusCodes.md │ │ ├── Coupon.md │ │ ├── CouponMgr.md │ │ ├── CouponRedemption.md │ │ ├── CouponStatusCodes.md │ │ ├── Discount.md │ │ ├── DiscountPlan.md │ │ ├── FixedPriceDiscount.md │ │ ├── FixedPriceShippingDiscount.md │ │ ├── FreeDiscount.md │ │ ├── FreeShippingDiscount.md │ │ ├── PercentageDiscount.md │ │ ├── PercentageOptionDiscount.md │ │ ├── PriceBookPriceDiscount.md │ │ ├── Promotion.md │ │ ├── PromotionMgr.md │ │ ├── PromotionPlan.md │ │ ├── SlotContent.md │ │ ├── SourceCodeGroup.md │ │ ├── SourceCodeInfo.md │ │ ├── SourceCodeStatusCodes.md │ │ └── TotalFixedPriceDiscount.md │ ├── dw_catalog │ │ ├── Catalog.md │ │ ├── CatalogMgr.md │ │ ├── Category.md │ │ ├── CategoryAssignment.md │ │ ├── CategoryLink.md │ │ ├── PriceBook.md │ │ ├── PriceBookMgr.md │ │ ├── Product.md │ │ ├── ProductActiveData.md │ │ ├── ProductAttributeModel.md │ │ ├── ProductAvailabilityLevels.md │ │ ├── ProductAvailabilityModel.md │ │ ├── ProductInventoryList.md │ │ ├── ProductInventoryMgr.md │ │ ├── ProductInventoryRecord.md │ │ ├── ProductLink.md │ │ ├── ProductMgr.md │ │ ├── ProductOption.md │ │ ├── ProductOptionModel.md │ │ ├── ProductOptionValue.md │ │ ├── ProductPriceInfo.md │ │ ├── ProductPriceModel.md │ │ ├── ProductPriceTable.md │ │ ├── ProductSearchHit.md │ │ ├── ProductSearchModel.md │ │ ├── ProductSearchRefinementDefinition.md │ │ ├── ProductSearchRefinements.md │ │ ├── ProductSearchRefinementValue.md │ │ ├── ProductVariationAttribute.md │ │ ├── ProductVariationAttributeValue.md │ │ ├── ProductVariationModel.md │ │ ├── Recommendation.md │ │ ├── SearchModel.md │ │ ├── SearchRefinementDefinition.md │ │ ├── SearchRefinements.md │ │ ├── SearchRefinementValue.md │ │ ├── SortingOption.md │ │ ├── SortingRule.md │ │ ├── Store.md │ │ ├── StoreGroup.md │ │ ├── StoreInventoryFilter.md │ │ ├── StoreInventoryFilterValue.md │ │ ├── StoreMgr.md │ │ ├── Variant.md │ │ └── VariationGroup.md │ ├── dw_content │ │ ├── Content.md │ │ ├── ContentMgr.md │ │ ├── ContentSearchModel.md │ │ ├── ContentSearchRefinementDefinition.md │ │ ├── ContentSearchRefinements.md │ │ ├── ContentSearchRefinementValue.md │ │ ├── Folder.md │ │ ├── Library.md │ │ ├── MarkupText.md │ │ └── MediaFile.md │ ├── dw_crypto │ │ ├── CertificateRef.md │ │ ├── CertificateUtils.md │ │ ├── Cipher.md │ │ ├── Encoding.md │ │ ├── JWE.md │ │ ├── JWEHeader.md │ │ ├── JWS.md │ │ ├── JWSHeader.md │ │ ├── KeyRef.md │ │ ├── Mac.md │ │ ├── MessageDigest.md │ │ ├── SecureRandom.md │ │ ├── Signature.md │ │ ├── WeakCipher.md │ │ ├── WeakMac.md │ │ ├── WeakMessageDigest.md │ │ ├── WeakSignature.md │ │ └── X509Certificate.md │ ├── dw_customer │ │ ├── AddressBook.md │ │ ├── AgentUserMgr.md │ │ ├── AgentUserStatusCodes.md │ │ ├── AuthenticationStatus.md │ │ ├── Credentials.md │ │ ├── Customer.md │ │ ├── CustomerActiveData.md │ │ ├── CustomerAddress.md │ │ ├── CustomerCDPData.md │ │ ├── CustomerContextMgr.md │ │ ├── CustomerGroup.md │ │ ├── CustomerList.md │ │ ├── CustomerMgr.md │ │ ├── CustomerPasswordConstraints.md │ │ ├── CustomerPaymentInstrument.md │ │ ├── CustomerStatusCodes.md │ │ ├── EncryptedObject.md │ │ ├── ExternalProfile.md │ │ ├── OrderHistory.md │ │ ├── ProductList.md │ │ ├── ProductListItem.md │ │ ├── ProductListItemPurchase.md │ │ ├── ProductListMgr.md │ │ ├── ProductListRegistrant.md │ │ ├── Profile.md │ │ └── Wallet.md │ ├── dw_extensions.applepay │ │ ├── ApplePayHookResult.md │ │ └── ApplePayHooks.md │ ├── dw_extensions.facebook │ │ ├── FacebookFeedHooks.md │ │ └── FacebookProduct.md │ ├── dw_extensions.paymentrequest │ │ ├── PaymentRequestHookResult.md │ │ └── PaymentRequestHooks.md │ ├── dw_extensions.payments │ │ ├── SalesforceBancontactPaymentDetails.md │ │ ├── SalesforceCardPaymentDetails.md │ │ ├── SalesforceEpsPaymentDetails.md │ │ ├── SalesforceIdealPaymentDetails.md │ │ ├── SalesforceKlarnaPaymentDetails.md │ │ ├── SalesforcePaymentDetails.md │ │ ├── SalesforcePaymentIntent.md │ │ ├── SalesforcePaymentMethod.md │ │ ├── SalesforcePaymentRequest.md │ │ ├── SalesforcePaymentsHooks.md │ │ ├── SalesforcePaymentsMgr.md │ │ ├── SalesforcePaymentsSiteConfiguration.md │ │ ├── SalesforcePayPalOrder.md │ │ ├── SalesforcePayPalOrderAddress.md │ │ ├── SalesforcePayPalOrderPayer.md │ │ ├── SalesforcePayPalPaymentDetails.md │ │ ├── SalesforceSepaDebitPaymentDetails.md │ │ └── SalesforceVenmoPaymentDetails.md │ ├── dw_extensions.pinterest │ │ ├── PinterestAvailability.md │ │ ├── PinterestFeedHooks.md │ │ ├── PinterestOrder.md │ │ ├── PinterestOrderHooks.md │ │ └── PinterestProduct.md │ ├── dw_io │ │ ├── CSVStreamReader.md │ │ ├── CSVStreamWriter.md │ │ ├── File.md │ │ ├── FileReader.md │ │ ├── FileWriter.md │ │ ├── InputStream.md │ │ ├── OutputStream.md │ │ ├── PrintWriter.md │ │ ├── RandomAccessFileReader.md │ │ ├── Reader.md │ │ ├── StringWriter.md │ │ ├── Writer.md │ │ ├── XMLIndentingStreamWriter.md │ │ ├── XMLStreamConstants.md │ │ ├── XMLStreamReader.md │ │ └── XMLStreamWriter.md │ ├── dw_job │ │ ├── JobExecution.md │ │ └── JobStepExecution.md │ ├── dw_net │ │ ├── FTPClient.md │ │ ├── FTPFileInfo.md │ │ ├── HTTPClient.md │ │ ├── HTTPRequestPart.md │ │ ├── Mail.md │ │ ├── SFTPClient.md │ │ ├── SFTPFileInfo.md │ │ ├── WebDAVClient.md │ │ └── WebDAVFileInfo.md │ ├── dw_object │ │ ├── ActiveData.md │ │ ├── CustomAttributes.md │ │ ├── CustomObject.md │ │ ├── CustomObjectMgr.md │ │ ├── Extensible.md │ │ ├── ExtensibleObject.md │ │ ├── Note.md │ │ ├── ObjectAttributeDefinition.md │ │ ├── ObjectAttributeGroup.md │ │ ├── ObjectAttributeValueDefinition.md │ │ ├── ObjectTypeDefinition.md │ │ ├── PersistentObject.md │ │ ├── SimpleExtensible.md │ │ └── SystemObjectMgr.md │ ├── dw_order │ │ ├── AbstractItem.md │ │ ├── AbstractItemCtnr.md │ │ ├── Appeasement.md │ │ ├── AppeasementItem.md │ │ ├── Basket.md │ │ ├── BasketMgr.md │ │ ├── BonusDiscountLineItem.md │ │ ├── CouponLineItem.md │ │ ├── CreateAgentBasketLimitExceededException.md │ │ ├── CreateBasketFromOrderException.md │ │ ├── CreateCouponLineItemException.md │ │ ├── CreateOrderException.md │ │ ├── CreateTemporaryBasketLimitExceededException.md │ │ ├── GiftCertificate.md │ │ ├── GiftCertificateLineItem.md │ │ ├── GiftCertificateMgr.md │ │ ├── GiftCertificateStatusCodes.md │ │ ├── Invoice.md │ │ ├── InvoiceItem.md │ │ ├── LineItem.md │ │ ├── LineItemCtnr.md │ │ ├── Order.md │ │ ├── OrderAddress.md │ │ ├── OrderItem.md │ │ ├── OrderMgr.md │ │ ├── OrderPaymentInstrument.md │ │ ├── OrderProcessStatusCodes.md │ │ ├── PaymentCard.md │ │ ├── PaymentInstrument.md │ │ ├── PaymentMethod.md │ │ ├── PaymentMgr.md │ │ ├── PaymentProcessor.md │ │ ├── PaymentStatusCodes.md │ │ ├── PaymentTransaction.md │ │ ├── PriceAdjustment.md │ │ ├── PriceAdjustmentLimitTypes.md │ │ ├── ProductLineItem.md │ │ ├── ProductShippingCost.md │ │ ├── ProductShippingLineItem.md │ │ ├── ProductShippingModel.md │ │ ├── Return.md │ │ ├── ReturnCase.md │ │ ├── ReturnCaseItem.md │ │ ├── ReturnItem.md │ │ ├── Shipment.md │ │ ├── ShipmentShippingCost.md │ │ ├── ShipmentShippingModel.md │ │ ├── ShippingLineItem.md │ │ ├── ShippingLocation.md │ │ ├── ShippingMethod.md │ │ ├── ShippingMgr.md │ │ ├── ShippingOrder.md │ │ ├── ShippingOrderItem.md │ │ ├── SumItem.md │ │ ├── TaxGroup.md │ │ ├── TaxItem.md │ │ ├── TaxMgr.md │ │ ├── TrackingInfo.md │ │ └── TrackingRef.md │ ├── dw_order.hooks │ │ ├── CalculateHooks.md │ │ ├── OrderHooks.md │ │ ├── PaymentHooks.md │ │ ├── ReturnHooks.md │ │ └── ShippingOrderHooks.md │ ├── dw_rpc │ │ ├── SOAPUtil.md │ │ ├── Stub.md │ │ └── WebReference.md │ ├── dw_suggest │ │ ├── BrandSuggestions.md │ │ ├── CategorySuggestions.md │ │ ├── ContentSuggestions.md │ │ ├── CustomSuggestions.md │ │ ├── ProductSuggestions.md │ │ ├── SearchPhraseSuggestions.md │ │ ├── SuggestedCategory.md │ │ ├── SuggestedContent.md │ │ ├── SuggestedPhrase.md │ │ ├── SuggestedProduct.md │ │ ├── SuggestedTerm.md │ │ ├── SuggestedTerms.md │ │ ├── Suggestions.md │ │ └── SuggestModel.md │ ├── dw_svc │ │ ├── FTPService.md │ │ ├── FTPServiceDefinition.md │ │ ├── HTTPFormService.md │ │ ├── HTTPFormServiceDefinition.md │ │ ├── HTTPService.md │ │ ├── HTTPServiceDefinition.md │ │ ├── LocalServiceRegistry.md │ │ ├── Result.md │ │ ├── Service.md │ │ ├── ServiceCallback.md │ │ ├── ServiceConfig.md │ │ ├── ServiceCredential.md │ │ ├── ServiceDefinition.md │ │ ├── ServiceProfile.md │ │ ├── ServiceRegistry.md │ │ ├── SOAPService.md │ │ └── SOAPServiceDefinition.md │ ├── dw_system │ │ ├── AgentUserStatusCodes.md │ │ ├── Cache.md │ │ ├── CacheMgr.md │ │ ├── HookMgr.md │ │ ├── InternalObject.md │ │ ├── JobProcessMonitor.md │ │ ├── Log.md │ │ ├── Logger.md │ │ ├── LogNDC.md │ │ ├── OrganizationPreferences.md │ │ ├── Pipeline.md │ │ ├── PipelineDictionary.md │ │ ├── RemoteInclude.md │ │ ├── Request.md │ │ ├── RequestHooks.md │ │ ├── Response.md │ │ ├── RESTErrorResponse.md │ │ ├── RESTResponseMgr.md │ │ ├── RESTSuccessResponse.md │ │ ├── SearchStatus.md │ │ ├── Session.md │ │ ├── Site.md │ │ ├── SitePreferences.md │ │ ├── Status.md │ │ ├── StatusItem.md │ │ ├── System.md │ │ └── Transaction.md │ ├── dw_util │ │ ├── ArrayList.md │ │ ├── Assert.md │ │ ├── BigInteger.md │ │ ├── Bytes.md │ │ ├── Calendar.md │ │ ├── Collection.md │ │ ├── Currency.md │ │ ├── DateUtils.md │ │ ├── Decimal.md │ │ ├── FilteringCollection.md │ │ ├── Geolocation.md │ │ ├── HashMap.md │ │ ├── HashSet.md │ │ ├── Iterator.md │ │ ├── LinkedHashMap.md │ │ ├── LinkedHashSet.md │ │ ├── List.md │ │ ├── Locale.md │ │ ├── Map.md │ │ ├── MapEntry.md │ │ ├── MappingKey.md │ │ ├── MappingMgr.md │ │ ├── PropertyComparator.md │ │ ├── SecureEncoder.md │ │ ├── SecureFilter.md │ │ ├── SeekableIterator.md │ │ ├── Set.md │ │ ├── SortedMap.md │ │ ├── SortedSet.md │ │ ├── StringUtils.md │ │ ├── Template.md │ │ └── UUIDUtils.md │ ├── dw_value │ │ ├── EnumValue.md │ │ ├── MimeEncodedText.md │ │ ├── Money.md │ │ └── Quantity.md │ ├── dw_web │ │ ├── ClickStream.md │ │ ├── ClickStreamEntry.md │ │ ├── Cookie.md │ │ ├── Cookies.md │ │ ├── CSRFProtection.md │ │ ├── Form.md │ │ ├── FormAction.md │ │ ├── FormElement.md │ │ ├── FormElementValidationResult.md │ │ ├── FormField.md │ │ ├── FormFieldOption.md │ │ ├── FormFieldOptions.md │ │ ├── FormGroup.md │ │ ├── FormList.md │ │ ├── FormListItem.md │ │ ├── Forms.md │ │ ├── HttpParameter.md │ │ ├── HttpParameterMap.md │ │ ├── LoopIterator.md │ │ ├── PageMetaData.md │ │ ├── PageMetaTag.md │ │ ├── PagingModel.md │ │ ├── Resource.md │ │ ├── URL.md │ │ ├── URLAction.md │ │ ├── URLParameter.md │ │ ├── URLRedirect.md │ │ ├── URLRedirectMgr.md │ │ └── URLUtils.md │ ├── sfra │ │ ├── account.md │ │ ├── address.md │ │ ├── billing.md │ │ ├── cart.md │ │ ├── categories.md │ │ ├── content.md │ │ ├── locale.md │ │ ├── order.md │ │ ├── payment.md │ │ ├── price-default.md │ │ ├── price-range.md │ │ ├── price-tiered.md │ │ ├── product-bundle.md │ │ ├── product-full.md │ │ ├── product-line-items.md │ │ ├── product-search.md │ │ ├── product-tile.md │ │ ├── querystring.md │ │ ├── render.md │ │ ├── request.md │ │ ├── response.md │ │ ├── server.md │ │ ├── shipping.md │ │ ├── store.md │ │ ├── stores.md │ │ └── totals.md │ └── TopLevel │ ├── APIException.md │ ├── arguments.md │ ├── Array.md │ ├── ArrayBuffer.md │ ├── BigInt.md │ ├── Boolean.md │ ├── ConversionError.md │ ├── DataView.md │ ├── Date.md │ ├── Error.md │ ├── ES6Iterator.md │ ├── EvalError.md │ ├── Fault.md │ ├── Float32Array.md │ ├── Float64Array.md │ ├── Function.md │ ├── Generator.md │ ├── global.md │ ├── Int16Array.md │ ├── Int32Array.md │ ├── Int8Array.md │ ├── InternalError.md │ ├── IOError.md │ ├── Iterable.md │ ├── Iterator.md │ ├── JSON.md │ ├── Map.md │ ├── Math.md │ ├── Module.md │ ├── Namespace.md │ ├── Number.md │ ├── Object.md │ ├── QName.md │ ├── RangeError.md │ ├── ReferenceError.md │ ├── RegExp.md │ ├── Set.md │ ├── StopIteration.md │ ├── String.md │ ├── Symbol.md │ ├── SyntaxError.md │ ├── SystemError.md │ ├── TypeError.md │ ├── Uint16Array.md │ ├── Uint32Array.md │ ├── Uint8Array.md │ ├── Uint8ClampedArray.md │ ├── URIError.md │ ├── WeakMap.md │ ├── WeakSet.md │ ├── XML.md │ ├── XMLList.md │ └── XMLStreamError.md ├── docs-site │ ├── .gitignore │ ├── App.tsx │ ├── components │ │ ├── Badge.tsx │ │ ├── BreadcrumbSchema.tsx │ │ ├── CodeBlock.tsx │ │ ├── Collapsible.tsx │ │ ├── ConfigBuilder.tsx │ │ ├── ConfigHero.tsx │ │ ├── ConfigModeTabs.tsx │ │ ├── icons.tsx │ │ ├── Layout.tsx │ │ ├── LightCodeContainer.tsx │ │ ├── NewcomerCTA.tsx │ │ ├── NextStepsStrip.tsx │ │ ├── OnThisPage.tsx │ │ ├── Search.tsx │ │ ├── SEO.tsx │ │ ├── Sidebar.tsx │ │ ├── StructuredData.tsx │ │ ├── ToolCard.tsx │ │ ├── ToolFilters.tsx │ │ ├── Typography.tsx │ │ └── VersionBadge.tsx │ ├── constants.tsx │ ├── index.html │ ├── main.tsx │ ├── metadata.json │ ├── package-lock.json │ ├── package.json │ ├── pages │ │ ├── AIInterfacesPage.tsx │ │ ├── ConfigurationPage.tsx │ │ ├── DevelopmentPage.tsx │ │ ├── ExamplesPage.tsx │ │ ├── FeaturesPage.tsx │ │ ├── HomePage.tsx │ │ ├── SecurityPage.tsx │ │ ├── ToolsPage.tsx │ │ └── TroubleshootingPage.tsx │ ├── postcss.config.js │ ├── public │ │ ├── .well-known │ │ │ └── security.txt │ │ ├── 404.html │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── explain-product-pricing-methods-no-mcp.png │ │ ├── explain-product-pricing-methods.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── llms.txt │ │ ├── robots.txt │ │ ├── site.webmanifest │ │ └── sitemap.xml │ ├── README.md │ ├── scripts │ │ ├── generate-search-index.js │ │ ├── generate-sitemap.js │ │ └── search-dev.js │ ├── src │ │ └── styles │ │ ├── input.css │ │ └── prism-theme.css │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── types.ts │ ├── utils │ │ ├── search.ts │ │ └── toolsData.ts │ └── vite.config.ts ├── eslint.config.js ├── jest.config.js ├── LICENSE ├── package-lock.json ├── package.json ├── README.md ├── scripts │ └── convert-docs.js ├── SECURITY.md ├── server.json ├── src │ ├── clients │ │ ├── base │ │ │ ├── http-client.ts │ │ │ ├── oauth-token.ts │ │ │ └── ocapi-auth-client.ts │ │ ├── best-practices-client.ts │ │ ├── cartridge-generation-client.ts │ │ ├── docs │ │ │ ├── class-content-parser.ts │ │ │ ├── class-name-resolver.ts │ │ │ ├── documentation-scanner.ts │ │ │ ├── index.ts │ │ │ └── referenced-types-extractor.ts │ │ ├── docs-client.ts │ │ ├── log-client.ts │ │ ├── logs │ │ │ ├── index.ts │ │ │ ├── log-analyzer.ts │ │ │ ├── log-client.ts │ │ │ ├── log-constants.ts │ │ │ ├── log-file-discovery.ts │ │ │ ├── log-file-reader.ts │ │ │ ├── log-formatter.ts │ │ │ ├── log-processor.ts │ │ │ ├── log-types.ts │ │ │ └── webdav-client-manager.ts │ │ ├── ocapi │ │ │ ├── code-versions-client.ts │ │ │ ├── site-preferences-client.ts │ │ │ └── system-objects-client.ts │ │ ├── ocapi-client.ts │ │ └── sfra-client.ts │ ├── config │ │ ├── configuration-factory.ts │ │ └── dw-json-loader.ts │ ├── core │ │ ├── handlers │ │ │ ├── abstract-log-tool-handler.ts │ │ │ ├── base-handler.ts │ │ │ ├── best-practices-handler.ts │ │ │ ├── cartridge-handler.ts │ │ │ ├── client-factory.ts │ │ │ ├── code-version-handler.ts │ │ │ ├── docs-handler.ts │ │ │ ├── job-log-handler.ts │ │ │ ├── job-log-tool-config.ts │ │ │ ├── log-handler.ts │ │ │ ├── log-tool-config.ts │ │ │ ├── sfra-handler.ts │ │ │ ├── system-object-handler.ts │ │ │ └── validation-helpers.ts │ │ ├── server.ts │ │ └── tool-definitions.ts │ ├── index.ts │ ├── main.ts │ ├── services │ │ ├── file-system-service.ts │ │ ├── index.ts │ │ └── path-service.ts │ ├── tool-configs │ │ ├── best-practices-tool-config.ts │ │ ├── cartridge-tool-config.ts │ │ ├── code-version-tool-config.ts │ │ ├── docs-tool-config.ts │ │ ├── job-log-tool-config.ts │ │ ├── log-tool-config.ts │ │ ├── sfra-tool-config.ts │ │ └── system-object-tool-config.ts │ ├── types │ │ └── types.ts │ └── utils │ ├── cache.ts │ ├── job-log-tool-config.ts │ ├── job-log-utils.ts │ ├── log-cache.ts │ ├── log-tool-config.ts │ ├── log-tool-constants.ts │ ├── log-tool-utils.ts │ ├── logger.ts │ ├── ocapi-url-builder.ts │ ├── path-resolver.ts │ ├── query-builder.ts │ ├── utils.ts │ └── validator.ts ├── tests │ ├── __mocks__ │ │ ├── docs-client.ts │ │ ├── src │ │ │ └── clients │ │ │ └── base │ │ │ └── http-client.js │ │ └── webdav.js │ ├── base-handler.test.ts │ ├── base-http-client.test.ts │ ├── best-practices-handler.test.ts │ ├── cache.test.ts │ ├── cartridge-handler.test.ts │ ├── class-content-parser.test.ts │ ├── class-name-resolver.test.ts │ ├── client-factory.test.ts │ ├── code-version-handler.test.ts │ ├── code-versions-client.test.ts │ ├── config.test.ts │ ├── configuration-factory.test.ts │ ├── docs-handler.test.ts │ ├── documentation-scanner.test.ts │ ├── file-system-service.test.ts │ ├── job-log-handler.test.ts │ ├── job-log-utils.test.ts │ ├── log-client.test.ts │ ├── log-handler.test.ts │ ├── log-processor.test.ts │ ├── logger.test.ts │ ├── mcp │ │ ├── AGENTS.md │ │ ├── node │ │ │ ├── activate-code-version-advanced.full-mode.programmatic.test.js │ │ │ ├── code-versions.full-mode.programmatic.test.js │ │ │ ├── generate-cartridge-structure.docs-only.programmatic.test.js │ │ │ ├── get-available-best-practice-guides.docs-only.programmatic.test.js │ │ │ ├── get-available-sfra-documents.programmatic.test.js │ │ │ ├── get-best-practice-guide.docs-only.programmatic.test.js │ │ │ ├── get-hook-reference.docs-only.programmatic.test.js │ │ │ ├── get-job-execution-summary.full-mode.programmatic.test.js │ │ │ ├── get-job-log-entries.full-mode.programmatic.test.js │ │ │ ├── get-latest-debug.full-mode.programmatic.test.js │ │ │ ├── get-latest-error.full-mode.programmatic.test.js │ │ │ ├── get-latest-info.full-mode.programmatic.test.js │ │ │ ├── get-latest-job-log-files.full-mode.programmatic.test.js │ │ │ ├── get-latest-warn.full-mode.programmatic.test.js │ │ │ ├── get-log-file-contents.full-mode.programmatic.test.js │ │ │ ├── get-sfcc-class-documentation.docs-only.programmatic.test.js │ │ │ ├── get-sfcc-class-info.docs-only.programmatic.test.js │ │ │ ├── get-sfra-categories.docs-only.programmatic.test.js │ │ │ ├── get-sfra-document.programmatic.test.js │ │ │ ├── get-sfra-documents-by-category.docs-only.programmatic.test.js │ │ │ ├── get-system-object-definition.full-mode.programmatic.test.js │ │ │ ├── get-system-object-definitions.docs-only.programmatic.test.js │ │ │ ├── get-system-object-definitions.full-mode.programmatic.test.js │ │ │ ├── list-log-files.full-mode.programmatic.test.js │ │ │ ├── list-sfcc-classes.docs-only.programmatic.test.js │ │ │ ├── search-best-practices.docs-only.programmatic.test.js │ │ │ ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js │ │ │ ├── search-job-logs-by-name.full-mode.programmatic.test.js │ │ │ ├── search-job-logs.full-mode.programmatic.test.js │ │ │ ├── search-logs.full-mode.programmatic.test.js │ │ │ ├── search-sfcc-classes.docs-only.programmatic.test.js │ │ │ ├── search-sfcc-methods.docs-only.programmatic.test.js │ │ │ ├── search-sfra-documentation.docs-only.programmatic.test.js │ │ │ ├── search-site-preferences.full-mode.programmatic.test.js │ │ │ ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js │ │ │ ├── search-system-object-attribute-groups.full-mode.programmatic.test.js │ │ │ ├── summarize-logs.full-mode.programmatic.test.js │ │ │ ├── tools.docs-only.programmatic.test.js │ │ │ └── tools.full-mode.programmatic.test.js │ │ ├── README.md │ │ ├── test-fixtures │ │ │ └── dw.json │ │ └── yaml │ │ ├── activate-code-version.docs-only.test.mcp.yml │ │ ├── activate-code-version.full-mode.test.mcp.yml │ │ ├── get_latest_error.test.mcp.yml │ │ ├── get-available-best-practice-guides.docs-only.test.mcp.yml │ │ ├── get-available-best-practice-guides.full-mode.test.mcp.yml │ │ ├── get-available-sfra-documents.docs-only.test.mcp.yml │ │ ├── get-available-sfra-documents.full-mode.test.mcp.yml │ │ ├── get-best-practice-guide.docs-only.test.mcp.yml │ │ ├── get-best-practice-guide.full-mode.test.mcp.yml │ │ ├── get-code-versions.docs-only.test.mcp.yml │ │ ├── get-code-versions.full-mode.test.mcp.yml │ │ ├── get-hook-reference.docs-only.test.mcp.yml │ │ ├── get-hook-reference.full-mode.test.mcp.yml │ │ ├── get-job-execution-summary.full-mode.test.mcp.yml │ │ ├── get-job-log-entries.full-mode.test.mcp.yml │ │ ├── get-latest-debug.full-mode.test.mcp.yml │ │ ├── get-latest-error.full-mode.test.mcp.yml │ │ ├── get-latest-info.full-mode.test.mcp.yml │ │ ├── get-latest-job-log-files.full-mode.test.mcp.yml │ │ ├── get-latest-warn.full-mode.test.mcp.yml │ │ ├── get-log-file-contents.full-mode.test.mcp.yml │ │ ├── get-sfcc-class-documentation.docs-only.test.mcp.yml │ │ ├── get-sfcc-class-documentation.full-mode.test.mcp.yml │ │ ├── get-sfcc-class-info.docs-only.test.mcp.yml │ │ ├── get-sfcc-class-info.full-mode.test.mcp.yml │ │ ├── get-sfra-categories.docs-only.test.mcp.yml │ │ ├── get-sfra-categories.full-mode.test.mcp.yml │ │ ├── get-sfra-document.docs-only.test.mcp.yml │ │ ├── get-sfra-document.full-mode.test.mcp.yml │ │ ├── get-sfra-documents-by-category.docs-only.test.mcp.yml │ │ ├── get-sfra-documents-by-category.full-mode.test.mcp.yml │ │ ├── get-system-object-definition.docs-only.test.mcp.yml │ │ ├── get-system-object-definition.full-mode.test.mcp.yml │ │ ├── get-system-object-definitions.docs-only.test.mcp.yml │ │ ├── get-system-object-definitions.full-mode.test.mcp.yml │ │ ├── list-log-files.full-mode.test.mcp.yml │ │ ├── list-sfcc-classes.docs-only.test.mcp.yml │ │ ├── list-sfcc-classes.full-mode.test.mcp.yml │ │ ├── search-best-practices.docs-only.test.mcp.yml │ │ ├── search-best-practices.full-mode.test.mcp.yml │ │ ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml │ │ ├── search-custom-object-attribute-definitions.test.mcp.yml │ │ ├── search-job-logs-by-name.full-mode.test.mcp.yml │ │ ├── search-job-logs.full-mode.test.mcp.yml │ │ ├── search-logs.full-mode.test.mcp.yml │ │ ├── search-sfcc-classes.docs-only.test.mcp.yml │ │ ├── search-sfcc-classes.full-mode.test.mcp.yml │ │ ├── search-sfcc-methods.docs-only.test.mcp.yml │ │ ├── search-sfcc-methods.full-mode.test.mcp.yml │ │ ├── search-sfra-documentation.docs-only.test.mcp.yml │ │ ├── search-sfra-documentation.full-mode.test.mcp.yml │ │ ├── search-site-preferences.docs-only.test.mcp.yml │ │ ├── search-site-preferences.full-mode.test.mcp.yml │ │ ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml │ │ ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml │ │ ├── search-system-object-attribute-groups.docs-only.test.mcp.yml │ │ ├── search-system-object-attribute-groups.full-mode.test.mcp.yml │ │ ├── summarize-logs.full-mode.test.mcp.yml │ │ ├── tools.docs-only.test.mcp.yml │ │ └── tools.full-mode.test.mcp.yml │ ├── oauth-token.test.ts │ ├── ocapi-auth-client.test.ts │ ├── ocapi-client.test.ts │ ├── path-service.test.ts │ ├── query-builder.test.ts │ ├── referenced-types-extractor.test.ts │ ├── servers │ │ ├── sfcc-mock-server │ │ │ ├── mock-data │ │ │ │ └── ocapi │ │ │ │ ├── code-versions.json │ │ │ │ ├── custom-object-attributes-customapi.json │ │ │ │ ├── custom-object-attributes-globalsettings.json │ │ │ │ ├── custom-object-attributes-versionhistory.json │ │ │ │ ├── site-preferences-ccv.json │ │ │ │ ├── site-preferences-fastforward.json │ │ │ │ ├── site-preferences-sfra.json │ │ │ │ ├── site-preferences-storefront.json │ │ │ │ ├── site-preferences-system.json │ │ │ │ ├── system-object-attribute-groups-campaign.json │ │ │ │ ├── system-object-attribute-groups-category.json │ │ │ │ ├── system-object-attribute-groups-order.json │ │ │ │ ├── system-object-attribute-groups-product.json │ │ │ │ ├── system-object-attribute-groups-sitepreferences.json │ │ │ │ ├── system-object-attributes-customeraddress.json │ │ │ │ ├── system-object-attributes-product-expanded.json │ │ │ │ ├── system-object-attributes-product.json │ │ │ │ ├── system-object-definition-category.json │ │ │ │ ├── system-object-definition-customer.json │ │ │ │ ├── system-object-definition-customeraddress.json │ │ │ │ ├── system-object-definition-order.json │ │ │ │ ├── system-object-definition-product.json │ │ │ │ ├── system-object-definitions-old.json │ │ │ │ └── system-object-definitions.json │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ ├── scripts │ │ │ │ └── setup-logs.js │ │ │ ├── server.js │ │ │ └── src │ │ │ ├── app.js │ │ │ ├── config │ │ │ │ └── server-config.js │ │ │ ├── middleware │ │ │ │ ├── auth.js │ │ │ │ ├── cors.js │ │ │ │ └── logging.js │ │ │ ├── routes │ │ │ │ ├── ocapi │ │ │ │ │ ├── code-versions-handler.js │ │ │ │ │ ├── oauth-handler.js │ │ │ │ │ ├── ocapi-error-utils.js │ │ │ │ │ ├── ocapi-utils.js │ │ │ │ │ ├── site-preferences-handler.js │ │ │ │ │ └── system-objects-handler.js │ │ │ │ ├── ocapi.js │ │ │ │ └── webdav.js │ │ │ └── utils │ │ │ ├── mock-data-loader.js │ │ │ └── webdav-xml.js │ │ └── sfcc-mock-server-manager.ts │ ├── sfcc-mock-server.test.ts │ ├── site-preferences-client.test.ts │ ├── system-objects-client.test.ts │ ├── utils.test.ts │ ├── validation-helpers.test.ts │ └── validator.test.ts ├── tsconfig.json └── tsconfig.test.json ``` # Files -------------------------------------------------------------------------------- /tests/docs-handler.test.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { DocsToolHandler } from '../src/core/handlers/docs-handler.js'; 2 | import { HandlerContext } from '../src/core/handlers/base-handler.js'; 3 | import { Logger } from '../src/utils/logger.js'; 4 | 5 | // Mock the SFCCDocumentationClient 6 | const mockSFCCDocumentationClient = { 7 | getClassDetailsExpanded: jest.fn(), 8 | getAvailableClasses: jest.fn(), 9 | searchClasses: jest.fn(), 10 | searchMethods: jest.fn(), 11 | getClassDocumentation: jest.fn(), 12 | }; 13 | 14 | jest.mock('../src/clients/docs-client.js', () => ({ 15 | SFCCDocumentationClient: jest.fn(() => mockSFCCDocumentationClient), 16 | })); 17 | 18 | describe('DocsToolHandler', () => { 19 | let mockLogger: jest.Mocked<Logger>; 20 | let mockDocsClient: typeof mockSFCCDocumentationClient; 21 | let context: HandlerContext; 22 | let handler: DocsToolHandler; 23 | 24 | beforeEach(() => { 25 | mockLogger = { 26 | debug: jest.fn(), 27 | log: jest.fn(), 28 | error: jest.fn(), 29 | timing: jest.fn(), 30 | methodEntry: jest.fn(), 31 | methodExit: jest.fn(), 32 | } as any; 33 | 34 | // Reset mocks 35 | jest.clearAllMocks(); 36 | 37 | // Use the mock client directly 38 | mockDocsClient = mockSFCCDocumentationClient; 39 | 40 | jest.spyOn(Logger, 'getChildLogger').mockReturnValue(mockLogger); 41 | 42 | context = { 43 | logger: mockLogger, 44 | config: null as any, 45 | capabilities: { canAccessLogs: false, canAccessOCAPI: false }, 46 | }; 47 | 48 | handler = new DocsToolHandler(context, 'Docs'); 49 | }); 50 | 51 | afterEach(() => { 52 | jest.restoreAllMocks(); 53 | }); 54 | 55 | // Helper function to initialize handler for tests that need it 56 | const initializeHandler = async () => { 57 | await (handler as any).initialize(); 58 | }; 59 | 60 | describe('canHandle', () => { 61 | it('should handle docs-related tools', () => { 62 | expect(handler.canHandle('get_sfcc_class_info')).toBe(true); 63 | expect(handler.canHandle('list_sfcc_classes')).toBe(true); 64 | expect(handler.canHandle('search_sfcc_classes')).toBe(true); 65 | expect(handler.canHandle('search_sfcc_methods')).toBe(true); 66 | expect(handler.canHandle('get_sfcc_class_documentation')).toBe(true); 67 | }); 68 | 69 | it('should not handle non-docs tools', () => { 70 | expect(handler.canHandle('get_latest_error')).toBe(false); 71 | expect(handler.canHandle('unknown_tool')).toBe(false); 72 | }); 73 | }); 74 | 75 | describe('initialization', () => { 76 | it('should initialize docs client', async () => { 77 | await initializeHandler(); 78 | 79 | const MockedConstructor = jest.requireMock('../src/clients/docs-client.js').SFCCDocumentationClient; 80 | expect(MockedConstructor).toHaveBeenCalled(); 81 | expect(mockLogger.debug).toHaveBeenCalledWith('Documentation client initialized'); 82 | }); 83 | }); 84 | 85 | describe('disposal', () => { 86 | it('should dispose docs client properly', async () => { 87 | await initializeHandler(); 88 | await (handler as any).dispose(); 89 | 90 | expect(mockLogger.debug).toHaveBeenCalledWith('Documentation client disposed'); 91 | }); 92 | }); 93 | 94 | describe('get_sfcc_class_info tool', () => { 95 | beforeEach(async () => { 96 | await initializeHandler(); 97 | mockDocsClient.getClassDetailsExpanded.mockResolvedValue({ 98 | className: 'Product', 99 | packageName: 'dw.catalog', 100 | description: 'Product class description', 101 | constants: [], 102 | properties: [ 103 | { name: 'ID', type: 'String', description: 'Product ID' }, 104 | { name: 'name', type: 'String', description: 'Product name' }, 105 | ], 106 | methods: [ 107 | { name: 'getID', signature: 'getID() : String', description: 'Get product ID' }, 108 | { name: 'getName', signature: 'getName() : String', description: 'Get product name' }, 109 | ], 110 | }); 111 | }); 112 | 113 | it('should handle get_sfcc_class_info with className', async () => { 114 | const args = { className: 'Product', expand: true }; 115 | const result = await handler.handle('get_sfcc_class_info', args, Date.now()); 116 | 117 | expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', true, { 118 | includeDescription: true, 119 | includeConstants: true, 120 | includeProperties: true, 121 | includeMethods: true, 122 | includeInheritance: true, 123 | search: undefined, 124 | }); 125 | expect(result.content[0].text).toContain('Product'); 126 | expect(result.content[0].text).toContain('Product class description'); 127 | }); 128 | 129 | it('should handle get_sfcc_class_info with default expand', async () => { 130 | const args = { className: 'Customer' }; 131 | await handler.handle('get_sfcc_class_info', args, Date.now()); 132 | 133 | expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Customer', false, { 134 | includeDescription: true, 135 | includeConstants: true, 136 | includeProperties: true, 137 | includeMethods: true, 138 | includeInheritance: true, 139 | search: undefined, 140 | }); 141 | }); 142 | 143 | it('should throw error when className is missing', async () => { 144 | const result = await handler.handle('get_sfcc_class_info', {}, Date.now()); 145 | expect(result.isError).toBe(true); 146 | expect(result.content[0].text).toContain('className must be a non-empty string'); 147 | }); 148 | 149 | it('should handle get_sfcc_class_info with filtering options', async () => { 150 | const args = { 151 | className: 'Product', 152 | includeDescription: false, 153 | includeConstants: false, 154 | includeProperties: true, 155 | includeMethods: false, 156 | includeInheritance: false, 157 | }; 158 | const result = await handler.handle('get_sfcc_class_info', args, Date.now()); 159 | 160 | expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', false, { 161 | includeDescription: false, 162 | includeConstants: false, 163 | includeProperties: true, 164 | includeMethods: false, 165 | includeInheritance: false, 166 | search: undefined, 167 | }); 168 | expect(result.content[0].text).toContain('Product'); 169 | }); 170 | 171 | it('should handle get_sfcc_class_info with search parameter', async () => { 172 | const args = { className: 'Product', search: 'image' }; 173 | const result = await handler.handle('get_sfcc_class_info', args, Date.now()); 174 | 175 | expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', false, { 176 | includeDescription: true, 177 | includeConstants: true, 178 | includeProperties: true, 179 | includeMethods: true, 180 | includeInheritance: true, 181 | search: 'image', 182 | }); 183 | expect(result.content[0].text).toContain('Product'); 184 | }); 185 | 186 | it('should handle get_sfcc_class_info with combined filtering and search', async () => { 187 | const args = { 188 | className: 'Product', 189 | expand: true, 190 | includeDescription: false, 191 | includeMethods: true, 192 | includeProperties: false, 193 | search: 'price', 194 | }; 195 | const result = await handler.handle('get_sfcc_class_info', args, Date.now()); 196 | 197 | expect(mockDocsClient.getClassDetailsExpanded).toHaveBeenCalledWith('Product', true, { 198 | includeDescription: false, 199 | includeConstants: true, 200 | includeProperties: false, 201 | includeMethods: true, 202 | includeInheritance: true, 203 | search: 'price', 204 | }); 205 | expect(result.content[0].text).toContain('Product'); 206 | }); 207 | }); 208 | 209 | describe('list_sfcc_classes tool', () => { 210 | beforeEach(async () => { 211 | await initializeHandler(); 212 | mockDocsClient.getAvailableClasses.mockResolvedValue([ 213 | 'Product', 'Customer', 'Order', 'Catalog', 214 | ]); 215 | }); 216 | 217 | it('should handle list_sfcc_classes', async () => { 218 | const result = await handler.handle('list_sfcc_classes', {}, Date.now()); 219 | 220 | expect(mockDocsClient.getAvailableClasses).toHaveBeenCalled(); 221 | expect(result.content[0].text).toContain('Product'); 222 | expect(result.content[0].text).toContain('Customer'); 223 | }); 224 | }); 225 | 226 | describe('search_sfcc_classes tool', () => { 227 | beforeEach(async () => { 228 | await initializeHandler(); 229 | mockDocsClient.searchClasses.mockResolvedValue([ 230 | 'Product', 'ProductSearchModel', 231 | ]); 232 | }); 233 | 234 | it('should handle search_sfcc_classes with query', async () => { 235 | const args = { query: 'product' }; 236 | const result = await handler.handle('search_sfcc_classes', args, Date.now()); 237 | 238 | expect(mockDocsClient.searchClasses).toHaveBeenCalledWith('product'); 239 | expect(result.content[0].text).toContain('Product'); 240 | expect(result.content[0].text).toContain('ProductSearchModel'); 241 | }); 242 | 243 | it('should throw error when query is missing', async () => { 244 | const result = await handler.handle('search_sfcc_classes', {}, Date.now()); 245 | expect(result.isError).toBe(true); 246 | expect(result.content[0].text).toContain('query must be a non-empty string'); 247 | }); 248 | 249 | it('should throw error when query is empty', async () => { 250 | const result = await handler.handle('search_sfcc_classes', { query: '' }, Date.now()); 251 | expect(result.isError).toBe(true); 252 | expect(result.content[0].text).toContain('query must be a non-empty string'); 253 | }); 254 | }); 255 | 256 | describe('search_sfcc_methods tool', () => { 257 | beforeEach(async () => { 258 | await initializeHandler(); 259 | mockDocsClient.searchMethods.mockResolvedValue([ 260 | { 261 | className: 'Product', 262 | method: { 263 | name: 'getID', 264 | signature: 'getID() : String', 265 | description: 'Get product ID', 266 | }, 267 | }, 268 | { 269 | className: 'Customer', 270 | method: { 271 | name: 'getID', 272 | signature: 'getID() : String', 273 | description: 'Get customer ID', 274 | }, 275 | }, 276 | ]); 277 | }); 278 | 279 | it('should handle search_sfcc_methods with methodName', async () => { 280 | const args = { methodName: 'getID' }; 281 | const result = await handler.handle('search_sfcc_methods', args, Date.now()); 282 | 283 | expect(mockDocsClient.searchMethods).toHaveBeenCalledWith('getID'); 284 | expect(result.content[0].text).toContain('getID'); 285 | expect(result.content[0].text).toContain('Product'); 286 | }); 287 | 288 | it('should throw error when methodName is missing', async () => { 289 | const result = await handler.handle('search_sfcc_methods', {}, Date.now()); 290 | expect(result.isError).toBe(true); 291 | expect(result.content[0].text).toContain('methodName must be a non-empty string'); 292 | }); 293 | }); 294 | 295 | describe('get_sfcc_class_documentation tool', () => { 296 | beforeEach(async () => { 297 | await initializeHandler(); 298 | mockDocsClient.getClassDocumentation.mockResolvedValue( 299 | 'Detailed documentation for Product class with examples and usage patterns.', 300 | ); 301 | }); 302 | 303 | it('should handle get_sfcc_class_documentation with className', async () => { 304 | const args = { className: 'Product' }; 305 | const result = await handler.handle('get_sfcc_class_documentation', args, Date.now()); 306 | 307 | expect(mockDocsClient.getClassDocumentation).toHaveBeenCalledWith('Product'); 308 | expect(result.content[0].text).toContain('Detailed documentation'); 309 | }); 310 | 311 | it('should throw error when className is missing', async () => { 312 | const result = await handler.handle('get_sfcc_class_documentation', {}, Date.now()); 313 | expect(result.isError).toBe(true); 314 | expect(result.content[0].text).toContain('className must be a non-empty string'); 315 | }); 316 | }); 317 | 318 | describe('error handling', () => { 319 | beforeEach(async () => { 320 | await initializeHandler(); 321 | }); 322 | 323 | it('should handle client errors gracefully', async () => { 324 | mockDocsClient.getClassDetailsExpanded.mockRejectedValue(new Error('Documentation not found')); 325 | 326 | const result = await handler.handle('get_sfcc_class_info', { className: 'UnknownClass' }, Date.now()); 327 | expect(result.isError).toBe(true); 328 | expect(result.content[0].text).toContain('Documentation not found'); 329 | }); 330 | 331 | it('should throw error for unsupported tools', async () => { 332 | await expect(handler.handle('unsupported_tool', {}, Date.now())) 333 | .rejects.toThrow('Unsupported tool'); 334 | }); 335 | }); 336 | 337 | describe('timing and logging', () => { 338 | beforeEach(async () => { 339 | await initializeHandler(); 340 | mockDocsClient.getAvailableClasses.mockResolvedValue(['Product', 'Customer']); 341 | }); 342 | 343 | it('should log timing information', async () => { 344 | const startTime = Date.now(); 345 | await handler.handle('list_sfcc_classes', {}, startTime); 346 | 347 | expect(mockLogger.timing).toHaveBeenCalledWith('list_sfcc_classes', startTime); 348 | }); 349 | 350 | it('should log execution details', async () => { 351 | await handler.handle('list_sfcc_classes', {}, Date.now()); 352 | 353 | expect(mockLogger.debug).toHaveBeenCalledWith( 354 | 'list_sfcc_classes completed successfully', 355 | expect.any(Object), 356 | ); 357 | }); 358 | }); 359 | }); 360 | ``` -------------------------------------------------------------------------------- /docs/TopLevel/XMLList.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: TopLevel 2 | 3 | # Class XMLList 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - XMLList 9 | 10 | ## Description 11 | 12 | An XMLList object is an ordered collection of properties. A XMLList object represents a XML document, an XML fragment, or an arbitrary collection of XML objects. An individual XML object is the same thing as an XMLList containing only that XML object. All operations available for the XML object are also available for an XMLList object that contains exactly one XML object. 13 | 14 | ## Constructor Summary 15 | 16 | XMLList(value : Object) Creates a new XMLList object using the specified value. 17 | 18 | ## Method Summary 19 | 20 | ### attribute 21 | 22 | **Signature:** `attribute(attributeName : String) : XMLList` 23 | 24 | Returns the attribute associated with this XMLList object that is identified by the specified name. 25 | 26 | ### attributes 27 | 28 | **Signature:** `attributes() : XMLList` 29 | 30 | Returns an XMList of the attributes in this XMLList Object. 31 | 32 | ### child 33 | 34 | **Signature:** `child(propertyName : Object) : XMLList` 35 | 36 | Returns the children of the XMLList object based on the specified property name. 37 | 38 | ### children 39 | 40 | **Signature:** `children() : XMLList` 41 | 42 | Returns an XMLList containing the children of this XMLList object, maintaing the sequence in which they appear. 43 | 44 | ### comments 45 | 46 | **Signature:** `comments() : XMLList` 47 | 48 | Returns the properties of the XMLList object that contain comments. 49 | 50 | ### contains 51 | 52 | **Signature:** `contains(value : XML) : boolean` 53 | 54 | Returns true if this XMLList object contains the specified XML object, false otherwise. 55 | 56 | ### copy 57 | 58 | **Signature:** `copy() : XMLList` 59 | 60 | Returns a deep copy of the this XMLList object. 61 | 62 | ### descendants 63 | 64 | **Signature:** `descendants() : XMLList` 65 | 66 | Calls the descendants() method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order. 67 | 68 | ### descendants 69 | 70 | **Signature:** `descendants(name : String) : XMLList` 71 | 72 | Calls the descendants(name) method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order. 73 | 74 | ### elements 75 | 76 | **Signature:** `elements() : XMLList` 77 | 78 | Calls the elements() method in each XML object in this XMLList object and returns an XMLList containing the results concatenated in order. 79 | 80 | ### elements 81 | 82 | **Signature:** `elements(name : Object) : XMLList` 83 | 84 | Calls the elements(name) method in each of the XML objects in this XMLList object and returns an XMLList containing the results concatenated in order. 85 | 86 | ### hasComplexContent 87 | 88 | **Signature:** `hasComplexContent() : boolean` 89 | 90 | Returns a Boolean value indicating whether this XMLList object contains complex content. 91 | 92 | ### hasOwnProperty 93 | 94 | **Signature:** `hasOwnProperty(prop : String) : boolean` 95 | 96 | Returns a Boolean value indicating whether this object has the property specified by prop. 97 | 98 | ### hasSimpleContent 99 | 100 | **Signature:** `hasSimpleContent() : boolean` 101 | 102 | Returns a Boolean value indicating whether this XML object contains simple content. 103 | 104 | ### length 105 | 106 | **Signature:** `length() : Number` 107 | 108 | Returns the number of children in this XMLList object. 109 | 110 | ### normalize 111 | 112 | **Signature:** `normalize() : XMLList` 113 | 114 | Puts all text nodes in this XMLList, all the XML objects it contains and the descendents of all the XML objects it contains into a normal form by merging adjacent text nodes and eliminating empty text nodes. 115 | 116 | ### parent 117 | 118 | **Signature:** `parent() : Object` 119 | 120 | Returns the parent of the XMLList object or null if the XMLList object does not have a parent. 121 | 122 | ### processingInstructions 123 | 124 | **Signature:** `processingInstructions() : XMLList` 125 | 126 | Calls the processingInstructions() method of each XML object in this XMLList object and returns an XMList containing the results in order. 127 | 128 | ### processingInstructions 129 | 130 | **Signature:** `processingInstructions(name : String) : XMLList` 131 | 132 | Calls the processingInstructions(name) method of each XML object in this XMLList object and returns an XMList containing the results in order. 133 | 134 | ### propertyIsEnumerable 135 | 136 | **Signature:** `propertyIsEnumerable(property : String) : boolean` 137 | 138 | Returns a Boolean indicating whether the specified property will be included in the set of properties iterated over when this XML object is used in a for..in statement. 139 | 140 | ### text 141 | 142 | **Signature:** `text() : XMLList` 143 | 144 | Calls the text() method of each XML object contained in this XMLList object and returns an XMLList containing the results concatenated in order. 145 | 146 | ### toString 147 | 148 | **Signature:** `toString() : String` 149 | 150 | Returns the String representation of this XMLList object. 151 | 152 | ### toXMLString 153 | 154 | **Signature:** `toXMLString() : String` 155 | 156 | Returns an XML-encoded String representation of the XMLList object by calling the toXMLString method on each property contained within this XMLList object. 157 | 158 | ### valueOf 159 | 160 | **Signature:** `valueOf() : XMLList` 161 | 162 | Returns this XMLList object. 163 | 164 | ## Constructor Detail 165 | 166 | ## Method Detail 167 | 168 | ## Method Details 169 | 170 | ### attribute 171 | 172 | **Signature:** `attribute(attributeName : String) : XMLList` 173 | 174 | **Description:** Returns the attribute associated with this XMLList object that is identified by the specified name. 175 | 176 | **Parameters:** 177 | 178 | - `attributeName`: the name of the attribute. 179 | 180 | **Returns:** 181 | 182 | the value of the attribute as either an XMLList or an empty XMLList 183 | 184 | --- 185 | 186 | ### attributes 187 | 188 | **Signature:** `attributes() : XMLList` 189 | 190 | **Description:** Returns an XMList of the attributes in this XMLList Object. 191 | 192 | **Returns:** 193 | 194 | an XMList of the attributes in this XMLList Object. 195 | 196 | --- 197 | 198 | ### child 199 | 200 | **Signature:** `child(propertyName : Object) : XMLList` 201 | 202 | **Description:** Returns the children of the XMLList object based on the specified property name. 203 | 204 | **Parameters:** 205 | 206 | - `propertyName`: the property name representing the children of this XMLList object. 207 | 208 | **Returns:** 209 | 210 | an XMLList of children that match the property name parameter. 211 | 212 | --- 213 | 214 | ### children 215 | 216 | **Signature:** `children() : XMLList` 217 | 218 | **Description:** Returns an XMLList containing the children of this XMLList object, maintaing the sequence in which they appear. 219 | 220 | **Returns:** 221 | 222 | an XMLList containing the children of this XMLList object. 223 | 224 | --- 225 | 226 | ### comments 227 | 228 | **Signature:** `comments() : XMLList` 229 | 230 | **Description:** Returns the properties of the XMLList object that contain comments. 231 | 232 | **Returns:** 233 | 234 | properties of the XMLList object that contain comments. 235 | 236 | --- 237 | 238 | ### contains 239 | 240 | **Signature:** `contains(value : XML) : boolean` 241 | 242 | **Description:** Returns true if this XMLList object contains the specified XML object, false otherwise. 243 | 244 | **Parameters:** 245 | 246 | - `value`: the object to locate in this XMLList object. 247 | 248 | **Returns:** 249 | 250 | true if this XMLList object contains the specified XML object, false otherwise. 251 | 252 | --- 253 | 254 | ### copy 255 | 256 | **Signature:** `copy() : XMLList` 257 | 258 | **Description:** Returns a deep copy of the this XMLList object. 259 | 260 | **Returns:** 261 | 262 | the deep copy of the object. 263 | 264 | --- 265 | 266 | ### descendants 267 | 268 | **Signature:** `descendants() : XMLList` 269 | 270 | **Description:** Calls the descendants() method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order. 271 | 272 | **Returns:** 273 | 274 | a list of all descendents of the XML objects in this XMLList object. 275 | 276 | --- 277 | 278 | ### descendants 279 | 280 | **Signature:** `descendants(name : String) : XMLList` 281 | 282 | **Description:** Calls the descendants(name) method of each XML object in this XMLList object and returns an XMLList containing the results concatenated in order. 283 | 284 | **Parameters:** 285 | 286 | - `name`: the name of the element to match. To return all descendents, use * as the name parameter. 287 | 288 | **Returns:** 289 | 290 | a list of all descendents of the XML objects in this XMLList constrained by the name parameter. 291 | 292 | --- 293 | 294 | ### elements 295 | 296 | **Signature:** `elements() : XMLList` 297 | 298 | **Description:** Calls the elements() method in each XML object in this XMLList object and returns an XMLList containing the results concatenated in order. 299 | 300 | --- 301 | 302 | ### elements 303 | 304 | **Signature:** `elements(name : Object) : XMLList` 305 | 306 | **Description:** Calls the elements(name) method in each of the XML objects in this XMLList object and returns an XMLList containing the results concatenated in order. name can be a QName, String, or any other data type that will be converted to a string prior to performing the search for elements of that name. To list all objects use * for the value of name. 307 | 308 | **Parameters:** 309 | 310 | - `name`: the name of the elements to return. 311 | 312 | **Returns:** 313 | 314 | a list of all elements of the XML objects in this XMLList constrained by the name parameter. 315 | 316 | --- 317 | 318 | ### hasComplexContent 319 | 320 | **Signature:** `hasComplexContent() : boolean` 321 | 322 | **Description:** Returns a Boolean value indicating whether this XMLList object contains complex content. An XMLList object is considered to contain complex content if it is not empty, contains a single XML item with complex content or contains elements. 323 | 324 | **Returns:** 325 | 326 | a Boolean value indicating whether this XMLList object contains complex content. 327 | 328 | --- 329 | 330 | ### hasOwnProperty 331 | 332 | **Signature:** `hasOwnProperty(prop : String) : boolean` 333 | 334 | **Description:** Returns a Boolean value indicating whether this object has the property specified by prop. 335 | 336 | **Parameters:** 337 | 338 | - `prop`: the property to locate. 339 | 340 | **Returns:** 341 | 342 | true if the property exists, false otherwise. 343 | 344 | --- 345 | 346 | ### hasSimpleContent 347 | 348 | **Signature:** `hasSimpleContent() : boolean` 349 | 350 | **Description:** Returns a Boolean value indicating whether this XML object contains simple content. An XMLList object is considered to contain simple content if it is empty, contains a single XML item with simple content or contains no elements. 351 | 352 | **Returns:** 353 | 354 | a Boolean value indicating whether this XML object contains simple content. 355 | 356 | --- 357 | 358 | ### length 359 | 360 | **Signature:** `length() : Number` 361 | 362 | **Description:** Returns the number of children in this XMLList object. 363 | 364 | **Returns:** 365 | 366 | the number of children in this XMLList object. 367 | 368 | --- 369 | 370 | ### normalize 371 | 372 | **Signature:** `normalize() : XMLList` 373 | 374 | **Description:** Puts all text nodes in this XMLList, all the XML objects it contains and the descendents of all the XML objects it contains into a normal form by merging adjacent text nodes and eliminating empty text nodes. 375 | 376 | **Returns:** 377 | 378 | the XMLList object containing normailzed objects. 379 | 380 | --- 381 | 382 | ### parent 383 | 384 | **Signature:** `parent() : Object` 385 | 386 | **Description:** Returns the parent of the XMLList object or null if the XMLList object does not have a parent. 387 | 388 | **Returns:** 389 | 390 | the parent of the XMLList object or null if the XMLList object does not have a parent. 391 | 392 | --- 393 | 394 | ### processingInstructions 395 | 396 | **Signature:** `processingInstructions() : XMLList` 397 | 398 | **Description:** Calls the processingInstructions() method of each XML object in this XMLList object and returns an XMList containing the results in order. 399 | 400 | **Returns:** 401 | 402 | an XMLList contaiing the result of calling the processingInstructions() method of each XML object in this XMLList object. 403 | 404 | --- 405 | 406 | ### processingInstructions 407 | 408 | **Signature:** `processingInstructions(name : String) : XMLList` 409 | 410 | **Description:** Calls the processingInstructions(name) method of each XML object in this XMLList object and returns an XMList containing the results in order. 411 | 412 | **Parameters:** 413 | 414 | - `name`: the name representing the processing-instructions you want to retreive. 415 | 416 | **Returns:** 417 | 418 | an XMLList containing the result of calling the processingInstructions(name) method of each XML object in this XMLList object. 419 | 420 | --- 421 | 422 | ### propertyIsEnumerable 423 | 424 | **Signature:** `propertyIsEnumerable(property : String) : boolean` 425 | 426 | **Description:** Returns a Boolean indicating whether the specified property will be included in the set of properties iterated over when this XML object is used in a for..in statement. 427 | 428 | **Parameters:** 429 | 430 | - `property`: the property to test. 431 | 432 | **Returns:** 433 | 434 | true when the property can be iterated in a for..in statement, false otherwise. 435 | 436 | --- 437 | 438 | ### text 439 | 440 | **Signature:** `text() : XMLList` 441 | 442 | **Description:** Calls the text() method of each XML object contained in this XMLList object and returns an XMLList containing the results concatenated in order. 443 | 444 | **Returns:** 445 | 446 | the concatenated results of calling the text() method of every XML object contained in this XMLList. 447 | 448 | --- 449 | 450 | ### toString 451 | 452 | **Signature:** `toString() : String` 453 | 454 | **Description:** Returns the String representation of this XMLList object. 455 | 456 | **Returns:** 457 | 458 | the String representation of this XMLList object. 459 | 460 | --- 461 | 462 | ### toXMLString 463 | 464 | **Signature:** `toXMLString() : String` 465 | 466 | **Description:** Returns an XML-encoded String representation of the XMLList object by calling the toXMLString method on each property contained within this XMLList object. 467 | 468 | **Returns:** 469 | 470 | an XML-encoded String representation of the XMLList object by calling the toXMLString method on each property contained within this XMLList object. 471 | 472 | --- 473 | 474 | ### valueOf 475 | 476 | **Signature:** `valueOf() : XMLList` 477 | 478 | **Description:** Returns this XMLList object. 479 | 480 | **Returns:** 481 | 482 | this XMLList object. 483 | 484 | --- ``` -------------------------------------------------------------------------------- /docs-site/utils/toolsData.ts: -------------------------------------------------------------------------------- ```typescript 1 | // Centralized metadata for MCP tools. Used by ToolsPage for dynamic rendering. 2 | // Keeps descriptive, param, and example prompt info in one place for reuse. 3 | 4 | export type ToolMode = 'docs' | 'full' | 'both'; 5 | export interface ToolParam { 6 | name: string; 7 | required?: boolean; 8 | description: string; 9 | } 10 | export interface ToolMeta { 11 | id: string; // unique id also used as anchor 12 | name: string; // tool name as exposed to MCP 13 | category: string; 14 | mode: ToolMode; // availability 15 | description: string; 16 | params?: ToolParam[]; 17 | examples?: string[]; // example AI prompts or usage 18 | tags?: string[]; 19 | popular?: boolean; // mark for quick actions 20 | } 21 | 22 | // Helper for brevity 23 | const p = (name: string, description: string, required = true): ToolParam => ({ name, description, required }); 24 | 25 | export const TOOL_CATEGORIES = [ 26 | 'Documentation', 27 | 'Best Practices', 28 | 'SFRA Docs', 29 | 'Cartridge Generation', 30 | 'Log Analysis', 31 | 'System Objects', 32 | 'Code Versions' 33 | ] as const; 34 | 35 | export const tools: ToolMeta[] = [ 36 | // Documentation (SFCC classes) 37 | { 38 | id: 'get-sfcc-class-info', 39 | name: 'get_sfcc_class_info', 40 | category: 'Documentation', 41 | mode: 'both', 42 | description: 'Detailed information about an SFCC class with filtering and search capabilities: properties, methods, descriptions.', 43 | params: [ 44 | p('className', "SFCC class (e.g. 'Catalog' or 'dw.catalog.Catalog')"), 45 | p('expand', 'Include referenced type details (boolean)', false), 46 | p('includeDescription', 'Include class description (boolean, default: true)', false), 47 | p('includeConstants', 'Include class constants (boolean, default: true)', false), 48 | p('includeProperties', 'Include class properties (boolean, default: true)', false), 49 | p('includeMethods', 'Include class methods (boolean, default: true)', false), 50 | p('includeInheritance', 'Include inheritance info (boolean, default: true)', false), 51 | p('search', 'Filter results by search term (string)', false) 52 | ], 53 | examples: [ 54 | 'Show methods and properties on dw.catalog.Product', 55 | 'Show only methods for dw.system.Status class', 56 | 'Search for "get" methods in dw.catalog.Product', 57 | 'Show dw.order.Order class without description or constants', 58 | 'Find "name" related properties and methods in dw.catalog.Product' 59 | ], 60 | tags: ['api','classes','introspection','filtering','search'], 61 | popular: true 62 | }, 63 | { id: 'search-sfcc-classes', name: 'search_sfcc_classes', category: 'Documentation', mode: 'both', description: 'Search SFCC classes by partial name (single word).', params: [p('query', 'Search term (single word)')], examples: ['Find classes related to price','Search for catalog classes'], tags: ['search'], popular: true }, 64 | { id: 'search-sfcc-methods', name: 'search_sfcc_methods', category: 'Documentation', mode: 'both', description: 'Search methods across all SFCC classes.', params: [p('methodName', 'Method name (single word)')], examples: ['Find get methods on system objects','Search for commit methods'], tags: ['methods','search'] }, 65 | { id: 'list-sfcc-classes', name: 'list_sfcc_classes', category: 'Documentation', mode: 'both', description: 'List of all available SFCC classes.', examples: ['List all available SFCC classes'] }, 66 | { id: 'get-sfcc-class-documentation', name: 'get_sfcc_class_documentation', category: 'Documentation', mode: 'both', description: 'Raw markdown documentation for an SFCC class.', params: [p('className','Exact class name')], examples: ['Get raw docs for dw.system.Logger'] }, 67 | 68 | // Best Practices 69 | { id: 'get-available-best-practice-guides', name: 'get_available_best_practice_guides', category: 'Best Practices', mode: 'both', description: 'List all best practice guides.', examples: ['List available best practice guides'] }, 70 | { id: 'get-best-practice-guide', name: 'get_best_practice_guide', category: 'Best Practices', mode: 'both', description: 'Full best practice guide content.', params: [p('guideName','Guide name (cartridge_creation, sfra_client_side_js, sfra_scss, security, performance, etc.)')], examples: ['Open the performance best practice guide'], tags: ['guides'] }, 71 | { id: 'search-best-practices', name: 'search_best_practices', category: 'Best Practices', mode: 'both', description: 'Search within all best practice guides.', params: [p('query','Search term')], examples: ['Search best practices for caching'], tags: ['search'] }, 72 | { id: 'get-hook-reference', name: 'get_hook_reference', category: 'Best Practices', mode: 'both', description: 'Hook reference tables for OCAPI or SCAPI.', params: [p('guideName','ocapi_hooks | scapi_hooks')], examples: ['List SCAPI hooks for product'] }, 73 | 74 | // SFRA Docs 75 | { id: 'get-available-sfra-documents', name: 'get_available_sfra_documents', category: 'SFRA Docs', mode: 'both', description: 'List all SFRA documents and models.', examples: ['List SFRA docs categories'] }, 76 | { id: 'get-sfra-document', name: 'get_sfra_document', category: 'SFRA Docs', mode: 'both', description: 'Full SFRA document (server, request, cart, product-full etc.).', params: [p('documentName','SFRA document name')], examples: ['Show the server module SFRA docs'] }, 77 | { id: 'search-sfra-documentation', name: 'search_sfra_documentation', category: 'SFRA Docs', mode: 'both', description: 'Search across SFRA docs.', params: [p('query','Search term')], examples: ['Search SFRA docs for middleware'], tags: ['search'] }, 78 | { id: 'get-sfra-categories', name: 'get_sfra_categories', category: 'SFRA Docs', mode: 'both', description: 'List SFRA document categories with counts.' }, 79 | { id: 'get-sfra-documents-by-category', name: 'get_sfra_documents_by_category', category: 'SFRA Docs', mode: 'both', description: 'Get SFRA documents for a category.', params: [p('category','core|product|order|customer|pricing|store|other')], examples: ['List all order category SFRA docs'] }, 80 | 81 | // Cartridge Generation 82 | { id: 'generate-cartridge-structure', name: 'generate_cartridge_structure', category: 'Cartridge Generation', mode: 'both', description: 'Generate cartridge directory structure.', params: [p('cartridgeName','Name of cartridge'), p('targetPath','Target path (optional)', false), p('fullProjectSetup','Include project scaffolding (boolean)', false)], examples: ['Generate cartridge named plugin_demo'], tags: ['scaffold'], popular: true }, 83 | 84 | // Log Analysis (Full Mode) 85 | { id: 'get-latest-error', name: 'get_latest_error', category: 'Log Analysis', mode: 'full', description: 'Fetch latest error log entries.', params: [p('date','YYYYMMDD (optional defaults today)', false), p('limit','Number of entries', false)], examples: ['Show last 5 error log entries'], tags: ['logs','errors'], popular: true }, 86 | { id: 'get-latest-warn', name: 'get_latest_warn', category: 'Log Analysis', mode: 'full', description: 'Fetch latest warn log entries.', params: [p('date','YYYYMMDD', false), p('limit','Entries', false)] }, 87 | { id: 'get-latest-info', name: 'get_latest_info', category: 'Log Analysis', mode: 'full', description: 'Fetch latest info log entries.', params: [p('date','YYYYMMDD', false), p('limit','Entries', false)] }, 88 | { id: 'get-latest-debug', name: 'get_latest_debug', category: 'Log Analysis', mode: 'full', description: 'Fetch latest debug log entries.', params: [p('date','YYYYMMDD', false), p('limit','Entries', false)] }, 89 | { id: 'search-logs', name: 'search_logs', category: 'Log Analysis', mode: 'full', description: 'Search across logs for a pattern.', params: [p('pattern','Search string'), p('date','YYYYMMDD', false), p('limit','Entries', false), p('logLevel','error|warn|info|debug', false)], examples: ['Search logs for OCAPI 500 errors'], tags: ['search'] }, 90 | { id: 'summarize-logs', name: 'summarize_logs', category: 'Log Analysis', mode: 'full', description: 'High level log activity summary.', params: [p('date','YYYYMMDD', false)], examples: ['Summarize today\'s logs'] }, 91 | { id: 'list-log-files', name: 'list_log_files', category: 'Log Analysis', mode: 'full', description: 'List available log files with metadata.', examples: ['List available log files'] }, 92 | { id: 'get-log-file-contents', name: 'get_log_file_contents', category: 'Log Analysis', mode: 'full', description: 'Fetch specific log file contents.', params: [p('filename','File name'), p('maxBytes','Max bytes', false), p('tailOnly','Tail only boolean', false)], examples: ['Show tail of error log'] }, 93 | { id: 'get-latest-job-log-files', name: 'get_latest_job_log_files', category: 'Log Analysis', mode: 'full', description: 'List latest job log files.', params: [p('limit','Number of files', false)], examples: ['List latest 3 job log files'] }, 94 | { id: 'get-job-log-entries', name: 'get_job_log_entries', category: 'Log Analysis', mode: 'full', description: 'Get job log entries filtered by level.', params: [p('jobName','Job name', false), p('level','error|warn|info|debug|all', false), p('limit','Entries', false)], examples: ['Get last 10 job log entries'] }, 95 | { id: 'search-job-logs', name: 'search_job_logs', category: 'Log Analysis', mode: 'full', description: 'Search job logs for pattern.', params: [p('pattern','Search string'), p('jobName','Job name', false), p('limit','Entries', false), p('level','error|warn|info|debug|all', false)], examples: ['Search job logs for timeout'] }, 96 | { id: 'search-job-logs-by-name', name: 'search_job_logs_by_name', category: 'Log Analysis', mode: 'full', description: 'Find job log files by job name.', params: [p('jobName','Partial job name'), p('limit','Files', false)], examples: ['Find job logs for OrderExport'] }, 97 | { id: 'get-job-execution-summary', name: 'get_job_execution_summary', category: 'Log Analysis', mode: 'full', description: 'Execution summary for specific job.', params: [p('jobName','Job name')], examples: ['Summarize last execution of DailyFeed job'] }, 98 | 99 | // System Objects 100 | { id: 'get-system-object-definitions', name: 'get_system_object_definitions', category: 'System Objects', mode: 'full', description: 'All system object definitions with pagination support.', params: [p('start','Start index', false), p('count','Max count', false), p('select','Property selector', false)], examples: ['List system object definitions', 'Get first 10 system objects', 'Get system objects starting from index 5'], tags: ['objects'], popular: true }, 101 | { id: 'get-system-object-definition', name: 'get_system_object_definition', category: 'System Objects', mode: 'full', description: 'Specific system object metadata.', params: [p('objectType','Object type e.g. Product')], examples: ['Get definition for Product object'] }, 102 | { id: 'search-system-object-attribute-definitions', name: 'search_system_object_attribute_definitions', category: 'System Objects', mode: 'full', description: 'Search attributes for a system object.', params: [p('objectType','System object type'), p('searchRequest','Search request body')], examples: ['Search Product attributes for inventory fields'] }, 103 | { id: 'search-system-object-attribute-groups', name: 'search_system_object_attribute_groups', category: 'System Objects', mode: 'full', description: 'Search attribute groups for a system object.', params: [p('objectType','System object type'), p('searchRequest','Search request body')], examples: ['List attribute groups for Product object'] }, 104 | { id: 'search-site-preferences', name: 'search_site_preferences', category: 'System Objects', mode: 'full', description: 'Search site preferences within a group.', params: [p('groupId','Preference group ID'), p('searchRequest','Search request body')], examples: ['Search site preferences in SitePreferencesMarketing group'] }, 105 | { id: 'search-custom-object-attribute-definitions', name: 'search_custom_object_attribute_definitions', category: 'System Objects', mode: 'full', description: 'Search custom object attributes.', params: [p('objectType','Custom object type'), p('searchRequest','Search request body')], examples: ['Search custom object attributes for Global_String'] }, 106 | 107 | // Code Versions 108 | { id: 'get-code-versions', name: 'get_code_versions', category: 'Code Versions', mode: 'full', description: 'List all code versions.', examples: ['List available code versions'], popular: true }, 109 | { id: 'activate-code-version', name: 'activate_code_version', category: 'Code Versions', mode: 'full', description: 'Activate a specific code version.', params: [p('codeVersionId','ID of code version')], examples: ['Activate code version int_2025_09'] } 110 | ]; 111 | 112 | export const popularTools = tools.filter(t => t.popular); 113 | export const categoriesWithCounts = TOOL_CATEGORIES.map(cat => ({ 114 | name: cat, 115 | count: tools.filter(t => t.category === cat).length 116 | })); 117 | ``` -------------------------------------------------------------------------------- /tests/servers/sfcc-mock-server/scripts/setup-logs.js: -------------------------------------------------------------------------------- ```javascript 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | /** 5 | * Setup Script for Mock SFCC Log Files 6 | * 7 | * This script creates a realistic directory structure and log files 8 | * that mimic the SFCC WebDAV log system for testing purposes. 9 | */ 10 | 11 | class MockLogGenerator { 12 | constructor() { 13 | this.baseDir = path.join(__dirname, '../mock-data'); 14 | this.logsDir = path.join(this.baseDir, 'logs'); 15 | this.jobsDir = path.join(this.logsDir, 'jobs'); 16 | 17 | // Current date for log file naming 18 | this.today = new Date(); 19 | this.dateString = this.formatDate(this.today); 20 | this.timeString = this.formatTime(this.today); 21 | } 22 | 23 | formatDate(date) { 24 | const year = date.getFullYear(); 25 | const month = String(date.getMonth() + 1).padStart(2, '0'); 26 | const day = String(date.getDate()).padStart(2, '0'); 27 | return `${year}${month}${day}`; 28 | } 29 | 30 | formatTime(date) { 31 | const hours = String(date.getHours()).padStart(2, '0'); 32 | const minutes = String(date.getMinutes()).padStart(2, '0'); 33 | const seconds = String(date.getSeconds()).padStart(2, '0'); 34 | return `${hours}${minutes}${seconds}`; 35 | } 36 | 37 | formatLogTimestamp(date) { 38 | // Format like real SFCC logs: [2025-09-14 12:00:00.000 GMT] 39 | const year = date.getFullYear(); 40 | const month = String(date.getMonth() + 1).padStart(2, '0'); 41 | const day = String(date.getDate()).padStart(2, '0'); 42 | const hours = String(date.getHours()).padStart(2, '0'); 43 | const minutes = String(date.getMinutes()).padStart(2, '0'); 44 | const seconds = String(date.getSeconds()).padStart(2, '0'); 45 | const milliseconds = String(date.getMilliseconds()).padStart(3, '0'); 46 | return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${milliseconds}`; 47 | } 48 | 49 | ensureDirectoryExists(dirPath) { 50 | if (!fs.existsSync(dirPath)) { 51 | fs.mkdirSync(dirPath, { recursive: true }); 52 | console.log(`📁 Created directory: ${dirPath}`); 53 | } 54 | } 55 | 56 | generateErrorLogs() { 57 | // Create timestamps with specific ordering - oldest first for proper log file structure 58 | const baseTime = new Date(); 59 | const timestamps = [ 60 | this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest) 61 | this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later 62 | this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later 63 | this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later 64 | this.formatLogTimestamp(new Date(baseTime.getTime() + 5000)) // 5 seconds later (newest) 65 | ]; 66 | 67 | const errorEntries = [ 68 | `[${timestamps[0]} GMT] ERROR PipelineCallServlet|1645761595|Sites-RefArchGlobal-Site|Cart-AddProduct|PipelineCall|nYJXtqnEfz custom [] Custom cartridge error: Unable to connect to external service`, 69 | `[${timestamps[1]} GMT] ERROR SystemJobThread|1581553813|sfcc-catalog-import|ImportCatalogStep com.demandware.beehive.core.internal.catalog.CatalogMgr Sites-Site JOB abc123def456 - Product import failed: Invalid category assignment`, 70 | `[${timestamps[2]} GMT] ERROR PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|V5YDtxRLpL custom [] Customer profile creation failed: Email already exists`, 71 | `[${timestamps[3]} GMT] ERROR PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|Qq38CuNXpX custom [] Payment authorization failed for order ORDER-000001234`, 72 | `[${timestamps[4]} GMT] ERROR SystemJobThread|1645761595|sfcc-download-gdpr-einstein-response-files-for-einstein|DownloadGDPRLogFiles com.demandware.component.transaction.cquotient.feed.s3.S3Store Sites-Site JOB bce341cf01 fd3d5c567c091a16392d5b865e 4815298613491841024 - CQ - AWS S3 Configuration Issue: bucketName is missing.` 73 | ]; 74 | 75 | const errorContent = errorEntries.join('\n') + '\n'; 76 | const errorFile = path.join(this.logsDir, `error-blade-${this.dateString}-${this.timeString}.log`); 77 | fs.writeFileSync(errorFile, errorContent); 78 | console.log(`📄 Created error log: ${errorFile}`); 79 | } 80 | 81 | generateWarnLogs() { 82 | // Create timestamps with specific ordering - oldest first for proper log file structure 83 | const baseTime = new Date(); 84 | const timestamps = [ 85 | this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest) 86 | this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later 87 | this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later 88 | this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later 89 | this.formatLogTimestamp(new Date(baseTime.getTime() + 5000)) // 5 seconds later (newest) 90 | ]; 91 | 92 | const warnEntries = [ 93 | `[${timestamps[0]} GMT] WARN PipelineCallServlet|1645761595|Sites-RefArchGlobal-Site|Product-Show|PipelineCall|AbcDef123G custom [] Product inventory low: SKU-789-XYZ has only 2 units remaining`, 94 | `[${timestamps[1]} GMT] WARN PipelineCallServlet|1581553813|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|nYJXtqnEfz custom [] Content asset with ID cookie_hint is offline`, 95 | `[${timestamps[2]} GMT] WARN PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|290fx4tnVR custom [] Content asset with ID cookie_hint is offline`, 96 | `[${timestamps[3]} GMT] WARN PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|V5YDtxRLpL custom [] Content asset with ID cookie_hint is offline`, 97 | `[${timestamps[4]} GMT] WARN PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Page-Include|PipelineCall|Qq38CuNXpX custom [] Content asset with ID cookie_hint is offline` 98 | ]; 99 | 100 | const warnContent = warnEntries.join('\n') + '\n'; 101 | const warnFile = path.join(this.logsDir, `warn-blade-${this.dateString}-${this.timeString}.log`); 102 | fs.writeFileSync(warnFile, warnContent); 103 | console.log(`📄 Created warn log: ${warnFile}`); 104 | } 105 | 106 | generateInfoLogs() { 107 | // Create timestamps with specific ordering - oldest first for proper log file structure 108 | const baseTime = new Date(); 109 | const timestamps = [ 110 | this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest) 111 | this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later 112 | this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later 113 | this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later 114 | this.formatLogTimestamp(new Date(baseTime.getTime() + 5000)) // 5 seconds later (newest) 115 | ]; 116 | 117 | const infoEntries = [ 118 | `[${timestamps[0]} GMT] INFO SystemJobThread|1581553813|sfcc-process-orders|ProcessOrdersStep com.demandware.beehive.core.internal.job.JobMgr Sites-Site JOB abc123def456 - Job started: ProcessOrders`, 119 | `[${timestamps[1]} GMT] INFO PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Account-SubmitRegistration|PipelineCall|V5YDtxRLpL custom [] Customer registration completed: customer.id=123456789`, 120 | `[${timestamps[2]} GMT] INFO PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Order-Confirm|PipelineCall|AbcDef123G custom [] Order created successfully: ORDER-000001234`, 121 | `[${timestamps[3]} GMT] INFO SystemJobThread|67038033|sfcc-export-dw-analytics-site-config|ExportDWAnalyticsSiteConfigurationStep Executing step [ExportDWAnalyticsSiteConfigurationStep][5846619] for [Organization]...`, 122 | `[${timestamps[4]} GMT] INFO SystemJobThread|67038033|sfcc-export-dw-analytics-site-config Executing job [sfcc-export-dw-analytics-site-config][2664334]...` 123 | ]; 124 | 125 | const infoContent = infoEntries.join('\n') + '\n'; 126 | const infoFile = path.join(this.logsDir, `info-blade-${this.dateString}-${this.timeString}.log`); 127 | fs.writeFileSync(infoFile, infoContent); 128 | console.log(`📄 Created info log: ${infoFile}`); 129 | } 130 | 131 | generateDebugLogs() { 132 | // Create timestamps with specific ordering - oldest first for proper log file structure 133 | const baseTime = new Date(); 134 | const timestamps = [ 135 | this.formatLogTimestamp(new Date(baseTime.getTime() + 1000)), // 1 second later (oldest) 136 | this.formatLogTimestamp(new Date(baseTime.getTime() + 2000)), // 2 seconds later 137 | this.formatLogTimestamp(new Date(baseTime.getTime() + 3000)), // 3 seconds later 138 | this.formatLogTimestamp(new Date(baseTime.getTime() + 4000)), // 4 seconds later 139 | this.formatLogTimestamp(new Date(baseTime.getTime() + 5000)) // 5 seconds later (newest) 140 | ]; 141 | 142 | const debugEntries = [ 143 | `[${timestamps[0]} GMT] DEBUG PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Account-Show|PipelineCall|290fx4tnVR custom [] Customer session validated: session timeout extended`, 144 | `[${timestamps[1]} GMT] DEBUG PipelineCallServlet|1645761595|Sites-RefArchGlobal-Site|Cart-Show|PipelineCall|nYJXtqnEfz custom [] Basket calculation: 3 items, subtotal $149.99`, 145 | `[${timestamps[2]} GMT] DEBUG SystemJobThread|1581553813|sfcc-data-replication|DataReplicationStep com.demandware.beehive.core.internal.system.SystemMgr Sites-Site JOB abc123def456 - Data replication sync started`, 146 | `[${timestamps[3]} GMT] DEBUG PipelineCallServlet|1050777654|Sites-RefArchGlobal-Site|Search-Show|PipelineCall|V5YDtxRLpL custom [] Search query executed: 'laptop' returned 45 results`, 147 | `[${timestamps[4]} GMT] DEBUG PipelineCallServlet|1912801078|Sites-RefArchGlobal-Site|Product-Show|PipelineCall|AbcDef123G custom [] Product cache hit: SKU ABC-123-XYZ` 148 | ]; 149 | 150 | const debugContent = debugEntries.join('\n') + '\n'; 151 | const debugFile = path.join(this.logsDir, `debug-blade-${this.dateString}-${this.timeString}.log`); 152 | fs.writeFileSync(debugFile, debugContent); 153 | console.log(`📄 Created debug log: ${debugFile}`); 154 | } 155 | 156 | generateJobLogs() { 157 | // Create job directories and logs 158 | const jobs = [ 159 | { 160 | name: 'ProcessOrders', 161 | id: '1234567890', 162 | steps: ['ValidateOrdersStep', 'ProcessPaymentsStep', 'UpdateInventoryStep'] 163 | }, 164 | { 165 | name: 'ImportCatalog', 166 | id: '0987654321', 167 | steps: ['ValidateCatalogStep', 'ImportProductsStep', 'IndexProductsStep'] 168 | } 169 | ]; 170 | 171 | jobs.forEach(job => { 172 | const jobDir = path.join(this.jobsDir, job.name); 173 | this.ensureDirectoryExists(jobDir); 174 | 175 | const timestamp = this.formatLogTimestamp(new Date()); 176 | 177 | const jobEntries = [ 178 | `[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name} Executing job [${job.name}][${job.id}]...` 179 | ]; 180 | 181 | // Add step entries 182 | job.steps.forEach(step => { 183 | jobEntries.push( 184 | `[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name}|${step} Executing step [${step}] for [Organization]...`, 185 | `[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name}|${step} Step [${step}] completed successfully` 186 | ); 187 | }); 188 | 189 | jobEntries.push(`[${timestamp} GMT] INFO SystemJobThread|${job.id}|${job.name} Execution of job finished with status [OK].`); 190 | 191 | const jobContent = jobEntries.join('\n') + '\n'; 192 | const jobFile = path.join(jobDir, `Job-${job.name}-${job.id}.log`); 193 | fs.writeFileSync(jobFile, jobContent); 194 | console.log(`📄 Created job log: ${jobFile}`); 195 | }); 196 | } 197 | 198 | run() { 199 | console.log('🚀 Starting mock log generation...'); 200 | 201 | // Ensure directories exist 202 | this.ensureDirectoryExists(this.baseDir); 203 | this.ensureDirectoryExists(this.logsDir); 204 | this.ensureDirectoryExists(this.jobsDir); 205 | 206 | // Generate all log types 207 | this.generateErrorLogs(); 208 | this.generateWarnLogs(); 209 | this.generateInfoLogs(); 210 | this.generateDebugLogs(); 211 | this.generateJobLogs(); 212 | 213 | console.log('✅ Mock log generation completed!'); 214 | console.log(`� Logs created in: ${this.logsDir}`); 215 | } 216 | } 217 | 218 | // Run the generator if called directly 219 | if (require.main === module) { 220 | const generator = new MockLogGenerator(); 221 | generator.run(); 222 | } 223 | 224 | module.exports = MockLogGenerator; ``` -------------------------------------------------------------------------------- /docs/dw_content/MediaFile.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.content 2 | 3 | # Class MediaFile 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.content.MediaFile 9 | 10 | ## Description 11 | 12 | This class represents references to media content (such as images) located within Commerce Cloud Digital or on external systems. Parameter transform: Some methods allow the specification of image transformation parameters. Image transformation is only performed if the Dynamic Imaging Service (DIS) is available for the Commerce Cloud Digital instance, otherwise a standard static content URL is returned. The to-be-transformed image needs to be hosted on Commerce Cloud Digital. Image transformation parameters are specified as JavaScript object literal. They are translated into URL parameters. See Create Image Transformation URLs. Type of transformation Parameters Description Scale an image scaleWidth scaleHeight scaleMode The scaleWidth and scaleHeight parameters are both integers; setting one of these parameters triggers a scaling operation. If both are provided, the one that scales the image less is used to calculate the scale factor. The image is then automatically cropped accord to the second dimension, with a centered position of the cropped area. If the parameter would scale the image larger, only this operation is applied, if the image remains within acceptable pixel dimensions. Note: scaleMode can only be used in combination with scaleHeight and scaleWidth. The scaleMode parameter can be set to cut or fit. The default scaleMode is cut, the behavior of which is explained above. If you specify fit as the scaleMode, the system scales the image into the given box of dimensions while keeping the aspect ratio (possibly resulting in a smaller image in one dimension). Overlay an image imageX imageY imageURI The imageX and imageY parameters are both integers. Valid values for these parameters are 0 or greater. Supported formats are png, jpg, jp2, and gif. The imageURI parameter can be set to the absolute path of the overlaid image. The value of the imageURI parameter must be given in proper URL encoding, and it cannot exceed 400 characters in length. The path may include query string parameters, which supports dynamically generating the overlaid image itself through this service; that is, the overlaid image can itself be a transformed image. If the overlaid image extends over the primary image's boundaries, the overlaid image is cropped so that it fits directly over the primary image. Crop an image cropX cropY cropWidth cropHeight The cropX, cropY, cropWidth, cropHeight parameters are integers. All four parameters must be specified to trigger a cropping operation. Valid values for the cropX and cropY parameters are 0 or greater. If the crop location defined by cropX and cropY is outside the image area, nothing is cropped. Valid values for the cropWidth and cropHeight parameters are 10 or greater. If the cropWidth and cropHeight parameters specify a size that is greater than the original image, the crop area is reduced to the actual image area. If cropWidth and cropHeight are 0 or less, no transformation is applied. Format an image format The format parameter specifies the target format of image. Supported formats are png, jpg, jp2, and gif. If no target format is specified, no format conversion is performed. The attribute value must reference the source image. Source image's format is recognized by the file extension which must be tif, tiff, jpg, jpeg, png, or gif. In the generated URL the file extension of the target format is used in the URL path. This is to make sure the image is loaded from an URL with a matching file extension. The source format is provided as URL parameter. Adjust image compression quality quality The quality parameter specifies a quality setting for jpg and jp2 images, and specifies the compression level for png images. For jpg and jp2 images, you can set values from 1–100 for the highest quality. The default quality is 80. If you're not changing the default quality, you don't need to pass in a value. For png images, the quality setting has no effect on the appearance of the png, since the compression is always lossless. Instead you can use the quality setting to set the zlib compression level and filter-type for PNG images. The tens digit sets the zlib compression level(1-9). The ones digit sets the filter type. If the png setting is not present or set to 0, it uses a default value of 75. If this setting is set to 100, it actually equals the quality setting 90. Adjust Metadata stripping strip The strip parameter specifies if metadata like EXIF and color profiles is stripped from the image during transformation. Valid values for the strip parameter are between true and false. The default is true Change background color bgcolor(color) or bgcolor(color+alpha) The bgcolor parameter specifies the background color for images that support transparency as well as JPEG images when being converted from a format that supports transparency. Optionally, alpha setting for PNG images are also supported. bgcolor expects a 6 digit hexadecimal value of RGB with an optional two hexadecimal characters representing alpha value that determines transparency. FF0000 = Red FF000077 = Red with 50% transparency Alpha values are optional. When the alpha value is omitted, the resulting color is opaque. Alpha values are only valid when the image output format is PNG. Example: The following code var url = product.getImage('thumbnail', 0).getImageURL({scaleWidth: 100, format: 'jpg'}); will produce an image transformation URL like http://<image server host name>/.../on/demandware.static/.../<path to image>/image.jpg?sw=100&sfrm=png. 13 | 14 | ## Properties 15 | 16 | ### absURL 17 | 18 | **Type:** URL (Read Only) 19 | 20 | An absolute URL to the referenced media file. The 21 | protocol for the reference is the current protocol of the current 22 | HTTP request. 23 | 24 | ### alt 25 | 26 | **Type:** String (Read Only) 27 | 28 | The alternative text assigned to the media file in current 29 | requests locale. If no alternative text was assigned or if no defaulting 30 | rule was defined, the method returns null. 31 | 32 | ### httpsURL 33 | 34 | **Type:** URL (Read Only) 35 | 36 | An absolute URL to the referenced media file. The 37 | protocol is https. 38 | 39 | ### httpURL 40 | 41 | **Type:** URL (Read Only) 42 | 43 | An absolute URL to the referenced media file. The 44 | protocol is http. 45 | 46 | ### title 47 | 48 | **Type:** String (Read Only) 49 | 50 | The title assigned to the media file in current requests locale. 51 | If no title was assigned or if no defaulting rule was defined, the 52 | method returns null. 53 | 54 | ### url 55 | 56 | **Type:** URL (Read Only) 57 | 58 | An URL to the referenced media file. The 59 | returned URL is a relative URL. 60 | 61 | ### URL 62 | 63 | **Type:** URL (Read Only) 64 | 65 | An URL to the referenced media file. The 66 | returned URL is a relative URL. 67 | 68 | ### viewType 69 | 70 | **Type:** String (Read Only) 71 | 72 | The view type annotation for the media file. The method returns 73 | null, if the media file has no view type annotation. 74 | 75 | ## Constructor Summary 76 | 77 | ## Method Summary 78 | 79 | ### getAbsImageURL 80 | 81 | **Signature:** `getAbsImageURL(transform : Object) : URL` 82 | 83 | Returns an URL to the referenced image file. 84 | 85 | ### getAbsURL 86 | 87 | **Signature:** `getAbsURL() : URL` 88 | 89 | Returns an absolute URL to the referenced media file. 90 | 91 | ### getAlt 92 | 93 | **Signature:** `getAlt() : String` 94 | 95 | Returns the alternative text assigned to the media file in current requests locale. 96 | 97 | ### getHttpImageURL 98 | 99 | **Signature:** `getHttpImageURL(transform : Object) : URL` 100 | 101 | Returns an URL to the referenced image file. 102 | 103 | ### getHttpsImageURL 104 | 105 | **Signature:** `getHttpsImageURL(transform : Object) : URL` 106 | 107 | Returns an URL to the referenced image file. 108 | 109 | ### getHttpsURL 110 | 111 | **Signature:** `getHttpsURL() : URL` 112 | 113 | Returns an absolute URL to the referenced media file. 114 | 115 | ### getHttpURL 116 | 117 | **Signature:** `getHttpURL() : URL` 118 | 119 | Returns an absolute URL to the referenced media file. 120 | 121 | ### getImageURL 122 | 123 | **Signature:** `getImageURL(transform : Object) : URL` 124 | 125 | Returns an URL to the referenced image file. 126 | 127 | ### getTitle 128 | 129 | **Signature:** `getTitle() : String` 130 | 131 | Returns the title assigned to the media file in current requests locale. 132 | 133 | ### getUrl 134 | 135 | **Signature:** `getUrl() : URL` 136 | 137 | Returns an URL to the referenced media file. 138 | 139 | ### getURL 140 | 141 | **Signature:** `getURL() : URL` 142 | 143 | Returns an URL to the referenced media file. 144 | 145 | ### getViewType 146 | 147 | **Signature:** `getViewType() : String` 148 | 149 | Returns the view type annotation for the media file. 150 | 151 | ## Method Detail 152 | 153 | ## Method Details 154 | 155 | ### getAbsImageURL 156 | 157 | **Signature:** `getAbsImageURL(transform : Object) : URL` 158 | 159 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. The protocol for the reference is the current protocol of the current HTTP request. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital. 160 | 161 | **Parameters:** 162 | 163 | - `transform`: Object with transformation parameters (see class header) 164 | 165 | **Returns:** 166 | 167 | an absolute URL to the referenced media file. The protocol for the reference is the current protocol of the current HTTP request. If the referenced media file is hosted externally, an URL to the external file is returned. 168 | 169 | --- 170 | 171 | ### getAbsURL 172 | 173 | **Signature:** `getAbsURL() : URL` 174 | 175 | **Description:** Returns an absolute URL to the referenced media file. The protocol for the reference is the current protocol of the current HTTP request. 176 | 177 | **Returns:** 178 | 179 | an absolute URL to the referenced media file. The protocol for the reference is the current protocol of the current HTTP request. 180 | 181 | --- 182 | 183 | ### getAlt 184 | 185 | **Signature:** `getAlt() : String` 186 | 187 | **Description:** Returns the alternative text assigned to the media file in current requests locale. If no alternative text was assigned or if no defaulting rule was defined, the method returns null. 188 | 189 | **Returns:** 190 | 191 | the alternative text annotated to this media file or null 192 | 193 | --- 194 | 195 | ### getHttpImageURL 196 | 197 | **Signature:** `getHttpImageURL(transform : Object) : URL` 198 | 199 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. The protocol is http. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital. 200 | 201 | **Parameters:** 202 | 203 | - `transform`: Object with transformation parameters (see class header) 204 | 205 | **Returns:** 206 | 207 | an absolute URL to the referenced media file. The protocol is http. If the referenced media file is hosted externally, an URL to the external file is returned. 208 | 209 | --- 210 | 211 | ### getHttpsImageURL 212 | 213 | **Signature:** `getHttpsImageURL(transform : Object) : URL` 214 | 215 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. The protocol is https. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital. 216 | 217 | **Parameters:** 218 | 219 | - `transform`: Object with transformation parameters (see class header) 220 | 221 | **Returns:** 222 | 223 | an absolute URL to the referenced media file. The protocol is https. If the referenced media file is hosted externally, an URL to the external file is returned. 224 | 225 | --- 226 | 227 | ### getHttpsURL 228 | 229 | **Signature:** `getHttpsURL() : URL` 230 | 231 | **Description:** Returns an absolute URL to the referenced media file. The protocol is https. 232 | 233 | **Returns:** 234 | 235 | an absolute URL to the referenced media file. The protocol is https. 236 | 237 | --- 238 | 239 | ### getHttpURL 240 | 241 | **Signature:** `getHttpURL() : URL` 242 | 243 | **Description:** Returns an absolute URL to the referenced media file. The protocol is http. 244 | 245 | **Returns:** 246 | 247 | an absolute URL to the referenced media file. The protocol is http. 248 | 249 | --- 250 | 251 | ### getImageURL 252 | 253 | **Signature:** `getImageURL(transform : Object) : URL` 254 | 255 | **Description:** Returns an URL to the referenced image file. Image transformation can be applied to the image. Image transformation can only be applied to images that are hosted on Commerce Cloud Digital. 256 | 257 | **Parameters:** 258 | 259 | - `transform`: Object with transformation parameters (see class header) 260 | 261 | **Returns:** 262 | 263 | an URL to the referenced media file. The returned URL is a relative URL. If the referenced media file is hosted externally, an URL to the external file is returned. 264 | 265 | --- 266 | 267 | ### getTitle 268 | 269 | **Signature:** `getTitle() : String` 270 | 271 | **Description:** Returns the title assigned to the media file in current requests locale. If no title was assigned or if no defaulting rule was defined, the method returns null. 272 | 273 | **Returns:** 274 | 275 | the title annotated to this media file or null 276 | 277 | --- 278 | 279 | ### getUrl 280 | 281 | **Signature:** `getUrl() : URL` 282 | 283 | **Description:** Returns an URL to the referenced media file. The returned URL is a relative URL. 284 | 285 | **Deprecated:** 286 | 287 | Use getURL() instead. 288 | 289 | **Returns:** 290 | 291 | an URL to the referenced media file. The returned URL is a relative URL. 292 | 293 | --- 294 | 295 | ### getURL 296 | 297 | **Signature:** `getURL() : URL` 298 | 299 | **Description:** Returns an URL to the referenced media file. The returned URL is a relative URL. 300 | 301 | **Returns:** 302 | 303 | an URL to the referenced media file. The returned URL is a relative URL. 304 | 305 | --- 306 | 307 | ### getViewType 308 | 309 | **Signature:** `getViewType() : String` 310 | 311 | **Description:** Returns the view type annotation for the media file. The method returns null, if the media file has no view type annotation. 312 | 313 | **Returns:** 314 | 315 | the view type annotated to this media file or null 316 | 317 | --- ``` -------------------------------------------------------------------------------- /docs/dw_campaign/CampaignMgr.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.campaign 2 | 3 | # Class CampaignMgr 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.campaign.CampaignMgr 9 | 10 | ## Description 11 | 12 | CampaignMgr provides static methods for managing campaign-specific operations such as accessing promotions or updating promotion line items. 13 | 14 | ## Properties 15 | 16 | ### applicablePromotions 17 | 18 | **Type:** Collection (Read Only) 19 | 20 | The enabled promotions of active campaigns applicable for the 21 | current customer and source code. 22 | 23 | Note that this method does not return any coupon-based promotions. 24 | 25 | ## Constructor Summary 26 | 27 | ## Method Summary 28 | 29 | ### applyBonusPromotions 30 | 31 | **Signature:** `static applyBonusPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 32 | 33 | This method has been deprecated and should not be used anymore. 34 | 35 | ### applyOrderPromotions 36 | 37 | **Signature:** `static applyOrderPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 38 | 39 | Applies the applicable order promotions in the specified collection to the specified line item container. 40 | 41 | ### applyProductPromotions 42 | 43 | **Signature:** `static applyProductPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 44 | 45 | Applies all applicable product promotions in the specified collection to the specified line item container. 46 | 47 | ### applyShippingPromotions 48 | 49 | **Signature:** `static applyShippingPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 50 | 51 | Applies all applicable shipping promotions in the specified collection to the specified line item container. 52 | 53 | ### getApplicableConditionalPromotions 54 | 55 | **Signature:** `static getApplicableConditionalPromotions(product : Product) : Collection` 56 | 57 | Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a qualifiying product. 58 | 59 | ### getApplicablePromotions 60 | 61 | **Signature:** `static getApplicablePromotions(product : Product) : Collection` 62 | 63 | Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a discounted product. 64 | 65 | ### getApplicablePromotions 66 | 67 | **Signature:** `static getApplicablePromotions(lineItemCtnr : LineItemCtnr) : Collection` 68 | 69 | Returns the enabled promotions of active campaigns applicable for the current customer, source code and any coupon contained in the specified line item container. 70 | 71 | ### getApplicablePromotions 72 | 73 | **Signature:** `static getApplicablePromotions() : Collection` 74 | 75 | Returns the enabled promotions of active campaigns applicable for the current customer and source code. 76 | 77 | ### getCampaignByID 78 | 79 | **Signature:** `static getCampaignByID(id : String) : Campaign` 80 | 81 | Returns the campaign identified by the specified ID. 82 | 83 | ### getConditionalPromotions 84 | 85 | **Signature:** `static getConditionalPromotions(product : Product) : Collection` 86 | 87 | Returns the enabled promotions of active campaigns for which the specified product is a qualifiying product. 88 | 89 | ### getPromotion 90 | 91 | **Signature:** `static getPromotion(couponCode : String) : Promotion` 92 | 93 | Returns the promotion associated with the specified coupon code. 94 | 95 | ### getPromotionByCouponCode 96 | 97 | **Signature:** `static getPromotionByCouponCode(couponCode : String) : Promotion` 98 | 99 | Returns the promotion associated with the specified coupon code. 100 | 101 | ### getPromotionByID 102 | 103 | **Signature:** `static getPromotionByID(id : String) : Promotion` 104 | 105 | Returns the promotion identified by the specified ID. 106 | 107 | ### getPromotions 108 | 109 | **Signature:** `static getPromotions(product : Product) : Collection` 110 | 111 | Returns the enabled promotions of active campaigns for which the specified product is a discounted product. 112 | 113 | ## Method Detail 114 | 115 | ## Method Details 116 | 117 | ### applyBonusPromotions 118 | 119 | **Signature:** `static applyBonusPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 120 | 121 | **Description:** This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. The method does nothing, since bonus promotions are applied as product or order promotions using methods applyProductPromotions(LineItemCtnr, Collection) and applyOrderPromotions(LineItemCtnr, Collection). The method returns 'true' if any the line item container contains any bonus product line items, and otherwise false. 122 | 123 | **Deprecated:** 124 | 125 | Use PromotionMgr instead. 126 | 127 | **Parameters:** 128 | 129 | - `lineItemCtnr`: Basket or order 130 | - `promotions`: Parameter not used, can be null 131 | 132 | **Returns:** 133 | 134 | True if line item container contains bonus product line items, else false 135 | 136 | --- 137 | 138 | ### applyOrderPromotions 139 | 140 | **Signature:** `static applyOrderPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 141 | 142 | **Description:** Applies the applicable order promotions in the specified collection to the specified line item container. This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. Note that the method does also apply any bonus discounts defined as order promotions (see also applyBonusPromotions(LineItemCtnr, Collection)). 143 | 144 | **Deprecated:** 145 | 146 | Use PromotionMgr 147 | 148 | **Parameters:** 149 | 150 | - `lineItemCtnr`: basket or order 151 | - `promotions`: list of all promotions to be applied 152 | 153 | **Returns:** 154 | 155 | true if changes were made to the line item container, false otherwise. 156 | 157 | --- 158 | 159 | ### applyProductPromotions 160 | 161 | **Signature:** `static applyProductPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 162 | 163 | **Description:** Applies all applicable product promotions in the specified collection to the specified line item container. This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. Note that the method does also apply any bonus discounts defined as product promotions (see also applyBonusPromotions(LineItemCtnr, Collection)). 164 | 165 | **Deprecated:** 166 | 167 | Use PromotionMgr 168 | 169 | **Parameters:** 170 | 171 | - `lineItemCtnr`: basket or order 172 | - `promotions`: list of all promotions to be applied 173 | 174 | **Returns:** 175 | 176 | true if changes were made to the line item container, false otherwise. 177 | 178 | --- 179 | 180 | ### applyShippingPromotions 181 | 182 | **Signature:** `static applyShippingPromotions(lineItemCtnr : LineItemCtnr, promotions : Collection) : boolean` 183 | 184 | **Description:** Applies all applicable shipping promotions in the specified collection to the specified line item container. This method has been deprecated and should not be used anymore. Instead, use PromotionMgr to apply promotions to line item containers. 185 | 186 | **Deprecated:** 187 | 188 | Use PromotionMgr 189 | 190 | **Parameters:** 191 | 192 | - `lineItemCtnr`: basket or order 193 | - `promotions`: list of all promotions to be applied 194 | 195 | **Returns:** 196 | 197 | true if changes were made to the line item container, false otherwise. 198 | 199 | --- 200 | 201 | ### getApplicableConditionalPromotions 202 | 203 | **Signature:** `static getApplicableConditionalPromotions(product : Product) : Collection` 204 | 205 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a qualifiying product. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getApplicableConditionalPromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product. 206 | 207 | **Deprecated:** 208 | 209 | Use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product) 210 | 211 | **Parameters:** 212 | 213 | - `product`: Qualifying product 214 | 215 | **Returns:** 216 | 217 | List of active promotions 218 | 219 | --- 220 | 221 | ### getApplicablePromotions 222 | 223 | **Signature:** `static getApplicablePromotions(product : Product) : Collection` 224 | 225 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer and source code for which the specified product is a discounted product. Note that this method does not return any coupon-based promotions. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getApplicablePromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product. 226 | 227 | **Deprecated:** 228 | 229 | Use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product) 230 | 231 | **Parameters:** 232 | 233 | - `product`: The product whose promotions are returned. 234 | 235 | **Returns:** 236 | 237 | A list of promotions 238 | 239 | --- 240 | 241 | ### getApplicablePromotions 242 | 243 | **Signature:** `static getApplicablePromotions(lineItemCtnr : LineItemCtnr) : Collection` 244 | 245 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer, source code and any coupon contained in the specified line item container. Note that although the method has been deprecated, no replacement method is provided. 246 | 247 | **Deprecated:** 248 | 249 | There is no replacement for this method. 250 | 251 | **Parameters:** 252 | 253 | - `lineItemCtnr`: the basket or order 254 | 255 | **Returns:** 256 | 257 | list of all applicable promotion for the given basket or order 258 | 259 | --- 260 | 261 | ### getApplicablePromotions 262 | 263 | **Signature:** `static getApplicablePromotions() : Collection` 264 | 265 | **Description:** Returns the enabled promotions of active campaigns applicable for the current customer and source code. Note that this method does not return any coupon-based promotions. 266 | 267 | **Deprecated:** 268 | 269 | Use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getPromotions() 270 | 271 | **Returns:** 272 | 273 | List of active promotions 274 | 275 | --- 276 | 277 | ### getCampaignByID 278 | 279 | **Signature:** `static getCampaignByID(id : String) : Campaign` 280 | 281 | **Description:** Returns the campaign identified by the specified ID. 282 | 283 | **Deprecated:** 284 | 285 | Use PromotionMgr.getCampaign(String) 286 | 287 | **Parameters:** 288 | 289 | - `id`: Campaign ID 290 | 291 | **Returns:** 292 | 293 | Campaign or null if not found 294 | 295 | --- 296 | 297 | ### getConditionalPromotions 298 | 299 | **Signature:** `static getConditionalPromotions(product : Product) : Collection` 300 | 301 | **Description:** Returns the enabled promotions of active campaigns for which the specified product is a qualifiying product. Note that the method also returns coupon-based promotions. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getConditionalPromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product. 302 | 303 | **Deprecated:** 304 | 305 | Use PromotionMgr.getActivePromotions() and PromotionPlan.getProductPromotions(Product) 306 | 307 | **Parameters:** 308 | 309 | - `product`: The product whose conditional promotions are returned. 310 | 311 | **Returns:** 312 | 313 | A list of promotions 314 | 315 | --- 316 | 317 | ### getPromotion 318 | 319 | **Signature:** `static getPromotion(couponCode : String) : Promotion` 320 | 321 | **Description:** Returns the promotion associated with the specified coupon code. 322 | 323 | **Deprecated:** 324 | 325 | Coupons are now related to multiple promotions. Method returns the first promotion associated with the coupon code in case of multiple assigned promotions. 326 | 327 | **Parameters:** 328 | 329 | - `couponCode`: The coupon code used to lookup the promotion 330 | 331 | **Returns:** 332 | 333 | The resolved promotion object or null if none was found 334 | 335 | --- 336 | 337 | ### getPromotionByCouponCode 338 | 339 | **Signature:** `static getPromotionByCouponCode(couponCode : String) : Promotion` 340 | 341 | **Description:** Returns the promotion associated with the specified coupon code. 342 | 343 | **Deprecated:** 344 | 345 | Coupons are now related to multiple promotions. Method returns the first promotion associated with the coupon in case of multiple assigned promotions 346 | 347 | **Parameters:** 348 | 349 | - `couponCode`: Coupon code 350 | 351 | **Returns:** 352 | 353 | The associated promotion or null 354 | 355 | --- 356 | 357 | ### getPromotionByID 358 | 359 | **Signature:** `static getPromotionByID(id : String) : Promotion` 360 | 361 | **Description:** Returns the promotion identified by the specified ID. 362 | 363 | **Deprecated:** 364 | 365 | Use PromotionMgr.getPromotion(String) 366 | 367 | **Parameters:** 368 | 369 | - `id`: Promotion ID 370 | 371 | **Returns:** 372 | 373 | Promotion or null if not found 374 | 375 | --- 376 | 377 | ### getPromotions 378 | 379 | **Signature:** `static getPromotions(product : Product) : Collection` 380 | 381 | **Description:** Returns the enabled promotions of active campaigns for which the specified product is a discounted product. Note that method does only return promotions based on customer groups or source codes. As a replacement of this deprecated method, use PromotionMgr.getActiveCustomerPromotions() and PromotionPlan.getProductPromotions(Product). Unlike getPromotions(Product), PromotionPlan.getProductPromotions(Product) returns all promotions related to the specified product, regardless of whether the product is qualifying, discounted, or both, and also returns promotions where the product is a bonus product. 382 | 383 | **Deprecated:** 384 | 385 | Use PromotionMgr.getActivePromotions() and PromotionPlan.getProductPromotions(Product) 386 | 387 | **Parameters:** 388 | 389 | - `product`: Discounted product 390 | 391 | **Returns:** 392 | 393 | List of promotions 394 | 395 | --- ``` -------------------------------------------------------------------------------- /docs/dw_value/Money.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.value 2 | 3 | # Class Money 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.value.Money 9 | 10 | ## Description 11 | 12 | Represents money in Commerce Cloud Digital. 13 | 14 | ## Constants 15 | 16 | ### NOT_AVAILABLE 17 | 18 | **Type:** Money 19 | 20 | Represents that there is no money available. 21 | 22 | ## Properties 23 | 24 | ### available 25 | 26 | **Type:** boolean (Read Only) 27 | 28 | Identifies if the instance contains settings for value and currency. 29 | 30 | ### currencyCode 31 | 32 | **Type:** String (Read Only) 33 | 34 | The ISO 4217 currency mnemonic (such as 'USD', 'EUR') of the currency the 35 | money value relates to. 36 | 37 | Note a money instance may also describe a price that is 'not available'. 38 | In this case the value of this attribute is N/A. 39 | 40 | ### decimalValue 41 | 42 | **Type:** Decimal (Read Only) 43 | 44 | The money as Decimal, null is returned when the money is not available. 45 | 46 | ### value 47 | 48 | **Type:** Number (Read Only) 49 | 50 | The value of the money instance. 51 | 52 | ### valueOrNull 53 | 54 | **Type:** Number (Read Only) 55 | 56 | Return the value of the money instance or null if the 57 | Money instance is NOT_AVAILABLE. 58 | 59 | ## Constructor Summary 60 | 61 | Money(value : Number, currencyCode : String) Constructs a new money instance with the specified amount for the specified currency. 62 | 63 | ## Method Summary 64 | 65 | ### add 66 | 67 | **Signature:** `add(value : Money) : Money` 68 | 69 | Returns a Money instance by adding the specified Money object to the current object. 70 | 71 | ### addPercent 72 | 73 | **Signature:** `addPercent(percent : Number) : Money` 74 | 75 | Adds a certain percentage to the money object. 76 | 77 | ### addRate 78 | 79 | **Signature:** `addRate(value : Number) : Money` 80 | 81 | Adds a rate (e.g. 82 | 83 | ### compareTo 84 | 85 | **Signature:** `compareTo(other : Money) : Number` 86 | 87 | Compares two Money values. 88 | 89 | ### divide 90 | 91 | **Signature:** `divide(divisor : Number) : Money` 92 | 93 | Divide Money object by specified divisor. 94 | 95 | ### equals 96 | 97 | **Signature:** `equals(other : Object) : boolean` 98 | 99 | Compares two money values whether they are equivalent. 100 | 101 | ### getCurrencyCode 102 | 103 | **Signature:** `getCurrencyCode() : String` 104 | 105 | Returns the ISO 4217 currency mnemonic (such as 'USD', 'EUR') of the currency the money value relates to. 106 | 107 | ### getDecimalValue 108 | 109 | **Signature:** `getDecimalValue() : Decimal` 110 | 111 | Returns the money as Decimal, null is returned when the money is not available. 112 | 113 | ### getValue 114 | 115 | **Signature:** `getValue() : Number` 116 | 117 | Returns the value of the money instance. 118 | 119 | ### getValueOrNull 120 | 121 | **Signature:** `getValueOrNull() : Number` 122 | 123 | Return the value of the money instance or null if the Money instance is NOT_AVAILABLE. 124 | 125 | ### hashCode 126 | 127 | **Signature:** `hashCode() : Number` 128 | 129 | Calculates the hash code for a money; 130 | 131 | ### isAvailable 132 | 133 | **Signature:** `isAvailable() : boolean` 134 | 135 | Identifies if the instance contains settings for value and currency. 136 | 137 | ### isOfSameCurrency 138 | 139 | **Signature:** `isOfSameCurrency(value : Money) : boolean` 140 | 141 | Identifies if two Money value have the same currency. 142 | 143 | ### multiply 144 | 145 | **Signature:** `multiply(factor : Number) : Money` 146 | 147 | Multiply Money object by specified factor. 148 | 149 | ### multiply 150 | 151 | **Signature:** `multiply(quantity : Quantity) : Money` 152 | 153 | Multiplies the Money object with the given quantity. 154 | 155 | ### newMoney 156 | 157 | **Signature:** `newMoney(value : Decimal) : Money` 158 | 159 | Method returns a new instance of Money with the same currency but different value. 160 | 161 | ### percentLessThan 162 | 163 | **Signature:** `percentLessThan(value : Money) : Number` 164 | 165 | Convenience method. 166 | 167 | ### percentOf 168 | 169 | **Signature:** `percentOf(value : Money) : Number` 170 | 171 | Convenience method. 172 | 173 | ### prorate 174 | 175 | **Signature:** `static prorate(dist : Money, values : Money...) : Money[]` 176 | 177 | Prorates the specified values using the specified discount. 178 | 179 | ### subtract 180 | 181 | **Signature:** `subtract(value : Money) : Money` 182 | 183 | Returns a new Money instance by substracting the specified Money object from the current object. 184 | 185 | ### subtractPercent 186 | 187 | **Signature:** `subtractPercent(percent : Number) : Money` 188 | 189 | Subtracts a certain percentage from the money object. 190 | 191 | ### subtractRate 192 | 193 | **Signature:** `subtractRate(value : Number) : Money` 194 | 195 | Subtracts a rate (e.g. 196 | 197 | ### toFormattedString 198 | 199 | **Signature:** `toFormattedString() : String` 200 | 201 | Returns a string representation of Money according to the regional settings configured for current request locale, for example '$59.00' or 'USD 59.00'. 202 | 203 | ### toNumberString 204 | 205 | **Signature:** `toNumberString() : String` 206 | 207 | Returns a string representation for the numeric value of this money. 208 | 209 | ### toString 210 | 211 | **Signature:** `toString() : String` 212 | 213 | Returns a string representation of this Money object. 214 | 215 | ### valueOf 216 | 217 | **Signature:** `valueOf() : Object` 218 | 219 | According to the ECMA spec returns the "natural" primitve value. 220 | 221 | ## Constructor Detail 222 | 223 | ## Method Detail 224 | 225 | ## Method Details 226 | 227 | ### add 228 | 229 | **Signature:** `add(value : Money) : Money` 230 | 231 | **Description:** Returns a Money instance by adding the specified Money object to the current object. Only objects representing the same currency can be added. If one of the Money values is N/A, the result is N/A. 232 | 233 | **Parameters:** 234 | 235 | - `value`: the Money object to add to this Money instance. 236 | 237 | **Returns:** 238 | 239 | the Money object representing the sum of the operands. 240 | 241 | --- 242 | 243 | ### addPercent 244 | 245 | **Signature:** `addPercent(percent : Number) : Money` 246 | 247 | **Description:** Adds a certain percentage to the money object. The percent value is given as true percent value, so for example 10 represent 10%. If this Money is N/A the result is also N/A. 248 | 249 | **Parameters:** 250 | 251 | - `percent`: the percent value 252 | 253 | **Returns:** 254 | 255 | new Money object with the result of the calculation 256 | 257 | --- 258 | 259 | ### addRate 260 | 261 | **Signature:** `addRate(value : Number) : Money` 262 | 263 | **Description:** Adds a rate (e.g. 0.05) to the money object. This is typically for example to add a tax rate. 264 | 265 | **Parameters:** 266 | 267 | - `value`: the rate to add. 268 | 269 | **Returns:** 270 | 271 | a new Money object with rate added. 272 | 273 | --- 274 | 275 | ### compareTo 276 | 277 | **Signature:** `compareTo(other : Money) : Number` 278 | 279 | **Description:** Compares two Money values. An exception is thrown if the two Money values are of different currency. If one of the Money values represents the N/A value it is treated as 0.0. 280 | 281 | **Parameters:** 282 | 283 | - `other`: the money instance to comare against this money instance. 284 | 285 | **Returns:** 286 | 287 | the comparison of 0 if the money instances are equal or non-0 if they are different. 288 | 289 | --- 290 | 291 | ### divide 292 | 293 | **Signature:** `divide(divisor : Number) : Money` 294 | 295 | **Description:** Divide Money object by specified divisor. If this Money is N/A the result is also N/A. 296 | 297 | **Parameters:** 298 | 299 | - `divisor`: the divisor. 300 | 301 | **Returns:** 302 | 303 | Money object representing division result 304 | 305 | --- 306 | 307 | ### equals 308 | 309 | **Signature:** `equals(other : Object) : boolean` 310 | 311 | **Description:** Compares two money values whether they are equivalent. 312 | 313 | **Parameters:** 314 | 315 | - `other`: the object to compare against this money instance. 316 | 317 | **Returns:** 318 | 319 | true if equal, false otherwise. 320 | 321 | --- 322 | 323 | ### getCurrencyCode 324 | 325 | **Signature:** `getCurrencyCode() : String` 326 | 327 | **Description:** Returns the ISO 4217 currency mnemonic (such as 'USD', 'EUR') of the currency the money value relates to. Note a money instance may also describe a price that is 'not available'. In this case the value of this attribute is N/A. 328 | 329 | **Returns:** 330 | 331 | the value of the currency code. 332 | 333 | --- 334 | 335 | ### getDecimalValue 336 | 337 | **Signature:** `getDecimalValue() : Decimal` 338 | 339 | **Description:** Returns the money as Decimal, null is returned when the money is not available. 340 | 341 | **Returns:** 342 | 343 | the money as Decimal 344 | 345 | --- 346 | 347 | ### getValue 348 | 349 | **Signature:** `getValue() : Number` 350 | 351 | **Description:** Returns the value of the money instance. 352 | 353 | **Returns:** 354 | 355 | the value of the money instance. 356 | 357 | **See Also:** 358 | 359 | getDecimalValue() 360 | 361 | --- 362 | 363 | ### getValueOrNull 364 | 365 | **Signature:** `getValueOrNull() : Number` 366 | 367 | **Description:** Return the value of the money instance or null if the Money instance is NOT_AVAILABLE. 368 | 369 | **Returns:** 370 | 371 | Value of money instance or null. 372 | 373 | --- 374 | 375 | ### hashCode 376 | 377 | **Signature:** `hashCode() : Number` 378 | 379 | **Description:** Calculates the hash code for a money; 380 | 381 | --- 382 | 383 | ### isAvailable 384 | 385 | **Signature:** `isAvailable() : boolean` 386 | 387 | **Description:** Identifies if the instance contains settings for value and currency. 388 | 389 | **Returns:** 390 | 391 | true if the instance is initialized with value and currency, false if the state is 'not available'. 392 | 393 | --- 394 | 395 | ### isOfSameCurrency 396 | 397 | **Signature:** `isOfSameCurrency(value : Money) : boolean` 398 | 399 | **Description:** Identifies if two Money value have the same currency. 400 | 401 | **Parameters:** 402 | 403 | - `value`: the Money value passed to be tested 404 | 405 | **Returns:** 406 | 407 | true if both instances have the same currency, false otherwise. 408 | 409 | --- 410 | 411 | ### multiply 412 | 413 | **Signature:** `multiply(factor : Number) : Money` 414 | 415 | **Description:** Multiply Money object by specified factor. If this Money is N/A the result is also N/A. 416 | 417 | **Parameters:** 418 | 419 | - `factor`: multiplication factor 420 | 421 | **Returns:** 422 | 423 | Money object representing multiplication result. 424 | 425 | --- 426 | 427 | ### multiply 428 | 429 | **Signature:** `multiply(quantity : Quantity) : Money` 430 | 431 | **Description:** Multiplies the Money object with the given quantity. If this Money is N/A the result is also N/A. 432 | 433 | **Parameters:** 434 | 435 | - `quantity`: the quantity to multiply the value by 436 | 437 | **Returns:** 438 | 439 | a new Money representing the multiplication result. 440 | 441 | --- 442 | 443 | ### newMoney 444 | 445 | **Signature:** `newMoney(value : Decimal) : Money` 446 | 447 | **Description:** Method returns a new instance of Money with the same currency but different value. An N/A instance is returned if value is null. 448 | 449 | **Parameters:** 450 | 451 | - `value`: as a decimal 452 | 453 | **Returns:** 454 | 455 | new Money instance with same currency 456 | 457 | --- 458 | 459 | ### percentLessThan 460 | 461 | **Signature:** `percentLessThan(value : Money) : Number` 462 | 463 | **Description:** Convenience method. Calculates and returns the percentage off this price represents in relation to the passed base price. The result is generally equal to 100.0 - this.percentOf(value). For example, if this value is $30 and the passed value is $50, then the return value will be 40.0, representing a 40% discount. This method will return null if the compare value is null, this value or the compare value is unavailable, or the compare value equals 0.0. 464 | 465 | **Parameters:** 466 | 467 | - `value`: The price to compare to this price 468 | 469 | **Returns:** 470 | 471 | The percentage discount this price represents in relation to the passed base price. 472 | 473 | **See Also:** 474 | 475 | percentOf(Money) 476 | 477 | **Throws:** 478 | 479 | IllegalArgumentException - If the currencies are not comparable. 480 | 481 | --- 482 | 483 | ### percentOf 484 | 485 | **Signature:** `percentOf(value : Money) : Number` 486 | 487 | **Description:** Convenience method. Calculates and returns the percentage of the passed value this price represents. For example, if this value is $30 and the passed value is $50, then the return value will be 60.0 (i.e. 60%). This method will return null if the compare value is null, this value or the compare value is unavailable, or the compare value equals 0.0. 488 | 489 | **Parameters:** 490 | 491 | - `value`: The price to compare to this price 492 | 493 | **Returns:** 494 | 495 | The percentage of the compare price this price represents, or null. 496 | 497 | **Throws:** 498 | 499 | IllegalArgumentException - If the currencies are not comparable. 500 | 501 | --- 502 | 503 | ### prorate 504 | 505 | **Signature:** `static prorate(dist : Money, values : Money...) : Money[]` 506 | 507 | **Description:** Prorates the specified values using the specified discount. 508 | 509 | **Parameters:** 510 | 511 | - `dist`: the proration discount. 512 | - `values`: the values to prorate. 513 | 514 | **Returns:** 515 | 516 | the prorated values. 517 | 518 | --- 519 | 520 | ### subtract 521 | 522 | **Signature:** `subtract(value : Money) : Money` 523 | 524 | **Description:** Returns a new Money instance by substracting the specified Money object from the current object. Only objects representing the same currency can be subtracted. If one of the Money values is N/A, the result is N/A. 525 | 526 | **Parameters:** 527 | 528 | - `value`: the Money object to subtract 529 | 530 | **Returns:** 531 | 532 | the Money object representing the result of subtraction. 533 | 534 | --- 535 | 536 | ### subtractPercent 537 | 538 | **Signature:** `subtractPercent(percent : Number) : Money` 539 | 540 | **Description:** Subtracts a certain percentage from the money object. The percent value is given as true percent value, so for example 10 represent 10%. If this Money is N/A the result is also N/A. 541 | 542 | **Parameters:** 543 | 544 | - `percent`: the percent value 545 | 546 | **Returns:** 547 | 548 | new Money object with the result of the calculation 549 | 550 | --- 551 | 552 | ### subtractRate 553 | 554 | **Signature:** `subtractRate(value : Number) : Money` 555 | 556 | **Description:** Subtracts a rate (e.g. 0.05) from the money object. This is typically for example to subtract a tax rates. 557 | 558 | **Parameters:** 559 | 560 | - `value`: the rate to subtract. 561 | 562 | **Returns:** 563 | 564 | a new Money object with rate subtracted. 565 | 566 | --- 567 | 568 | ### toFormattedString 569 | 570 | **Signature:** `toFormattedString() : String` 571 | 572 | **Description:** Returns a string representation of Money according to the regional settings configured for current request locale, for example '$59.00' or 'USD 59.00'. 573 | 574 | **Returns:** 575 | 576 | The formatted String representation of the passed money. In case of an error the string 'N/A' is returned. 577 | 578 | --- 579 | 580 | ### toNumberString 581 | 582 | **Signature:** `toNumberString() : String` 583 | 584 | **Description:** Returns a string representation for the numeric value of this money. The number is formatted with the decimal symbols of the platforms default locale. 585 | 586 | **Returns:** 587 | 588 | a string representation for the numeric value of this money. 589 | 590 | --- 591 | 592 | ### toString 593 | 594 | **Signature:** `toString() : String` 595 | 596 | **Description:** Returns a string representation of this Money object. 597 | 598 | **Returns:** 599 | 600 | a string representation of this Money object. 601 | 602 | --- 603 | 604 | ### valueOf 605 | 606 | **Signature:** `valueOf() : Object` 607 | 608 | **Description:** According to the ECMA spec returns the "natural" primitve value. Here the value portion of the Money is returned. 609 | 610 | --- ``` -------------------------------------------------------------------------------- /docs/dw_customer/CustomerAddress.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.customer 2 | 3 | # Class CustomerAddress 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.object.PersistentObject 9 | - dw.object.ExtensibleObject 10 | - dw.customer.CustomerAddress 11 | 12 | ## Description 13 | 14 | The Address class represents a customer's address. Note: this class allows access to sensitive personal and private information. Pay attention to appropriate legal and regulatory requirements. 15 | 16 | ## Properties 17 | 18 | ### address1 19 | 20 | **Type:** String 21 | 22 | The customer's first address. 23 | 24 | ### address2 25 | 26 | **Type:** String 27 | 28 | The customer's second address value. 29 | 30 | ### city 31 | 32 | **Type:** String 33 | 34 | The customer's city. 35 | 36 | ### companyName 37 | 38 | **Type:** String 39 | 40 | The customer's company name. 41 | 42 | ### countryCode 43 | 44 | **Type:** EnumValue 45 | 46 | The customer's country code. Commerce Cloud Digital supports two-character 47 | country codes per ISO 3166-1 alpha-2. See 48 | http://www.iso.org/iso/country_codes/iso_3166-faqs/iso_3166_faqs_general.htm 49 | for additional information. 50 | 51 | ### firstName 52 | 53 | **Type:** String 54 | 55 | The customer's first name. 56 | 57 | ### fullName 58 | 59 | **Type:** String (Read Only) 60 | 61 | A concatenation of the customer's first, middle, 62 | and last names and its suffix. 63 | 64 | ### ID 65 | 66 | **Type:** String 67 | 68 | The name of the address. 69 | 70 | ### jobTitle 71 | 72 | **Type:** String 73 | 74 | The customer's job title. 75 | 76 | ### lastName 77 | 78 | **Type:** String 79 | 80 | The customer's last name. 81 | 82 | ### phone 83 | 84 | **Type:** String 85 | 86 | The customer's phone number. 87 | 88 | ### postalCode 89 | 90 | **Type:** String 91 | 92 | The customer's postal code. 93 | 94 | ### postBox 95 | 96 | **Type:** String 97 | 98 | The customer's post box. 99 | 100 | ### salutation 101 | 102 | **Type:** String 103 | 104 | The customer's salutation. 105 | 106 | ### secondName 107 | 108 | **Type:** String 109 | 110 | The customer's second name. 111 | 112 | ### stateCode 113 | 114 | **Type:** String 115 | 116 | The customer's state. 117 | 118 | ### suffix 119 | 120 | **Type:** String 121 | 122 | The customer's suffix. 123 | 124 | ### suite 125 | 126 | **Type:** String 127 | 128 | The customer's suite. 129 | 130 | ### title 131 | 132 | **Type:** String 133 | 134 | The customer's title. 135 | 136 | ## Constructor Summary 137 | 138 | ## Method Summary 139 | 140 | ### getAddress1 141 | 142 | **Signature:** `getAddress1() : String` 143 | 144 | Returns the customer's first address. 145 | 146 | ### getAddress2 147 | 148 | **Signature:** `getAddress2() : String` 149 | 150 | Returns the customer's second address value. 151 | 152 | ### getCity 153 | 154 | **Signature:** `getCity() : String` 155 | 156 | Returns the customer's city. 157 | 158 | ### getCompanyName 159 | 160 | **Signature:** `getCompanyName() : String` 161 | 162 | Returns the customer's company name. 163 | 164 | ### getCountryCode 165 | 166 | **Signature:** `getCountryCode() : EnumValue` 167 | 168 | Returns the customer's country code. 169 | 170 | ### getFirstName 171 | 172 | **Signature:** `getFirstName() : String` 173 | 174 | Returns the customer's first name. 175 | 176 | ### getFullName 177 | 178 | **Signature:** `getFullName() : String` 179 | 180 | Returns a concatenation of the customer's first, middle, and last names and its suffix. 181 | 182 | ### getID 183 | 184 | **Signature:** `getID() : String` 185 | 186 | Returns the name of the address. 187 | 188 | ### getJobTitle 189 | 190 | **Signature:** `getJobTitle() : String` 191 | 192 | Returns the customer's job title. 193 | 194 | ### getLastName 195 | 196 | **Signature:** `getLastName() : String` 197 | 198 | Returns the customer's last name. 199 | 200 | ### getPhone 201 | 202 | **Signature:** `getPhone() : String` 203 | 204 | Returns the customer's phone number. 205 | 206 | ### getPostalCode 207 | 208 | **Signature:** `getPostalCode() : String` 209 | 210 | Returns the customer's postal code. 211 | 212 | ### getPostBox 213 | 214 | **Signature:** `getPostBox() : String` 215 | 216 | Returns the customer's post box. 217 | 218 | ### getSalutation 219 | 220 | **Signature:** `getSalutation() : String` 221 | 222 | Returns the customer's salutation. 223 | 224 | ### getSecondName 225 | 226 | **Signature:** `getSecondName() : String` 227 | 228 | Returns the customer's second name. 229 | 230 | ### getStateCode 231 | 232 | **Signature:** `getStateCode() : String` 233 | 234 | Returns the customer's state. 235 | 236 | ### getSuffix 237 | 238 | **Signature:** `getSuffix() : String` 239 | 240 | Returns the customer's suffix. 241 | 242 | ### getSuite 243 | 244 | **Signature:** `getSuite() : String` 245 | 246 | Returns the customer's suite. 247 | 248 | ### getTitle 249 | 250 | **Signature:** `getTitle() : String` 251 | 252 | Returns the customer's title. 253 | 254 | ### isEquivalentAddress 255 | 256 | **Signature:** `isEquivalentAddress(address : Object) : boolean` 257 | 258 | Returns true if the specified address is equivalent to this address. 259 | 260 | ### setAddress1 261 | 262 | **Signature:** `setAddress1(value : String) : void` 263 | 264 | Sets the value of the customer's first address. 265 | 266 | ### setAddress2 267 | 268 | **Signature:** `setAddress2(value : String) : void` 269 | 270 | Sets the customer's second address value. 271 | 272 | ### setCity 273 | 274 | **Signature:** `setCity(city : String) : void` 275 | 276 | Sets the customer's city. 277 | 278 | ### setCompanyName 279 | 280 | **Signature:** `setCompanyName(companyName : String) : void` 281 | 282 | Sets the customer's company name. 283 | 284 | ### setCountryCode 285 | 286 | **Signature:** `setCountryCode(countryCode : String) : void` 287 | 288 | Sets the customer's country code. 289 | 290 | ### setFirstName 291 | 292 | **Signature:** `setFirstName(firstName : String) : void` 293 | 294 | Sets the customer's first name. 295 | 296 | ### setID 297 | 298 | **Signature:** `setID(value : String) : void` 299 | 300 | Sets the address name. 301 | 302 | ### setJobTitle 303 | 304 | **Signature:** `setJobTitle(jobTitle : String) : void` 305 | 306 | Sets the customer's job title. 307 | 308 | ### setLastName 309 | 310 | **Signature:** `setLastName(lastName : String) : void` 311 | 312 | Sets the customer's last name. 313 | 314 | ### setPhone 315 | 316 | **Signature:** `setPhone(phoneNumber : String) : void` 317 | 318 | Sets the customer's phone number. 319 | 320 | ### setPostalCode 321 | 322 | **Signature:** `setPostalCode(postalCode : String) : void` 323 | 324 | Sets the customer's postal code. 325 | 326 | ### setPostBox 327 | 328 | **Signature:** `setPostBox(postBox : String) : void` 329 | 330 | Sets the customer's post box. 331 | 332 | ### setSaluation 333 | 334 | **Signature:** `setSaluation(value : String) : void` 335 | 336 | Sets the customer's salutation. 337 | 338 | ### setSalutation 339 | 340 | **Signature:** `setSalutation(value : String) : void` 341 | 342 | Sets the customer's salutation. 343 | 344 | ### setSecondName 345 | 346 | **Signature:** `setSecondName(secondName : String) : void` 347 | 348 | Sets the customer's second name. 349 | 350 | ### setStateCode 351 | 352 | **Signature:** `setStateCode(state : String) : void` 353 | 354 | Sets the customer's state. 355 | 356 | ### setSuffix 357 | 358 | **Signature:** `setSuffix(suffix : String) : void` 359 | 360 | Sets the customer's suffix. 361 | 362 | ### setSuite 363 | 364 | **Signature:** `setSuite(value : String) : void` 365 | 366 | Sets the customer's suite. 367 | 368 | ### setTitle 369 | 370 | **Signature:** `setTitle(title : String) : void` 371 | 372 | Sets the customer's title. 373 | 374 | ## Method Detail 375 | 376 | ## Method Details 377 | 378 | ### getAddress1 379 | 380 | **Signature:** `getAddress1() : String` 381 | 382 | **Description:** Returns the customer's first address. 383 | 384 | **Returns:** 385 | 386 | the first address value. 387 | 388 | --- 389 | 390 | ### getAddress2 391 | 392 | **Signature:** `getAddress2() : String` 393 | 394 | **Description:** Returns the customer's second address value. 395 | 396 | **Returns:** 397 | 398 | the value of the second address. 399 | 400 | --- 401 | 402 | ### getCity 403 | 404 | **Signature:** `getCity() : String` 405 | 406 | **Description:** Returns the customer's city. 407 | 408 | **Returns:** 409 | 410 | the customer's city. 411 | 412 | --- 413 | 414 | ### getCompanyName 415 | 416 | **Signature:** `getCompanyName() : String` 417 | 418 | **Description:** Returns the customer's company name. 419 | 420 | **Returns:** 421 | 422 | the company name. 423 | 424 | --- 425 | 426 | ### getCountryCode 427 | 428 | **Signature:** `getCountryCode() : EnumValue` 429 | 430 | **Description:** Returns the customer's country code. Commerce Cloud Digital supports two-character country codes per ISO 3166-1 alpha-2. See http://www.iso.org/iso/country_codes/iso_3166-faqs/iso_3166_faqs_general.htm for additional information. 431 | 432 | **Returns:** 433 | 434 | the two-digit country code. 435 | 436 | --- 437 | 438 | ### getFirstName 439 | 440 | **Signature:** `getFirstName() : String` 441 | 442 | **Description:** Returns the customer's first name. 443 | 444 | **Returns:** 445 | 446 | the customer first name. 447 | 448 | --- 449 | 450 | ### getFullName 451 | 452 | **Signature:** `getFullName() : String` 453 | 454 | **Description:** Returns a concatenation of the customer's first, middle, and last names and its suffix. 455 | 456 | **Returns:** 457 | 458 | a concatenation of the customer's first, middle, and last names and its suffix. 459 | 460 | --- 461 | 462 | ### getID 463 | 464 | **Signature:** `getID() : String` 465 | 466 | **Description:** Returns the name of the address. 467 | 468 | **Returns:** 469 | 470 | the address name. 471 | 472 | --- 473 | 474 | ### getJobTitle 475 | 476 | **Signature:** `getJobTitle() : String` 477 | 478 | **Description:** Returns the customer's job title. 479 | 480 | **Returns:** 481 | 482 | the job title. 483 | 484 | --- 485 | 486 | ### getLastName 487 | 488 | **Signature:** `getLastName() : String` 489 | 490 | **Description:** Returns the customer's last name. 491 | 492 | **Returns:** 493 | 494 | the last name. 495 | 496 | --- 497 | 498 | ### getPhone 499 | 500 | **Signature:** `getPhone() : String` 501 | 502 | **Description:** Returns the customer's phone number. 503 | 504 | **Returns:** 505 | 506 | the phone number. 507 | 508 | --- 509 | 510 | ### getPostalCode 511 | 512 | **Signature:** `getPostalCode() : String` 513 | 514 | **Description:** Returns the customer's postal code. 515 | 516 | **Returns:** 517 | 518 | the postal code. 519 | 520 | --- 521 | 522 | ### getPostBox 523 | 524 | **Signature:** `getPostBox() : String` 525 | 526 | **Description:** Returns the customer's post box. 527 | 528 | **Returns:** 529 | 530 | the post box. 531 | 532 | --- 533 | 534 | ### getSalutation 535 | 536 | **Signature:** `getSalutation() : String` 537 | 538 | **Description:** Returns the customer's salutation. 539 | 540 | **Returns:** 541 | 542 | the salutation. 543 | 544 | --- 545 | 546 | ### getSecondName 547 | 548 | **Signature:** `getSecondName() : String` 549 | 550 | **Description:** Returns the customer's second name. 551 | 552 | **Returns:** 553 | 554 | the second name. 555 | 556 | --- 557 | 558 | ### getStateCode 559 | 560 | **Signature:** `getStateCode() : String` 561 | 562 | **Description:** Returns the customer's state. 563 | 564 | **Returns:** 565 | 566 | the state. 567 | 568 | --- 569 | 570 | ### getSuffix 571 | 572 | **Signature:** `getSuffix() : String` 573 | 574 | **Description:** Returns the customer's suffix. 575 | 576 | **Returns:** 577 | 578 | the suffix. 579 | 580 | --- 581 | 582 | ### getSuite 583 | 584 | **Signature:** `getSuite() : String` 585 | 586 | **Description:** Returns the customer's suite. 587 | 588 | **Returns:** 589 | 590 | the suite. 591 | 592 | --- 593 | 594 | ### getTitle 595 | 596 | **Signature:** `getTitle() : String` 597 | 598 | **Description:** Returns the customer's title. 599 | 600 | **Returns:** 601 | 602 | the title. 603 | 604 | --- 605 | 606 | ### isEquivalentAddress 607 | 608 | **Signature:** `isEquivalentAddress(address : Object) : boolean` 609 | 610 | **Description:** Returns true if the specified address is equivalent to this address. An equivalent address is an address whose core attributes contain the same values. The core attributes are: address1 address2 city companyName countryCode firstName lastName postalCode postBox stateCode 611 | 612 | **Parameters:** 613 | 614 | - `address`: the address to test. 615 | 616 | **Returns:** 617 | 618 | true if the specified address is equivalent to this address, false otherwise. 619 | 620 | --- 621 | 622 | ### setAddress1 623 | 624 | **Signature:** `setAddress1(value : String) : void` 625 | 626 | **Description:** Sets the value of the customer's first address. 627 | 628 | **Parameters:** 629 | 630 | - `value`: The value to set. 631 | 632 | --- 633 | 634 | ### setAddress2 635 | 636 | **Signature:** `setAddress2(value : String) : void` 637 | 638 | **Description:** Sets the customer's second address value. 639 | 640 | **Parameters:** 641 | 642 | - `value`: The value to set. 643 | 644 | --- 645 | 646 | ### setCity 647 | 648 | **Signature:** `setCity(city : String) : void` 649 | 650 | **Description:** Sets the customer's city. 651 | 652 | **Parameters:** 653 | 654 | - `city`: the customer's city to set. 655 | 656 | --- 657 | 658 | ### setCompanyName 659 | 660 | **Signature:** `setCompanyName(companyName : String) : void` 661 | 662 | **Description:** Sets the customer's company name. 663 | 664 | **Parameters:** 665 | 666 | - `companyName`: the name of the company. 667 | 668 | --- 669 | 670 | ### setCountryCode 671 | 672 | **Signature:** `setCountryCode(countryCode : String) : void` 673 | 674 | **Description:** Sets the customer's country code. Commerce Cloud Digital supports two-character country codes per ISO 3166-1 alpha-2. See http://www.iso.org/iso/country_codes/iso_3166-faqs/iso_3166_faqs_general.htm for additional information. 675 | 676 | **Parameters:** 677 | 678 | - `countryCode`: the country code, must be no more than 2 characters or will be truncated. 679 | 680 | --- 681 | 682 | ### setFirstName 683 | 684 | **Signature:** `setFirstName(firstName : String) : void` 685 | 686 | **Description:** Sets the customer's first name. 687 | 688 | **Parameters:** 689 | 690 | - `firstName`: the customer's first name to set. 691 | 692 | --- 693 | 694 | ### setID 695 | 696 | **Signature:** `setID(value : String) : void` 697 | 698 | **Description:** Sets the address name. 699 | 700 | **Parameters:** 701 | 702 | - `value`: the name to use. 703 | 704 | --- 705 | 706 | ### setJobTitle 707 | 708 | **Signature:** `setJobTitle(jobTitle : String) : void` 709 | 710 | **Description:** Sets the customer's job title. 711 | 712 | **Parameters:** 713 | 714 | - `jobTitle`: The jobTitle to set. 715 | 716 | --- 717 | 718 | ### setLastName 719 | 720 | **Signature:** `setLastName(lastName : String) : void` 721 | 722 | **Description:** Sets the customer's last name. 723 | 724 | **Parameters:** 725 | 726 | - `lastName`: The last name to set. 727 | 728 | --- 729 | 730 | ### setPhone 731 | 732 | **Signature:** `setPhone(phoneNumber : String) : void` 733 | 734 | **Description:** Sets the customer's phone number. The length is restricted to 32 characters. 735 | 736 | **Parameters:** 737 | 738 | - `phoneNumber`: The phone number to set. 739 | 740 | --- 741 | 742 | ### setPostalCode 743 | 744 | **Signature:** `setPostalCode(postalCode : String) : void` 745 | 746 | **Description:** Sets the customer's postal code. 747 | 748 | **Parameters:** 749 | 750 | - `postalCode`: The postal code to set. 751 | 752 | --- 753 | 754 | ### setPostBox 755 | 756 | **Signature:** `setPostBox(postBox : String) : void` 757 | 758 | **Description:** Sets the customer's post box. 759 | 760 | **Parameters:** 761 | 762 | - `postBox`: The post box to set. 763 | 764 | --- 765 | 766 | ### setSaluation 767 | 768 | **Signature:** `setSaluation(value : String) : void` 769 | 770 | **Description:** Sets the customer's salutation. 771 | 772 | **Deprecated:** 773 | 774 | Use setSalutation(String) 775 | 776 | **Parameters:** 777 | 778 | - `value`: the salutation. 779 | 780 | --- 781 | 782 | ### setSalutation 783 | 784 | **Signature:** `setSalutation(value : String) : void` 785 | 786 | **Description:** Sets the customer's salutation. 787 | 788 | **Parameters:** 789 | 790 | - `value`: the salutation. 791 | 792 | --- 793 | 794 | ### setSecondName 795 | 796 | **Signature:** `setSecondName(secondName : String) : void` 797 | 798 | **Description:** Sets the customer's second name. 799 | 800 | **Parameters:** 801 | 802 | - `secondName`: The second name to set. 803 | 804 | --- 805 | 806 | ### setStateCode 807 | 808 | **Signature:** `setStateCode(state : String) : void` 809 | 810 | **Description:** Sets the customer's state. 811 | 812 | **Parameters:** 813 | 814 | - `state`: The state to set. 815 | 816 | --- 817 | 818 | ### setSuffix 819 | 820 | **Signature:** `setSuffix(suffix : String) : void` 821 | 822 | **Description:** Sets the customer's suffix. 823 | 824 | **Parameters:** 825 | 826 | - `suffix`: The suffix to set. 827 | 828 | --- 829 | 830 | ### setSuite 831 | 832 | **Signature:** `setSuite(value : String) : void` 833 | 834 | **Description:** Sets the customer's suite. The length is restricted to 32 characters. 835 | 836 | **Parameters:** 837 | 838 | - `value`: the suite to set. 839 | 840 | --- 841 | 842 | ### setTitle 843 | 844 | **Signature:** `setTitle(title : String) : void` 845 | 846 | **Description:** Sets the customer's title. 847 | 848 | **Parameters:** 849 | 850 | - `title`: The title to set. 851 | 852 | --- ``` -------------------------------------------------------------------------------- /docs/dw_catalog/ProductAttributeModel.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.catalog 2 | 3 | # Class ProductAttributeModel 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.catalog.ProductAttributeModel 9 | 10 | ## Description 11 | 12 | Class representing the complete attribute model for products in the system. An instance of this class provides methods to access the attribute definitions and groups for the system object type 'Product' and perhaps additional information depending on how the instance is obtained. A ProductAttributeModel can be obtained in one of three ways: ProductAttributeModel(): When the no-arg constructor is used the model represents: the attribute groups of the system object type 'Product' (i.e. the global product attribute groups) and their bound attributes Category.getProductAttributeModel(): When the attribute model for a Category is retrieved, the model represents: the global product attribute groups product attribute groups of the calling category product attribute groups of any parent categories of the calling category Product.getAttributeModel(): When the attribute model for a Product is retrieved, the model represents: the global product attribute groups product attribute groups of the product's classification category product attribute groups of any parent categories of the product's classification category In this case, the model additionally provides access to the attribute values of the product. If the product lacks a classification category, then only the global product attribute group is considered by the model. The ProductAttributeModel provides a generic way to display the attribute values of a product on a product detail page organized into appropriate visual groups. This is typically done as follows: On the product detail page, call Product.getAttributeModel() to get the attribute model for the product. Call getVisibleAttributeGroups() to get the groups that are appropriate for this product and all other products assigned to the same classification category. Iterate the groups, and display each as a "group" in the UI. Call getVisibleAttributeDefinitions(ObjectAttributeGroup) for each group. Iterate and display the attribute names using ObjectAttributeDefinition.getDisplayName(). For each attribute, get the product's display value(s) for that attribute, using getDisplayValue(). This might require custom display logic based on the type of attribute (strings, dates, multi-value attributes, etc). 13 | 14 | ## Properties 15 | 16 | ### attributeGroups 17 | 18 | **Type:** Collection (Read Only) 19 | 20 | A sorted collection of attribute groups of this model. The groups 21 | returned depends on how this model is constructed and what it represents. 22 | (See class-level documentation for details). 23 | 24 | The collection of returned groups is sorted first by scope and secondly 25 | by explicit sort order. Global groups always appear before 26 | category-specific groups in the list. Groups of parent categories always 27 | appear before groups belonging to subcategories. At each scope, groups 28 | have an explicit sort order which can be managed within the Business 29 | Manager. 30 | 31 | When there are multiple attribute groups with the same ID, the following 32 | rules apply: 33 | 34 | 35 | If this model represents the global product attribute group only 36 | (e.g. the no-arg constructor was used), duplicates cannot occur since 37 | only one group can be defined with a given ID at that scope. 38 | If this model is associated with specific categories (e.g. it is 39 | constructed from a product with a classification category), then a 40 | category product attribute group might have the same ID as a global 41 | product attribute group. In this case, the category group overrides the 42 | global one. 43 | If a category and one of its ancestor categories both define a 44 | product attribute group with the same ID, the sub-category group 45 | overrides the parent group. 46 | 47 | 48 | As a result of these rules, this method will never return two attribute 49 | groups with the same ID. 50 | 51 | ### orderRequiredAttributeDefinitions 52 | 53 | **Type:** Collection (Read Only) 54 | 55 | An unsorted collection of attribute definitions marked as 56 | order-required. Order-required attributes are usually copied into order 57 | line items. 58 | 59 | The returned attribute definitions are sorted according to the explicit 60 | sort order defined for the attributes in the group. This is managed by 61 | merchant in the Business Manager. 62 | 63 | ### visibleAttributeGroups 64 | 65 | **Type:** Collection (Read Only) 66 | 67 | A sorted collection of visible attribute groups of this model. 68 | This method is similar to getAttributeGroups() but only includes 69 | attribute groups containing at least one attribute definition that is 70 | visible. See 71 | getVisibleAttributeDefinitions(ObjectAttributeGroup). 72 | 73 | ## Constructor Summary 74 | 75 | ProductAttributeModel() Constructs a product attribute model that is not based on a product nor a category. 76 | 77 | ## Method Summary 78 | 79 | ### getAttributeDefinition 80 | 81 | **Signature:** `getAttributeDefinition(id : String) : ObjectAttributeDefinition` 82 | 83 | Returns the attribute definition with the given id from the product attribute model. 84 | 85 | ### getAttributeDefinitions 86 | 87 | **Signature:** `getAttributeDefinitions(group : ObjectAttributeGroup) : Collection` 88 | 89 | Returns a sorted collection of attribute definitions for the given attribute group. 90 | 91 | ### getAttributeGroup 92 | 93 | **Signature:** `getAttributeGroup(id : String) : ObjectAttributeGroup` 94 | 95 | Returns the attribute group with the given id from the product attribute model. 96 | 97 | ### getAttributeGroups 98 | 99 | **Signature:** `getAttributeGroups() : Collection` 100 | 101 | Returns a sorted collection of attribute groups of this model. 102 | 103 | ### getDisplayValue 104 | 105 | **Signature:** `getDisplayValue(definition : ObjectAttributeDefinition) : Object` 106 | 107 | Returns the value that the underlying product defines for the given attribute definition in the current locale. 108 | 109 | ### getOrderRequiredAttributeDefinitions 110 | 111 | **Signature:** `getOrderRequiredAttributeDefinitions() : Collection` 112 | 113 | Returns an unsorted collection of attribute definitions marked as order-required. 114 | 115 | ### getValue 116 | 117 | **Signature:** `getValue(definition : ObjectAttributeDefinition) : Object` 118 | 119 | Returns the attribute value for the specified attribute definition. 120 | 121 | ### getVisibleAttributeDefinitions 122 | 123 | **Signature:** `getVisibleAttributeDefinitions(group : ObjectAttributeGroup) : Collection` 124 | 125 | Returns a sorted collection of all visible attribute definitions for the given attribute group. 126 | 127 | ### getVisibleAttributeGroups 128 | 129 | **Signature:** `getVisibleAttributeGroups() : Collection` 130 | 131 | Returns a sorted collection of visible attribute groups of this model. 132 | 133 | ## Constructor Detail 134 | 135 | ## Method Detail 136 | 137 | ## Method Details 138 | 139 | ### getAttributeDefinition 140 | 141 | **Signature:** `getAttributeDefinition(id : String) : ObjectAttributeDefinition` 142 | 143 | **Description:** Returns the attribute definition with the given id from the product attribute model. If attribute definition does not exist, null is returned. 144 | 145 | **Parameters:** 146 | 147 | - `id`: the identifier of the attribute definition. 148 | 149 | **Returns:** 150 | 151 | attribute definition or null if not exist 152 | 153 | --- 154 | 155 | ### getAttributeDefinitions 156 | 157 | **Signature:** `getAttributeDefinitions(group : ObjectAttributeGroup) : Collection` 158 | 159 | **Description:** Returns a sorted collection of attribute definitions for the given attribute group. If no attribute definition exist for the group, an empty collection is returned. The returned attribute definitions are sorted according to the explicit sort order defined for the attributes in the group. This is managed by merchant in the Business Manager. 160 | 161 | **Parameters:** 162 | 163 | - `group`: the group whose attribute definitions are returned. 164 | 165 | **Returns:** 166 | 167 | a sorted collection of ObjectAttributeDefinition instances. 168 | 169 | --- 170 | 171 | ### getAttributeGroup 172 | 173 | **Signature:** `getAttributeGroup(id : String) : ObjectAttributeGroup` 174 | 175 | **Description:** Returns the attribute group with the given id from the product attribute model. If attribute group does not exist, null is returned. 176 | 177 | **Parameters:** 178 | 179 | - `id`: the attribute group identifier. 180 | 181 | **Returns:** 182 | 183 | the attribute group or null if not exist 184 | 185 | --- 186 | 187 | ### getAttributeGroups 188 | 189 | **Signature:** `getAttributeGroups() : Collection` 190 | 191 | **Description:** Returns a sorted collection of attribute groups of this model. The groups returned depends on how this model is constructed and what it represents. (See class-level documentation for details). The collection of returned groups is sorted first by scope and secondly by explicit sort order. Global groups always appear before category-specific groups in the list. Groups of parent categories always appear before groups belonging to subcategories. At each scope, groups have an explicit sort order which can be managed within the Business Manager. When there are multiple attribute groups with the same ID, the following rules apply: If this model represents the global product attribute group only (e.g. the no-arg constructor was used), duplicates cannot occur since only one group can be defined with a given ID at that scope. If this model is associated with specific categories (e.g. it is constructed from a product with a classification category), then a category product attribute group might have the same ID as a global product attribute group. In this case, the category group overrides the global one. If a category and one of its ancestor categories both define a product attribute group with the same ID, the sub-category group overrides the parent group. As a result of these rules, this method will never return two attribute groups with the same ID. 192 | 193 | **Returns:** 194 | 195 | collection of all attribute groups. 196 | 197 | --- 198 | 199 | ### getDisplayValue 200 | 201 | **Signature:** `getDisplayValue(definition : ObjectAttributeDefinition) : Object` 202 | 203 | **Description:** Returns the value that the underlying product defines for the given attribute definition in the current locale. In case the attribute definition defines localized attribute values, the product's value is used as an id to find the localized display value. In case of an Image attribute this method returns a MediaFile instance. In previous versions this method returned a String with the image path. In case of an HTML attribute this method returns a MarkupText instance. In previous versions this method returned a String with the HTML source. 204 | 205 | **API Versioned:** 206 | 207 | From version 10.6. In prior versions this method returned a String with the image path or a String with the HTML source 208 | 209 | **Parameters:** 210 | 211 | - `definition`: the definition to use. 212 | 213 | **Returns:** 214 | 215 | The localized product attribute display value. 216 | 217 | --- 218 | 219 | ### getOrderRequiredAttributeDefinitions 220 | 221 | **Signature:** `getOrderRequiredAttributeDefinitions() : Collection` 222 | 223 | **Description:** Returns an unsorted collection of attribute definitions marked as order-required. Order-required attributes are usually copied into order line items. The returned attribute definitions are sorted according to the explicit sort order defined for the attributes in the group. This is managed by merchant in the Business Manager. 224 | 225 | **Returns:** 226 | 227 | a collection of order-required ObjectAttributeDefinition instances. 228 | 229 | --- 230 | 231 | ### getValue 232 | 233 | **Signature:** `getValue(definition : ObjectAttributeDefinition) : Object` 234 | 235 | **Description:** Returns the attribute value for the specified attribute definition. If the product does not define a value, null is returned. Note: this method may only be used where the attribute model was created for a specific product; otherwise it will always return null. If the attribute is localized, the value for the current session locale is returned. In case of an Image attribute this method returns a MediaFile instance. In previous versions this method returned a String with the image path. In case of an HTML attribute this method returns a MarkupText instance. In previous versions this method returned a String with the HTML source. 236 | 237 | **API Versioned:** 238 | 239 | From version 10.6. In prior versions this method returned a String with the image path or a String with the HTML source. 240 | 241 | **Parameters:** 242 | 243 | - `definition`: the attribute definition to use when locating and returning the value. 244 | 245 | **Returns:** 246 | 247 | value the value associated with the object attribute definition. 248 | 249 | --- 250 | 251 | ### getVisibleAttributeDefinitions 252 | 253 | **Signature:** `getVisibleAttributeDefinitions(group : ObjectAttributeGroup) : Collection` 254 | 255 | **Description:** Returns a sorted collection of all visible attribute definitions for the given attribute group. If no visible attribute definition exist for the group, an empty collection is returned. An attribute definition is considered visible if is marked as visible. If the product attribute model is created for a specific product, the product must also define a value for the attribute definition; else the attribute definition is considered as invisible. The returned attribute definitions are sorted according to the explicit sort order defined for the attributes in the group. This is managed by merchant in the Business Manager. 256 | 257 | **Parameters:** 258 | 259 | - `group`: the group whose visible attribute definitions are returned. 260 | 261 | **Returns:** 262 | 263 | a sorted collection of visible ObjectAttributeDefinition instances. 264 | 265 | --- 266 | 267 | ### getVisibleAttributeGroups 268 | 269 | **Signature:** `getVisibleAttributeGroups() : Collection` 270 | 271 | **Description:** Returns a sorted collection of visible attribute groups of this model. This method is similar to getAttributeGroups() but only includes attribute groups containing at least one attribute definition that is visible. See getVisibleAttributeDefinitions(ObjectAttributeGroup). 272 | 273 | **Returns:** 274 | 275 | sorted collection of visible ObjectAttributeGroup instances. 276 | 277 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/get-sfra-document.docs-only.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | description: "Test get_sfra_document tool for retrieving SFRA documentation" 2 | tests: 3 | # Smoke test - ensure tool is available and accessible 4 | - it: "should be available in tools list" 5 | request: 6 | jsonrpc: "2.0" 7 | id: "list-sfra-document-tool" 8 | method: "tools/list" 9 | params: {} 10 | expect: 11 | response: 12 | jsonrpc: "2.0" 13 | id: "list-sfra-document-tool" 14 | result: 15 | tools: 16 | match:arrayContains:name:get_sfra_document 17 | stderr: "toBeEmpty" 18 | 19 | # Valid document tests - Core SFRA classes 20 | - it: "should retrieve server document successfully" 21 | request: 22 | jsonrpc: "2.0" 23 | id: "get-server-doc" 24 | method: "tools/call" 25 | params: 26 | name: "get_sfra_document" 27 | arguments: 28 | documentName: "server" 29 | expect: 30 | response: 31 | jsonrpc: "2.0" 32 | id: "get-server-doc" 33 | result: 34 | content: 35 | - type: "text" 36 | text: "match:contains:Class Server" 37 | isError: false 38 | performance: 39 | maxResponseTime: "2000ms" 40 | stderr: "toBeEmpty" 41 | 42 | - it: "should retrieve request document successfully" 43 | request: 44 | jsonrpc: "2.0" 45 | id: "get-request-doc" 46 | method: "tools/call" 47 | params: 48 | name: "get_sfra_document" 49 | arguments: 50 | documentName: "request" 51 | expect: 52 | response: 53 | jsonrpc: "2.0" 54 | id: "get-request-doc" 55 | result: 56 | content: 57 | - type: "text" 58 | text: "match:contains:Class Request" 59 | isError: false 60 | performance: 61 | maxResponseTime: "2000ms" 62 | stderr: "toBeEmpty" 63 | 64 | - it: "should retrieve response document successfully" 65 | request: 66 | jsonrpc: "2.0" 67 | id: "get-response-doc" 68 | method: "tools/call" 69 | params: 70 | name: "get_sfra_document" 71 | arguments: 72 | documentName: "response" 73 | expect: 74 | response: 75 | jsonrpc: "2.0" 76 | id: "get-response-doc" 77 | result: 78 | content: 79 | - type: "text" 80 | text: "match:contains:Class Response" 81 | isError: false 82 | performance: 83 | maxResponseTime: "2000ms" 84 | stderr: "toBeEmpty" 85 | 86 | - it: "should retrieve querystring document successfully" 87 | request: 88 | jsonrpc: "2.0" 89 | id: "get-querystring-doc" 90 | method: "tools/call" 91 | params: 92 | name: "get_sfra_document" 93 | arguments: 94 | documentName: "querystring" 95 | expect: 96 | response: 97 | jsonrpc: "2.0" 98 | id: "get-querystring-doc" 99 | result: 100 | content: 101 | - type: "text" 102 | text: "match:contains:QueryString" 103 | isError: false 104 | performance: 105 | maxResponseTime: "2000ms" 106 | stderr: "toBeEmpty" 107 | 108 | - it: "should retrieve render document successfully" 109 | request: 110 | jsonrpc: "2.0" 111 | id: "get-render-doc" 112 | method: "tools/call" 113 | params: 114 | name: "get_sfra_document" 115 | arguments: 116 | documentName: "render" 117 | expect: 118 | response: 119 | jsonrpc: "2.0" 120 | id: "get-render-doc" 121 | result: 122 | content: 123 | - type: "text" 124 | text: "match:contains:render" 125 | isError: false 126 | performance: 127 | maxResponseTime: "2000ms" 128 | stderr: "toBeEmpty" 129 | 130 | # Product model tests 131 | - it: "should retrieve product-full document successfully" 132 | request: 133 | jsonrpc: "2.0" 134 | id: "get-product-full-doc" 135 | method: "tools/call" 136 | params: 137 | name: "get_sfra_document" 138 | arguments: 139 | documentName: "product-full" 140 | expect: 141 | response: 142 | jsonrpc: "2.0" 143 | id: "get-product-full-doc" 144 | result: 145 | content: 146 | - type: "text" 147 | text: "match:contains:product" 148 | isError: false 149 | performance: 150 | maxResponseTime: "2000ms" 151 | stderr: "toBeEmpty" 152 | 153 | - it: "should retrieve cart document successfully" 154 | request: 155 | jsonrpc: "2.0" 156 | id: "get-cart-doc" 157 | method: "tools/call" 158 | params: 159 | name: "get_sfra_document" 160 | arguments: 161 | documentName: "cart" 162 | expect: 163 | response: 164 | jsonrpc: "2.0" 165 | id: "get-cart-doc" 166 | result: 167 | content: 168 | - type: "text" 169 | text: "match:contains:cart" 170 | isError: false 171 | performance: 172 | maxResponseTime: "2000ms" 173 | stderr: "toBeEmpty" 174 | 175 | # Customer model tests 176 | - it: "should retrieve account document successfully" 177 | request: 178 | jsonrpc: "2.0" 179 | id: "get-account-doc" 180 | method: "tools/call" 181 | params: 182 | name: "get_sfra_document" 183 | arguments: 184 | documentName: "account" 185 | expect: 186 | response: 187 | jsonrpc: "2.0" 188 | id: "get-account-doc" 189 | result: 190 | content: 191 | - type: "text" 192 | text: "match:contains:account" 193 | isError: false 194 | performance: 195 | maxResponseTime: "2000ms" 196 | stderr: "toBeEmpty" 197 | 198 | # Response format validation tests 199 | - it: "should return properly structured JSON content" 200 | request: 201 | jsonrpc: "2.0" 202 | id: "validate-server-structure" 203 | method: "tools/call" 204 | params: 205 | name: "get_sfra_document" 206 | arguments: 207 | documentName: "server" 208 | expect: 209 | response: 210 | jsonrpc: "2.0" 211 | id: "validate-server-structure" 212 | result: 213 | content: 214 | - type: "text" 215 | text: "match:regex:\\{[\\s\\S]*title[\\s\\S]*sections[\\s\\S]*content[\\s\\S]*\\}" 216 | isError: false 217 | stderr: "toBeEmpty" 218 | 219 | - it: "should include document metadata" 220 | request: 221 | jsonrpc: "2.0" 222 | id: "validate-metadata" 223 | method: "tools/call" 224 | params: 225 | name: "get_sfra_document" 226 | arguments: 227 | documentName: "server" 228 | expect: 229 | response: 230 | jsonrpc: "2.0" 231 | id: "validate-metadata" 232 | result: 233 | content: 234 | - type: "text" 235 | text: "match:regex:[\\s\\S]*type[\\s\\S]*category[\\s\\S]*filename[\\s\\S]*lastModified[\\s\\S]*" 236 | isError: false 237 | stderr: "toBeEmpty" 238 | 239 | - it: "should include sections array" 240 | request: 241 | jsonrpc: "2.0" 242 | id: "validate-sections" 243 | method: "tools/call" 244 | params: 245 | name: "get_sfra_document" 246 | arguments: 247 | documentName: "server" 248 | expect: 249 | response: 250 | jsonrpc: "2.0" 251 | id: "validate-sections" 252 | result: 253 | content: 254 | - type: "text" 255 | text: "match:regex:[\\s\\S]*sections[\\s\\S]*\\[[\\s\\S]*\\][\\s\\S]*" 256 | isError: false 257 | stderr: "toBeEmpty" 258 | 259 | - it: "should include comprehensive content" 260 | request: 261 | jsonrpc: "2.0" 262 | id: "validate-content-detail" 263 | method: "tools/call" 264 | params: 265 | name: "get_sfra_document" 266 | arguments: 267 | documentName: "server" 268 | expect: 269 | response: 270 | jsonrpc: "2.0" 271 | id: "validate-content-detail" 272 | result: 273 | content: 274 | - type: "text" 275 | text: "match:regex:[\\s\\S]*Description[\\s\\S]*Method Summary[\\s\\S]*Method Detail[\\s\\S]*" 276 | isError: false 277 | stderr: "toBeEmpty" 278 | 279 | # Error handling tests 280 | - it: "should handle nonexistent document gracefully" 281 | request: 282 | jsonrpc: "2.0" 283 | id: "error-nonexistent" 284 | method: "tools/call" 285 | params: 286 | name: "get_sfra_document" 287 | arguments: 288 | documentName: "nonexistent-document" 289 | expect: 290 | response: 291 | jsonrpc: "2.0" 292 | id: "error-nonexistent" 293 | result: 294 | content: 295 | - type: "text" 296 | text: "match:contains:not found" 297 | isError: true 298 | stderr: "toBeEmpty" 299 | 300 | - it: "should handle empty document name" 301 | request: 302 | jsonrpc: "2.0" 303 | id: "error-empty-name" 304 | method: "tools/call" 305 | params: 306 | name: "get_sfra_document" 307 | arguments: 308 | documentName: "" 309 | expect: 310 | response: 311 | jsonrpc: "2.0" 312 | id: "error-empty-name" 313 | result: 314 | content: 315 | - type: "text" 316 | text: "match:regex:(Error|not found|invalid)" 317 | isError: true 318 | stderr: "toBeEmpty" 319 | 320 | - it: "should handle invalid document name characters" 321 | request: 322 | jsonrpc: "2.0" 323 | id: "error-invalid-chars" 324 | method: "tools/call" 325 | params: 326 | name: "get_sfra_document" 327 | arguments: 328 | documentName: "invalid/document/name" 329 | expect: 330 | response: 331 | jsonrpc: "2.0" 332 | id: "error-invalid-chars" 333 | result: 334 | content: 335 | - type: "text" 336 | text: "match:regex:(Error|not found|invalid)" 337 | isError: true 338 | stderr: "toBeEmpty" 339 | 340 | - it: "should handle missing documentName parameter" 341 | request: 342 | jsonrpc: "2.0" 343 | id: "error-missing-param" 344 | method: "tools/call" 345 | params: 346 | name: "get_sfra_document" 347 | arguments: {} 348 | expect: 349 | response: 350 | jsonrpc: "2.0" 351 | id: "error-missing-param" 352 | result: 353 | content: 354 | - type: "text" 355 | text: "match:regex:(Error|required|missing|documentName|non-empty string)" 356 | isError: true 357 | stderr: "toBeEmpty" 358 | 359 | # Case sensitivity tests - it appears the tool is case-insensitive 360 | - it: "should handle case variations for document names" 361 | request: 362 | jsonrpc: "2.0" 363 | id: "case-insensitive-upper" 364 | method: "tools/call" 365 | params: 366 | name: "get_sfra_document" 367 | arguments: 368 | documentName: "SERVER" 369 | expect: 370 | response: 371 | jsonrpc: "2.0" 372 | id: "case-insensitive-upper" 373 | result: 374 | content: 375 | - type: "text" 376 | text: "match:contains:Class Server" 377 | isError: false 378 | stderr: "toBeEmpty" 379 | 380 | - it: "should handle mixed case document names" 381 | request: 382 | jsonrpc: "2.0" 383 | id: "case-insensitive-mixed" 384 | method: "tools/call" 385 | params: 386 | name: "get_sfra_document" 387 | arguments: 388 | documentName: "Server" 389 | expect: 390 | response: 391 | jsonrpc: "2.0" 392 | id: "case-insensitive-mixed" 393 | result: 394 | content: 395 | - type: "text" 396 | text: "match:contains:Class Server" 397 | isError: false 398 | stderr: "toBeEmpty" 399 | 400 | # Content quality tests 401 | - it: "should provide meaningful content for server document" 402 | request: 403 | jsonrpc: "2.0" 404 | id: "content-quality-server" 405 | method: "tools/call" 406 | params: 407 | name: "get_sfra_document" 408 | arguments: 409 | documentName: "server" 410 | expect: 411 | response: 412 | jsonrpc: "2.0" 413 | id: "content-quality-server" 414 | result: 415 | content: 416 | - type: "text" 417 | text: "match:regex:[\\s\\S]*middleware[\\s\\S]*routing[\\s\\S]*HTTP[\\s\\S]*" 418 | isError: false 419 | stderr: "toBeEmpty" 420 | 421 | - it: "should provide meaningful content for request document" 422 | request: 423 | jsonrpc: "2.0" 424 | id: "content-quality-request" 425 | method: "tools/call" 426 | params: 427 | name: "get_sfra_document" 428 | arguments: 429 | documentName: "request" 430 | expect: 431 | response: 432 | jsonrpc: "2.0" 433 | id: "content-quality-request" 434 | result: 435 | content: 436 | - type: "text" 437 | text: "match:regex:[\\s\\S]*HTTP[\\s\\S]*session[\\s\\S]*customer[\\s\\S]*" 438 | isError: false 439 | stderr: "toBeEmpty" 440 | 441 | # Additional model document tests 442 | - it: "should retrieve billing document successfully" 443 | request: 444 | jsonrpc: "2.0" 445 | id: "get-billing-doc" 446 | method: "tools/call" 447 | params: 448 | name: "get_sfra_document" 449 | arguments: 450 | documentName: "billing" 451 | expect: 452 | response: 453 | jsonrpc: "2.0" 454 | id: "get-billing-doc" 455 | result: 456 | content: 457 | - type: "text" 458 | text: "match:contains:billing" 459 | isError: false 460 | performance: 461 | maxResponseTime: "2000ms" 462 | stderr: "toBeEmpty" 463 | 464 | - it: "should retrieve shipping document successfully" 465 | request: 466 | jsonrpc: "2.0" 467 | id: "get-shipping-doc" 468 | method: "tools/call" 469 | params: 470 | name: "get_sfra_document" 471 | arguments: 472 | documentName: "shipping" 473 | expect: 474 | response: 475 | jsonrpc: "2.0" 476 | id: "get-shipping-doc" 477 | result: 478 | content: 479 | - type: "text" 480 | text: "match:contains:shipping" 481 | isError: false 482 | performance: 483 | maxResponseTime: "2000ms" 484 | stderr: "toBeEmpty" 485 | 486 | # Edge case tests 487 | - it: "should handle document names with hyphens" 488 | request: 489 | jsonrpc: "2.0" 490 | id: "hyphen-document" 491 | method: "tools/call" 492 | params: 493 | name: "get_sfra_document" 494 | arguments: 495 | documentName: "product-full" 496 | expect: 497 | response: 498 | jsonrpc: "2.0" 499 | id: "hyphen-document" 500 | result: 501 | content: 502 | - type: "text" 503 | text: "match:type:string" 504 | isError: false 505 | stderr: "toBeEmpty" 506 | 507 | - it: "should handle very long nonexistent document names" 508 | request: 509 | jsonrpc: "2.0" 510 | id: "long-nonexistent" 511 | method: "tools/call" 512 | params: 513 | name: "get_sfra_document" 514 | arguments: 515 | documentName: "this-is-a-very-long-document-name-that-definitely-does-not-exist-anywhere" 516 | expect: 517 | response: 518 | jsonrpc: "2.0" 519 | id: "long-nonexistent" 520 | result: 521 | content: 522 | - type: "text" 523 | text: "match:regex:(Error|not found)" 524 | isError: true 525 | stderr: "toBeEmpty" 526 | ```