This is page 7 of 61. Use http://codebase.md/taurgis/sfcc-dev-mcp?lines=true&page={x} to view the full context.
# Directory Structure
```
├── .DS_Store
├── .github
│ ├── dependabot.yml
│ ├── instructions
│ │ ├── mcp-node-tests.instructions.md
│ │ └── mcp-yml-tests.instructions.md
│ ├── ISSUE_TEMPLATE
│ │ ├── bug_report.yml
│ │ ├── config.yml
│ │ ├── documentation.yml
│ │ ├── feature_request.yml
│ │ └── question.yml
│ ├── PULL_REQUEST_TEMPLATE
│ │ ├── bug_fix.md
│ │ ├── documentation.md
│ │ └── new_tool.md
│ ├── pull_request_template.md
│ └── workflows
│ ├── ci.yml
│ ├── deploy-pages.yml
│ ├── publish.yml
│ └── update-docs.yml
├── .gitignore
├── .husky
│ └── pre-commit
├── aegis.config.docs-only.json
├── aegis.config.json
├── aegis.config.with-dw.json
├── AGENTS.md
├── ai-instructions
│ ├── claude-desktop
│ │ └── claude_custom_instructions.md
│ ├── cursor
│ │ └── .cursor
│ │ └── rules
│ │ ├── debugging-workflows.mdc
│ │ ├── hooks-development.mdc
│ │ ├── isml-templates.mdc
│ │ ├── job-framework.mdc
│ │ ├── performance-optimization.mdc
│ │ ├── scapi-endpoints.mdc
│ │ ├── security-patterns.mdc
│ │ ├── sfcc-development.mdc
│ │ ├── sfra-controllers.mdc
│ │ ├── sfra-models.mdc
│ │ ├── system-objects.mdc
│ │ └── testing-patterns.mdc
│ └── github-copilot
│ └── copilot-instructions.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── docs
│ ├── best-practices
│ │ ├── cartridge_creation.md
│ │ ├── isml_templates.md
│ │ ├── job_framework.md
│ │ ├── localserviceregistry.md
│ │ ├── ocapi_hooks.md
│ │ ├── performance.md
│ │ ├── scapi_custom_endpoint.md
│ │ ├── scapi_hooks.md
│ │ ├── security.md
│ │ ├── sfra_client_side_js.md
│ │ ├── sfra_controllers.md
│ │ ├── sfra_models.md
│ │ └── sfra_scss.md
│ ├── dw_campaign
│ │ ├── ABTest.md
│ │ ├── ABTestMgr.md
│ │ ├── ABTestSegment.md
│ │ ├── AmountDiscount.md
│ │ ├── ApproachingDiscount.md
│ │ ├── BonusChoiceDiscount.md
│ │ ├── BonusDiscount.md
│ │ ├── Campaign.md
│ │ ├── CampaignMgr.md
│ │ ├── CampaignStatusCodes.md
│ │ ├── Coupon.md
│ │ ├── CouponMgr.md
│ │ ├── CouponRedemption.md
│ │ ├── CouponStatusCodes.md
│ │ ├── Discount.md
│ │ ├── DiscountPlan.md
│ │ ├── FixedPriceDiscount.md
│ │ ├── FixedPriceShippingDiscount.md
│ │ ├── FreeDiscount.md
│ │ ├── FreeShippingDiscount.md
│ │ ├── PercentageDiscount.md
│ │ ├── PercentageOptionDiscount.md
│ │ ├── PriceBookPriceDiscount.md
│ │ ├── Promotion.md
│ │ ├── PromotionMgr.md
│ │ ├── PromotionPlan.md
│ │ ├── SlotContent.md
│ │ ├── SourceCodeGroup.md
│ │ ├── SourceCodeInfo.md
│ │ ├── SourceCodeStatusCodes.md
│ │ └── TotalFixedPriceDiscount.md
│ ├── dw_catalog
│ │ ├── Catalog.md
│ │ ├── CatalogMgr.md
│ │ ├── Category.md
│ │ ├── CategoryAssignment.md
│ │ ├── CategoryLink.md
│ │ ├── PriceBook.md
│ │ ├── PriceBookMgr.md
│ │ ├── Product.md
│ │ ├── ProductActiveData.md
│ │ ├── ProductAttributeModel.md
│ │ ├── ProductAvailabilityLevels.md
│ │ ├── ProductAvailabilityModel.md
│ │ ├── ProductInventoryList.md
│ │ ├── ProductInventoryMgr.md
│ │ ├── ProductInventoryRecord.md
│ │ ├── ProductLink.md
│ │ ├── ProductMgr.md
│ │ ├── ProductOption.md
│ │ ├── ProductOptionModel.md
│ │ ├── ProductOptionValue.md
│ │ ├── ProductPriceInfo.md
│ │ ├── ProductPriceModel.md
│ │ ├── ProductPriceTable.md
│ │ ├── ProductSearchHit.md
│ │ ├── ProductSearchModel.md
│ │ ├── ProductSearchRefinementDefinition.md
│ │ ├── ProductSearchRefinements.md
│ │ ├── ProductSearchRefinementValue.md
│ │ ├── ProductVariationAttribute.md
│ │ ├── ProductVariationAttributeValue.md
│ │ ├── ProductVariationModel.md
│ │ ├── Recommendation.md
│ │ ├── SearchModel.md
│ │ ├── SearchRefinementDefinition.md
│ │ ├── SearchRefinements.md
│ │ ├── SearchRefinementValue.md
│ │ ├── SortingOption.md
│ │ ├── SortingRule.md
│ │ ├── Store.md
│ │ ├── StoreGroup.md
│ │ ├── StoreInventoryFilter.md
│ │ ├── StoreInventoryFilterValue.md
│ │ ├── StoreMgr.md
│ │ ├── Variant.md
│ │ └── VariationGroup.md
│ ├── dw_content
│ │ ├── Content.md
│ │ ├── ContentMgr.md
│ │ ├── ContentSearchModel.md
│ │ ├── ContentSearchRefinementDefinition.md
│ │ ├── ContentSearchRefinements.md
│ │ ├── ContentSearchRefinementValue.md
│ │ ├── Folder.md
│ │ ├── Library.md
│ │ ├── MarkupText.md
│ │ └── MediaFile.md
│ ├── dw_crypto
│ │ ├── CertificateRef.md
│ │ ├── CertificateUtils.md
│ │ ├── Cipher.md
│ │ ├── Encoding.md
│ │ ├── JWE.md
│ │ ├── JWEHeader.md
│ │ ├── JWS.md
│ │ ├── JWSHeader.md
│ │ ├── KeyRef.md
│ │ ├── Mac.md
│ │ ├── MessageDigest.md
│ │ ├── SecureRandom.md
│ │ ├── Signature.md
│ │ ├── WeakCipher.md
│ │ ├── WeakMac.md
│ │ ├── WeakMessageDigest.md
│ │ ├── WeakSignature.md
│ │ └── X509Certificate.md
│ ├── dw_customer
│ │ ├── AddressBook.md
│ │ ├── AgentUserMgr.md
│ │ ├── AgentUserStatusCodes.md
│ │ ├── AuthenticationStatus.md
│ │ ├── Credentials.md
│ │ ├── Customer.md
│ │ ├── CustomerActiveData.md
│ │ ├── CustomerAddress.md
│ │ ├── CustomerCDPData.md
│ │ ├── CustomerContextMgr.md
│ │ ├── CustomerGroup.md
│ │ ├── CustomerList.md
│ │ ├── CustomerMgr.md
│ │ ├── CustomerPasswordConstraints.md
│ │ ├── CustomerPaymentInstrument.md
│ │ ├── CustomerStatusCodes.md
│ │ ├── EncryptedObject.md
│ │ ├── ExternalProfile.md
│ │ ├── OrderHistory.md
│ │ ├── ProductList.md
│ │ ├── ProductListItem.md
│ │ ├── ProductListItemPurchase.md
│ │ ├── ProductListMgr.md
│ │ ├── ProductListRegistrant.md
│ │ ├── Profile.md
│ │ └── Wallet.md
│ ├── dw_extensions.applepay
│ │ ├── ApplePayHookResult.md
│ │ └── ApplePayHooks.md
│ ├── dw_extensions.facebook
│ │ ├── FacebookFeedHooks.md
│ │ └── FacebookProduct.md
│ ├── dw_extensions.paymentrequest
│ │ ├── PaymentRequestHookResult.md
│ │ └── PaymentRequestHooks.md
│ ├── dw_extensions.payments
│ │ ├── SalesforceBancontactPaymentDetails.md
│ │ ├── SalesforceCardPaymentDetails.md
│ │ ├── SalesforceEpsPaymentDetails.md
│ │ ├── SalesforceIdealPaymentDetails.md
│ │ ├── SalesforceKlarnaPaymentDetails.md
│ │ ├── SalesforcePaymentDetails.md
│ │ ├── SalesforcePaymentIntent.md
│ │ ├── SalesforcePaymentMethod.md
│ │ ├── SalesforcePaymentRequest.md
│ │ ├── SalesforcePaymentsHooks.md
│ │ ├── SalesforcePaymentsMgr.md
│ │ ├── SalesforcePaymentsSiteConfiguration.md
│ │ ├── SalesforcePayPalOrder.md
│ │ ├── SalesforcePayPalOrderAddress.md
│ │ ├── SalesforcePayPalOrderPayer.md
│ │ ├── SalesforcePayPalPaymentDetails.md
│ │ ├── SalesforceSepaDebitPaymentDetails.md
│ │ └── SalesforceVenmoPaymentDetails.md
│ ├── dw_extensions.pinterest
│ │ ├── PinterestAvailability.md
│ │ ├── PinterestFeedHooks.md
│ │ ├── PinterestOrder.md
│ │ ├── PinterestOrderHooks.md
│ │ └── PinterestProduct.md
│ ├── dw_io
│ │ ├── CSVStreamReader.md
│ │ ├── CSVStreamWriter.md
│ │ ├── File.md
│ │ ├── FileReader.md
│ │ ├── FileWriter.md
│ │ ├── InputStream.md
│ │ ├── OutputStream.md
│ │ ├── PrintWriter.md
│ │ ├── RandomAccessFileReader.md
│ │ ├── Reader.md
│ │ ├── StringWriter.md
│ │ ├── Writer.md
│ │ ├── XMLIndentingStreamWriter.md
│ │ ├── XMLStreamConstants.md
│ │ ├── XMLStreamReader.md
│ │ └── XMLStreamWriter.md
│ ├── dw_job
│ │ ├── JobExecution.md
│ │ └── JobStepExecution.md
│ ├── dw_net
│ │ ├── FTPClient.md
│ │ ├── FTPFileInfo.md
│ │ ├── HTTPClient.md
│ │ ├── HTTPRequestPart.md
│ │ ├── Mail.md
│ │ ├── SFTPClient.md
│ │ ├── SFTPFileInfo.md
│ │ ├── WebDAVClient.md
│ │ └── WebDAVFileInfo.md
│ ├── dw_object
│ │ ├── ActiveData.md
│ │ ├── CustomAttributes.md
│ │ ├── CustomObject.md
│ │ ├── CustomObjectMgr.md
│ │ ├── Extensible.md
│ │ ├── ExtensibleObject.md
│ │ ├── Note.md
│ │ ├── ObjectAttributeDefinition.md
│ │ ├── ObjectAttributeGroup.md
│ │ ├── ObjectAttributeValueDefinition.md
│ │ ├── ObjectTypeDefinition.md
│ │ ├── PersistentObject.md
│ │ ├── SimpleExtensible.md
│ │ └── SystemObjectMgr.md
│ ├── dw_order
│ │ ├── AbstractItem.md
│ │ ├── AbstractItemCtnr.md
│ │ ├── Appeasement.md
│ │ ├── AppeasementItem.md
│ │ ├── Basket.md
│ │ ├── BasketMgr.md
│ │ ├── BonusDiscountLineItem.md
│ │ ├── CouponLineItem.md
│ │ ├── CreateAgentBasketLimitExceededException.md
│ │ ├── CreateBasketFromOrderException.md
│ │ ├── CreateCouponLineItemException.md
│ │ ├── CreateOrderException.md
│ │ ├── CreateTemporaryBasketLimitExceededException.md
│ │ ├── GiftCertificate.md
│ │ ├── GiftCertificateLineItem.md
│ │ ├── GiftCertificateMgr.md
│ │ ├── GiftCertificateStatusCodes.md
│ │ ├── Invoice.md
│ │ ├── InvoiceItem.md
│ │ ├── LineItem.md
│ │ ├── LineItemCtnr.md
│ │ ├── Order.md
│ │ ├── OrderAddress.md
│ │ ├── OrderItem.md
│ │ ├── OrderMgr.md
│ │ ├── OrderPaymentInstrument.md
│ │ ├── OrderProcessStatusCodes.md
│ │ ├── PaymentCard.md
│ │ ├── PaymentInstrument.md
│ │ ├── PaymentMethod.md
│ │ ├── PaymentMgr.md
│ │ ├── PaymentProcessor.md
│ │ ├── PaymentStatusCodes.md
│ │ ├── PaymentTransaction.md
│ │ ├── PriceAdjustment.md
│ │ ├── PriceAdjustmentLimitTypes.md
│ │ ├── ProductLineItem.md
│ │ ├── ProductShippingCost.md
│ │ ├── ProductShippingLineItem.md
│ │ ├── ProductShippingModel.md
│ │ ├── Return.md
│ │ ├── ReturnCase.md
│ │ ├── ReturnCaseItem.md
│ │ ├── ReturnItem.md
│ │ ├── Shipment.md
│ │ ├── ShipmentShippingCost.md
│ │ ├── ShipmentShippingModel.md
│ │ ├── ShippingLineItem.md
│ │ ├── ShippingLocation.md
│ │ ├── ShippingMethod.md
│ │ ├── ShippingMgr.md
│ │ ├── ShippingOrder.md
│ │ ├── ShippingOrderItem.md
│ │ ├── SumItem.md
│ │ ├── TaxGroup.md
│ │ ├── TaxItem.md
│ │ ├── TaxMgr.md
│ │ ├── TrackingInfo.md
│ │ └── TrackingRef.md
│ ├── dw_order.hooks
│ │ ├── CalculateHooks.md
│ │ ├── OrderHooks.md
│ │ ├── PaymentHooks.md
│ │ ├── ReturnHooks.md
│ │ └── ShippingOrderHooks.md
│ ├── dw_rpc
│ │ ├── SOAPUtil.md
│ │ ├── Stub.md
│ │ └── WebReference.md
│ ├── dw_suggest
│ │ ├── BrandSuggestions.md
│ │ ├── CategorySuggestions.md
│ │ ├── ContentSuggestions.md
│ │ ├── CustomSuggestions.md
│ │ ├── ProductSuggestions.md
│ │ ├── SearchPhraseSuggestions.md
│ │ ├── SuggestedCategory.md
│ │ ├── SuggestedContent.md
│ │ ├── SuggestedPhrase.md
│ │ ├── SuggestedProduct.md
│ │ ├── SuggestedTerm.md
│ │ ├── SuggestedTerms.md
│ │ ├── Suggestions.md
│ │ └── SuggestModel.md
│ ├── dw_svc
│ │ ├── FTPService.md
│ │ ├── FTPServiceDefinition.md
│ │ ├── HTTPFormService.md
│ │ ├── HTTPFormServiceDefinition.md
│ │ ├── HTTPService.md
│ │ ├── HTTPServiceDefinition.md
│ │ ├── LocalServiceRegistry.md
│ │ ├── Result.md
│ │ ├── Service.md
│ │ ├── ServiceCallback.md
│ │ ├── ServiceConfig.md
│ │ ├── ServiceCredential.md
│ │ ├── ServiceDefinition.md
│ │ ├── ServiceProfile.md
│ │ ├── ServiceRegistry.md
│ │ ├── SOAPService.md
│ │ └── SOAPServiceDefinition.md
│ ├── dw_system
│ │ ├── AgentUserStatusCodes.md
│ │ ├── Cache.md
│ │ ├── CacheMgr.md
│ │ ├── HookMgr.md
│ │ ├── InternalObject.md
│ │ ├── JobProcessMonitor.md
│ │ ├── Log.md
│ │ ├── Logger.md
│ │ ├── LogNDC.md
│ │ ├── OrganizationPreferences.md
│ │ ├── Pipeline.md
│ │ ├── PipelineDictionary.md
│ │ ├── RemoteInclude.md
│ │ ├── Request.md
│ │ ├── RequestHooks.md
│ │ ├── Response.md
│ │ ├── RESTErrorResponse.md
│ │ ├── RESTResponseMgr.md
│ │ ├── RESTSuccessResponse.md
│ │ ├── SearchStatus.md
│ │ ├── Session.md
│ │ ├── Site.md
│ │ ├── SitePreferences.md
│ │ ├── Status.md
│ │ ├── StatusItem.md
│ │ ├── System.md
│ │ └── Transaction.md
│ ├── dw_util
│ │ ├── ArrayList.md
│ │ ├── Assert.md
│ │ ├── BigInteger.md
│ │ ├── Bytes.md
│ │ ├── Calendar.md
│ │ ├── Collection.md
│ │ ├── Currency.md
│ │ ├── DateUtils.md
│ │ ├── Decimal.md
│ │ ├── FilteringCollection.md
│ │ ├── Geolocation.md
│ │ ├── HashMap.md
│ │ ├── HashSet.md
│ │ ├── Iterator.md
│ │ ├── LinkedHashMap.md
│ │ ├── LinkedHashSet.md
│ │ ├── List.md
│ │ ├── Locale.md
│ │ ├── Map.md
│ │ ├── MapEntry.md
│ │ ├── MappingKey.md
│ │ ├── MappingMgr.md
│ │ ├── PropertyComparator.md
│ │ ├── SecureEncoder.md
│ │ ├── SecureFilter.md
│ │ ├── SeekableIterator.md
│ │ ├── Set.md
│ │ ├── SortedMap.md
│ │ ├── SortedSet.md
│ │ ├── StringUtils.md
│ │ ├── Template.md
│ │ └── UUIDUtils.md
│ ├── dw_value
│ │ ├── EnumValue.md
│ │ ├── MimeEncodedText.md
│ │ ├── Money.md
│ │ └── Quantity.md
│ ├── dw_web
│ │ ├── ClickStream.md
│ │ ├── ClickStreamEntry.md
│ │ ├── Cookie.md
│ │ ├── Cookies.md
│ │ ├── CSRFProtection.md
│ │ ├── Form.md
│ │ ├── FormAction.md
│ │ ├── FormElement.md
│ │ ├── FormElementValidationResult.md
│ │ ├── FormField.md
│ │ ├── FormFieldOption.md
│ │ ├── FormFieldOptions.md
│ │ ├── FormGroup.md
│ │ ├── FormList.md
│ │ ├── FormListItem.md
│ │ ├── Forms.md
│ │ ├── HttpParameter.md
│ │ ├── HttpParameterMap.md
│ │ ├── LoopIterator.md
│ │ ├── PageMetaData.md
│ │ ├── PageMetaTag.md
│ │ ├── PagingModel.md
│ │ ├── Resource.md
│ │ ├── URL.md
│ │ ├── URLAction.md
│ │ ├── URLParameter.md
│ │ ├── URLRedirect.md
│ │ ├── URLRedirectMgr.md
│ │ └── URLUtils.md
│ ├── sfra
│ │ ├── account.md
│ │ ├── address.md
│ │ ├── billing.md
│ │ ├── cart.md
│ │ ├── categories.md
│ │ ├── content.md
│ │ ├── locale.md
│ │ ├── order.md
│ │ ├── payment.md
│ │ ├── price-default.md
│ │ ├── price-range.md
│ │ ├── price-tiered.md
│ │ ├── product-bundle.md
│ │ ├── product-full.md
│ │ ├── product-line-items.md
│ │ ├── product-search.md
│ │ ├── product-tile.md
│ │ ├── querystring.md
│ │ ├── render.md
│ │ ├── request.md
│ │ ├── response.md
│ │ ├── server.md
│ │ ├── shipping.md
│ │ ├── store.md
│ │ ├── stores.md
│ │ └── totals.md
│ └── TopLevel
│ ├── APIException.md
│ ├── arguments.md
│ ├── Array.md
│ ├── ArrayBuffer.md
│ ├── BigInt.md
│ ├── Boolean.md
│ ├── ConversionError.md
│ ├── DataView.md
│ ├── Date.md
│ ├── Error.md
│ ├── ES6Iterator.md
│ ├── EvalError.md
│ ├── Fault.md
│ ├── Float32Array.md
│ ├── Float64Array.md
│ ├── Function.md
│ ├── Generator.md
│ ├── global.md
│ ├── Int16Array.md
│ ├── Int32Array.md
│ ├── Int8Array.md
│ ├── InternalError.md
│ ├── IOError.md
│ ├── Iterable.md
│ ├── Iterator.md
│ ├── JSON.md
│ ├── Map.md
│ ├── Math.md
│ ├── Module.md
│ ├── Namespace.md
│ ├── Number.md
│ ├── Object.md
│ ├── QName.md
│ ├── RangeError.md
│ ├── ReferenceError.md
│ ├── RegExp.md
│ ├── Set.md
│ ├── StopIteration.md
│ ├── String.md
│ ├── Symbol.md
│ ├── SyntaxError.md
│ ├── SystemError.md
│ ├── TypeError.md
│ ├── Uint16Array.md
│ ├── Uint32Array.md
│ ├── Uint8Array.md
│ ├── Uint8ClampedArray.md
│ ├── URIError.md
│ ├── WeakMap.md
│ ├── WeakSet.md
│ ├── XML.md
│ ├── XMLList.md
│ └── XMLStreamError.md
├── docs-site
│ ├── .gitignore
│ ├── App.tsx
│ ├── components
│ │ ├── Badge.tsx
│ │ ├── BreadcrumbSchema.tsx
│ │ ├── CodeBlock.tsx
│ │ ├── Collapsible.tsx
│ │ ├── ConfigBuilder.tsx
│ │ ├── ConfigHero.tsx
│ │ ├── ConfigModeTabs.tsx
│ │ ├── icons.tsx
│ │ ├── Layout.tsx
│ │ ├── LightCodeContainer.tsx
│ │ ├── NewcomerCTA.tsx
│ │ ├── NextStepsStrip.tsx
│ │ ├── OnThisPage.tsx
│ │ ├── Search.tsx
│ │ ├── SEO.tsx
│ │ ├── Sidebar.tsx
│ │ ├── StructuredData.tsx
│ │ ├── ToolCard.tsx
│ │ ├── ToolFilters.tsx
│ │ ├── Typography.tsx
│ │ └── VersionBadge.tsx
│ ├── constants.tsx
│ ├── index.html
│ ├── main.tsx
│ ├── metadata.json
│ ├── package-lock.json
│ ├── package.json
│ ├── pages
│ │ ├── AIInterfacesPage.tsx
│ │ ├── ConfigurationPage.tsx
│ │ ├── DevelopmentPage.tsx
│ │ ├── ExamplesPage.tsx
│ │ ├── FeaturesPage.tsx
│ │ ├── HomePage.tsx
│ │ ├── SecurityPage.tsx
│ │ ├── ToolsPage.tsx
│ │ └── TroubleshootingPage.tsx
│ ├── postcss.config.js
│ ├── public
│ │ ├── .well-known
│ │ │ └── security.txt
│ │ ├── 404.html
│ │ ├── android-chrome-192x192.png
│ │ ├── android-chrome-512x512.png
│ │ ├── apple-touch-icon.png
│ │ ├── explain-product-pricing-methods-no-mcp.png
│ │ ├── explain-product-pricing-methods.png
│ │ ├── favicon-16x16.png
│ │ ├── favicon-32x32.png
│ │ ├── favicon.ico
│ │ ├── llms.txt
│ │ ├── robots.txt
│ │ ├── site.webmanifest
│ │ └── sitemap.xml
│ ├── README.md
│ ├── scripts
│ │ ├── generate-search-index.js
│ │ ├── generate-sitemap.js
│ │ └── search-dev.js
│ ├── src
│ │ └── styles
│ │ ├── input.css
│ │ └── prism-theme.css
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── types.ts
│ ├── utils
│ │ ├── search.ts
│ │ └── toolsData.ts
│ └── vite.config.ts
├── eslint.config.js
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│ └── convert-docs.js
├── SECURITY.md
├── server.json
├── src
│ ├── clients
│ │ ├── base
│ │ │ ├── http-client.ts
│ │ │ ├── oauth-token.ts
│ │ │ └── ocapi-auth-client.ts
│ │ ├── best-practices-client.ts
│ │ ├── cartridge-generation-client.ts
│ │ ├── docs
│ │ │ ├── class-content-parser.ts
│ │ │ ├── class-name-resolver.ts
│ │ │ ├── documentation-scanner.ts
│ │ │ ├── index.ts
│ │ │ └── referenced-types-extractor.ts
│ │ ├── docs-client.ts
│ │ ├── log-client.ts
│ │ ├── logs
│ │ │ ├── index.ts
│ │ │ ├── log-analyzer.ts
│ │ │ ├── log-client.ts
│ │ │ ├── log-constants.ts
│ │ │ ├── log-file-discovery.ts
│ │ │ ├── log-file-reader.ts
│ │ │ ├── log-formatter.ts
│ │ │ ├── log-processor.ts
│ │ │ ├── log-types.ts
│ │ │ └── webdav-client-manager.ts
│ │ ├── ocapi
│ │ │ ├── code-versions-client.ts
│ │ │ ├── site-preferences-client.ts
│ │ │ └── system-objects-client.ts
│ │ ├── ocapi-client.ts
│ │ └── sfra-client.ts
│ ├── config
│ │ ├── configuration-factory.ts
│ │ └── dw-json-loader.ts
│ ├── core
│ │ ├── handlers
│ │ │ ├── abstract-log-tool-handler.ts
│ │ │ ├── base-handler.ts
│ │ │ ├── best-practices-handler.ts
│ │ │ ├── cartridge-handler.ts
│ │ │ ├── client-factory.ts
│ │ │ ├── code-version-handler.ts
│ │ │ ├── docs-handler.ts
│ │ │ ├── job-log-handler.ts
│ │ │ ├── job-log-tool-config.ts
│ │ │ ├── log-handler.ts
│ │ │ ├── log-tool-config.ts
│ │ │ ├── sfra-handler.ts
│ │ │ ├── system-object-handler.ts
│ │ │ └── validation-helpers.ts
│ │ ├── server.ts
│ │ └── tool-definitions.ts
│ ├── index.ts
│ ├── main.ts
│ ├── services
│ │ ├── file-system-service.ts
│ │ ├── index.ts
│ │ └── path-service.ts
│ ├── tool-configs
│ │ ├── best-practices-tool-config.ts
│ │ ├── cartridge-tool-config.ts
│ │ ├── code-version-tool-config.ts
│ │ ├── docs-tool-config.ts
│ │ ├── job-log-tool-config.ts
│ │ ├── log-tool-config.ts
│ │ ├── sfra-tool-config.ts
│ │ └── system-object-tool-config.ts
│ ├── types
│ │ └── types.ts
│ └── utils
│ ├── cache.ts
│ ├── job-log-tool-config.ts
│ ├── job-log-utils.ts
│ ├── log-cache.ts
│ ├── log-tool-config.ts
│ ├── log-tool-constants.ts
│ ├── log-tool-utils.ts
│ ├── logger.ts
│ ├── ocapi-url-builder.ts
│ ├── path-resolver.ts
│ ├── query-builder.ts
│ ├── utils.ts
│ └── validator.ts
├── tests
│ ├── __mocks__
│ │ ├── docs-client.ts
│ │ ├── src
│ │ │ └── clients
│ │ │ └── base
│ │ │ └── http-client.js
│ │ └── webdav.js
│ ├── base-handler.test.ts
│ ├── base-http-client.test.ts
│ ├── best-practices-handler.test.ts
│ ├── cache.test.ts
│ ├── cartridge-handler.test.ts
│ ├── class-content-parser.test.ts
│ ├── class-name-resolver.test.ts
│ ├── client-factory.test.ts
│ ├── code-version-handler.test.ts
│ ├── code-versions-client.test.ts
│ ├── config.test.ts
│ ├── configuration-factory.test.ts
│ ├── docs-handler.test.ts
│ ├── documentation-scanner.test.ts
│ ├── file-system-service.test.ts
│ ├── job-log-handler.test.ts
│ ├── job-log-utils.test.ts
│ ├── log-client.test.ts
│ ├── log-handler.test.ts
│ ├── log-processor.test.ts
│ ├── logger.test.ts
│ ├── mcp
│ │ ├── AGENTS.md
│ │ ├── node
│ │ │ ├── activate-code-version-advanced.full-mode.programmatic.test.js
│ │ │ ├── code-versions.full-mode.programmatic.test.js
│ │ │ ├── generate-cartridge-structure.docs-only.programmatic.test.js
│ │ │ ├── get-available-best-practice-guides.docs-only.programmatic.test.js
│ │ │ ├── get-available-sfra-documents.programmatic.test.js
│ │ │ ├── get-best-practice-guide.docs-only.programmatic.test.js
│ │ │ ├── get-hook-reference.docs-only.programmatic.test.js
│ │ │ ├── get-job-execution-summary.full-mode.programmatic.test.js
│ │ │ ├── get-job-log-entries.full-mode.programmatic.test.js
│ │ │ ├── get-latest-debug.full-mode.programmatic.test.js
│ │ │ ├── get-latest-error.full-mode.programmatic.test.js
│ │ │ ├── get-latest-info.full-mode.programmatic.test.js
│ │ │ ├── get-latest-job-log-files.full-mode.programmatic.test.js
│ │ │ ├── get-latest-warn.full-mode.programmatic.test.js
│ │ │ ├── get-log-file-contents.full-mode.programmatic.test.js
│ │ │ ├── get-sfcc-class-documentation.docs-only.programmatic.test.js
│ │ │ ├── get-sfcc-class-info.docs-only.programmatic.test.js
│ │ │ ├── get-sfra-categories.docs-only.programmatic.test.js
│ │ │ ├── get-sfra-document.programmatic.test.js
│ │ │ ├── get-sfra-documents-by-category.docs-only.programmatic.test.js
│ │ │ ├── get-system-object-definition.full-mode.programmatic.test.js
│ │ │ ├── get-system-object-definitions.docs-only.programmatic.test.js
│ │ │ ├── get-system-object-definitions.full-mode.programmatic.test.js
│ │ │ ├── list-log-files.full-mode.programmatic.test.js
│ │ │ ├── list-sfcc-classes.docs-only.programmatic.test.js
│ │ │ ├── search-best-practices.docs-only.programmatic.test.js
│ │ │ ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js
│ │ │ ├── search-job-logs-by-name.full-mode.programmatic.test.js
│ │ │ ├── search-job-logs.full-mode.programmatic.test.js
│ │ │ ├── search-logs.full-mode.programmatic.test.js
│ │ │ ├── search-sfcc-classes.docs-only.programmatic.test.js
│ │ │ ├── search-sfcc-methods.docs-only.programmatic.test.js
│ │ │ ├── search-sfra-documentation.docs-only.programmatic.test.js
│ │ │ ├── search-site-preferences.full-mode.programmatic.test.js
│ │ │ ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js
│ │ │ ├── search-system-object-attribute-groups.full-mode.programmatic.test.js
│ │ │ ├── summarize-logs.full-mode.programmatic.test.js
│ │ │ ├── tools.docs-only.programmatic.test.js
│ │ │ └── tools.full-mode.programmatic.test.js
│ │ ├── README.md
│ │ ├── test-fixtures
│ │ │ └── dw.json
│ │ └── yaml
│ │ ├── activate-code-version.docs-only.test.mcp.yml
│ │ ├── activate-code-version.full-mode.test.mcp.yml
│ │ ├── get_latest_error.test.mcp.yml
│ │ ├── get-available-best-practice-guides.docs-only.test.mcp.yml
│ │ ├── get-available-best-practice-guides.full-mode.test.mcp.yml
│ │ ├── get-available-sfra-documents.docs-only.test.mcp.yml
│ │ ├── get-available-sfra-documents.full-mode.test.mcp.yml
│ │ ├── get-best-practice-guide.docs-only.test.mcp.yml
│ │ ├── get-best-practice-guide.full-mode.test.mcp.yml
│ │ ├── get-code-versions.docs-only.test.mcp.yml
│ │ ├── get-code-versions.full-mode.test.mcp.yml
│ │ ├── get-hook-reference.docs-only.test.mcp.yml
│ │ ├── get-hook-reference.full-mode.test.mcp.yml
│ │ ├── get-job-execution-summary.full-mode.test.mcp.yml
│ │ ├── get-job-log-entries.full-mode.test.mcp.yml
│ │ ├── get-latest-debug.full-mode.test.mcp.yml
│ │ ├── get-latest-error.full-mode.test.mcp.yml
│ │ ├── get-latest-info.full-mode.test.mcp.yml
│ │ ├── get-latest-job-log-files.full-mode.test.mcp.yml
│ │ ├── get-latest-warn.full-mode.test.mcp.yml
│ │ ├── get-log-file-contents.full-mode.test.mcp.yml
│ │ ├── get-sfcc-class-documentation.docs-only.test.mcp.yml
│ │ ├── get-sfcc-class-documentation.full-mode.test.mcp.yml
│ │ ├── get-sfcc-class-info.docs-only.test.mcp.yml
│ │ ├── get-sfcc-class-info.full-mode.test.mcp.yml
│ │ ├── get-sfra-categories.docs-only.test.mcp.yml
│ │ ├── get-sfra-categories.full-mode.test.mcp.yml
│ │ ├── get-sfra-document.docs-only.test.mcp.yml
│ │ ├── get-sfra-document.full-mode.test.mcp.yml
│ │ ├── get-sfra-documents-by-category.docs-only.test.mcp.yml
│ │ ├── get-sfra-documents-by-category.full-mode.test.mcp.yml
│ │ ├── get-system-object-definition.docs-only.test.mcp.yml
│ │ ├── get-system-object-definition.full-mode.test.mcp.yml
│ │ ├── get-system-object-definitions.docs-only.test.mcp.yml
│ │ ├── get-system-object-definitions.full-mode.test.mcp.yml
│ │ ├── list-log-files.full-mode.test.mcp.yml
│ │ ├── list-sfcc-classes.docs-only.test.mcp.yml
│ │ ├── list-sfcc-classes.full-mode.test.mcp.yml
│ │ ├── search-best-practices.docs-only.test.mcp.yml
│ │ ├── search-best-practices.full-mode.test.mcp.yml
│ │ ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml
│ │ ├── search-custom-object-attribute-definitions.test.mcp.yml
│ │ ├── search-job-logs-by-name.full-mode.test.mcp.yml
│ │ ├── search-job-logs.full-mode.test.mcp.yml
│ │ ├── search-logs.full-mode.test.mcp.yml
│ │ ├── search-sfcc-classes.docs-only.test.mcp.yml
│ │ ├── search-sfcc-classes.full-mode.test.mcp.yml
│ │ ├── search-sfcc-methods.docs-only.test.mcp.yml
│ │ ├── search-sfcc-methods.full-mode.test.mcp.yml
│ │ ├── search-sfra-documentation.docs-only.test.mcp.yml
│ │ ├── search-sfra-documentation.full-mode.test.mcp.yml
│ │ ├── search-site-preferences.docs-only.test.mcp.yml
│ │ ├── search-site-preferences.full-mode.test.mcp.yml
│ │ ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml
│ │ ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml
│ │ ├── search-system-object-attribute-groups.docs-only.test.mcp.yml
│ │ ├── search-system-object-attribute-groups.full-mode.test.mcp.yml
│ │ ├── summarize-logs.full-mode.test.mcp.yml
│ │ ├── tools.docs-only.test.mcp.yml
│ │ └── tools.full-mode.test.mcp.yml
│ ├── oauth-token.test.ts
│ ├── ocapi-auth-client.test.ts
│ ├── ocapi-client.test.ts
│ ├── path-service.test.ts
│ ├── query-builder.test.ts
│ ├── referenced-types-extractor.test.ts
│ ├── servers
│ │ ├── sfcc-mock-server
│ │ │ ├── mock-data
│ │ │ │ └── ocapi
│ │ │ │ ├── code-versions.json
│ │ │ │ ├── custom-object-attributes-customapi.json
│ │ │ │ ├── custom-object-attributes-globalsettings.json
│ │ │ │ ├── custom-object-attributes-versionhistory.json
│ │ │ │ ├── site-preferences-ccv.json
│ │ │ │ ├── site-preferences-fastforward.json
│ │ │ │ ├── site-preferences-sfra.json
│ │ │ │ ├── site-preferences-storefront.json
│ │ │ │ ├── site-preferences-system.json
│ │ │ │ ├── system-object-attribute-groups-campaign.json
│ │ │ │ ├── system-object-attribute-groups-category.json
│ │ │ │ ├── system-object-attribute-groups-order.json
│ │ │ │ ├── system-object-attribute-groups-product.json
│ │ │ │ ├── system-object-attribute-groups-sitepreferences.json
│ │ │ │ ├── system-object-attributes-customeraddress.json
│ │ │ │ ├── system-object-attributes-product-expanded.json
│ │ │ │ ├── system-object-attributes-product.json
│ │ │ │ ├── system-object-definition-category.json
│ │ │ │ ├── system-object-definition-customer.json
│ │ │ │ ├── system-object-definition-customeraddress.json
│ │ │ │ ├── system-object-definition-order.json
│ │ │ │ ├── system-object-definition-product.json
│ │ │ │ ├── system-object-definitions-old.json
│ │ │ │ └── system-object-definitions.json
│ │ │ ├── package-lock.json
│ │ │ ├── package.json
│ │ │ ├── README.md
│ │ │ ├── scripts
│ │ │ │ └── setup-logs.js
│ │ │ ├── server.js
│ │ │ └── src
│ │ │ ├── app.js
│ │ │ ├── config
│ │ │ │ └── server-config.js
│ │ │ ├── middleware
│ │ │ │ ├── auth.js
│ │ │ │ ├── cors.js
│ │ │ │ └── logging.js
│ │ │ ├── routes
│ │ │ │ ├── ocapi
│ │ │ │ │ ├── code-versions-handler.js
│ │ │ │ │ ├── oauth-handler.js
│ │ │ │ │ ├── ocapi-error-utils.js
│ │ │ │ │ ├── ocapi-utils.js
│ │ │ │ │ ├── site-preferences-handler.js
│ │ │ │ │ └── system-objects-handler.js
│ │ │ │ ├── ocapi.js
│ │ │ │ └── webdav.js
│ │ │ └── utils
│ │ │ ├── mock-data-loader.js
│ │ │ └── webdav-xml.js
│ │ └── sfcc-mock-server-manager.ts
│ ├── sfcc-mock-server.test.ts
│ ├── site-preferences-client.test.ts
│ ├── system-objects-client.test.ts
│ ├── utils.test.ts
│ ├── validation-helpers.test.ts
│ └── validator.test.ts
├── tsconfig.json
└── tsconfig.test.json
```
# Files
--------------------------------------------------------------------------------
/src/utils/job-log-tool-config.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { ToolSpec, LogToolValidators } from './log-tool-utils.js';
2 | import { ValidationHelpers, CommonValidations } from '../core/handlers/validation-helpers.js';
3 | import { JobLogToolName, getLimit } from './log-tool-constants.js';
4 | import { JobLogValidators, JobLogFormatters } from './job-log-utils.js';
5 |
6 | /**
7 | * Configuration for job log tools
8 | * Maps each tool to its validation, execution, and messaging logic
9 | */
10 | export const JOB_LOG_TOOL_CONFIG: Record<JobLogToolName, ToolSpec> = {
11 | get_latest_job_log_files: {
12 | defaults: (args) => ({
13 | limit: getLimit(args.limit as number, 'jobFiles'),
14 | }),
15 | validate: (args, toolName) => LogToolValidators.validateLimit(args.limit as number, toolName),
16 | exec: async (args, client) => client.getLatestJobLogFiles(args.limit as number),
17 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching latest job log files', {
18 | limit: args.limit as number,
19 | }),
20 | },
21 |
22 | search_job_logs_by_name: {
23 | defaults: (args) => ({
24 | limit: getLimit(args.limit as number, 'jobFiles'),
25 | }),
26 | validate: (args, toolName) => {
27 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
28 | LogToolValidators.validateLimit(args.limit as number, toolName);
29 | },
30 | exec: async (args, client) => client.searchJobLogsByName(args.jobName as string, args.limit as number),
31 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs by name', {
32 | jobName: args.jobName as string,
33 | limit: args.limit as number,
34 | }),
35 | },
36 |
37 | get_job_log_entries: {
38 | defaults: (args) => ({
39 | level: args.level ?? 'all',
40 | limit: getLimit(args.limit as number, 'jobEntries'),
41 | }),
42 | validate: (args, toolName) => {
43 | JobLogValidators.validateJobLogLevel(args.level as string, toolName);
44 | LogToolValidators.validateLimit(args.limit as number, toolName);
45 | },
46 | exec: async (args, client) => client.getJobLogEntries(
47 | args.level as any,
48 | args.limit as number,
49 | args.jobName as string,
50 | ),
51 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching job log entries', {
52 | level: args.level as string,
53 | limit: args.limit as number,
54 | jobName: args.jobName as string,
55 | }),
56 | },
57 |
58 | search_job_logs: {
59 | defaults: (args) => ({
60 | level: args.level ?? 'all',
61 | limit: getLimit(args.limit as number, 'jobSearch'),
62 | }),
63 | validate: (args, toolName) => {
64 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('pattern'), toolName);
65 | JobLogValidators.validateJobLogLevel(args.level as string, toolName);
66 | LogToolValidators.validateLimit(args.limit as number, toolName);
67 | },
68 | exec: async (args, client) => client.searchJobLogs(
69 | args.pattern as string,
70 | args.level as any,
71 | args.limit as number,
72 | args.jobName as string,
73 | ),
74 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs', {
75 | pattern: args.pattern as string,
76 | level: args.level as string,
77 | limit: args.limit as number,
78 | jobName: args.jobName as string,
79 | }),
80 | },
81 |
82 | get_job_execution_summary: {
83 | validate: (args, toolName) => {
84 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
85 | },
86 | exec: async (args, client) => client.getJobExecutionSummary(args.jobName as string),
87 | logMessage: (args) => `Getting job execution summary for: ${args.jobName as string}`,
88 | },
89 | };
90 |
```
--------------------------------------------------------------------------------
/tests/file-system-service.test.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { FileSystemService, MockFileSystemService } from '../src/services/file-system-service.js';
2 |
3 | describe('FileSystemService', () => {
4 | describe('Production FileSystemService', () => {
5 | let service: FileSystemService;
6 |
7 | beforeEach(() => {
8 | service = new FileSystemService();
9 | });
10 |
11 | it('should be instantiable', () => {
12 | expect(service).toBeInstanceOf(FileSystemService);
13 | });
14 |
15 | // Note: Testing actual file operations would require integration tests
16 | // For unit tests, we mainly test the interface compliance
17 | });
18 |
19 | describe('MockFileSystemService', () => {
20 | let mockService: MockFileSystemService;
21 |
22 | beforeEach(() => {
23 | mockService = new MockFileSystemService();
24 | });
25 |
26 | afterEach(() => {
27 | mockService.clearMocks();
28 | });
29 |
30 | it('should be instantiable', () => {
31 | expect(mockService).toBeInstanceOf(MockFileSystemService);
32 | });
33 |
34 | it('should handle mock files correctly', async () => {
35 | const filePath = '/test/file.txt';
36 | const content = 'test content';
37 |
38 | // Initially file should not exist
39 | expect(await mockService.exists(filePath)).toBe(false);
40 |
41 | // Set mock file
42 | mockService.setMockFile(filePath, content);
43 | expect(await mockService.exists(filePath)).toBe(true);
44 |
45 | // Read mock file
46 | const readContent = await mockService.readFile(filePath);
47 | expect(readContent).toBe(content);
48 | });
49 |
50 | it('should handle mock directories correctly', async () => {
51 | const dirPath = '/test/dir';
52 |
53 | // Initially directory should not exist
54 | expect(await mockService.exists(dirPath)).toBe(false);
55 |
56 | // Set mock directory
57 | mockService.setMockDirectory(dirPath);
58 | expect(await mockService.exists(dirPath)).toBe(true);
59 | });
60 |
61 | it('should create directories through mkdir', async () => {
62 | const dirPath = '/test/new-dir';
63 |
64 | await mockService.mkdir(dirPath, { recursive: true });
65 | expect(await mockService.exists(dirPath)).toBe(true);
66 | });
67 |
68 | it('should create files through writeFile', async () => {
69 | const filePath = '/test/new-file.txt';
70 | const content = 'new content';
71 |
72 | await mockService.writeFile(filePath, content);
73 | expect(await mockService.exists(filePath)).toBe(true);
74 |
75 | const readContent = await mockService.readFile(filePath);
76 | expect(readContent).toBe(content);
77 | });
78 |
79 | it('should throw error when reading non-existent file', async () => {
80 | const filePath = '/test/non-existent.txt';
81 |
82 | await expect(mockService.readFile(filePath)).rejects.toThrow('File not found');
83 | });
84 |
85 | it('should handle access correctly', async () => {
86 | const existingPath = '/test/existing';
87 | const nonExistentPath = '/test/non-existent';
88 |
89 | mockService.setMockFile(existingPath, 'content');
90 |
91 | await expect(mockService.access(existingPath)).resolves.not.toThrow();
92 | await expect(mockService.access(nonExistentPath)).rejects.toThrow('Path not accessible');
93 | });
94 |
95 | it('should clear mocks correctly', async () => {
96 | const filePath = '/test/file.txt';
97 | const dirPath = '/test/dir';
98 |
99 | mockService.setMockFile(filePath, 'content');
100 | mockService.setMockDirectory(dirPath);
101 |
102 | expect(await mockService.exists(filePath)).toBe(true);
103 | expect(await mockService.exists(dirPath)).toBe(true);
104 |
105 | mockService.clearMocks();
106 |
107 | expect(await mockService.exists(filePath)).toBe(false);
108 | expect(await mockService.exists(dirPath)).toBe(false);
109 | });
110 | });
111 | });
112 |
```
--------------------------------------------------------------------------------
/docs/dw_svc/ServiceRegistry.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.svc
2 |
3 | # Class ServiceRegistry
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.svc.ServiceRegistry
9 |
10 | ## Description
11 |
12 | The ServiceRegistry is responsible for managing Service definitions and their instances. Typical usage involves several steps: The service is defined in the Business Manager and configured with necessary credentials. The service callback is configured once during cartridge initialization: ServiceRegistry.configure("MyFTPService", { mockExec : function(svc:FTPService, params) { return [ { "name": "file1", "timestamp": new Date(2011, 02, 21)}, { "name": "file2", "timestamp": new Date(2012, 02, 21)}, { "name": "file3", "timestamp": new Date(2013, 02, 21)} ]; }, createRequest: function(svc:FTPService, params) { svc.setOperation("list", "/"); }, parseResponse : function(svc:FTPService, listOutput) { var x : Array = []; var resp : Array = listOutput; for(var i = 0; i < resp.length; i++) { var f = resp[i]; x.push( { "name": f['name'], "timestamp": f['timestamp'] } ); } return x; } }); A new service instance is created and called in order to perform the operation: var result : Result = ServiceRegistry.get("MyFTPService").call(); if(result.status == 'OK') { // The result.object is the object returned by the 'after' callback. } else { // Handle the error. See result.error for more information. } See ServiceCallback for all the callback options, and individual ServiceDefinition classes for customization specific to a service type.
13 |
14 | ## Constructor Summary
15 |
16 | ## Method Summary
17 |
18 | ### configure
19 |
20 | **Signature:** `static configure(serviceID : String, configObj : Object) : ServiceDefinition`
21 |
22 | Configure the given serviceId with a callback.
23 |
24 | ### get
25 |
26 | **Signature:** `static get(serviceID : String) : Service`
27 |
28 | Constructs a new instance of the given service.
29 |
30 | ### getDefinition
31 |
32 | **Signature:** `static getDefinition(serviceID : String) : ServiceDefinition`
33 |
34 | Gets a Service Definition.
35 |
36 | ### isConfigured
37 |
38 | **Signature:** `static isConfigured(serviceID : String) : boolean`
39 |
40 | Returns the status of whether the given service has been configured with a callback.
41 |
42 | ## Method Detail
43 |
44 | ## Method Details
45 |
46 | ### configure
47 |
48 | **Signature:** `static configure(serviceID : String, configObj : Object) : ServiceDefinition`
49 |
50 | **Description:** Configure the given serviceId with a callback. If the service is already configured, the given callback will replace any existing one.
51 |
52 | **Parameters:**
53 |
54 | - `serviceID`: Unique Service ID.
55 | - `configObj`: Configuration callback. See ServiceCallback for a description of available callback methods.
56 |
57 | **Returns:**
58 |
59 | Associated ServiceDefinition, which can be used for further protocol-specific configuration.
60 |
61 | ---
62 |
63 | ### get
64 |
65 | **Signature:** `static get(serviceID : String) : Service`
66 |
67 | **Description:** Constructs a new instance of the given service.
68 |
69 | **Parameters:**
70 |
71 | - `serviceID`: Unique Service ID.
72 |
73 | **Returns:**
74 |
75 | Service instance.
76 |
77 | ---
78 |
79 | ### getDefinition
80 |
81 | **Signature:** `static getDefinition(serviceID : String) : ServiceDefinition`
82 |
83 | **Description:** Gets a Service Definition. This Service Definition is shared across all Service instances returned by get(String).
84 |
85 | **Parameters:**
86 |
87 | - `serviceID`: Unique Service ID.
88 |
89 | **Returns:**
90 |
91 | ServiceDefinition
92 |
93 | ---
94 |
95 | ### isConfigured
96 |
97 | **Signature:** `static isConfigured(serviceID : String) : boolean`
98 |
99 | **Description:** Returns the status of whether the given service has been configured with a callback.
100 |
101 | **Parameters:**
102 |
103 | - `serviceID`: Unique Service ID.
104 |
105 | **Returns:**
106 |
107 | true if configure has already been called, false otherwise.
108 |
109 | ---
```
--------------------------------------------------------------------------------
/src/core/handlers/job-log-tool-config.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { ToolSpec, LogToolValidators } from '../../utils/log-tool-utils.js';
2 | import { ValidationHelpers, CommonValidations } from './validation-helpers.js';
3 | import { JobLogToolName, getLimit } from '../../utils/log-tool-constants.js';
4 | import { JobLogValidators, JobLogFormatters } from '../../utils/job-log-utils.js';
5 |
6 | /**
7 | * Configuration for job log tools
8 | * Maps each tool to its validation, execution, and messaging logic
9 | */
10 | export const JOB_LOG_TOOL_CONFIG: Record<JobLogToolName, ToolSpec> = {
11 | get_latest_job_log_files: {
12 | defaults: (args) => ({
13 | limit: getLimit(args.limit as number, 'jobFiles'),
14 | }),
15 | validate: (args, toolName) => LogToolValidators.validateLimit(args.limit as number, toolName),
16 | exec: async (args, client) => client.getLatestJobLogFiles(args.limit as number),
17 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching latest job log files', {
18 | limit: args.limit as number,
19 | }),
20 | },
21 |
22 | search_job_logs_by_name: {
23 | defaults: (args) => ({
24 | limit: getLimit(args.limit as number, 'jobFiles'),
25 | }),
26 | validate: (args, toolName) => {
27 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
28 | LogToolValidators.validateLimit(args.limit as number, toolName);
29 | },
30 | exec: async (args, client) => client.searchJobLogsByName(args.jobName as string, args.limit as number),
31 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs by name', {
32 | jobName: args.jobName as string,
33 | limit: args.limit as number,
34 | }),
35 | },
36 |
37 | get_job_log_entries: {
38 | defaults: (args) => ({
39 | level: args.level ?? 'all',
40 | limit: getLimit(args.limit as number, 'jobEntries'),
41 | }),
42 | validate: (args, toolName) => {
43 | JobLogValidators.validateJobLogLevel(args.level as string, toolName);
44 | LogToolValidators.validateLimit(args.limit as number, toolName);
45 | },
46 | exec: async (args, client) => client.getJobLogEntries(
47 | args.level as any,
48 | args.limit as number,
49 | args.jobName as string,
50 | ),
51 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Fetching job log entries', {
52 | level: args.level as string,
53 | limit: args.limit as number,
54 | jobName: args.jobName as string,
55 | }),
56 | },
57 |
58 | search_job_logs: {
59 | defaults: (args) => ({
60 | level: args.level ?? 'all',
61 | limit: getLimit(args.limit as number, 'jobSearch'),
62 | }),
63 | validate: (args, toolName) => {
64 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('pattern'), toolName);
65 | JobLogValidators.validateJobLogLevel(args.level as string, toolName);
66 | LogToolValidators.validateLimit(args.limit as number, toolName);
67 | },
68 | exec: async (args, client) => client.searchJobLogs(
69 | args.pattern as string,
70 | args.level as any,
71 | args.limit as number,
72 | args.jobName as string,
73 | ),
74 | logMessage: (args) => JobLogFormatters.formatJobLogMessage('Searching job logs', {
75 | pattern: args.pattern as string,
76 | level: args.level as string,
77 | limit: args.limit as number,
78 | jobName: args.jobName as string,
79 | }),
80 | },
81 |
82 | get_job_execution_summary: {
83 | validate: (args, toolName) => {
84 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName);
85 | },
86 | exec: async (args, client) => client.getJobExecutionSummary(args.jobName as string),
87 | logMessage: (args) => `Getting job execution summary for: ${args.jobName as string}`,
88 | },
89 | };
90 |
```
--------------------------------------------------------------------------------
/docs-site/scripts/search-dev.js:
--------------------------------------------------------------------------------
```javascript
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Development utility script for the search index
5 | * Provides commands for generation, validation, and testing
6 | */
7 |
8 | import { generateSearchIndex, writeSearchIndex } from './generate-search-index.js';
9 | import fs from 'fs';
10 | import path from 'path';
11 | import { fileURLToPath } from 'url';
12 |
13 | const __filename = fileURLToPath(import.meta.url);
14 | const __dirname = path.dirname(__filename);
15 |
16 | const command = process.argv[2];
17 |
18 | switch (command) {
19 | case 'generate':
20 | console.log('🔄 Generating search index...');
21 | try {
22 | const index = generateSearchIndex();
23 | writeSearchIndex(index);
24 | } catch (error) {
25 | console.error('❌ Failed to generate search index:', error.message);
26 | process.exit(1);
27 | }
28 | break;
29 |
30 | case 'validate':
31 | console.log('✅ Validating search index...');
32 | try {
33 | const indexPath = path.join(__dirname, '../src/generated-search-index.ts');
34 | if (!fs.existsSync(indexPath)) {
35 | console.error('❌ Search index file not found. Run "generate" first.');
36 | process.exit(1);
37 | }
38 |
39 | const stats = fs.statSync(indexPath);
40 | const content = fs.readFileSync(indexPath, 'utf-8');
41 | const lines = content.split('\n').length;
42 | const size = (stats.size / 1024).toFixed(1);
43 |
44 | // Extract the number of entries
45 | const match = content.match(/GENERATED_SEARCH_INDEX: SearchableItem\[\] = \[([\s\S]*)\];/);
46 | if (match) {
47 | const entriesCount = (match[1].match(/\{/g) || []).length;
48 | console.log('📊 Search index statistics:');
49 | console.log(` • File size: ${size} KB`);
50 | console.log(` • Lines: ${lines}`);
51 | console.log(` • Search entries: ${entriesCount}`);
52 | console.log(` • Last modified: ${stats.mtime.toLocaleString()}`);
53 | console.log('✅ Search index is valid');
54 | } else {
55 | throw new Error('Invalid search index format');
56 | }
57 | } catch (error) {
58 | console.error('❌ Search index validation failed:', error.message);
59 | process.exit(1);
60 | }
61 | break;
62 |
63 | case 'search': {
64 | const query = process.argv[3];
65 | if (!query) {
66 | console.error('❌ Please provide a search query: npm run search-dev search "your query"');
67 | process.exit(1);
68 | }
69 |
70 | console.log(`🔍 Testing search for: "${query}"`);
71 | try {
72 | // Dynamically import and test the search function
73 | const { searchDocs } = await import('../utils/search.ts');
74 | const results = searchDocs(query);
75 |
76 | if (results.length === 0) {
77 | console.log('📭 No results found');
78 | } else {
79 | console.log(`📋 Found ${results.length} results:`);
80 | results.forEach((result, index) => {
81 | console.log(`\n${index + 1}. ${result.heading} (${result.pageTitle})`);
82 | console.log(` Path: ${result.path}`);
83 | console.log(` Score: ${result.score}`);
84 | console.log(` Snippet: ${result.snippet.substring(0, 100)}...`);
85 | });
86 | }
87 | } catch (error) {
88 | console.error('❌ Search test failed:', error.message);
89 | process.exit(1);
90 | }
91 | break;
92 | }
93 |
94 | default:
95 | console.log(`
96 | 🔧 Search Index Development Utility
97 |
98 | Usage:
99 | node scripts/search-dev.js <command>
100 |
101 | Commands:
102 | generate Generate the search index from React components
103 | validate Check if the search index is valid and show statistics
104 | search Test search functionality with a query
105 |
106 | Examples:
107 | node scripts/search-dev.js generate
108 | node scripts/search-dev.js validate
109 | node scripts/search-dev.js search "pattern matching"
110 | `);
111 | break;
112 | }
113 |
```
--------------------------------------------------------------------------------
/docs/dw_customer/ExternalProfile.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.customer
2 |
3 | # Class ExternalProfile
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.customer.ExternalProfile
9 |
10 | ## Description
11 |
12 | Represents the credentials of a customer. Since 13.6 it is possible to have customers who are not authenticated through a login and password but through an external authentication provider via the OAuth2 protocol. In such cases, the AuthenticationProviderID will point to an OAuth provider configured in the system and the ExternalID will be the unique identifier of the customer on the Authentication Provider's system. For example, if an authentication provider with ID "Google123" is configured pointing to Google and the customer has a logged in into Google in the past and has created a profile there, Google assigns a unique number identifier to that customer. If the storefront is configured to allow authentication through Google and a new customer logs into the storefront using Google, the AuthenticationProviderID property of his Credentials will contain "Google123" and the ExternalID property will contain whatever unique identifier Google has assigned to him. Note: this class handles sensitive security-related data. Pay special attention to PCI DSS v3. requirements 2, 4, and 12.
13 |
14 | ## Properties
15 |
16 | ### authenticationProviderID
17 |
18 | **Type:** String (Read Only)
19 |
20 | The authentication provider ID.
21 |
22 | ### customer
23 |
24 | **Type:** Customer (Read Only)
25 |
26 | The customer object related to this profile.
27 |
28 | ### email
29 |
30 | **Type:** String
31 |
32 | The customer's email address.
33 |
34 | ### externalID
35 |
36 | **Type:** String (Read Only)
37 |
38 | The external ID.
39 |
40 | ### lastLoginTime
41 |
42 | **Type:** Date (Read Only)
43 |
44 | The last login time of the customer through the external provider
45 |
46 | ## Constructor Summary
47 |
48 | ## Method Summary
49 |
50 | ### getAuthenticationProviderID
51 |
52 | **Signature:** `getAuthenticationProviderID() : String`
53 |
54 | Returns the authentication provider ID.
55 |
56 | ### getCustomer
57 |
58 | **Signature:** `getCustomer() : Customer`
59 |
60 | Returns the customer object related to this profile.
61 |
62 | ### getEmail
63 |
64 | **Signature:** `getEmail() : String`
65 |
66 | Returns the customer's email address.
67 |
68 | ### getExternalID
69 |
70 | **Signature:** `getExternalID() : String`
71 |
72 | Returns the external ID.
73 |
74 | ### getLastLoginTime
75 |
76 | **Signature:** `getLastLoginTime() : Date`
77 |
78 | Returns the last login time of the customer through the external provider
79 |
80 | ### setEmail
81 |
82 | **Signature:** `setEmail(email : String) : void`
83 |
84 | Sets the customer's email address.
85 |
86 | ## Method Detail
87 |
88 | ## Method Details
89 |
90 | ### getAuthenticationProviderID
91 |
92 | **Signature:** `getAuthenticationProviderID() : String`
93 |
94 | **Description:** Returns the authentication provider ID.
95 |
96 | **Returns:**
97 |
98 | the authentication provider ID.
99 |
100 | ---
101 |
102 | ### getCustomer
103 |
104 | **Signature:** `getCustomer() : Customer`
105 |
106 | **Description:** Returns the customer object related to this profile.
107 |
108 | **Returns:**
109 |
110 | customer object related to profile.
111 |
112 | ---
113 |
114 | ### getEmail
115 |
116 | **Signature:** `getEmail() : String`
117 |
118 | **Description:** Returns the customer's email address.
119 |
120 | **Returns:**
121 |
122 | the customer's email address.
123 |
124 | ---
125 |
126 | ### getExternalID
127 |
128 | **Signature:** `getExternalID() : String`
129 |
130 | **Description:** Returns the external ID.
131 |
132 | **Returns:**
133 |
134 | the external ID.
135 |
136 | ---
137 |
138 | ### getLastLoginTime
139 |
140 | **Signature:** `getLastLoginTime() : Date`
141 |
142 | **Description:** Returns the last login time of the customer through the external provider
143 |
144 | **Returns:**
145 |
146 | the time, when the customer was last logged in through this external provider
147 |
148 | ---
149 |
150 | ### setEmail
151 |
152 | **Signature:** `setEmail(email : String) : void`
153 |
154 | **Description:** Sets the customer's email address.
155 |
156 | **Parameters:**
157 |
158 | - `email`: the customer's email address.
159 |
160 | ---
```
--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/src/middleware/logging.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * Logging Middleware
3 | *
4 | * Provides request/response logging functionality for debugging and monitoring.
5 | * Configurable logging levels and output formatting.
6 | */
7 |
8 | /**
9 | * Create request logging middleware
10 | */
11 | function createRequestLogger(isDevMode = false) {
12 | if (!isDevMode) {
13 | // Return no-op middleware in production mode
14 | return (req, res, next) => next();
15 | }
16 |
17 | return (req, res, next) => {
18 | const timestamp = new Date().toISOString();
19 | const method = req.method;
20 | const url = req.url;
21 | const userAgent = req.headers['user-agent'] || 'Unknown';
22 |
23 | console.log(`📥 [${timestamp}] ${method} ${url}`, {
24 | headers: {
25 | authorization: req.headers.authorization ? '[REDACTED]' : undefined,
26 | 'content-type': req.headers['content-type'],
27 | 'depth': req.headers.depth,
28 | 'range': req.headers.range,
29 | 'user-agent': userAgent
30 | },
31 | query: Object.keys(req.query).length > 0 ? req.query : undefined,
32 | body: req.body && Object.keys(req.body).length > 0 ? req.body : undefined
33 | });
34 |
35 | next();
36 | };
37 | }
38 |
39 | /**
40 | * Create response logging middleware
41 | */
42 | function createResponseLogger(isDevMode = false) {
43 | if (!isDevMode) {
44 | // Return no-op middleware in production mode
45 | return (req, res, next) => next();
46 | }
47 |
48 | return (req, res, next) => {
49 | const originalSend = res.send;
50 | const originalJson = res.json;
51 |
52 | // Override res.send
53 | res.send = function(body) {
54 | logResponse(req, res, body, 'send');
55 | return originalSend.call(this, body);
56 | };
57 |
58 | // Override res.json
59 | res.json = function(obj) {
60 | logResponse(req, res, obj, 'json');
61 | return originalJson.call(this, obj);
62 | };
63 |
64 | next();
65 | };
66 | }
67 |
68 | /**
69 | * Log response details
70 | */
71 | function logResponse(req, res, body, type) {
72 | const timestamp = new Date().toISOString();
73 | const method = req.method;
74 | const url = req.url;
75 | const statusCode = res.statusCode;
76 |
77 | let bodyPreview = body;
78 |
79 | // Truncate large responses for readability
80 | if (typeof body === 'string' && body.length > 500) {
81 | bodyPreview = body.substring(0, 500) + '... [truncated]';
82 | } else if (typeof body === 'object' && body !== null) {
83 | const bodyStr = JSON.stringify(body);
84 | if (bodyStr.length > 500) {
85 | bodyPreview = JSON.stringify(body, null, 2).substring(0, 500) + '... [truncated]';
86 | }
87 | }
88 |
89 | console.log(`📤 [${timestamp}] ${method} ${url} -> ${statusCode}`, {
90 | headers: {
91 | 'content-type': res.getHeader('content-type'),
92 | 'content-length': res.getHeader('content-length'),
93 | 'content-range': res.getHeader('content-range')
94 | },
95 | type,
96 | body: bodyPreview
97 | });
98 | }
99 |
100 | /**
101 | * Create error logging middleware
102 | */
103 | function createErrorLogger() {
104 | return (err, req, res, next) => {
105 | const timestamp = new Date().toISOString();
106 | const method = req.method;
107 | const url = req.url;
108 |
109 | console.error(`❌ [${timestamp}] ERROR ${method} ${url}:`, {
110 | message: err.message,
111 | stack: err.stack,
112 | code: err.code
113 | });
114 |
115 | // Don't handle the error, just log it
116 | next(err);
117 | };
118 | }
119 |
120 | module.exports = {
121 | createRequestLogger,
122 | createResponseLogger,
123 | createErrorLogger
124 | };
```
--------------------------------------------------------------------------------
/docs/dw_campaign/CouponMgr.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.campaign
2 |
3 | # Class CouponMgr
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.campaign.CouponMgr
9 |
10 | ## Description
11 |
12 | Manager to access coupons.
13 |
14 | ## Constants
15 |
16 | ### MR_ERROR_INVALID_SITE_ID
17 |
18 | **Type:** String = "MASKREDEMPTIONS_SITE_NOT_FOUND"
19 |
20 | Indicates that an error occurred because a valid data domain cannot be found for given siteID.
21 |
22 | ## Properties
23 |
24 | ### coupons
25 |
26 | **Type:** Collection (Read Only)
27 |
28 | All coupons in the current site in no specific order.
29 |
30 | ## Constructor Summary
31 |
32 | ## Method Summary
33 |
34 | ### getCoupon
35 |
36 | **Signature:** `static getCoupon(couponID : String) : Coupon`
37 |
38 | Returns the coupon with the specified ID.
39 |
40 | ### getCouponByCode
41 |
42 | **Signature:** `static getCouponByCode(couponCode : String) : Coupon`
43 |
44 | Tries to find a coupon for the given coupon code.
45 |
46 | ### getCoupons
47 |
48 | **Signature:** `static getCoupons() : Collection`
49 |
50 | Returns all coupons in the current site in no specific order.
51 |
52 | ### getRedemptions
53 |
54 | **Signature:** `static getRedemptions(couponID : String, couponCode : String) : Collection`
55 |
56 | Returns list of CouponRedemptions for the specified coupon and coupon code, sorted by redemption date descending (i.e.
57 |
58 | ### maskRedemptions
59 |
60 | **Signature:** `static maskRedemptions(siteID : String, email : String) : Status`
61 |
62 | Mask customer email address in coupon redemptions for the given siteID and email address
63 |
64 | ## Method Detail
65 |
66 | ## Method Details
67 |
68 | ### getCoupon
69 |
70 | **Signature:** `static getCoupon(couponID : String) : Coupon`
71 |
72 | **Description:** Returns the coupon with the specified ID.
73 |
74 | **Parameters:**
75 |
76 | - `couponID`: the coupon identifier.
77 |
78 | **Returns:**
79 |
80 | Coupon with specified ID or null
81 |
82 | ---
83 |
84 | ### getCouponByCode
85 |
86 | **Signature:** `static getCouponByCode(couponCode : String) : Coupon`
87 |
88 | **Description:** Tries to find a coupon for the given coupon code. The method first searches for a coupon with a fixed code matching the passed value. If no such fixed coupon is found, it searches for a coupon with a system-generated code matching the passed value. If found, the coupon is returned. Otherwise, the method returns null.
89 |
90 | **Parameters:**
91 |
92 | - `couponCode`: The coupon code to get the coupon for.
93 |
94 | **Returns:**
95 |
96 | The coupon with the matching coupon code or null if no coupon was found.
97 |
98 | ---
99 |
100 | ### getCoupons
101 |
102 | **Signature:** `static getCoupons() : Collection`
103 |
104 | **Description:** Returns all coupons in the current site in no specific order.
105 |
106 | **Returns:**
107 |
108 | Coupons in current site
109 |
110 | ---
111 |
112 | ### getRedemptions
113 |
114 | **Signature:** `static getRedemptions(couponID : String, couponCode : String) : Collection`
115 |
116 | **Description:** Returns list of CouponRedemptions for the specified coupon and coupon code, sorted by redemption date descending (i.e. last redemption first). Usually, there should only either be 0 or 1 redemption. But if a coupon and code is removed and recreated and re-issued later, there might be multiple such redemption records. Returns an empty list if no redemption record exists in system for the specified coupon and code.
117 |
118 | **Parameters:**
119 |
120 | - `couponID`: The coupon id to find redemption for.
121 | - `couponCode`: The coupon code to find redemption for.
122 |
123 | **Returns:**
124 |
125 | A sorted list of CouponRedemptions for the specified coupon and coupon code or an empty list if no redemption record exists.
126 |
127 | ---
128 |
129 | ### maskRedemptions
130 |
131 | **Signature:** `static maskRedemptions(siteID : String, email : String) : Status`
132 |
133 | **Description:** Mask customer email address in coupon redemptions for the given siteID and email address
134 |
135 | **Parameters:**
136 |
137 | - `siteID`: the site ID
138 | - `email`: the customer email address
139 |
140 | **Returns:**
141 |
142 | The status of the masking result
143 |
144 | ---
```
--------------------------------------------------------------------------------
/docs/dw_content/ContentMgr.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.content
2 |
3 | # Class ContentMgr
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.content.ContentMgr
9 |
10 | ## Description
11 |
12 | Provides helper methods for getting content assets, library folders and the content library of the current site.
13 |
14 | ## Constants
15 |
16 | ### PRIVATE_LIBRARY
17 |
18 | **Type:** String = "PrivateLibrary"
19 |
20 | The input string to identify that the library is a private site library when invoking getLibrary(String).
21 |
22 | ## Properties
23 |
24 | ### siteLibrary
25 |
26 | **Type:** Library (Read Only)
27 |
28 | The content library of the current site.
29 |
30 | ## Constructor Summary
31 |
32 | ## Method Summary
33 |
34 | ### getContent
35 |
36 | **Signature:** `static getContent(id : String) : Content`
37 |
38 | Returns the content with the corresponding identifier within the current site's site library.
39 |
40 | ### getContent
41 |
42 | **Signature:** `static getContent(library : Library, id : String) : Content`
43 |
44 | Returns the content with the corresponding identifier within the specified library.
45 |
46 | ### getFolder
47 |
48 | **Signature:** `static getFolder(id : String) : Folder`
49 |
50 | Returns the folder identified by the specified id within the current site's site library.
51 |
52 | ### getFolder
53 |
54 | **Signature:** `static getFolder(library : Library, id : String) : Folder`
55 |
56 | Returns the folder identified by the specified id within the specified library.
57 |
58 | ### getLibrary
59 |
60 | **Signature:** `static getLibrary(libraryId : String) : Library`
61 |
62 | Returns the content library specified by the given id.
63 |
64 | ### getSiteLibrary
65 |
66 | **Signature:** `static getSiteLibrary() : Library`
67 |
68 | Returns the content library of the current site.
69 |
70 | ## Method Detail
71 |
72 | ## Method Details
73 |
74 | ### getContent
75 |
76 | **Signature:** `static getContent(id : String) : Content`
77 |
78 | **Description:** Returns the content with the corresponding identifier within the current site's site library.
79 |
80 | **Parameters:**
81 |
82 | - `id`: the ID of the content asset to find.
83 |
84 | **Returns:**
85 |
86 | the content if found, or null if not found.
87 |
88 | ---
89 |
90 | ### getContent
91 |
92 | **Signature:** `static getContent(library : Library, id : String) : Content`
93 |
94 | **Description:** Returns the content with the corresponding identifier within the specified library.
95 |
96 | **Parameters:**
97 |
98 | - `library`: the content library to look for the content in
99 | - `id`: the ID of the content asset to find.
100 |
101 | **Returns:**
102 |
103 | the content if found, or null if not found.
104 |
105 | ---
106 |
107 | ### getFolder
108 |
109 | **Signature:** `static getFolder(id : String) : Folder`
110 |
111 | **Description:** Returns the folder identified by the specified id within the current site's site library.
112 |
113 | **Parameters:**
114 |
115 | - `id`: the ID of the folder to find.
116 |
117 | **Returns:**
118 |
119 | the folder, or null if not found.
120 |
121 | ---
122 |
123 | ### getFolder
124 |
125 | **Signature:** `static getFolder(library : Library, id : String) : Folder`
126 |
127 | **Description:** Returns the folder identified by the specified id within the specified library.
128 |
129 | **Parameters:**
130 |
131 | - `library`: the content library to look for the folder in
132 | - `id`: the ID of the folder to find.
133 |
134 | **Returns:**
135 |
136 | the folder, or null if not found.
137 |
138 | ---
139 |
140 | ### getLibrary
141 |
142 | **Signature:** `static getLibrary(libraryId : String) : Library`
143 |
144 | **Description:** Returns the content library specified by the given id. If PRIVATE_LIBRARY is used, then the current site's private library will be returned.
145 |
146 | **Parameters:**
147 |
148 | - `libraryId`: the id of the library to return.
149 |
150 | **Returns:**
151 |
152 | the library for the passed id. Returns null if there is no content library with that id.
153 |
154 | ---
155 |
156 | ### getSiteLibrary
157 |
158 | **Signature:** `static getSiteLibrary() : Library`
159 |
160 | **Description:** Returns the content library of the current site.
161 |
162 | **Returns:**
163 |
164 | the content library of the current site, or null if there is not content library assigned to the current site.
165 |
166 | ---
```
--------------------------------------------------------------------------------
/docs/dw_customer/CustomerGroup.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.customer
2 |
3 | # Class CustomerGroup
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.object.PersistentObject
9 | - dw.object.ExtensibleObject
10 | - dw.customer.CustomerGroup
11 |
12 | ## Description
13 |
14 | CustomerGroups provide a means to segment customers by various criteria. A merchant can then provide different site experiences (e.g. promotions, prices, sorting rules) to each customer segment. Customer groups can consist of either an explicit list of customers or a business rule that dynamically determines whether a customer is a member. The former type is called "explicit" and the latter type is called "dynamic". Explicit customer group: Consists of an explicit list of customers. Only registered customers can be member of such a group. isRuleBased==false. Dynamic customer group: Memberships are evaluated by a business rule that is attached to the customer group. Registered as well as anonymous customers can be member of such a group. isRuleBased==true. Note: this class might allow access to sensitive personal and private information, depending on how you segment your customers and the names given to your custoemer groups. Pay attention to appropriate legal and regulatory requirements when developing with this data.
15 |
16 | ## Properties
17 |
18 | ### description
19 |
20 | **Type:** String (Read Only)
21 |
22 | Gets the value of the description of the customer group.
23 |
24 | ### ID
25 |
26 | **Type:** String (Read Only)
27 |
28 | The unique ID of the customer group.
29 |
30 | ### ruleBased
31 |
32 | **Type:** boolean (Read Only)
33 |
34 | Returns true if the group determines the membership of customers
35 | based on rules. Returns false if the group provides explicit assignement
36 | of customers.
37 |
38 | ## Constructor Summary
39 |
40 | ## Method Summary
41 |
42 | ### assignCustomer
43 |
44 | **Signature:** `assignCustomer(customer : Customer) : void`
45 |
46 | Assigns the specified customer to this group.
47 |
48 | ### getDescription
49 |
50 | **Signature:** `getDescription() : String`
51 |
52 | Gets the value of the description of the customer group.
53 |
54 | ### getID
55 |
56 | **Signature:** `getID() : String`
57 |
58 | Returns the unique ID of the customer group.
59 |
60 | ### isRuleBased
61 |
62 | **Signature:** `isRuleBased() : boolean`
63 |
64 | Returns true if the group determines the membership of customers based on rules.
65 |
66 | ### unassignCustomer
67 |
68 | **Signature:** `unassignCustomer(customer : Customer) : void`
69 |
70 | Unassigns the specified customer from this group.
71 |
72 | ## Method Detail
73 |
74 | ## Method Details
75 |
76 | ### assignCustomer
77 |
78 | **Signature:** `assignCustomer(customer : Customer) : void`
79 |
80 | **Description:** Assigns the specified customer to this group. The customer must be registered and the group must not be rule-based.
81 |
82 | **Parameters:**
83 |
84 | - `customer`: Registered customer, must not be null.
85 |
86 | ---
87 |
88 | ### getDescription
89 |
90 | **Signature:** `getDescription() : String`
91 |
92 | **Description:** Gets the value of the description of the customer group.
93 |
94 | **Returns:**
95 |
96 | the description of the customer group
97 |
98 | ---
99 |
100 | ### getID
101 |
102 | **Signature:** `getID() : String`
103 |
104 | **Description:** Returns the unique ID of the customer group.
105 |
106 | **Returns:**
107 |
108 | The unique semantic ID of the customer group.
109 |
110 | ---
111 |
112 | ### isRuleBased
113 |
114 | **Signature:** `isRuleBased() : boolean`
115 |
116 | **Description:** Returns true if the group determines the membership of customers based on rules. Returns false if the group provides explicit assignement of customers.
117 |
118 | **Returns:**
119 |
120 | True, if the customer group is rule based.
121 |
122 | ---
123 |
124 | ### unassignCustomer
125 |
126 | **Signature:** `unassignCustomer(customer : Customer) : void`
127 |
128 | **Description:** Unassigns the specified customer from this group. The customer must be registered and the group must not be rule-based.
129 |
130 | **Parameters:**
131 |
132 | - `customer`: Registered customer, must not be null.
133 |
134 | ---
```
--------------------------------------------------------------------------------
/src/core/handlers/client-factory.ts:
--------------------------------------------------------------------------------
```typescript
1 | import { HandlerContext } from './base-handler.js';
2 | import { SFCCLogClient } from '../../clients/log-client.js';
3 | import { OCAPIClient } from '../../clients/ocapi-client.js';
4 | import { OCAPICodeVersionsClient } from '../../clients/ocapi/code-versions-client.js';
5 | import { CartridgeGenerationClient } from '../../clients/cartridge-generation-client.js';
6 | import { Logger } from '../../utils/logger.js';
7 | import { IFileSystemService, IPathService, FileSystemService, PathService } from '../../services/index.js';
8 |
9 | /**
10 | * Centralized client factory that handles complex initialization logic
11 | * and encapsulates the requirements for different client types.
12 | */
13 | export class ClientFactory {
14 | private context: HandlerContext;
15 | private logger: Logger;
16 |
17 | constructor(context: HandlerContext, logger: Logger) {
18 | this.context = context;
19 | this.logger = logger;
20 | }
21 |
22 | /**
23 | * Create an SFCC Log Client if log access is available
24 | */
25 | createLogClient(): SFCCLogClient | null {
26 | if (!this.context.capabilities?.canAccessLogs || !this.context.config) {
27 | this.logger.debug('Log client not created: missing log access capability or config');
28 | return null;
29 | }
30 |
31 | this.logger.debug('Creating SFCC Log Client');
32 | return new SFCCLogClient(this.context.config);
33 | }
34 |
35 | /**
36 | * Create an OCAPI Client if OCAPI access is available
37 | */
38 | createOCAPIClient(): OCAPIClient | null {
39 | if (!this.hasOCAPICredentials()) {
40 | this.logger.debug('OCAPI client not created: missing OCAPI credentials or capability');
41 | return null;
42 | }
43 |
44 | this.logger.debug('Creating OCAPI Client');
45 | return new OCAPIClient({
46 | hostname: this.context.config!.hostname!,
47 | clientId: this.context.config!.clientId!,
48 | clientSecret: this.context.config!.clientSecret!,
49 | version: 'v23_2',
50 | });
51 | }
52 |
53 | /**
54 | * Create an OCAPI Code Versions Client if OCAPI access is available
55 | */
56 | createCodeVersionsClient(): OCAPICodeVersionsClient | null {
57 | if (!this.hasOCAPICredentials()) {
58 | this.logger.debug('Code versions client not created: missing OCAPI credentials or capability');
59 | return null;
60 | }
61 |
62 | this.logger.debug('Creating OCAPI Code Versions Client');
63 | return new OCAPICodeVersionsClient({
64 | hostname: this.context.config!.hostname!,
65 | clientId: this.context.config!.clientId!,
66 | clientSecret: this.context.config!.clientSecret!,
67 | version: 'v23_2',
68 | });
69 | }
70 |
71 | /**
72 | * Check if OCAPI credentials and capability are available
73 | */
74 | private hasOCAPICredentials(): boolean {
75 | return !!(
76 | this.context.capabilities?.canAccessOCAPI &&
77 | this.context.config?.hostname &&
78 | this.context.config?.clientId &&
79 | this.context.config?.clientSecret
80 | );
81 | }
82 |
83 | /**
84 | * Create a Cartridge Generation Client with injected dependencies
85 | */
86 | createCartridgeClient(
87 | fileSystemService?: IFileSystemService,
88 | pathService?: IPathService,
89 | ): CartridgeGenerationClient {
90 | this.logger.debug('Creating Cartridge Generation Client');
91 | return new CartridgeGenerationClient(
92 | fileSystemService ?? new FileSystemService(),
93 | pathService ?? new PathService(),
94 | );
95 | }
96 |
97 | /**
98 | * Get the required error message for a client type
99 | */
100 | static getClientRequiredError(clientType: 'OCAPI' | 'Log'): string {
101 | switch (clientType) {
102 | case 'OCAPI':
103 | return 'OCAPI client not configured - ensure credentials are provided in full mode.';
104 | case 'Log':
105 | return 'Log client not configured - ensure log access is enabled.';
106 | default:
107 | return 'Required client not configured.';
108 | }
109 | }
110 | }
111 |
```
--------------------------------------------------------------------------------
/docs/dw_catalog/ProductOption.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.catalog
2 |
3 | # Class ProductOption
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.object.PersistentObject
9 | - dw.object.ExtensibleObject
10 | - dw.catalog.ProductOption
11 |
12 | ## Description
13 |
14 | Represents a product option.
15 |
16 | ## Properties
17 |
18 | ### defaultValue
19 |
20 | **Type:** ProductOptionValue (Read Only)
21 |
22 | The default value for the product option.
23 |
24 | ### description
25 |
26 | **Type:** String (Read Only)
27 |
28 | The product option's short description in the current locale.
29 |
30 | ### displayName
31 |
32 | **Type:** String (Read Only)
33 |
34 | The product option's display name in the current locale.
35 |
36 | ### htmlName
37 |
38 | **Type:** String (Read Only)
39 |
40 | An HTML representation of the option id.
41 |
42 | ### ID
43 |
44 | **Type:** String (Read Only)
45 |
46 | The product option ID.
47 |
48 | ### image
49 |
50 | **Type:** MediaFile (Read Only)
51 |
52 | The product option's image.
53 |
54 | ### optionValues
55 |
56 | **Type:** Collection (Read Only)
57 |
58 | A collection containing the product option values.
59 |
60 | ## Constructor Summary
61 |
62 | ## Method Summary
63 |
64 | ### getDefaultValue
65 |
66 | **Signature:** `getDefaultValue() : ProductOptionValue`
67 |
68 | Returns the default value for the product option.
69 |
70 | ### getDescription
71 |
72 | **Signature:** `getDescription() : String`
73 |
74 | Returns the product option's short description in the current locale.
75 |
76 | ### getDisplayName
77 |
78 | **Signature:** `getDisplayName() : String`
79 |
80 | Returns the product option's display name in the current locale.
81 |
82 | ### getHtmlName
83 |
84 | **Signature:** `getHtmlName() : String`
85 |
86 | Returns an HTML representation of the option id.
87 |
88 | ### getHtmlName
89 |
90 | **Signature:** `getHtmlName(prefix : String) : String`
91 |
92 | Returns an HTML representation of the option id with the custom prefix.
93 |
94 | ### getID
95 |
96 | **Signature:** `getID() : String`
97 |
98 | Returns the product option ID.
99 |
100 | ### getImage
101 |
102 | **Signature:** `getImage() : MediaFile`
103 |
104 | Returns the product option's image.
105 |
106 | ### getOptionValues
107 |
108 | **Signature:** `getOptionValues() : Collection`
109 |
110 | Returns a collection containing the product option values.
111 |
112 | ## Method Detail
113 |
114 | ## Method Details
115 |
116 | ### getDefaultValue
117 |
118 | **Signature:** `getDefaultValue() : ProductOptionValue`
119 |
120 | **Description:** Returns the default value for the product option.
121 |
122 | **Returns:**
123 |
124 | the object for the relation 'defaultValue'
125 |
126 | ---
127 |
128 | ### getDescription
129 |
130 | **Signature:** `getDescription() : String`
131 |
132 | **Description:** Returns the product option's short description in the current locale.
133 |
134 | **Returns:**
135 |
136 | The value of the short description in the current locale, or null if it wasn't found.
137 |
138 | ---
139 |
140 | ### getDisplayName
141 |
142 | **Signature:** `getDisplayName() : String`
143 |
144 | **Description:** Returns the product option's display name in the current locale.
145 |
146 | **Returns:**
147 |
148 | The value of the display name in the current locale, or null if it wasn't found.
149 |
150 | ---
151 |
152 | ### getHtmlName
153 |
154 | **Signature:** `getHtmlName() : String`
155 |
156 | **Description:** Returns an HTML representation of the option id.
157 |
158 | **Returns:**
159 |
160 | an HTML representation of the option id.
161 |
162 | ---
163 |
164 | ### getHtmlName
165 |
166 | **Signature:** `getHtmlName(prefix : String) : String`
167 |
168 | **Description:** Returns an HTML representation of the option id with the custom prefix.
169 |
170 | **Parameters:**
171 |
172 | - `prefix`: a custom prefix for the html name.
173 |
174 | **Returns:**
175 |
176 | an HTML representation of the option id.
177 |
178 | ---
179 |
180 | ### getID
181 |
182 | **Signature:** `getID() : String`
183 |
184 | **Description:** Returns the product option ID.
185 |
186 | **Returns:**
187 |
188 | the product option identifier.
189 |
190 | ---
191 |
192 | ### getImage
193 |
194 | **Signature:** `getImage() : MediaFile`
195 |
196 | **Description:** Returns the product option's image.
197 |
198 | **Returns:**
199 |
200 | the product option's image.
201 |
202 | ---
203 |
204 | ### getOptionValues
205 |
206 | **Signature:** `getOptionValues() : Collection`
207 |
208 | **Description:** Returns a collection containing the product option values.
209 |
210 | **Returns:**
211 |
212 | a collection containing the product option values.
213 |
214 | ---
```
--------------------------------------------------------------------------------
/docs/dw_suggest/SuggestedTerm.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.suggest
2 |
3 | # Class SuggestedTerm
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.suggest.SuggestedTerm
9 |
10 | ## Description
11 |
12 | A single suggested term. Each user input term of the search phrase is being processed separately by the suggestion engine. For each original term, a list of terms will be suggested, either completed terms, corrected terms or even the exact term if it is known to the engine. Each suggested term is represented by a instance of this class. The list of suggested terms belonging to a single original term is represented by a instance of SuggestedTerms class. The suggested term value can either be the completed version of the original term, the corrected version of the original term or exactly the original term.
13 |
14 | ## Properties
15 |
16 | ### additional
17 |
18 | **Type:** boolean (Read Only)
19 |
20 | Returns whether this suggested term is a additional term that has no corresponding term in the original search phrase.
21 |
22 | ### completed
23 |
24 | **Type:** boolean (Read Only)
25 |
26 | Returns whether this suggested term is a auto completed version of the original term.
27 | In other words, this method returns true if the original term is a prefix of this suggested term.
28 |
29 | ### corrected
30 |
31 | **Type:** boolean (Read Only)
32 |
33 | Returns whether this suggested term is a corrected version of the original term.
34 |
35 | ### exactMatch
36 |
37 | **Type:** boolean (Read Only)
38 |
39 | Returns whether this suggested term is exactly matching the original term.
40 |
41 | ### value
42 |
43 | **Type:** String (Read Only)
44 |
45 | Returns this suggested term as String value.
46 |
47 | ## Constructor Summary
48 |
49 | ## Method Summary
50 |
51 | ### getValue
52 |
53 | **Signature:** `getValue() : String`
54 |
55 | Returns this suggested term as String value.
56 |
57 | ### isAdditional
58 |
59 | **Signature:** `isAdditional() : boolean`
60 |
61 | Returns whether this suggested term is a additional term that has no corresponding term in the original search phrase.
62 |
63 | ### isCompleted
64 |
65 | **Signature:** `isCompleted() : boolean`
66 |
67 | Returns whether this suggested term is a auto completed version of the original term.
68 |
69 | ### isCorrected
70 |
71 | **Signature:** `isCorrected() : boolean`
72 |
73 | Returns whether this suggested term is a corrected version of the original term.
74 |
75 | ### isExactMatch
76 |
77 | **Signature:** `isExactMatch() : boolean`
78 |
79 | Returns whether this suggested term is exactly matching the original term.
80 |
81 | ## Method Detail
82 |
83 | ## Method Details
84 |
85 | ### getValue
86 |
87 | **Signature:** `getValue() : String`
88 |
89 | **Description:** Returns this suggested term as String value.
90 |
91 | **Returns:**
92 |
93 | the string representation of this suggested term
94 |
95 | ---
96 |
97 | ### isAdditional
98 |
99 | **Signature:** `isAdditional() : boolean`
100 |
101 | **Description:** Returns whether this suggested term is a additional term that has no corresponding term in the original search phrase.
102 |
103 | **Returns:**
104 |
105 | true if this suggested term is a additional term, false otherwise
106 |
107 | ---
108 |
109 | ### isCompleted
110 |
111 | **Signature:** `isCompleted() : boolean`
112 |
113 | **Description:** Returns whether this suggested term is a auto completed version of the original term. In other words, this method returns true if the original term is a prefix of this suggested term.
114 |
115 | **Returns:**
116 |
117 | true if this suggested term is evaluated by auto completion, false otherwise
118 |
119 | ---
120 |
121 | ### isCorrected
122 |
123 | **Signature:** `isCorrected() : boolean`
124 |
125 | **Description:** Returns whether this suggested term is a corrected version of the original term.
126 |
127 | **Returns:**
128 |
129 | true if this suggested term is a corrected version of the original term, false otherwise
130 |
131 | ---
132 |
133 | ### isExactMatch
134 |
135 | **Signature:** `isExactMatch() : boolean`
136 |
137 | **Description:** Returns whether this suggested term is exactly matching the original term.
138 |
139 | **Returns:**
140 |
141 | true if this suggested term exactly matches the original term, false otherwise
142 |
143 | ---
```
--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/src/utils/webdav-xml.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * WebDAV XML Response Utilities
3 | *
4 | * Handles generation of WebDAV XML responses for PROPFIND and other operations.
5 | * Provides clean, reusable functions for XML generation.
6 | */
7 |
8 | const path = require('path');
9 |
10 | /**
11 | * Generate WebDAV XML response for a single file
12 | */
13 | function generateFileXmlResponse(urlPath, stats) {
14 | const filename = path.basename(urlPath);
15 |
16 | return `<?xml version="1.0" encoding="utf-8"?>
17 | <D:multistatus xmlns:D="DAV:">
18 | <D:response>
19 | <D:href>${urlPath}</D:href>
20 | <D:propstat>
21 | <D:prop>
22 | <D:displayname>${filename}</D:displayname>
23 | <D:getcontentlength>${stats.size}</D:getcontentlength>
24 | <D:getlastmodified>${stats.mtime.toUTCString()}</D:getlastmodified>
25 | <D:resourcetype></D:resourcetype>
26 | <D:getcontenttype>text/plain</D:getcontenttype>
27 | </D:prop>
28 | <D:status>HTTP/1.1 200 OK</D:status>
29 | </D:propstat>
30 | </D:response>
31 | </D:multistatus>`;
32 | }
33 |
34 | /**
35 | * Generate WebDAV XML response for directory listing
36 | */
37 | function generateDirectoryXmlResponse(urlPath, items, stats) {
38 | const directoryName = path.basename(urlPath) || 'Logs';
39 |
40 | // Generate individual item entries
41 | const xmlItems = items.map(item => {
42 | const isDirectory = item.stats.isDirectory();
43 | const itemUrl = urlPath.endsWith('/') ? `${urlPath}${item.name}` : `${urlPath}/${item.name}`;
44 |
45 | return `
46 | <D:response>
47 | <D:href>${itemUrl}${isDirectory ? '/' : ''}</D:href>
48 | <D:propstat>
49 | <D:prop>
50 | <D:displayname>${item.name}</D:displayname>
51 | <D:getcontentlength>${isDirectory ? '' : item.stats.size}</D:getcontentlength>
52 | <D:getlastmodified>${item.stats.mtime.toUTCString()}</D:getlastmodified>
53 | <D:resourcetype>${isDirectory ? '<D:collection/>' : ''}</D:resourcetype>
54 | ${!isDirectory ? '<D:getcontenttype>text/plain</D:getcontenttype>' : ''}
55 | </D:prop>
56 | <D:status>HTTP/1.1 200 OK</D:status>
57 | </D:propstat>
58 | </D:response>`;
59 | }).join('');
60 |
61 | return `<?xml version="1.0" encoding="utf-8"?>
62 | <D:multistatus xmlns:D="DAV:">
63 | <D:response>
64 | <D:href>${urlPath}</D:href>
65 | <D:propstat>
66 | <D:prop>
67 | <D:displayname>${directoryName}</D:displayname>
68 | <D:resourcetype><D:collection/></D:resourcetype>
69 | </D:prop>
70 | <D:status>HTTP/1.1 200 OK</D:status>
71 | </D:propstat>
72 | </D:response>${xmlItems}
73 | </D:multistatus>`;
74 | }
75 |
76 | /**
77 | * Generate WebDAV error response
78 | */
79 | function generateErrorXmlResponse(urlPath, statusCode, message) {
80 | return `<?xml version="1.0" encoding="utf-8"?>
81 | <D:multistatus xmlns:D="DAV:">
82 | <D:response>
83 | <D:href>${urlPath}</D:href>
84 | <D:propstat>
85 | <D:status>HTTP/1.1 ${statusCode} ${message}</D:status>
86 | </D:propstat>
87 | </D:response>
88 | </D:multistatus>`;
89 | }
90 |
91 | /**
92 | * Parse WebDAV depth header
93 | */
94 | function parseDepthHeader(depthHeader) {
95 | if (!depthHeader) return 'infinity';
96 |
97 | const depth = depthHeader.toLowerCase();
98 | if (depth === '0') return 0;
99 | if (depth === '1') return 1;
100 | return 'infinity';
101 | }
102 |
103 | /**
104 | * Escape XML special characters
105 | */
106 | function escapeXml(text) {
107 | return text
108 | .replace(/&/g, '&')
109 | .replace(/</g, '<')
110 | .replace(/>/g, '>')
111 | .replace(/"/g, '"')
112 | .replace(/'/g, ''');
113 | }
114 |
115 | module.exports = {
116 | generateFileXmlResponse,
117 | generateDirectoryXmlResponse,
118 | generateErrorXmlResponse,
119 | parseDepthHeader,
120 | escapeXml
121 | };
```
--------------------------------------------------------------------------------
/docs/sfra/store.md:
--------------------------------------------------------------------------------
```markdown
1 | # SFRA Store Model
2 |
3 | ## Overview
4 |
5 | The Store model represents a physical store location in SFRA applications. It provides store information including location details, contact information, and store hours for store locator functionality and in-store pickup features.
6 |
7 | ## Constructor
8 |
9 | ```javascript
10 | function store(storeObject)
11 | ```
12 |
13 | Creates a Store model instance from a store object.
14 |
15 | ### Parameters
16 |
17 | - `storeObject` (dw.catalog.Store) - A Store object from the SFCC API
18 |
19 | ## Properties
20 |
21 | ### ID
22 | **Type:** string
23 |
24 | Unique identifier for the store.
25 |
26 | ### name
27 | **Type:** string
28 |
29 | Display name of the store.
30 |
31 | ### address1
32 | **Type:** string
33 |
34 | Primary address line of the store location.
35 |
36 | ### address2
37 | **Type:** string
38 |
39 | Secondary address line (suite, building, etc.).
40 |
41 | ### city
42 | **Type:** string
43 |
44 | City where the store is located.
45 |
46 | ### postalCode
47 | **Type:** string
48 |
49 | Postal/ZIP code for the store location.
50 |
51 | ### latitude
52 | **Type:** number
53 |
54 | Latitude coordinate for the store location (used for mapping and distance calculations).
55 |
56 | ### longitude
57 | **Type:** number
58 |
59 | Longitude coordinate for the store location (used for mapping and distance calculations).
60 |
61 | ### phone
62 | **Type:** string (optional)
63 |
64 | Store phone number for customer contact.
65 |
66 | ### stateCode
67 | **Type:** string (optional)
68 |
69 | State or province code for the store location.
70 |
71 | ### countryCode
72 | **Type:** string (optional)
73 |
74 | Country code for the store location (extracted from countryCode.value).
75 |
76 | ### storeHours
77 | **Type:** string (optional)
78 |
79 | Store hours information as markup/HTML content for display.
80 |
81 | ## Usage Example
82 |
83 | ```javascript
84 | var store = require('*/cartridge/models/store');
85 | var StoreMgr = require('dw/catalog/StoreMgr');
86 |
87 | // Get a specific store
88 | var storeObject = StoreMgr.getStore('store-001');
89 | var storeModel = new store(storeObject);
90 |
91 | // Access store properties
92 | console.log(storeModel.name); // "Downtown Location"
93 | console.log(storeModel.address1); // "123 Main St"
94 | console.log(storeModel.city); // "New York"
95 | console.log(storeModel.phone); // "555-123-4567"
96 |
97 | // Use coordinates for mapping
98 | if (storeModel.latitude && storeModel.longitude) {
99 | console.log('Location: ' + storeModel.latitude + ', ' + storeModel.longitude);
100 | }
101 |
102 | // Display store hours
103 | if (storeModel.storeHours) {
104 | console.log(storeModel.storeHours); // HTML markup for hours display
105 | }
106 | ```
107 |
108 | ## Coordinate System
109 |
110 | The model provides geographic coordinates for:
111 | - **Mapping Integration** - Display stores on maps
112 | - **Distance Calculations** - Find nearest stores
113 | - **Location Services** - GPS-based store finding
114 |
115 | ## Conditional Properties
116 |
117 | Several properties are only included if they exist in the source store object:
118 | - **phone** - Only included if store has a phone number
119 | - **stateCode** - Only included for locations with state/province
120 | - **countryCode** - Only included if country is specified
121 | - **storeHours** - Only included if store hours are configured
122 |
123 | ## Store Hours Format
124 |
125 | Store hours are provided as markup/HTML content, allowing for:
126 | - Rich formatting of hours display
127 | - Multiple day ranges and special hours
128 | - Holiday hours and exceptions
129 | - Custom styling and presentation
130 |
131 | ## Notes
132 |
133 | - Handles missing store data gracefully
134 | - Provides essential location information for store locators
135 | - Includes geographic coordinates for mapping functionality
136 | - Supports international stores with flexible address formats
137 | - Store hours support rich HTML formatting
138 | - Null-safe property access for optional fields
139 |
140 | ## Related Models
141 |
142 | - **Stores Model** - Collection of store models
143 | - **Product Models** - May include store availability
144 | - **Cart Models** - May include store pickup options
145 | - **Address Models** - Similar address structure
146 |
```
--------------------------------------------------------------------------------
/docs/dw_campaign/SourceCodeInfo.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.campaign
2 |
3 | # Class SourceCodeInfo
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.campaign.SourceCodeInfo
9 |
10 | ## Description
11 |
12 | Class representing a code (i.e. a "source code") that has been applied to a customer's session. Source codes can qualify customers for different campaigns, promotions, and other site experiences from those that the typical customer sees. Codes are organized into source code groups. Typically, a code is applied to a customer's session automatically by Commerce Cloud Digital when a customer accesses a Digital URL with a well known request parameter in the querystring. A code may also be explicitly applied to a customer session using the SetSourceCode pipelet.
13 |
14 | ## Constants
15 |
16 | ### STATUS_ACTIVE
17 |
18 | **Type:** Number = 2
19 |
20 | The literal source-code is found and currently active.
21 |
22 | ### STATUS_INACTIVE
23 |
24 | **Type:** Number = 1
25 |
26 | The literal source-code is found but not active.
27 |
28 | ### STATUS_INVALID
29 |
30 | **Type:** Number = 0
31 |
32 | The literal source-code is not found in the system.
33 |
34 | ## Properties
35 |
36 | ### code
37 |
38 | **Type:** String (Read Only)
39 |
40 | The literal source-code.
41 |
42 | ### group
43 |
44 | **Type:** SourceCodeGroup (Read Only)
45 |
46 | The associated source-code group.
47 |
48 | ### redirect
49 |
50 | **Type:** URLRedirect (Read Only)
51 |
52 | Retrieves the redirect information from the last processed SourceCodeGroup (active or inactive). If none exists,
53 | then the redirect information is retrieved from the source-code preferences, based on the active/inactive status
54 | of the SourceCodeGroup. The redirect information is then resolved to the output URL. If the redirect information
55 | cannot be resolved to a URL, or there is an error retrieving the preferences, then null is returned.
56 |
57 | ### status
58 |
59 | **Type:** Number (Read Only)
60 |
61 | The status of the source-code. One of the following:
62 | STATUS_INVALID - The source code is not found in the system.
63 | STATUS_INACTIVE - The source code is found but not active.
64 | STATUS_INACTIVE - The source code is found and active.
65 |
66 | ## Constructor Summary
67 |
68 | ## Method Summary
69 |
70 | ### getCode
71 |
72 | **Signature:** `getCode() : String`
73 |
74 | The literal source-code.
75 |
76 | ### getGroup
77 |
78 | **Signature:** `getGroup() : SourceCodeGroup`
79 |
80 | The associated source-code group.
81 |
82 | ### getRedirect
83 |
84 | **Signature:** `getRedirect() : URLRedirect`
85 |
86 | Retrieves the redirect information from the last processed SourceCodeGroup (active or inactive).
87 |
88 | ### getStatus
89 |
90 | **Signature:** `getStatus() : Number`
91 |
92 | The status of the source-code.
93 |
94 | ## Method Detail
95 |
96 | ## Method Details
97 |
98 | ### getCode
99 |
100 | **Signature:** `getCode() : String`
101 |
102 | **Description:** The literal source-code.
103 |
104 | **Returns:**
105 |
106 | the source-code.
107 |
108 | ---
109 |
110 | ### getGroup
111 |
112 | **Signature:** `getGroup() : SourceCodeGroup`
113 |
114 | **Description:** The associated source-code group.
115 |
116 | **Returns:**
117 |
118 | the source-code group.
119 |
120 | ---
121 |
122 | ### getRedirect
123 |
124 | **Signature:** `getRedirect() : URLRedirect`
125 |
126 | **Description:** Retrieves the redirect information from the last processed SourceCodeGroup (active or inactive). If none exists, then the redirect information is retrieved from the source-code preferences, based on the active/inactive status of the SourceCodeGroup. The redirect information is then resolved to the output URL. If the redirect information cannot be resolved to a URL, or there is an error retrieving the preferences, then null is returned.
127 |
128 | **Returns:**
129 |
130 | URLRedirect containing the location and status code, null in case of no redirect was found
131 |
132 | ---
133 |
134 | ### getStatus
135 |
136 | **Signature:** `getStatus() : Number`
137 |
138 | **Description:** The status of the source-code. One of the following: STATUS_INVALID - The source code is not found in the system. STATUS_INACTIVE - The source code is found but not active. STATUS_INACTIVE - The source code is found and active.
139 |
140 | **Returns:**
141 |
142 | the status.
143 |
144 | ---
```
--------------------------------------------------------------------------------
/docs/dw_util/FilteringCollection.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.util
2 |
3 | # Class FilteringCollection
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.util.Collection
9 | - dw.util.FilteringCollection
10 |
11 | ## Description
12 |
13 | FilteringCollection is an extension of Collection which provides possibilities to filter the elements to return a new FilteringCollection with a filtered set of elements sort the elements to return a new FilteringCollection with a defined sort order transform the elements to return a new FilteringCollection containing related elements provide a map of the elements against a predefined key Usage - In the current version each FilteringCollection provides a set of predefined qualifier constants which can be passed into the select(Object) method used to filter the elements. Generally qualifiers have the prefix QUALIFIER_. A second method sort(Object) is used to create a new instance with a different element ordering, which takes an orderB< constant. Generally orderBys have the prefix ORDERBY_: examples are ShippingOrder.ORDERBY_ITEMID, ShippingOrder.ORDERBY_ITEMPOSITION, and ORDERBY_REVERSE can be used to provide a FilteringCollection with the reverse ordering. An example with method ShippingOrder.getItems(): var allItems : FilteringCollection = shippingOrder.items; var productItems : FilteringCollection = allItems.select(ShippingOrder.QUALIFIER_PRODUCTITEMS); var serviceItems : FilteringCollection = allItems.select(ShippingOrder.QUALIFIER_SERVICEITEMS); var byPosition : FilteringCollection = productItems.sort(ShippingOrder.ORDERBY_ITEMPOSITION); var revByPosition: FilteringCollection = byPosition.sort(FilteringCollection.ORDERBY_REVERSE); var mapByItemID : Map = allItems.asMap();
14 |
15 | ## Constants
16 |
17 | ### ORDERBY_REVERSE
18 |
19 | **Type:** Object
20 |
21 | Pass this orderBy with the sort(Object) method to obtain a new FilteringCollection with the reversed sort order. Only use on a FilteringCollection which has been previously sorted.
22 |
23 | ## Properties
24 |
25 | ## Constructor Summary
26 |
27 | ## Method Summary
28 |
29 | ### asMap
30 |
31 | **Signature:** `asMap() : Map`
32 |
33 | Returns a Map containing the elements of this FilteringCollection against a predefined key.
34 |
35 | ### select
36 |
37 | **Signature:** `select(qualifier : Object) : FilteringCollection`
38 |
39 | Select a new FilteringCollection instance by passing a predefined qualifier as an argument to this method.
40 |
41 | ### sort
42 |
43 | **Signature:** `sort(orderBy : Object) : FilteringCollection`
44 |
45 | Select a new FilteringCollection instance by passing a predefined orderBy as an argument to this method.
46 |
47 | ## Method Detail
48 |
49 | ## Method Details
50 |
51 | ### asMap
52 |
53 | **Signature:** `asMap() : Map`
54 |
55 | **Description:** Returns a Map containing the elements of this FilteringCollection against a predefined key. The key used is documented in the method returning the FilteringCollection and is typically the ItemID assigned to an element in the collection.
56 |
57 | **Returns:**
58 |
59 | a Map containing the elements of this FilteringCollection against a predefined key.
60 |
61 | ---
62 |
63 | ### select
64 |
65 | **Signature:** `select(qualifier : Object) : FilteringCollection`
66 |
67 | **Description:** Select a new FilteringCollection instance by passing a predefined qualifier as an argument to this method. See FilteringCollection.
68 |
69 | **Parameters:**
70 |
71 | - `qualifier`: possible qualifiers are documented in the method returning the FilteringCollection
72 |
73 | **Returns:**
74 |
75 | a new FilteringCollection instance
76 |
77 | ---
78 |
79 | ### sort
80 |
81 | **Signature:** `sort(orderBy : Object) : FilteringCollection`
82 |
83 | **Description:** Select a new FilteringCollection instance by passing a predefined orderBy as an argument to this method. See FilteringCollection.
84 |
85 | **Parameters:**
86 |
87 | - `orderBy`: possible orderBys are documented in the method returning the FilteringCollection
88 |
89 | **Returns:**
90 |
91 | a new FilteringCollection instance
92 |
93 | ---
```
--------------------------------------------------------------------------------
/docs/dw_catalog/CategoryAssignment.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.catalog
2 |
3 | # Class CategoryAssignment
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.object.PersistentObject
9 | - dw.object.ExtensibleObject
10 | - dw.catalog.CategoryAssignment
11 |
12 | ## Description
13 |
14 | Represents a category assignment in Commerce Cloud Digital.
15 |
16 | ## Properties
17 |
18 | ### calloutMsg
19 |
20 | **Type:** MarkupText (Read Only)
21 |
22 | The category assignment's callout message in the current locale.
23 |
24 | ### category
25 |
26 | **Type:** Category (Read Only)
27 |
28 | The category to which this category assignment is bound.
29 |
30 | ### image
31 |
32 | **Type:** MediaFile (Read Only)
33 |
34 | The category assignment's image.
35 |
36 | ### longDescription
37 |
38 | **Type:** MarkupText (Read Only)
39 |
40 | The category assignment's long description in the current locale.
41 |
42 | ### name
43 |
44 | **Type:** String (Read Only)
45 |
46 | The name of the category assignment in the current locale.
47 |
48 | ### product
49 |
50 | **Type:** Product (Read Only)
51 |
52 | The product to which this category assignment is bound.
53 |
54 | ### shortDescription
55 |
56 | **Type:** MarkupText (Read Only)
57 |
58 | The category assignment's short description in the current locale.
59 |
60 | ## Constructor Summary
61 |
62 | ## Method Summary
63 |
64 | ### getCalloutMsg
65 |
66 | **Signature:** `getCalloutMsg() : MarkupText`
67 |
68 | Returns the category assignment's callout message in the current locale.
69 |
70 | ### getCategory
71 |
72 | **Signature:** `getCategory() : Category`
73 |
74 | Returns the category to which this category assignment is bound.
75 |
76 | ### getImage
77 |
78 | **Signature:** `getImage() : MediaFile`
79 |
80 | Returns the category assignment's image.
81 |
82 | ### getLongDescription
83 |
84 | **Signature:** `getLongDescription() : MarkupText`
85 |
86 | Returns the category assignment's long description in the current locale.
87 |
88 | ### getName
89 |
90 | **Signature:** `getName() : String`
91 |
92 | Returns the name of the category assignment in the current locale.
93 |
94 | ### getProduct
95 |
96 | **Signature:** `getProduct() : Product`
97 |
98 | Returns the product to which this category assignment is bound.
99 |
100 | ### getShortDescription
101 |
102 | **Signature:** `getShortDescription() : MarkupText`
103 |
104 | Returns the category assignment's short description in the current locale.
105 |
106 | ## Method Detail
107 |
108 | ## Method Details
109 |
110 | ### getCalloutMsg
111 |
112 | **Signature:** `getCalloutMsg() : MarkupText`
113 |
114 | **Description:** Returns the category assignment's callout message in the current locale.
115 |
116 | **Returns:**
117 |
118 | the category assignment's callout message in the current locale, or null if it wasn't found.
119 |
120 | ---
121 |
122 | ### getCategory
123 |
124 | **Signature:** `getCategory() : Category`
125 |
126 | **Description:** Returns the category to which this category assignment is bound.
127 |
128 | **Returns:**
129 |
130 | The category to which this category assignment is bound.
131 |
132 | ---
133 |
134 | ### getImage
135 |
136 | **Signature:** `getImage() : MediaFile`
137 |
138 | **Description:** Returns the category assignment's image.
139 |
140 | **Returns:**
141 |
142 | the category assignment's image.
143 |
144 | ---
145 |
146 | ### getLongDescription
147 |
148 | **Signature:** `getLongDescription() : MarkupText`
149 |
150 | **Description:** Returns the category assignment's long description in the current locale.
151 |
152 | **Returns:**
153 |
154 | The category assignment's long description in the current locale, or null if it wasn't found.
155 |
156 | ---
157 |
158 | ### getName
159 |
160 | **Signature:** `getName() : String`
161 |
162 | **Description:** Returns the name of the category assignment in the current locale.
163 |
164 | **Returns:**
165 |
166 | The name of the category assignment for the current locale, or null if it wasn't found.
167 |
168 | ---
169 |
170 | ### getProduct
171 |
172 | **Signature:** `getProduct() : Product`
173 |
174 | **Description:** Returns the product to which this category assignment is bound.
175 |
176 | **Returns:**
177 |
178 | The product to which this category assignment is bound.
179 |
180 | ---
181 |
182 | ### getShortDescription
183 |
184 | **Signature:** `getShortDescription() : MarkupText`
185 |
186 | **Description:** Returns the category assignment's short description in the current locale.
187 |
188 | **Returns:**
189 |
190 | the category assignment's short description in the current locale, or null if it wasn't found.
191 |
192 | ---
```
--------------------------------------------------------------------------------
/tests/servers/sfcc-mock-server/src/config/server-config.js:
--------------------------------------------------------------------------------
```javascript
1 | /**
2 | * Server Configuration Management
3 | *
4 | * Handles server configuration with sensible defaults and environment overrides.
5 | * Follows single responsibility principle for configuration management.
6 | */
7 |
8 | class ServerConfig {
9 | constructor(options = {}) {
10 | // Server basics
11 | this.port = options.port || process.env.PORT || 3000;
12 | this.host = options.host || process.env.HOST || 'localhost';
13 | this.isDevMode = options.dev || process.env.NODE_ENV === 'development' || false;
14 |
15 | // API versions
16 | this.ocapiVersion = options.ocapiVersion || 'v23_2';
17 |
18 | // Paths
19 | this.mockDataPath = options.mockDataPath || require('path').join(__dirname, '../../mock-data');
20 | this.webdavBasePath = '/on/demandware.servlet/webdav/Sites';
21 |
22 | // Authentication - Mock credentials for testing
23 | this.validCredentials = {
24 | clientId: 'test-client-id',
25 | clientSecret: 'test-client-secret',
26 | username: 'test-user',
27 | password: 'test-password'
28 | };
29 |
30 | // Features toggle
31 | this.features = {
32 | webdav: options.enableWebdav !== false, // enabled by default
33 | ocapi: options.enableOcapi !== false, // enabled by default
34 | cors: options.enableCors !== false, // enabled by default
35 | logging: options.enableLogging !== false, // enabled by default
36 | randomErrors: options.enableRandomErrors === true // disabled by default for reliable tests
37 | };
38 | }
39 |
40 | /**
41 | * Get WebDAV configuration
42 | */
43 | getWebdavConfig() {
44 | return {
45 | basePath: this.webdavBasePath,
46 | logsPath: require('path').join(this.mockDataPath, 'logs'),
47 | enabled: this.features.webdav
48 | };
49 | }
50 |
51 | /**
52 | * Get OCAPI configuration
53 | */
54 | getOcapiConfig() {
55 | return {
56 | version: this.ocapiVersion,
57 | basePath: `/s/-/dw/data/${this.ocapiVersion}`,
58 | mockDataPath: require('path').join(this.mockDataPath, 'ocapi'),
59 | enabled: this.features.ocapi
60 | };
61 | }
62 |
63 | /**
64 | * Get full server URL
65 | */
66 | getServerUrl() {
67 | return `http://${this.host}:${this.port}`;
68 | }
69 |
70 | /**
71 | * Get WebDAV logs URL
72 | */
73 | getWebdavLogsUrl() {
74 | return `${this.getServerUrl()}${this.webdavBasePath}/Logs/`;
75 | }
76 |
77 | /**
78 | * Get OCAPI base URL
79 | */
80 | getOcapiBaseUrl() {
81 | return `${this.getServerUrl()}/s/-/dw/data/${this.ocapiVersion}`;
82 | }
83 |
84 | /**
85 | * Validate configuration
86 | */
87 | validate() {
88 | const errors = [];
89 |
90 | if (!this.port || this.port < 1 || this.port > 65535) {
91 | errors.push('Invalid port number');
92 | }
93 |
94 | if (!this.host || typeof this.host !== 'string') {
95 | errors.push('Invalid host');
96 | }
97 |
98 | if (!this.features.webdav && !this.features.ocapi) {
99 | errors.push('At least one feature (WebDAV or OCAPI) must be enabled');
100 | }
101 |
102 | return errors;
103 | }
104 |
105 | /**
106 | * Get configuration summary for logging
107 | */
108 | getSummary() {
109 | return {
110 | server: `${this.host}:${this.port}`,
111 | mode: this.isDevMode ? 'development' : 'production',
112 | features: Object.entries(this.features)
113 | .filter(([_, enabled]) => enabled)
114 | .map(([feature, _]) => feature),
115 | endpoints: {
116 | ...(this.features.webdav && { webdav: this.getWebdavLogsUrl() }),
117 | ...(this.features.ocapi && { ocapi: this.getOcapiBaseUrl() }),
118 | health: `${this.getServerUrl()}/health`
119 | }
120 | };
121 | }
122 | }
123 |
124 | module.exports = ServerConfig;
```
--------------------------------------------------------------------------------
/docs/dw_system/RemoteInclude.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.system
2 |
3 | # Class RemoteInclude
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.system.RemoteInclude
9 |
10 | ## Description
11 |
12 | The class represents a remote include value that can be assigned to JSON Object properties. Important notes: Authentication and authorization checks are performed only for the top level request, but NOT for remote include requests. The RestResponseMgr method createScapiRemoteInclude() allows only SCAPI URLs. The RestResponseMgr method createStorefrontControllerRemoteInclude() allows only Controller URLs. Correct rendering of RemoteInclude-containing objects is only performed when processed by dw.system.RESTSuccessResponse.render() method. Please check the provided examples. Example 1. Specify remote include properties. function specifyRemoteIncludeProperties() { var includeValue0 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/0", dw.web.URLParameter("siteId", "TestWapi")); var includeValue1 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/1", dw.web.URLParameter("siteId", "TestWapi")); var greeting = { "hello": "world", "includeProperty0": includeValue0, "includeProperty1": includeValue1 }; dw.system.RESTResponseMgr.createSuccess(greeting).render(); } Example 2. Specify array of remote include properties. function specifyArrayOfRemoteIncludes() { var includeValue0 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/0", dw.web.URLParameter("siteId", "TestWapi")); var includeValue1 = dw.system.RESTResponseMgr.createScapiRemoteInclude("custom", "sample", "v1", "resource/path/1", dw.web.URLParameter("siteId", "TestWapi")); var greeting = { "hello": "world", "includeArray": [includeValue0, includeValue1] }; dw.system.RESTResponseMgr.createSuccess(greeting).render(); } Example 3. Storefront controller remote include. function storefrontRemoteInclude() { let remoteInclude = dw.system.RESTResponseMgr.createStorefrontControllerRemoteInclude(new URLAction("Category-Show", "Sites-MyShop-Site", dw.web.URLParameter("cid", "root"))); let json = { status: "JSONOK", include: remoteInclude }; dw.system.RESTResponseMgr.createSuccess(json).render(); } Error handling: SCAPI: In case of 404 response received on included resource, an empty JSON object '{}' will be supplied in final JSON. In case of 201..299, 3xx, 4xx (excluding 404), 5xx response from included resource, final response status will be 500 'Internal Server Error' Controllers: In case of any non 200 response from the included resource an empty string will be included. Note: In case your response format is JSON be aware that this can result in invalid JSON.
13 |
14 | ## Properties
15 |
16 | ### url
17 |
18 | **Type:** String (Read Only)
19 |
20 | The URL string value specified for the current instance.
21 |
22 | ### value
23 |
24 | **Type:** String (Read Only)
25 |
26 | ## Constructor Summary
27 |
28 | ## Method Summary
29 |
30 | ### getUrl
31 |
32 | **Signature:** `getUrl() : String`
33 |
34 | Returns the URL string value specified for the current instance.
35 |
36 | ### toString
37 |
38 | **Signature:** `toString() : String`
39 |
40 | Returns the URL string value specified for the current instance, same as getUrl().
41 |
42 | ### valueOf
43 |
44 | **Signature:** `valueOf() : Object`
45 |
46 | Returns the URL string value specified for the current instance, same as getUrl().
47 |
48 | ## Method Detail
49 |
50 | ## Method Details
51 |
52 | ### getUrl
53 |
54 | **Signature:** `getUrl() : String`
55 |
56 | **Description:** Returns the URL string value specified for the current instance.
57 |
58 | ---
59 |
60 | ### toString
61 |
62 | **Signature:** `toString() : String`
63 |
64 | **Description:** Returns the URL string value specified for the current instance, same as getUrl().
65 |
66 | ---
67 |
68 | ### valueOf
69 |
70 | **Signature:** `valueOf() : Object`
71 |
72 | **Description:** Returns the URL string value specified for the current instance, same as getUrl().
73 |
74 | ---
```
--------------------------------------------------------------------------------
/docs/sfra/price-tiered.md:
--------------------------------------------------------------------------------
```markdown
1 | # SFRA Tiered Price Model
2 |
3 | ## Overview
4 |
5 | The Tiered Price model represents quantity-based pricing in SFRA applications, where products have different prices based on the quantity purchased. This enables bulk discounts and volume pricing strategies.
6 |
7 | ## Constructor
8 |
9 | ```javascript
10 | function TieredPrice(priceTable, useSimplePrice)
11 | ```
12 |
13 | Creates a Tiered Price model instance with quantity-based pricing tiers.
14 |
15 | ### Parameters
16 |
17 | - `priceTable` (dw.catalog.ProductPriceTable) - Product price table from the API
18 | - `useSimplePrice` (boolean) - Flag indicating if this is for a product tile (optional)
19 |
20 | ## Properties
21 |
22 | ### type
23 | **Type:** string
24 |
25 | Always set to 'tiered' to identify this as a tiered price model.
26 |
27 | ### useSimplePrice
28 | **Type:** boolean
29 |
30 | Flag indicating whether this price is intended for simplified display (e.g., product tiles). Defaults to false.
31 |
32 | ### tiers
33 | **Type:** Array<Object>
34 |
35 | Array of pricing tier objects, each containing:
36 | - `quantity` (number) - Minimum quantity for this price tier
37 | - `price` (DefaultPrice) - Price object for this quantity tier
38 |
39 | ### startingFromPrice
40 | **Type:** DefaultPrice
41 |
42 | The lowest price available across all tiers, representing the "starting from" price for marketing display. Access the formatted price via `.sales.formatted`.
43 |
44 | ## Tier Structure
45 |
46 | Each tier object in the tiers array contains:
47 |
48 | ### quantity
49 | Minimum quantity required to qualify for this price tier.
50 |
51 | ### price
52 | ### price
53 | Complete DefaultPrice object created with only the sales price for this tier (accessed via `.sales` property).
54 |
55 | ## Usage Example
56 |
57 | ```javascript
58 | var TieredPrice = require('*/cartridge/models/price/tiered');
59 |
60 | // Get tiered pricing from product
61 | var product = ProductMgr.getProduct('bulk-product-id');
62 | var priceTable = product.getPriceModel().getPriceTable();
63 |
64 | var tieredPrice = new TieredPrice(priceTable, false);
65 |
66 | console.log(tieredPrice.type); // "tiered"
67 | console.log('Starting from: ' + tieredPrice.startingFromPrice.sales.formatted);
68 |
69 | // Display all price tiers
70 | tieredPrice.tiers.forEach(function(tier) {
71 | console.log('Buy ' + tier.quantity + '+ for ' + tier.price.sales.formatted + ' each');
72 | });
73 |
74 | // Example output:
75 | // Buy 1+ for $10.00 each
76 | // Buy 5+ for $9.00 each
77 | // Buy 10+ for $8.00 each
78 | ```
79 |
80 | ## Price Calculation Logic
81 |
82 | The model automatically:
83 | 1. **Processes all quantity breaks** from the price table using `collections.map`
84 | 2. **Creates DefaultPrice instances** with only sales price for each tier
85 | 3. **Identifies the lowest price** by comparing `price.sales.value` across all tiers
86 | 4. **Sets startingFromPrice** to the best available price
87 | 5. **Maintains tier order** based on quantity requirements
88 | 6. **Converts quantities** to numeric values using `quantity.getValue()`
89 |
90 | ## Display Modes
91 |
92 | ### Full Pricing (useSimplePrice = false)
93 | - Shows all pricing tiers
94 | - Includes complete quantity break information
95 | - Used on product detail pages
96 |
97 | ### Simple Pricing (useSimplePrice = true)
98 | - Optimized for product tiles and listings
99 | - Focuses on starting price and key tiers
100 | - Simplified display for grid views
101 |
102 | ## Notes
103 |
104 | - Automatically calculates the best "starting from" price by comparing sales values
105 | - Each tier DefaultPrice is created with only sales price (access via `.sales` property)
106 | - Uses `collections.map` utility to process price table quantities
107 | - Supports unlimited number of quantity tiers
108 | - Each tier uses DefaultPrice for consistent formatting
109 | - Useful for B2B and bulk purchasing scenarios
110 | - Type property enables template conditional logic
111 | - `useSimplePrice` defaults to `false` if not provided
112 |
113 | ## Related Models
114 |
115 | - **DefaultPrice Model** - Used for individual tier pricing
116 | - **RangePrice Model** - Alternative pricing model for price ranges
117 | - **Product Models** - Use tiered prices for bulk products
118 |
```
--------------------------------------------------------------------------------
/docs/sfra/cart.md:
--------------------------------------------------------------------------------
```markdown
1 | # SFRA Cart Model
2 |
3 | ## Overview
4 |
5 | The Cart model represents the current customer's shopping basket in SFRA applications. It provides comprehensive cart functionality including product line items, shipping methods, totals, discounts, and cart actions.
6 |
7 | ## Constructor
8 |
9 | ```javascript
10 | function CartModel(basket)
11 | ```
12 |
13 | Creates a Cart model instance from a basket object.
14 |
15 | ### Parameters
16 |
17 | - `basket` (dw.order.Basket) - Current user's basket
18 |
19 | ## Properties
20 |
21 | ### items
22 | **Type:** Array<Object>
23 |
24 | Array of product line items in the cart. Each item contains product information, quantity, pricing, and other details.
25 |
26 | ### numItems
27 | **Type:** number
28 |
29 | Total number of items (quantity) in the cart.
30 |
31 | ### totals
32 | **Type:** TotalsModel
33 |
34 | Totals model containing cart pricing information including subtotals, taxes, shipping costs, and grand total.
35 |
36 | ### shipments
37 | **Type:** Array<Object>
38 |
39 | Array of shipment objects, each containing:
40 | - `shippingMethods` - Available shipping methods for the shipment
41 | - `selectedShippingMethod` - ID of the currently selected shipping method
42 |
43 | ### numOfShipments
44 | **Type:** number
45 |
46 | Number of shipments in the cart.
47 |
48 | ### hasBonusProduct
49 | **Type:** boolean
50 |
51 | Indicates whether the cart contains any bonus products from promotions.
52 |
53 | ### actionUrls
54 | **Type:** Object
55 |
56 | Object containing URLs for cart actions:
57 | - `removeProductLineItemUrl` - URL to remove product line items
58 | - `updateQuantityUrl` - URL to update item quantities
59 | - `selectShippingUrl` - URL to select shipping methods
60 | - `submitCouponCodeUrl` - URL to add coupon codes
61 | - `removeCouponLineItem` - URL to remove coupon line items
62 |
63 | ### approachingDiscounts
64 | **Type:** Array<Object>
65 |
66 | Array of approaching discount objects, each containing:
67 | - `discountMsg` - Message describing the approaching discount
68 |
69 | ### valid
70 | **Type:** boolean
71 |
72 | Indicates whether the basket is valid based on validation hooks.
73 |
74 | ### resources
75 | **Type:** Object
76 |
77 | Object containing localized resource strings:
78 | - `numberOfItems` - Formatted message showing number of items in cart
79 | - `minicartCountOfItems` - Formatted message for minicart count
80 | - `emptyCartMsg` - Message displayed when cart is empty
81 |
82 | ## Helper Functions
83 |
84 | ### getApproachingDiscounts(basket, discountPlan)
85 | Generates an object of approaching discounts based on current basket and discount plan.
86 |
87 | **Parameters:**
88 | - `basket` (dw.order.Basket) - Current user's basket
89 | - `discountPlan` (dw.campaign.DiscountPlan) - Set of applicable discounts
90 |
91 | **Returns:** Object - Object containing approaching discount information
92 |
93 | ### getCartActionUrls()
94 | Generates an object of URLs used for cart actions.
95 |
96 | **Returns:** Object - Object containing cart action URLs in string format
97 |
98 | ## Usage Example
99 |
100 | ```javascript
101 | var CartModel = require('*/cartridge/models/cart');
102 | var BasketMgr = require('dw/order/BasketMgr');
103 |
104 | var currentBasket = BasketMgr.getCurrentBasket();
105 | var cart = new CartModel(currentBasket);
106 |
107 | // Access cart properties
108 | console.log(cart.numItems);
109 | console.log(cart.totals.grandTotal);
110 | console.log(cart.actionUrls.updateQuantityUrl);
111 |
112 | // Check if cart has items
113 | if (cart.items && cart.items.length > 0) {
114 | // Process cart items
115 | cart.items.forEach(function(item) {
116 | console.log(item.productName);
117 | });
118 | }
119 | ```
120 |
121 | ## Notes
122 |
123 | - If basket is null, the cart will have empty items array and numItems of 0
124 | - The model automatically calculates shipping methods for each shipment
125 | - Bonus products from promotions are tracked separately
126 | - Cart validation is performed using hooks
127 | - All action URLs are generated dynamically using URLUtils
128 |
129 | ## Related Models
130 |
131 | - **TotalsModel** - Used for cart pricing calculations
132 | - **ProductLineItemsModel** - Used for product line item formatting
133 | - **Shipping Models** - Used for shipping method information
134 | - **Address Model** - Used for shipping addresses
135 |
```
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
```javascript
1 | import js from '@eslint/js';
2 | import tseslint from 'typescript-eslint';
3 |
4 | export default tseslint.config(
5 | // Base recommended configs
6 | js.configs.recommended,
7 | ...tseslint.configs.recommended,
8 |
9 | // Global settings
10 | {
11 | languageOptions: {
12 | ecmaVersion: 2022,
13 | sourceType: 'module',
14 | globals: {
15 | console: 'readonly',
16 | process: 'readonly',
17 | Buffer: 'readonly',
18 | __dirname: 'readonly',
19 | __filename: 'readonly',
20 | },
21 | },
22 | },
23 |
24 | // TypeScript files
25 | {
26 | files: ['**/*.ts', '**/*.tsx'],
27 | languageOptions: {
28 | parser: tseslint.parser,
29 | parserOptions: {
30 | project: ['./tsconfig.json', './tsconfig.test.json'],
31 | tsconfigRootDir: import.meta.dirname,
32 | },
33 | },
34 | rules: {
35 | // TypeScript specific rules
36 | '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
37 | '@typescript-eslint/no-explicit-any': 'off',
38 | '@typescript-eslint/explicit-function-return-type': 'off',
39 | '@typescript-eslint/explicit-module-boundary-types': 'off',
40 | '@typescript-eslint/no-non-null-assertion': 'off',
41 | '@typescript-eslint/prefer-nullish-coalescing': 'error',
42 | '@typescript-eslint/prefer-optional-chain': 'error',
43 | '@typescript-eslint/no-empty-object-type': 'off',
44 |
45 | // General code quality rules
46 | 'no-console': 'off',
47 | 'prefer-const': 'error',
48 | 'no-var': 'error',
49 | 'object-shorthand': 'error',
50 | 'prefer-arrow-callback': 'error',
51 | 'prefer-template': 'error',
52 | 'no-trailing-spaces': 'error',
53 | 'eol-last': 'error',
54 | 'comma-dangle': ['error', 'always-multiline'],
55 | 'quotes': ['error', 'single', { avoidEscape: true }],
56 | 'semi': ['error', 'always'],
57 |
58 | // Basic formatting rules
59 | 'indent': ['error', 2, { SwitchCase: 1 }],
60 | 'linebreak-style': ['error', 'unix'],
61 | 'max-len': ['error', { code: 120, ignoreUrls: true, ignoreStrings: true, ignoreTemplateLiterals: true }],
62 | 'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1 }],
63 | 'object-curly-spacing': ['error', 'always'],
64 | 'array-bracket-spacing': ['error', 'never'],
65 | 'key-spacing': ['error', { beforeColon: false, afterColon: true }],
66 | 'comma-spacing': ['error', { before: false, after: true }],
67 | 'space-before-blocks': ['error', 'always'],
68 | 'space-infix-ops': 'error',
69 | 'brace-style': ['error', '1tbs', { allowSingleLine: true }],
70 | 'curly': ['error', 'all'],
71 | },
72 | },
73 |
74 | // Test files
75 | {
76 | files: ['**/*.test.ts', '**/*.spec.ts', 'tests/**/*.ts'],
77 | languageOptions: {
78 | globals: {
79 | jest: 'readonly',
80 | describe: 'readonly',
81 | it: 'readonly',
82 | expect: 'readonly',
83 | beforeEach: 'readonly',
84 | afterEach: 'readonly',
85 | beforeAll: 'readonly',
86 | afterAll: 'readonly',
87 | },
88 | },
89 | rules: {
90 | '@typescript-eslint/no-explicit-any': 'off',
91 | '@typescript-eslint/no-non-null-assertion': 'off',
92 | },
93 | },
94 |
95 | // Script files
96 | {
97 | files: ['scripts/**/*.js'],
98 | languageOptions: {
99 | sourceType: 'module',
100 | globals: {
101 | console: 'readonly',
102 | process: 'readonly',
103 | Buffer: 'readonly',
104 | __dirname: 'readonly',
105 | __filename: 'readonly',
106 | },
107 | },
108 | },
109 |
110 | // Mock files (CommonJS format)
111 | {
112 | files: ['**/__mocks__/**/*.js'],
113 | languageOptions: {
114 | sourceType: 'script',
115 | globals: {
116 | module: 'writable',
117 | exports: 'writable',
118 | jest: 'readonly',
119 | },
120 | },
121 | },
122 |
123 | // Ignore patterns
124 | {
125 | ignores: [
126 | 'tmp/**',
127 | 'dist/**',
128 | 'node_modules/**',
129 | 'coverage/**',
130 | 'docs-site/**',
131 | 'docs-site-old/**',
132 | '*.config.js',
133 | 'jest.config.js',
134 | 'tests/servers/**',
135 | ],
136 | },
137 | );
138 |
```
--------------------------------------------------------------------------------
/docs/dw_crypto/X509Certificate.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.crypto
2 |
3 | # Class X509Certificate
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.crypto.CertificateRef
9 | - dw.crypto.X509Certificate
10 |
11 | ## Description
12 |
13 | Represents an X.509 public key certificate as defined in RFC 5280. It provides access to the standard fields of an X.509 certificate including version, serial number, validity period, distinguished names, and signature algorithm.
14 |
15 | ## Properties
16 |
17 | ### issuerDN
18 |
19 | **Type:** String (Read Only)
20 |
21 | The X.500 distinguished name of the entity that signed this certificate.
22 |
23 | ### notAfter
24 |
25 | **Type:** Date (Read Only)
26 |
27 | The end date of the certificate validity period.
28 |
29 | ### notBefore
30 |
31 | **Type:** Date (Read Only)
32 |
33 | The start date of the certificate validity period.
34 |
35 | ### serialNumber
36 |
37 | **Type:** String (Read Only)
38 |
39 | The certificate serial number in string format. The serial number is a unique positive integer assigned
40 | by the CA to each certificate.
41 |
42 | ### sigAlgName
43 |
44 | **Type:** String (Read Only)
45 |
46 | The algorithm used to sign this certificate. The name follows the format defined in RFC 5280 (e.g.,
47 | "SHA256withRSA", "SHA384withECDSA").
48 |
49 | ### subjectDN
50 |
51 | **Type:** String (Read Only)
52 |
53 | The X.500 distinguished name of the entity this certificate belongs to.
54 |
55 | ### version
56 |
57 | **Type:** Number (Read Only)
58 |
59 | The X.509 certificate version number.
60 |
61 | ## Constructor Summary
62 |
63 | ## Method Summary
64 |
65 | ### getIssuerDN
66 |
67 | **Signature:** `getIssuerDN() : String`
68 |
69 | Returns the X.500 distinguished name of the entity that signed this certificate.
70 |
71 | ### getNotAfter
72 |
73 | **Signature:** `getNotAfter() : Date`
74 |
75 | Returns the end date of the certificate validity period.
76 |
77 | ### getNotBefore
78 |
79 | **Signature:** `getNotBefore() : Date`
80 |
81 | Returns the start date of the certificate validity period.
82 |
83 | ### getSerialNumber
84 |
85 | **Signature:** `getSerialNumber() : String`
86 |
87 | Returns the certificate serial number in string format.
88 |
89 | ### getSigAlgName
90 |
91 | **Signature:** `getSigAlgName() : String`
92 |
93 | Returns the algorithm used to sign this certificate.
94 |
95 | ### getSubjectDN
96 |
97 | **Signature:** `getSubjectDN() : String`
98 |
99 | Returns the X.500 distinguished name of the entity this certificate belongs to.
100 |
101 | ### getVersion
102 |
103 | **Signature:** `getVersion() : Number`
104 |
105 | Returns the X.509 certificate version number.
106 |
107 | ## Method Detail
108 |
109 | ## Method Details
110 |
111 | ### getIssuerDN
112 |
113 | **Signature:** `getIssuerDN() : String`
114 |
115 | **Description:** Returns the X.500 distinguished name of the entity that signed this certificate.
116 |
117 | **Returns:**
118 |
119 | the issuer's X.500 distinguished name
120 |
121 | ---
122 |
123 | ### getNotAfter
124 |
125 | **Signature:** `getNotAfter() : Date`
126 |
127 | **Description:** Returns the end date of the certificate validity period.
128 |
129 | **Returns:**
130 |
131 | the date after which this certificate is not valid
132 |
133 | ---
134 |
135 | ### getNotBefore
136 |
137 | **Signature:** `getNotBefore() : Date`
138 |
139 | **Description:** Returns the start date of the certificate validity period.
140 |
141 | **Returns:**
142 |
143 | the date before which this certificate is not valid
144 |
145 | ---
146 |
147 | ### getSerialNumber
148 |
149 | **Signature:** `getSerialNumber() : String`
150 |
151 | **Description:** Returns the certificate serial number in string format. The serial number is a unique positive integer assigned by the CA to each certificate.
152 |
153 | **Returns:**
154 |
155 | the certificate serial number as a string
156 |
157 | ---
158 |
159 | ### getSigAlgName
160 |
161 | **Signature:** `getSigAlgName() : String`
162 |
163 | **Description:** Returns the algorithm used to sign this certificate. The name follows the format defined in RFC 5280 (e.g., "SHA256withRSA", "SHA384withECDSA").
164 |
165 | **Returns:**
166 |
167 | the signature algorithm name
168 |
169 | ---
170 |
171 | ### getSubjectDN
172 |
173 | **Signature:** `getSubjectDN() : String`
174 |
175 | **Description:** Returns the X.500 distinguished name of the entity this certificate belongs to.
176 |
177 | **Returns:**
178 |
179 | the subject's X.500 distinguished name
180 |
181 | ---
182 |
183 | ### getVersion
184 |
185 | **Signature:** `getVersion() : Number`
186 |
187 | **Description:** Returns the X.509 certificate version number.
188 |
189 | **Returns:**
190 |
191 | certificate version (typically 1, 2, or 3)
192 |
193 | ---
```
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: 🐛 Bug Report
2 | description: Report a bug or unexpected behavior in the SFCC Development MCP Server
3 | title: "[Bug]: "
4 | labels: ["bug", "needs-triage"]
5 | assignees: []
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | Thanks for taking the time to report a bug! Please fill out the information below to help us investigate and fix the issue.
11 |
12 | - type: checkboxes
13 | id: terms
14 | attributes:
15 | label: Pre-flight Checklist
16 | description: Please confirm you have completed these steps before submitting the bug report.
17 | options:
18 | - label: I have searched existing issues to ensure this bug hasn't been reported already
19 | required: true
20 | - label: I have read the documentation and troubleshooting guide
21 | required: true
22 | - label: I am using a supported Node.js version (18+)
23 | required: true
24 |
25 | - type: dropdown
26 | id: operating-mode
27 | attributes:
28 | label: Operating Mode
29 | description: Which mode were you using when the bug occurred?
30 | options:
31 | - Documentation-only mode
32 | - Full mode (with SFCC credentials)
33 | - Not sure
34 | validations:
35 | required: true
36 |
37 | - type: textarea
38 | id: bug-description
39 | attributes:
40 | label: Bug Description
41 | description: A clear and concise description of what the bug is.
42 | placeholder: Describe what happened and what you expected to happen instead.
43 | validations:
44 | required: true
45 |
46 | - type: textarea
47 | id: reproduction-steps
48 | attributes:
49 | label: Steps to Reproduce
50 | description: Detailed steps to reproduce the behavior.
51 | placeholder: |
52 | 1. Start the MCP server with...
53 | 2. Call the tool...
54 | 3. Observe the error...
55 | validations:
56 | required: true
57 |
58 | - type: textarea
59 | id: expected-behavior
60 | attributes:
61 | label: Expected Behavior
62 | description: What you expected to happen.
63 | validations:
64 | required: true
65 |
66 | - type: textarea
67 | id: actual-behavior
68 | attributes:
69 | label: Actual Behavior
70 | description: What actually happened, including any error messages.
71 | validations:
72 | required: true
73 |
74 | - type: textarea
75 | id: environment
76 | attributes:
77 | label: Environment Information
78 | description: Information about your environment
79 | value: |
80 | - OS: [e.g., macOS 14.1, Windows 11, Ubuntu 22.04]
81 | - Node.js version: [run `node --version`]
82 | - NPM/Yarn version: [run `npm --version` or `yarn --version`]
83 | - SFCC Dev MCP version: [check package.json version]
84 | - MCP Client: [e.g., Claude Desktop, Custom implementation]
85 | validations:
86 | required: true
87 |
88 | - type: textarea
89 | id: logs
90 | attributes:
91 | label: Relevant Logs
92 | description: Any relevant log output or error messages
93 | render: shell
94 | placeholder: Paste any relevant logs here (please remove any sensitive information like credentials)
95 |
96 | - type: textarea
97 | id: configuration
98 | attributes:
99 | label: Configuration (Sanitized)
100 | description: Your configuration (with sensitive information removed)
101 | render: json
102 | placeholder: |
103 | {
104 | "hostname": "your-instance.demandware.net",
105 | "clientId": "[REDACTED]",
106 | "version": "v21_3"
107 | }
108 |
109 | - type: dropdown
110 | id: affected-tools
111 | attributes:
112 | label: Affected Tools
113 | description: Which MCP tools are affected by this bug?
114 | multiple: true
115 | options:
116 | - SFCC Class Documentation Tools
117 | - Best Practices Guide Tools
118 | - Log Analysis Tools
119 | - System Object Tools
120 | - Authentication/OAuth
121 | - Configuration Loading
122 | - All Tools
123 | - Not sure
124 |
125 | - type: textarea
126 | id: additional-context
127 | attributes:
128 | label: Additional Context
129 | description: Any other context, screenshots, or information that might be helpful.
130 |
```
--------------------------------------------------------------------------------
/docs-site/scripts/generate-sitemap.js:
--------------------------------------------------------------------------------
```javascript
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Sitemap Generator for SFCC Development MCP Server Documentation
5 | *
6 | * This script generates an XML sitemap for the SFCC Development MCP Server documentation site.
7 | * Run this whenever you add new pages or want to update the sitemap.
8 | *
9 | * Usage: node scripts/generate-sitemap.js
10 | */
11 |
12 | import fs from 'fs';
13 | import path from 'path';
14 | import { fileURLToPath } from 'url';
15 |
16 | const __filename = fileURLToPath(import.meta.url);
17 | const __dirname = path.dirname(__filename);
18 |
19 | const baseUrl = 'https://sfcc-mcp-dev.rhino-inquisitor.com';
20 | const currentDate = new Date().toISOString().split('T')[0];
21 |
22 | // Define all pages with their priorities and change frequencies
23 | const pages = [
24 | {
25 | path: '/',
26 | priority: '1.0',
27 | changefreq: 'weekly',
28 | description: 'SFCC Development MCP Server Homepage',
29 | },
30 | {
31 | path: '/configuration/',
32 | priority: '0.9',
33 | changefreq: 'monthly',
34 | description: 'Configuration Guide',
35 | },
36 | {
37 | path: '/ai-interfaces/',
38 | priority: '0.8',
39 | changefreq: 'monthly',
40 | description: 'AI Interface Setup Guide',
41 | },
42 | {
43 | path: '/features/',
44 | priority: '0.8',
45 | changefreq: 'monthly',
46 | description: 'Features Overview',
47 | },
48 | {
49 | path: '/tools/',
50 | priority: '0.8',
51 | changefreq: 'monthly',
52 | description: 'Available Tools',
53 | },
54 | {
55 | path: '/examples/',
56 | priority: '0.8',
57 | changefreq: 'monthly',
58 | description: 'Examples and Use Cases',
59 | },
60 | {
61 | path: '/security/',
62 | priority: '0.7',
63 | changefreq: 'monthly',
64 | description: 'Security Guidelines',
65 | },
66 | {
67 | path: '/development/',
68 | priority: '0.6',
69 | changefreq: 'monthly',
70 | description: 'Development Guide',
71 | },
72 | {
73 | path: '/troubleshooting/',
74 | priority: '0.7',
75 | changefreq: 'monthly',
76 | description: 'Troubleshooting Guide',
77 | },
78 | ];
79 |
80 | function generateSitemap() {
81 | const header = `<?xml version="1.0" encoding="UTF-8"?>
82 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
83 | xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
84 | xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
85 | http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">`;
86 |
87 | const footer = `
88 | </urlset>`;
89 |
90 | const urls = pages.map(page => {
91 | // For SSG routing, URLs should point to clean paths without hash fragments
92 | const url = page.path === '/' ? baseUrl : `${baseUrl}${page.path}`;
93 | return `
94 | <!-- ${page.description} -->
95 | <url>
96 | <loc>${url}</loc>
97 | <lastmod>${currentDate}</lastmod>
98 | <changefreq>${page.changefreq}</changefreq>
99 | <priority>${page.priority}</priority>
100 | </url>`;
101 | }).join('');
102 |
103 | return header + urls + footer;
104 | }
105 |
106 | function generateRobotsTxt() {
107 | return `User-agent: *
108 | Allow: /
109 |
110 | # Sitemap
111 | Sitemap: ${baseUrl}/sitemap.xml
112 |
113 | # Crawl-delay for respectful crawling
114 | Crawl-delay: 1
115 |
116 | # Allow all common search engines
117 | User-agent: Googlebot
118 | Allow: /
119 |
120 | User-agent: Bingbot
121 | Allow: /
122 |
123 | User-agent: Slurp
124 | Allow: /
125 |
126 | User-agent: DuckDuckBot
127 | Allow: /
128 |
129 | # Block certain paths if needed
130 | # Disallow: /temp/
131 | # Disallow: /private/`;
132 | }
133 |
134 | // Generate files
135 | const sitemap = generateSitemap();
136 | const robots = generateRobotsTxt();
137 |
138 | // Write files
139 | const publicDir = path.join(__dirname, '..', 'public');
140 | if (!fs.existsSync(publicDir)) {
141 | fs.mkdirSync(publicDir, { recursive: true });
142 | }
143 |
144 | fs.writeFileSync(path.join(publicDir, 'sitemap.xml'), sitemap);
145 | fs.writeFileSync(path.join(publicDir, 'robots.txt'), robots);
146 |
147 | console.log('✅ Sitemap and robots.txt generated successfully!');
148 | console.log(`📄 Generated ${pages.length} URLs in sitemap.xml`);
149 | console.log('🤖 Updated robots.txt with sitemap reference');
150 | console.log(`📅 Last modified: ${currentDate}`);
151 |
152 | // Also log the pages for verification
153 | console.log('\n📋 Pages included in sitemap:');
154 | pages.forEach(page => {
155 | console.log(` ${page.path} (Priority: ${page.priority}, ${page.changefreq})`);
156 | });
157 |
```
--------------------------------------------------------------------------------
/docs/dw_catalog/Catalog.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.catalog
2 |
3 | # Class Catalog
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.object.PersistentObject
9 | - dw.object.ExtensibleObject
10 | - dw.catalog.Catalog
11 |
12 | ## Description
13 |
14 | Represents a Commerce Cloud Digital Catalog. Catalogs are containers of products and other product-related information and can be shared between sites. Every product in the system is contained in (or "owned by") exactly one catalog. Every site has a single "site catalog" which defines the products that are available to purchase on that site. The static method CatalogMgr.getSiteCatalog() returns the site catalog for the current site. Catalogs are organized into a tree of categories with a single top-level root category. Products are assigned to categories within catalogs. They can be assigned to categories in their owning catalog, or other catalogs. They can be assigned to multiple categories within the same catalog. Products that are not assigned to any categories are considered "uncategorized." A product has a single "classification category" in some catalog, and one "primary category" per catalog. The classification category defines the attribute set of the product. The primary category is used as standard presentation context within that catalog in the storefront. While Commerce Cloud Digital does not currently distinguish different catalog types, it is common practice to have two general types of catalog: "Product catalogs" typically contain detailed product information and are frequently generated from some backend PIM system. "Site Catalogs" define the category structure of the storefront and contain primarily the assignments of these categories to the products defined in the product catalogs. The site catalog is assigned to the site. In addition to products and categories, catalogs contain recommendations, shared variation attributes which can be used by multiple master products, and shared product options which can be used by multiple option products.
15 |
16 | ## Properties
17 |
18 | ### description
19 |
20 | **Type:** String (Read Only)
21 |
22 | The value of the localized extensible object attribute
23 | "shortDescription" for the current locale.
24 |
25 | ### displayName
26 |
27 | **Type:** String (Read Only)
28 |
29 | The value of the localized extensible object attribute
30 | "displayName" for the current locale.
31 |
32 | ### ID
33 |
34 | **Type:** String (Read Only)
35 |
36 | The value of attribute 'id'.
37 |
38 | ### root
39 |
40 | **Type:** Category (Read Only)
41 |
42 | The object for the relation 'root'.
43 |
44 | ## Constructor Summary
45 |
46 | ## Method Summary
47 |
48 | ### getDescription
49 |
50 | **Signature:** `getDescription() : String`
51 |
52 | Returns the value of the localized extensible object attribute "shortDescription" for the current locale.
53 |
54 | ### getDisplayName
55 |
56 | **Signature:** `getDisplayName() : String`
57 |
58 | Returns the value of the localized extensible object attribute "displayName" for the current locale.
59 |
60 | ### getID
61 |
62 | **Signature:** `getID() : String`
63 |
64 | Returns the value of attribute 'id'.
65 |
66 | ### getRoot
67 |
68 | **Signature:** `getRoot() : Category`
69 |
70 | Returns the object for the relation 'root'.
71 |
72 | ## Method Detail
73 |
74 | ## Method Details
75 |
76 | ### getDescription
77 |
78 | **Signature:** `getDescription() : String`
79 |
80 | **Description:** Returns the value of the localized extensible object attribute "shortDescription" for the current locale.
81 |
82 | **Returns:**
83 |
84 | The value of the attribute for the current locale, or null if it wasn't found.
85 |
86 | ---
87 |
88 | ### getDisplayName
89 |
90 | **Signature:** `getDisplayName() : String`
91 |
92 | **Description:** Returns the value of the localized extensible object attribute "displayName" for the current locale.
93 |
94 | **Returns:**
95 |
96 | The value of the attribute for the current locale, or null if it wasn't found.
97 |
98 | ---
99 |
100 | ### getID
101 |
102 | **Signature:** `getID() : String`
103 |
104 | **Description:** Returns the value of attribute 'id'.
105 |
106 | **Returns:**
107 |
108 | the value of the attribute 'id'
109 |
110 | ---
111 |
112 | ### getRoot
113 |
114 | **Signature:** `getRoot() : Category`
115 |
116 | **Description:** Returns the object for the relation 'root'.
117 |
118 | **Returns:**
119 |
120 | the object for the relation 'root'.
121 |
122 | ---
```
--------------------------------------------------------------------------------
/docs/dw_catalog/ProductMgr.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.catalog
2 |
3 | # Class ProductMgr
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.catalog.ProductMgr
9 |
10 | ## Description
11 |
12 | Provides helper methods for getting products based on Product ID or Catalog.
13 |
14 | ## Constructor Summary
15 |
16 | ## Method Summary
17 |
18 | ### getProduct
19 |
20 | **Signature:** `static getProduct(productID : String) : Product`
21 |
22 | Returns the product with the specified id.
23 |
24 | ### queryAllSiteProducts
25 |
26 | **Signature:** `static queryAllSiteProducts() : SeekableIterator`
27 |
28 | Returns all products assigned to the current site.
29 |
30 | ### queryAllSiteProductsSorted
31 |
32 | **Signature:** `static queryAllSiteProductsSorted() : SeekableIterator`
33 |
34 | Returns all products assigned to the current site.
35 |
36 | ### queryProductsInCatalog
37 |
38 | **Signature:** `static queryProductsInCatalog(catalog : Catalog) : SeekableIterator`
39 |
40 | Returns all products assigned to the the specified catalog, where assignment has the same meaning as it does for queryAllSiteProducts().
41 |
42 | ### queryProductsInCatalogSorted
43 |
44 | **Signature:** `static queryProductsInCatalogSorted(catalog : Catalog) : SeekableIterator`
45 |
46 | Returns all products assigned to the the specified catalog.
47 |
48 | ## Method Detail
49 |
50 | ## Method Details
51 |
52 | ### getProduct
53 |
54 | **Signature:** `static getProduct(productID : String) : Product`
55 |
56 | **Description:** Returns the product with the specified id.
57 |
58 | **Parameters:**
59 |
60 | - `productID`: the product identifier.
61 |
62 | **Returns:**
63 |
64 | Product for specified id or null
65 |
66 | ---
67 |
68 | ### queryAllSiteProducts
69 |
70 | **Signature:** `static queryAllSiteProducts() : SeekableIterator`
71 |
72 | **Description:** Returns all products assigned to the current site. A product is assigned to a site if it is assigned to at least one category of the site catalog or it is a variant and it's master product is assigned to the current site It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
73 |
74 | **Returns:**
75 |
76 | Iterator of all site products
77 |
78 | **See Also:**
79 |
80 | SeekableIterator.close()
81 |
82 | ---
83 |
84 | ### queryAllSiteProductsSorted
85 |
86 | **Signature:** `static queryAllSiteProductsSorted() : SeekableIterator`
87 |
88 | **Description:** Returns all products assigned to the current site. Works like queryAllSiteProducts(), but additionally sorts the result set by product ID. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
89 |
90 | **Returns:**
91 |
92 | Iterator of all site products sorted by product ID.
93 |
94 | **See Also:**
95 |
96 | SeekableIterator.close()
97 |
98 | ---
99 |
100 | ### queryProductsInCatalog
101 |
102 | **Signature:** `static queryProductsInCatalog(catalog : Catalog) : SeekableIterator`
103 |
104 | **Description:** Returns all products assigned to the the specified catalog, where assignment has the same meaning as it does for queryAllSiteProducts(). It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
105 |
106 | **Parameters:**
107 |
108 | - `catalog`: The catalog whose assigned products should be returned.
109 |
110 | **Returns:**
111 |
112 | Iterator of all products assigned to specified catalog.
113 |
114 | **See Also:**
115 |
116 | SeekableIterator.close()
117 |
118 | ---
119 |
120 | ### queryProductsInCatalogSorted
121 |
122 | **Signature:** `static queryProductsInCatalogSorted(catalog : Catalog) : SeekableIterator`
123 |
124 | **Description:** Returns all products assigned to the the specified catalog. Works like queryProductsInCatalog(), but additionally sorts the result set by product ID. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources.
125 |
126 | **Parameters:**
127 |
128 | - `catalog`: The catalog whose assigned products should be returned.
129 |
130 | **Returns:**
131 |
132 | Iterator of all products assigned to specified catalog sorted by product ID.
133 |
134 | **See Also:**
135 |
136 | SeekableIterator.close()
137 |
138 | ---
```
--------------------------------------------------------------------------------
/docs/dw_catalog/CatalogMgr.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.catalog
2 |
3 | # Class CatalogMgr
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.catalog.CatalogMgr
9 |
10 | ## Description
11 |
12 | Provides helper methods for getting categories.
13 |
14 | ## Properties
15 |
16 | ### siteCatalog
17 |
18 | **Type:** Catalog (Read Only)
19 |
20 | The catalog of the current site or null if no catalog is assigned to the site.
21 |
22 | ### sortingOptions
23 |
24 | **Type:** List (Read Only)
25 |
26 | A list containing the sorting options configured for this site.
27 |
28 | ### sortingRules
29 |
30 | **Type:** Collection (Read Only)
31 |
32 | A collection containing all of the sorting rules for this site, including global sorting rules.
33 |
34 | ## Constructor Summary
35 |
36 | ## Method Summary
37 |
38 | ### getCatalog
39 |
40 | **Signature:** `static getCatalog(id : String) : Catalog`
41 |
42 | Returns the catalog identified by the specified catalog id.
43 |
44 | ### getCategory
45 |
46 | **Signature:** `static getCategory(id : String) : Category`
47 |
48 | Returns the category of the site catalog identified by the specified category id.
49 |
50 | ### getSiteCatalog
51 |
52 | **Signature:** `static getSiteCatalog() : Catalog`
53 |
54 | Returns the catalog of the current site or null if no catalog is assigned to the site.
55 |
56 | ### getSortingOption
57 |
58 | **Signature:** `static getSortingOption(id : String) : SortingOption`
59 |
60 | Returns the sorting option with the given ID for this site, or null if there is no such option.
61 |
62 | ### getSortingOptions
63 |
64 | **Signature:** `static getSortingOptions() : List`
65 |
66 | Returns a list containing the sorting options configured for this site.
67 |
68 | ### getSortingRule
69 |
70 | **Signature:** `static getSortingRule(id : String) : SortingRule`
71 |
72 | Returns the sorting rule with the given ID for this site, or null if there is no such rule.
73 |
74 | ### getSortingRules
75 |
76 | **Signature:** `static getSortingRules() : Collection`
77 |
78 | Returns a collection containing all of the sorting rules for this site, including global sorting rules.
79 |
80 | ## Method Detail
81 |
82 | ## Method Details
83 |
84 | ### getCatalog
85 |
86 | **Signature:** `static getCatalog(id : String) : Catalog`
87 |
88 | **Description:** Returns the catalog identified by the specified catalog id. Returns null if no catalog with the specified id exists in the current organization context.
89 |
90 | **Parameters:**
91 |
92 | - `id`: Catalog id
93 |
94 | **Returns:**
95 |
96 | the catalog or null.
97 |
98 | ---
99 |
100 | ### getCategory
101 |
102 | **Signature:** `static getCategory(id : String) : Category`
103 |
104 | **Description:** Returns the category of the site catalog identified by the specified category id. Returns null if no site catalog is defined, or no category with the specified id is found in the site catalog.
105 |
106 | **Parameters:**
107 |
108 | - `id`: the category identifier.
109 |
110 | **Returns:**
111 |
112 | the category of the site catalog identified by the specified category id or null if no site catalog is found.
113 |
114 | ---
115 |
116 | ### getSiteCatalog
117 |
118 | **Signature:** `static getSiteCatalog() : Catalog`
119 |
120 | **Description:** Returns the catalog of the current site or null if no catalog is assigned to the site.
121 |
122 | **Returns:**
123 |
124 | the catalog of the current site or null.
125 |
126 | ---
127 |
128 | ### getSortingOption
129 |
130 | **Signature:** `static getSortingOption(id : String) : SortingOption`
131 |
132 | **Description:** Returns the sorting option with the given ID for this site, or null if there is no such option.
133 |
134 | **Parameters:**
135 |
136 | - `id`: the ID of the sorting option
137 |
138 | **Returns:**
139 |
140 | a SortingOption or null.
141 |
142 | ---
143 |
144 | ### getSortingOptions
145 |
146 | **Signature:** `static getSortingOptions() : List`
147 |
148 | **Description:** Returns a list containing the sorting options configured for this site.
149 |
150 | **Returns:**
151 |
152 | a list of SortingOption objects
153 |
154 | ---
155 |
156 | ### getSortingRule
157 |
158 | **Signature:** `static getSortingRule(id : String) : SortingRule`
159 |
160 | **Description:** Returns the sorting rule with the given ID for this site, or null if there is no such rule.
161 |
162 | **Parameters:**
163 |
164 | - `id`: the ID of the sorting rule
165 |
166 | **Returns:**
167 |
168 | a SortingRule or null.
169 |
170 | ---
171 |
172 | ### getSortingRules
173 |
174 | **Signature:** `static getSortingRules() : Collection`
175 |
176 | **Description:** Returns a collection containing all of the sorting rules for this site, including global sorting rules.
177 |
178 | **Returns:**
179 |
180 | a collection of SortingRule objects
181 |
182 | ---
```
--------------------------------------------------------------------------------
/docs/dw_util/SortedSet.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.util
2 |
3 | # Class SortedSet
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.util.Collection
9 | - dw.util.Set
10 | - dw.util.SortedSet
11 |
12 | ## Description
13 |
14 | A set that further guarantees that its iterator will traverse the set in ascending element order, sorted according to the natural ordering of its elements (only supported for Number, String, Date, Money and Quantity), or by a comparator provided at sorted set creation time.
15 |
16 | ## Constructor Summary
17 |
18 | SortedSet() Constructor to create a new SortedSet.
19 |
20 | SortedSet(comparator : Object) Constructor to create a new SortedSet.
21 |
22 | SortedSet(collection : Collection) Constructor for a new SortedSet.
23 |
24 | ## Method Summary
25 |
26 | ### clone
27 |
28 | **Signature:** `clone() : SortedSet`
29 |
30 | Returns a shallow copy of this set.
31 |
32 | ### first
33 |
34 | **Signature:** `first() : Object`
35 |
36 | Returns the first (lowest) element currently in this sorted set.
37 |
38 | ### headSet
39 |
40 | **Signature:** `headSet(key : Object) : SortedSet`
41 |
42 | Returns a view of the portion of this sorted set whose elements are strictly less than toElement.
43 |
44 | ### last
45 |
46 | **Signature:** `last() : Object`
47 |
48 | Returns the last (highest) element currently in this sorted set.
49 |
50 | ### subSet
51 |
52 | **Signature:** `subSet(from : Object, to : Object) : SortedSet`
53 |
54 | Returns a view of the portion of this sorted set whose elements range from fromElement, inclusive, to toElement, exclusive.
55 |
56 | ### tailSet
57 |
58 | **Signature:** `tailSet(key : Object) : SortedSet`
59 |
60 | Returns a view of the portion of this sorted set whose elements are greater than or equal to fromElement.
61 |
62 | ## Constructor Detail
63 |
64 | ## Method Detail
65 |
66 | ## Method Details
67 |
68 | ### clone
69 |
70 | **Signature:** `clone() : SortedSet`
71 |
72 | **Description:** Returns a shallow copy of this set.
73 |
74 | **Returns:**
75 |
76 | a shallow copy of this set.
77 |
78 | ---
79 |
80 | ### first
81 |
82 | **Signature:** `first() : Object`
83 |
84 | **Description:** Returns the first (lowest) element currently in this sorted set.
85 |
86 | **Returns:**
87 |
88 | the first (lowest) element currently in this sorted set.
89 |
90 | ---
91 |
92 | ### headSet
93 |
94 | **Signature:** `headSet(key : Object) : SortedSet`
95 |
96 | **Description:** Returns a view of the portion of this sorted set whose elements are strictly less than toElement. The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations.
97 |
98 | **Parameters:**
99 |
100 | - `key`: high endpoint (exclusive) of the headSet.
101 |
102 | **Returns:**
103 |
104 | a view of the specified initial range of this sorted set.
105 |
106 | ---
107 |
108 | ### last
109 |
110 | **Signature:** `last() : Object`
111 |
112 | **Description:** Returns the last (highest) element currently in this sorted set.
113 |
114 | **Returns:**
115 |
116 | the last (highest) element currently in this sorted set.
117 |
118 | ---
119 |
120 | ### subSet
121 |
122 | **Signature:** `subSet(from : Object, to : Object) : SortedSet`
123 |
124 | **Description:** Returns a view of the portion of this sorted set whose elements range from fromElement, inclusive, to toElement, exclusive. (If fromElement and toElement are equal, the returned sorted set is empty.) The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations that this sorted set supports.
125 |
126 | **Parameters:**
127 |
128 | - `from`: low endpoint (inclusive) of the subSet.
129 | - `to`: high endpoint (exclusive) of the subSet.
130 |
131 | **Returns:**
132 |
133 | a view of the specified range within this sorted set.
134 |
135 | ---
136 |
137 | ### tailSet
138 |
139 | **Signature:** `tailSet(key : Object) : SortedSet`
140 |
141 | **Description:** Returns a view of the portion of this sorted set whose elements are greater than or equal to fromElement. The returned sorted set is backed by this sorted set, so changes in the returned sorted set are reflected in this sorted set, and vice-versa. The returned sorted set supports all optional set operations.
142 |
143 | **Parameters:**
144 |
145 | - `key`: low endpoint (inclusive) of the tailSet.
146 |
147 | **Returns:**
148 |
149 | a view of the specified final range of this sorted set.
150 |
151 | ---
```
--------------------------------------------------------------------------------
/docs/dw_catalog/PriceBook.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.catalog
2 |
3 | # Class PriceBook
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.object.PersistentObject
9 | - dw.object.ExtensibleObject
10 | - dw.catalog.PriceBook
11 |
12 | ## Description
13 |
14 | Represents a price book.
15 |
16 | ## Properties
17 |
18 | ### currencyCode
19 |
20 | **Type:** String (Read Only)
21 |
22 | The currency code of the price book.
23 |
24 | ### description
25 |
26 | **Type:** String (Read Only)
27 |
28 | The description of the price book.
29 |
30 | ### displayName
31 |
32 | **Type:** String (Read Only)
33 |
34 | The display name of the price book.
35 |
36 | ### ID
37 |
38 | **Type:** String (Read Only)
39 |
40 | The ID of the price book.
41 |
42 | ### online
43 |
44 | **Type:** boolean (Read Only)
45 |
46 | The online status of the price book. The online status
47 | is calculated from the online status flag and the onlineFrom
48 | onlineTo dates defined for the price book.
49 |
50 | ### onlineFlag
51 |
52 | **Type:** boolean (Read Only)
53 |
54 | The online status flag of the price book.
55 |
56 | ### onlineFrom
57 |
58 | **Type:** Date (Read Only)
59 |
60 | The date from which the price book is online or valid.
61 |
62 | ### onlineTo
63 |
64 | **Type:** Date (Read Only)
65 |
66 | The date until which the price book is online or valid.
67 |
68 | ### parentPriceBook
69 |
70 | **Type:** PriceBook (Read Only)
71 |
72 | The parent price book.
73 |
74 | ## Constructor Summary
75 |
76 | ## Method Summary
77 |
78 | ### getCurrencyCode
79 |
80 | **Signature:** `getCurrencyCode() : String`
81 |
82 | Returns the currency code of the price book.
83 |
84 | ### getDescription
85 |
86 | **Signature:** `getDescription() : String`
87 |
88 | Returns the description of the price book.
89 |
90 | ### getDisplayName
91 |
92 | **Signature:** `getDisplayName() : String`
93 |
94 | Returns the display name of the price book.
95 |
96 | ### getID
97 |
98 | **Signature:** `getID() : String`
99 |
100 | Returns the ID of the price book.
101 |
102 | ### getOnlineFlag
103 |
104 | **Signature:** `getOnlineFlag() : boolean`
105 |
106 | Returns the online status flag of the price book.
107 |
108 | ### getOnlineFrom
109 |
110 | **Signature:** `getOnlineFrom() : Date`
111 |
112 | Returns the date from which the price book is online or valid.
113 |
114 | ### getOnlineTo
115 |
116 | **Signature:** `getOnlineTo() : Date`
117 |
118 | Returns the date until which the price book is online or valid.
119 |
120 | ### getParentPriceBook
121 |
122 | **Signature:** `getParentPriceBook() : PriceBook`
123 |
124 | Returns the parent price book.
125 |
126 | ### isOnline
127 |
128 | **Signature:** `isOnline() : boolean`
129 |
130 | Returns the online status of the price book.
131 |
132 | ## Method Detail
133 |
134 | ## Method Details
135 |
136 | ### getCurrencyCode
137 |
138 | **Signature:** `getCurrencyCode() : String`
139 |
140 | **Description:** Returns the currency code of the price book.
141 |
142 | **Returns:**
143 |
144 | Currency code of the price book
145 |
146 | ---
147 |
148 | ### getDescription
149 |
150 | **Signature:** `getDescription() : String`
151 |
152 | **Description:** Returns the description of the price book.
153 |
154 | **Returns:**
155 |
156 | Currency code of the price book
157 |
158 | ---
159 |
160 | ### getDisplayName
161 |
162 | **Signature:** `getDisplayName() : String`
163 |
164 | **Description:** Returns the display name of the price book.
165 |
166 | **Returns:**
167 |
168 | Display name of the price book
169 |
170 | ---
171 |
172 | ### getID
173 |
174 | **Signature:** `getID() : String`
175 |
176 | **Description:** Returns the ID of the price book.
177 |
178 | **Returns:**
179 |
180 | ID of the price book
181 |
182 | ---
183 |
184 | ### getOnlineFlag
185 |
186 | **Signature:** `getOnlineFlag() : boolean`
187 |
188 | **Description:** Returns the online status flag of the price book.
189 |
190 | **Returns:**
191 |
192 | the online status flag of the price book.
193 |
194 | ---
195 |
196 | ### getOnlineFrom
197 |
198 | **Signature:** `getOnlineFrom() : Date`
199 |
200 | **Description:** Returns the date from which the price book is online or valid.
201 |
202 | **Returns:**
203 |
204 | the date from which the price book is online or valid.
205 |
206 | ---
207 |
208 | ### getOnlineTo
209 |
210 | **Signature:** `getOnlineTo() : Date`
211 |
212 | **Description:** Returns the date until which the price book is online or valid.
213 |
214 | **Returns:**
215 |
216 | the date until which the price book is online or valid.
217 |
218 | ---
219 |
220 | ### getParentPriceBook
221 |
222 | **Signature:** `getParentPriceBook() : PriceBook`
223 |
224 | **Description:** Returns the parent price book.
225 |
226 | **Returns:**
227 |
228 | Parent price book
229 |
230 | ---
231 |
232 | ### isOnline
233 |
234 | **Signature:** `isOnline() : boolean`
235 |
236 | **Description:** Returns the online status of the price book. The online status is calculated from the online status flag and the onlineFrom onlineTo dates defined for the price book.
237 |
238 | **Returns:**
239 |
240 | The online status of the price book.
241 |
242 | ---
```
--------------------------------------------------------------------------------
/docs/dw_system/Cache.md:
--------------------------------------------------------------------------------
```markdown
1 | ## Package: dw.system
2 |
3 | # Class Cache
4 |
5 | ## Inheritance Hierarchy
6 |
7 | - Object
8 | - dw.system.Cache
9 |
10 | ## Description
11 |
12 | The Cache class represents a custom cache. A cache stores data over multiple requests. Each cartridge can define its own caches for different business requirements. To limit the visibility of cache entries by scope, for example, by site, catalog, or external system, include the scope reference when constructing the key. For example: var cache = CacheMgr.getCache( 'SiteConfigurations' ); cache.get( Site.current.ID + "config", function loadSiteConfiguration() {return loadCfg( Site.current );} ); Do not build the cache key using personal user data, since the key might be visible in log messages. There is never a guarantee that a stored object can be retrieved from the cache. The storage allocated for entries is limited and clearing or invalidation might occur at any time. To maintain the cache size limits, the cache evicts entries that are less likely to be used again. For example, the cache might evict an entry because it hasn't been used recently or very often. Cache entries aren't synchronized between different application servers. The cache returns immutable copies of the original objects put into the cache. Lists are converted to arrays during this process. Only JavaScript primitive values and tree-like object structures can be stored as entries. Object structures can consist of arrays, lists, and basic JavaScript objects. Script API classes are not supported, except List and its subclasses. null can be stored as a value. undefined can't be stored. See CacheMgr for details about how to configure a custom cache.
13 |
14 | ## Constructor Summary
15 |
16 | ## Method Summary
17 |
18 | ### get
19 |
20 | **Signature:** `get(key : String, loader : Function) : Object`
21 |
22 | Returns the value associated with key in this cache, or invokes the loader function to generate the entry if there is no entry found.
23 |
24 | ### get
25 |
26 | **Signature:** `get(key : String) : Object`
27 |
28 | Returns the value associated with key in this cache.
29 |
30 | ### invalidate
31 |
32 | **Signature:** `invalidate(key : String) : void`
33 |
34 | Removes the cache entry for key (if one exists) manually before the cache's eviction strategy goes into effect.
35 |
36 | ### put
37 |
38 | **Signature:** `put(key : String, value : Object) : void`
39 |
40 | Stores the specified entry directly into the cache, replacing any previously cached entry for key if one exists.
41 |
42 | ## Method Detail
43 |
44 | ## Method Details
45 |
46 | ### get
47 |
48 | **Signature:** `get(key : String, loader : Function) : Object`
49 |
50 | **Description:** Returns the value associated with key in this cache, or invokes the loader function to generate the entry if there is no entry found. The generated entry is stored for future retrieval. If the loader function returns undefined, this value is not stored in the cache.
51 |
52 | **Parameters:**
53 |
54 | - `key`: The cache key.
55 | - `loader`: The loader function that is called if no value is stored in the cache.
56 |
57 | **Returns:**
58 |
59 | The value found in the cache or the value returned from the loader function call.
60 |
61 | ---
62 |
63 | ### get
64 |
65 | **Signature:** `get(key : String) : Object`
66 |
67 | **Description:** Returns the value associated with key in this cache. If there is no entry in the cache then undefined is returned.
68 |
69 | **Parameters:**
70 |
71 | - `key`: The cache key.
72 |
73 | **Returns:**
74 |
75 | The stored value or undefined if no value is found in the cache.
76 |
77 | ---
78 |
79 | ### invalidate
80 |
81 | **Signature:** `invalidate(key : String) : void`
82 |
83 | **Description:** Removes the cache entry for key (if one exists) manually before the cache's eviction strategy goes into effect.
84 |
85 | **Parameters:**
86 |
87 | - `key`: The cache key.
88 |
89 | ---
90 |
91 | ### put
92 |
93 | **Signature:** `put(key : String, value : Object) : void`
94 |
95 | **Description:** Stores the specified entry directly into the cache, replacing any previously cached entry for key if one exists. Storing undefined as value has the same effect as calling invalidate(String) for that key.
96 |
97 | **Parameters:**
98 |
99 | - `key`: The cache key.
100 | - `value`: The value to be store in the cache.
101 |
102 | ---
```