This is page 10 of 61. Use http://codebase.md/taurgis/sfcc-dev-mcp?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .DS_Store ├── .github │ ├── dependabot.yml │ ├── instructions │ │ ├── mcp-node-tests.instructions.md │ │ └── mcp-yml-tests.instructions.md │ ├── ISSUE_TEMPLATE │ │ ├── bug_report.yml │ │ ├── config.yml │ │ ├── documentation.yml │ │ ├── feature_request.yml │ │ └── question.yml │ ├── PULL_REQUEST_TEMPLATE │ │ ├── bug_fix.md │ │ ├── documentation.md │ │ └── new_tool.md │ ├── pull_request_template.md │ └── workflows │ ├── ci.yml │ ├── deploy-pages.yml │ ├── publish.yml │ └── update-docs.yml ├── .gitignore ├── .husky │ └── pre-commit ├── aegis.config.docs-only.json ├── aegis.config.json ├── aegis.config.with-dw.json ├── AGENTS.md ├── ai-instructions │ ├── claude-desktop │ │ └── claude_custom_instructions.md │ ├── cursor │ │ └── .cursor │ │ └── rules │ │ ├── debugging-workflows.mdc │ │ ├── hooks-development.mdc │ │ ├── isml-templates.mdc │ │ ├── job-framework.mdc │ │ ├── performance-optimization.mdc │ │ ├── scapi-endpoints.mdc │ │ ├── security-patterns.mdc │ │ ├── sfcc-development.mdc │ │ ├── sfra-controllers.mdc │ │ ├── sfra-models.mdc │ │ ├── system-objects.mdc │ │ └── testing-patterns.mdc │ └── github-copilot │ └── copilot-instructions.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── docs │ ├── best-practices │ │ ├── cartridge_creation.md │ │ ├── isml_templates.md │ │ ├── job_framework.md │ │ ├── localserviceregistry.md │ │ ├── ocapi_hooks.md │ │ ├── performance.md │ │ ├── scapi_custom_endpoint.md │ │ ├── scapi_hooks.md │ │ ├── security.md │ │ ├── sfra_client_side_js.md │ │ ├── sfra_controllers.md │ │ ├── sfra_models.md │ │ └── sfra_scss.md │ ├── dw_campaign │ │ ├── ABTest.md │ │ ├── ABTestMgr.md │ │ ├── ABTestSegment.md │ │ ├── AmountDiscount.md │ │ ├── ApproachingDiscount.md │ │ ├── BonusChoiceDiscount.md │ │ ├── BonusDiscount.md │ │ ├── Campaign.md │ │ ├── CampaignMgr.md │ │ ├── CampaignStatusCodes.md │ │ ├── Coupon.md │ │ ├── CouponMgr.md │ │ ├── CouponRedemption.md │ │ ├── CouponStatusCodes.md │ │ ├── Discount.md │ │ ├── DiscountPlan.md │ │ ├── FixedPriceDiscount.md │ │ ├── FixedPriceShippingDiscount.md │ │ ├── FreeDiscount.md │ │ ├── FreeShippingDiscount.md │ │ ├── PercentageDiscount.md │ │ ├── PercentageOptionDiscount.md │ │ ├── PriceBookPriceDiscount.md │ │ ├── Promotion.md │ │ ├── PromotionMgr.md │ │ ├── PromotionPlan.md │ │ ├── SlotContent.md │ │ ├── SourceCodeGroup.md │ │ ├── SourceCodeInfo.md │ │ ├── SourceCodeStatusCodes.md │ │ └── TotalFixedPriceDiscount.md │ ├── dw_catalog │ │ ├── Catalog.md │ │ ├── CatalogMgr.md │ │ ├── Category.md │ │ ├── CategoryAssignment.md │ │ ├── CategoryLink.md │ │ ├── PriceBook.md │ │ ├── PriceBookMgr.md │ │ ├── Product.md │ │ ├── ProductActiveData.md │ │ ├── ProductAttributeModel.md │ │ ├── ProductAvailabilityLevels.md │ │ ├── ProductAvailabilityModel.md │ │ ├── ProductInventoryList.md │ │ ├── ProductInventoryMgr.md │ │ ├── ProductInventoryRecord.md │ │ ├── ProductLink.md │ │ ├── ProductMgr.md │ │ ├── ProductOption.md │ │ ├── ProductOptionModel.md │ │ ├── ProductOptionValue.md │ │ ├── ProductPriceInfo.md │ │ ├── ProductPriceModel.md │ │ ├── ProductPriceTable.md │ │ ├── ProductSearchHit.md │ │ ├── ProductSearchModel.md │ │ ├── ProductSearchRefinementDefinition.md │ │ ├── ProductSearchRefinements.md │ │ ├── ProductSearchRefinementValue.md │ │ ├── ProductVariationAttribute.md │ │ ├── ProductVariationAttributeValue.md │ │ ├── ProductVariationModel.md │ │ ├── Recommendation.md │ │ ├── SearchModel.md │ │ ├── SearchRefinementDefinition.md │ │ ├── SearchRefinements.md │ │ ├── SearchRefinementValue.md │ │ ├── SortingOption.md │ │ ├── SortingRule.md │ │ ├── Store.md │ │ ├── StoreGroup.md │ │ ├── StoreInventoryFilter.md │ │ ├── StoreInventoryFilterValue.md │ │ ├── StoreMgr.md │ │ ├── Variant.md │ │ └── VariationGroup.md │ ├── dw_content │ │ ├── Content.md │ │ ├── ContentMgr.md │ │ ├── ContentSearchModel.md │ │ ├── ContentSearchRefinementDefinition.md │ │ ├── ContentSearchRefinements.md │ │ ├── ContentSearchRefinementValue.md │ │ ├── Folder.md │ │ ├── Library.md │ │ ├── MarkupText.md │ │ └── MediaFile.md │ ├── dw_crypto │ │ ├── CertificateRef.md │ │ ├── CertificateUtils.md │ │ ├── Cipher.md │ │ ├── Encoding.md │ │ ├── JWE.md │ │ ├── JWEHeader.md │ │ ├── JWS.md │ │ ├── JWSHeader.md │ │ ├── KeyRef.md │ │ ├── Mac.md │ │ ├── MessageDigest.md │ │ ├── SecureRandom.md │ │ ├── Signature.md │ │ ├── WeakCipher.md │ │ ├── WeakMac.md │ │ ├── WeakMessageDigest.md │ │ ├── WeakSignature.md │ │ └── X509Certificate.md │ ├── dw_customer │ │ ├── AddressBook.md │ │ ├── AgentUserMgr.md │ │ ├── AgentUserStatusCodes.md │ │ ├── AuthenticationStatus.md │ │ ├── Credentials.md │ │ ├── Customer.md │ │ ├── CustomerActiveData.md │ │ ├── CustomerAddress.md │ │ ├── CustomerCDPData.md │ │ ├── CustomerContextMgr.md │ │ ├── CustomerGroup.md │ │ ├── CustomerList.md │ │ ├── CustomerMgr.md │ │ ├── CustomerPasswordConstraints.md │ │ ├── CustomerPaymentInstrument.md │ │ ├── CustomerStatusCodes.md │ │ ├── EncryptedObject.md │ │ ├── ExternalProfile.md │ │ ├── OrderHistory.md │ │ ├── ProductList.md │ │ ├── ProductListItem.md │ │ ├── ProductListItemPurchase.md │ │ ├── ProductListMgr.md │ │ ├── ProductListRegistrant.md │ │ ├── Profile.md │ │ └── Wallet.md │ ├── dw_extensions.applepay │ │ ├── ApplePayHookResult.md │ │ └── ApplePayHooks.md │ ├── dw_extensions.facebook │ │ ├── FacebookFeedHooks.md │ │ └── FacebookProduct.md │ ├── dw_extensions.paymentrequest │ │ ├── PaymentRequestHookResult.md │ │ └── PaymentRequestHooks.md │ ├── dw_extensions.payments │ │ ├── SalesforceBancontactPaymentDetails.md │ │ ├── SalesforceCardPaymentDetails.md │ │ ├── SalesforceEpsPaymentDetails.md │ │ ├── SalesforceIdealPaymentDetails.md │ │ ├── SalesforceKlarnaPaymentDetails.md │ │ ├── SalesforcePaymentDetails.md │ │ ├── SalesforcePaymentIntent.md │ │ ├── SalesforcePaymentMethod.md │ │ ├── SalesforcePaymentRequest.md │ │ ├── SalesforcePaymentsHooks.md │ │ ├── SalesforcePaymentsMgr.md │ │ ├── SalesforcePaymentsSiteConfiguration.md │ │ ├── SalesforcePayPalOrder.md │ │ ├── SalesforcePayPalOrderAddress.md │ │ ├── SalesforcePayPalOrderPayer.md │ │ ├── SalesforcePayPalPaymentDetails.md │ │ ├── SalesforceSepaDebitPaymentDetails.md │ │ └── SalesforceVenmoPaymentDetails.md │ ├── dw_extensions.pinterest │ │ ├── PinterestAvailability.md │ │ ├── PinterestFeedHooks.md │ │ ├── PinterestOrder.md │ │ ├── PinterestOrderHooks.md │ │ └── PinterestProduct.md │ ├── dw_io │ │ ├── CSVStreamReader.md │ │ ├── CSVStreamWriter.md │ │ ├── File.md │ │ ├── FileReader.md │ │ ├── FileWriter.md │ │ ├── InputStream.md │ │ ├── OutputStream.md │ │ ├── PrintWriter.md │ │ ├── RandomAccessFileReader.md │ │ ├── Reader.md │ │ ├── StringWriter.md │ │ ├── Writer.md │ │ ├── XMLIndentingStreamWriter.md │ │ ├── XMLStreamConstants.md │ │ ├── XMLStreamReader.md │ │ └── XMLStreamWriter.md │ ├── dw_job │ │ ├── JobExecution.md │ │ └── JobStepExecution.md │ ├── dw_net │ │ ├── FTPClient.md │ │ ├── FTPFileInfo.md │ │ ├── HTTPClient.md │ │ ├── HTTPRequestPart.md │ │ ├── Mail.md │ │ ├── SFTPClient.md │ │ ├── SFTPFileInfo.md │ │ ├── WebDAVClient.md │ │ └── WebDAVFileInfo.md │ ├── dw_object │ │ ├── ActiveData.md │ │ ├── CustomAttributes.md │ │ ├── CustomObject.md │ │ ├── CustomObjectMgr.md │ │ ├── Extensible.md │ │ ├── ExtensibleObject.md │ │ ├── Note.md │ │ ├── ObjectAttributeDefinition.md │ │ ├── ObjectAttributeGroup.md │ │ ├── ObjectAttributeValueDefinition.md │ │ ├── ObjectTypeDefinition.md │ │ ├── PersistentObject.md │ │ ├── SimpleExtensible.md │ │ └── SystemObjectMgr.md │ ├── dw_order │ │ ├── AbstractItem.md │ │ ├── AbstractItemCtnr.md │ │ ├── Appeasement.md │ │ ├── AppeasementItem.md │ │ ├── Basket.md │ │ ├── BasketMgr.md │ │ ├── BonusDiscountLineItem.md │ │ ├── CouponLineItem.md │ │ ├── CreateAgentBasketLimitExceededException.md │ │ ├── CreateBasketFromOrderException.md │ │ ├── CreateCouponLineItemException.md │ │ ├── CreateOrderException.md │ │ ├── CreateTemporaryBasketLimitExceededException.md │ │ ├── GiftCertificate.md │ │ ├── GiftCertificateLineItem.md │ │ ├── GiftCertificateMgr.md │ │ ├── GiftCertificateStatusCodes.md │ │ ├── Invoice.md │ │ ├── InvoiceItem.md │ │ ├── LineItem.md │ │ ├── LineItemCtnr.md │ │ ├── Order.md │ │ ├── OrderAddress.md │ │ ├── OrderItem.md │ │ ├── OrderMgr.md │ │ ├── OrderPaymentInstrument.md │ │ ├── OrderProcessStatusCodes.md │ │ ├── PaymentCard.md │ │ ├── PaymentInstrument.md │ │ ├── PaymentMethod.md │ │ ├── PaymentMgr.md │ │ ├── PaymentProcessor.md │ │ ├── PaymentStatusCodes.md │ │ ├── PaymentTransaction.md │ │ ├── PriceAdjustment.md │ │ ├── PriceAdjustmentLimitTypes.md │ │ ├── ProductLineItem.md │ │ ├── ProductShippingCost.md │ │ ├── ProductShippingLineItem.md │ │ ├── ProductShippingModel.md │ │ ├── Return.md │ │ ├── ReturnCase.md │ │ ├── ReturnCaseItem.md │ │ ├── ReturnItem.md │ │ ├── Shipment.md │ │ ├── ShipmentShippingCost.md │ │ ├── ShipmentShippingModel.md │ │ ├── ShippingLineItem.md │ │ ├── ShippingLocation.md │ │ ├── ShippingMethod.md │ │ ├── ShippingMgr.md │ │ ├── ShippingOrder.md │ │ ├── ShippingOrderItem.md │ │ ├── SumItem.md │ │ ├── TaxGroup.md │ │ ├── TaxItem.md │ │ ├── TaxMgr.md │ │ ├── TrackingInfo.md │ │ └── TrackingRef.md │ ├── dw_order.hooks │ │ ├── CalculateHooks.md │ │ ├── OrderHooks.md │ │ ├── PaymentHooks.md │ │ ├── ReturnHooks.md │ │ └── ShippingOrderHooks.md │ ├── dw_rpc │ │ ├── SOAPUtil.md │ │ ├── Stub.md │ │ └── WebReference.md │ ├── dw_suggest │ │ ├── BrandSuggestions.md │ │ ├── CategorySuggestions.md │ │ ├── ContentSuggestions.md │ │ ├── CustomSuggestions.md │ │ ├── ProductSuggestions.md │ │ ├── SearchPhraseSuggestions.md │ │ ├── SuggestedCategory.md │ │ ├── SuggestedContent.md │ │ ├── SuggestedPhrase.md │ │ ├── SuggestedProduct.md │ │ ├── SuggestedTerm.md │ │ ├── SuggestedTerms.md │ │ ├── Suggestions.md │ │ └── SuggestModel.md │ ├── dw_svc │ │ ├── FTPService.md │ │ ├── FTPServiceDefinition.md │ │ ├── HTTPFormService.md │ │ ├── HTTPFormServiceDefinition.md │ │ ├── HTTPService.md │ │ ├── HTTPServiceDefinition.md │ │ ├── LocalServiceRegistry.md │ │ ├── Result.md │ │ ├── Service.md │ │ ├── ServiceCallback.md │ │ ├── ServiceConfig.md │ │ ├── ServiceCredential.md │ │ ├── ServiceDefinition.md │ │ ├── ServiceProfile.md │ │ ├── ServiceRegistry.md │ │ ├── SOAPService.md │ │ └── SOAPServiceDefinition.md │ ├── dw_system │ │ ├── AgentUserStatusCodes.md │ │ ├── Cache.md │ │ ├── CacheMgr.md │ │ ├── HookMgr.md │ │ ├── InternalObject.md │ │ ├── JobProcessMonitor.md │ │ ├── Log.md │ │ ├── Logger.md │ │ ├── LogNDC.md │ │ ├── OrganizationPreferences.md │ │ ├── Pipeline.md │ │ ├── PipelineDictionary.md │ │ ├── RemoteInclude.md │ │ ├── Request.md │ │ ├── RequestHooks.md │ │ ├── Response.md │ │ ├── RESTErrorResponse.md │ │ ├── RESTResponseMgr.md │ │ ├── RESTSuccessResponse.md │ │ ├── SearchStatus.md │ │ ├── Session.md │ │ ├── Site.md │ │ ├── SitePreferences.md │ │ ├── Status.md │ │ ├── StatusItem.md │ │ ├── System.md │ │ └── Transaction.md │ ├── dw_util │ │ ├── ArrayList.md │ │ ├── Assert.md │ │ ├── BigInteger.md │ │ ├── Bytes.md │ │ ├── Calendar.md │ │ ├── Collection.md │ │ ├── Currency.md │ │ ├── DateUtils.md │ │ ├── Decimal.md │ │ ├── FilteringCollection.md │ │ ├── Geolocation.md │ │ ├── HashMap.md │ │ ├── HashSet.md │ │ ├── Iterator.md │ │ ├── LinkedHashMap.md │ │ ├── LinkedHashSet.md │ │ ├── List.md │ │ ├── Locale.md │ │ ├── Map.md │ │ ├── MapEntry.md │ │ ├── MappingKey.md │ │ ├── MappingMgr.md │ │ ├── PropertyComparator.md │ │ ├── SecureEncoder.md │ │ ├── SecureFilter.md │ │ ├── SeekableIterator.md │ │ ├── Set.md │ │ ├── SortedMap.md │ │ ├── SortedSet.md │ │ ├── StringUtils.md │ │ ├── Template.md │ │ └── UUIDUtils.md │ ├── dw_value │ │ ├── EnumValue.md │ │ ├── MimeEncodedText.md │ │ ├── Money.md │ │ └── Quantity.md │ ├── dw_web │ │ ├── ClickStream.md │ │ ├── ClickStreamEntry.md │ │ ├── Cookie.md │ │ ├── Cookies.md │ │ ├── CSRFProtection.md │ │ ├── Form.md │ │ ├── FormAction.md │ │ ├── FormElement.md │ │ ├── FormElementValidationResult.md │ │ ├── FormField.md │ │ ├── FormFieldOption.md │ │ ├── FormFieldOptions.md │ │ ├── FormGroup.md │ │ ├── FormList.md │ │ ├── FormListItem.md │ │ ├── Forms.md │ │ ├── HttpParameter.md │ │ ├── HttpParameterMap.md │ │ ├── LoopIterator.md │ │ ├── PageMetaData.md │ │ ├── PageMetaTag.md │ │ ├── PagingModel.md │ │ ├── Resource.md │ │ ├── URL.md │ │ ├── URLAction.md │ │ ├── URLParameter.md │ │ ├── URLRedirect.md │ │ ├── URLRedirectMgr.md │ │ └── URLUtils.md │ ├── sfra │ │ ├── account.md │ │ ├── address.md │ │ ├── billing.md │ │ ├── cart.md │ │ ├── categories.md │ │ ├── content.md │ │ ├── locale.md │ │ ├── order.md │ │ ├── payment.md │ │ ├── price-default.md │ │ ├── price-range.md │ │ ├── price-tiered.md │ │ ├── product-bundle.md │ │ ├── product-full.md │ │ ├── product-line-items.md │ │ ├── product-search.md │ │ ├── product-tile.md │ │ ├── querystring.md │ │ ├── render.md │ │ ├── request.md │ │ ├── response.md │ │ ├── server.md │ │ ├── shipping.md │ │ ├── store.md │ │ ├── stores.md │ │ └── totals.md │ └── TopLevel │ ├── APIException.md │ ├── arguments.md │ ├── Array.md │ ├── ArrayBuffer.md │ ├── BigInt.md │ ├── Boolean.md │ ├── ConversionError.md │ ├── DataView.md │ ├── Date.md │ ├── Error.md │ ├── ES6Iterator.md │ ├── EvalError.md │ ├── Fault.md │ ├── Float32Array.md │ ├── Float64Array.md │ ├── Function.md │ ├── Generator.md │ ├── global.md │ ├── Int16Array.md │ ├── Int32Array.md │ ├── Int8Array.md │ ├── InternalError.md │ ├── IOError.md │ ├── Iterable.md │ ├── Iterator.md │ ├── JSON.md │ ├── Map.md │ ├── Math.md │ ├── Module.md │ ├── Namespace.md │ ├── Number.md │ ├── Object.md │ ├── QName.md │ ├── RangeError.md │ ├── ReferenceError.md │ ├── RegExp.md │ ├── Set.md │ ├── StopIteration.md │ ├── String.md │ ├── Symbol.md │ ├── SyntaxError.md │ ├── SystemError.md │ ├── TypeError.md │ ├── Uint16Array.md │ ├── Uint32Array.md │ ├── Uint8Array.md │ ├── Uint8ClampedArray.md │ ├── URIError.md │ ├── WeakMap.md │ ├── WeakSet.md │ ├── XML.md │ ├── XMLList.md │ └── XMLStreamError.md ├── docs-site │ ├── .gitignore │ ├── App.tsx │ ├── components │ │ ├── Badge.tsx │ │ ├── BreadcrumbSchema.tsx │ │ ├── CodeBlock.tsx │ │ ├── Collapsible.tsx │ │ ├── ConfigBuilder.tsx │ │ ├── ConfigHero.tsx │ │ ├── ConfigModeTabs.tsx │ │ ├── icons.tsx │ │ ├── Layout.tsx │ │ ├── LightCodeContainer.tsx │ │ ├── NewcomerCTA.tsx │ │ ├── NextStepsStrip.tsx │ │ ├── OnThisPage.tsx │ │ ├── Search.tsx │ │ ├── SEO.tsx │ │ ├── Sidebar.tsx │ │ ├── StructuredData.tsx │ │ ├── ToolCard.tsx │ │ ├── ToolFilters.tsx │ │ ├── Typography.tsx │ │ └── VersionBadge.tsx │ ├── constants.tsx │ ├── index.html │ ├── main.tsx │ ├── metadata.json │ ├── package-lock.json │ ├── package.json │ ├── pages │ │ ├── AIInterfacesPage.tsx │ │ ├── ConfigurationPage.tsx │ │ ├── DevelopmentPage.tsx │ │ ├── ExamplesPage.tsx │ │ ├── FeaturesPage.tsx │ │ ├── HomePage.tsx │ │ ├── SecurityPage.tsx │ │ ├── ToolsPage.tsx │ │ └── TroubleshootingPage.tsx │ ├── postcss.config.js │ ├── public │ │ ├── .well-known │ │ │ └── security.txt │ │ ├── 404.html │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── explain-product-pricing-methods-no-mcp.png │ │ ├── explain-product-pricing-methods.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── llms.txt │ │ ├── robots.txt │ │ ├── site.webmanifest │ │ └── sitemap.xml │ ├── README.md │ ├── scripts │ │ ├── generate-search-index.js │ │ ├── generate-sitemap.js │ │ └── search-dev.js │ ├── src │ │ └── styles │ │ ├── input.css │ │ └── prism-theme.css │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── types.ts │ ├── utils │ │ ├── search.ts │ │ └── toolsData.ts │ └── vite.config.ts ├── eslint.config.js ├── jest.config.js ├── LICENSE ├── package-lock.json ├── package.json ├── README.md ├── scripts │ └── convert-docs.js ├── SECURITY.md ├── server.json ├── src │ ├── clients │ │ ├── base │ │ │ ├── http-client.ts │ │ │ ├── oauth-token.ts │ │ │ └── ocapi-auth-client.ts │ │ ├── best-practices-client.ts │ │ ├── cartridge-generation-client.ts │ │ ├── docs │ │ │ ├── class-content-parser.ts │ │ │ ├── class-name-resolver.ts │ │ │ ├── documentation-scanner.ts │ │ │ ├── index.ts │ │ │ └── referenced-types-extractor.ts │ │ ├── docs-client.ts │ │ ├── log-client.ts │ │ ├── logs │ │ │ ├── index.ts │ │ │ ├── log-analyzer.ts │ │ │ ├── log-client.ts │ │ │ ├── log-constants.ts │ │ │ ├── log-file-discovery.ts │ │ │ ├── log-file-reader.ts │ │ │ ├── log-formatter.ts │ │ │ ├── log-processor.ts │ │ │ ├── log-types.ts │ │ │ └── webdav-client-manager.ts │ │ ├── ocapi │ │ │ ├── code-versions-client.ts │ │ │ ├── site-preferences-client.ts │ │ │ └── system-objects-client.ts │ │ ├── ocapi-client.ts │ │ └── sfra-client.ts │ ├── config │ │ ├── configuration-factory.ts │ │ └── dw-json-loader.ts │ ├── core │ │ ├── handlers │ │ │ ├── abstract-log-tool-handler.ts │ │ │ ├── base-handler.ts │ │ │ ├── best-practices-handler.ts │ │ │ ├── cartridge-handler.ts │ │ │ ├── client-factory.ts │ │ │ ├── code-version-handler.ts │ │ │ ├── docs-handler.ts │ │ │ ├── job-log-handler.ts │ │ │ ├── job-log-tool-config.ts │ │ │ ├── log-handler.ts │ │ │ ├── log-tool-config.ts │ │ │ ├── sfra-handler.ts │ │ │ ├── system-object-handler.ts │ │ │ └── validation-helpers.ts │ │ ├── server.ts │ │ └── tool-definitions.ts │ ├── index.ts │ ├── main.ts │ ├── services │ │ ├── file-system-service.ts │ │ ├── index.ts │ │ └── path-service.ts │ ├── tool-configs │ │ ├── best-practices-tool-config.ts │ │ ├── cartridge-tool-config.ts │ │ ├── code-version-tool-config.ts │ │ ├── docs-tool-config.ts │ │ ├── job-log-tool-config.ts │ │ ├── log-tool-config.ts │ │ ├── sfra-tool-config.ts │ │ └── system-object-tool-config.ts │ ├── types │ │ └── types.ts │ └── utils │ ├── cache.ts │ ├── job-log-tool-config.ts │ ├── job-log-utils.ts │ ├── log-cache.ts │ ├── log-tool-config.ts │ ├── log-tool-constants.ts │ ├── log-tool-utils.ts │ ├── logger.ts │ ├── ocapi-url-builder.ts │ ├── path-resolver.ts │ ├── query-builder.ts │ ├── utils.ts │ └── validator.ts ├── tests │ ├── __mocks__ │ │ ├── docs-client.ts │ │ ├── src │ │ │ └── clients │ │ │ └── base │ │ │ └── http-client.js │ │ └── webdav.js │ ├── base-handler.test.ts │ ├── base-http-client.test.ts │ ├── best-practices-handler.test.ts │ ├── cache.test.ts │ ├── cartridge-handler.test.ts │ ├── class-content-parser.test.ts │ ├── class-name-resolver.test.ts │ ├── client-factory.test.ts │ ├── code-version-handler.test.ts │ ├── code-versions-client.test.ts │ ├── config.test.ts │ ├── configuration-factory.test.ts │ ├── docs-handler.test.ts │ ├── documentation-scanner.test.ts │ ├── file-system-service.test.ts │ ├── job-log-handler.test.ts │ ├── job-log-utils.test.ts │ ├── log-client.test.ts │ ├── log-handler.test.ts │ ├── log-processor.test.ts │ ├── logger.test.ts │ ├── mcp │ │ ├── AGENTS.md │ │ ├── node │ │ │ ├── activate-code-version-advanced.full-mode.programmatic.test.js │ │ │ ├── code-versions.full-mode.programmatic.test.js │ │ │ ├── generate-cartridge-structure.docs-only.programmatic.test.js │ │ │ ├── get-available-best-practice-guides.docs-only.programmatic.test.js │ │ │ ├── get-available-sfra-documents.programmatic.test.js │ │ │ ├── get-best-practice-guide.docs-only.programmatic.test.js │ │ │ ├── get-hook-reference.docs-only.programmatic.test.js │ │ │ ├── get-job-execution-summary.full-mode.programmatic.test.js │ │ │ ├── get-job-log-entries.full-mode.programmatic.test.js │ │ │ ├── get-latest-debug.full-mode.programmatic.test.js │ │ │ ├── get-latest-error.full-mode.programmatic.test.js │ │ │ ├── get-latest-info.full-mode.programmatic.test.js │ │ │ ├── get-latest-job-log-files.full-mode.programmatic.test.js │ │ │ ├── get-latest-warn.full-mode.programmatic.test.js │ │ │ ├── get-log-file-contents.full-mode.programmatic.test.js │ │ │ ├── get-sfcc-class-documentation.docs-only.programmatic.test.js │ │ │ ├── get-sfcc-class-info.docs-only.programmatic.test.js │ │ │ ├── get-sfra-categories.docs-only.programmatic.test.js │ │ │ ├── get-sfra-document.programmatic.test.js │ │ │ ├── get-sfra-documents-by-category.docs-only.programmatic.test.js │ │ │ ├── get-system-object-definition.full-mode.programmatic.test.js │ │ │ ├── get-system-object-definitions.docs-only.programmatic.test.js │ │ │ ├── get-system-object-definitions.full-mode.programmatic.test.js │ │ │ ├── list-log-files.full-mode.programmatic.test.js │ │ │ ├── list-sfcc-classes.docs-only.programmatic.test.js │ │ │ ├── search-best-practices.docs-only.programmatic.test.js │ │ │ ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js │ │ │ ├── search-job-logs-by-name.full-mode.programmatic.test.js │ │ │ ├── search-job-logs.full-mode.programmatic.test.js │ │ │ ├── search-logs.full-mode.programmatic.test.js │ │ │ ├── search-sfcc-classes.docs-only.programmatic.test.js │ │ │ ├── search-sfcc-methods.docs-only.programmatic.test.js │ │ │ ├── search-sfra-documentation.docs-only.programmatic.test.js │ │ │ ├── search-site-preferences.full-mode.programmatic.test.js │ │ │ ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js │ │ │ ├── search-system-object-attribute-groups.full-mode.programmatic.test.js │ │ │ ├── summarize-logs.full-mode.programmatic.test.js │ │ │ ├── tools.docs-only.programmatic.test.js │ │ │ └── tools.full-mode.programmatic.test.js │ │ ├── README.md │ │ ├── test-fixtures │ │ │ └── dw.json │ │ └── yaml │ │ ├── activate-code-version.docs-only.test.mcp.yml │ │ ├── activate-code-version.full-mode.test.mcp.yml │ │ ├── get_latest_error.test.mcp.yml │ │ ├── get-available-best-practice-guides.docs-only.test.mcp.yml │ │ ├── get-available-best-practice-guides.full-mode.test.mcp.yml │ │ ├── get-available-sfra-documents.docs-only.test.mcp.yml │ │ ├── get-available-sfra-documents.full-mode.test.mcp.yml │ │ ├── get-best-practice-guide.docs-only.test.mcp.yml │ │ ├── get-best-practice-guide.full-mode.test.mcp.yml │ │ ├── get-code-versions.docs-only.test.mcp.yml │ │ ├── get-code-versions.full-mode.test.mcp.yml │ │ ├── get-hook-reference.docs-only.test.mcp.yml │ │ ├── get-hook-reference.full-mode.test.mcp.yml │ │ ├── get-job-execution-summary.full-mode.test.mcp.yml │ │ ├── get-job-log-entries.full-mode.test.mcp.yml │ │ ├── get-latest-debug.full-mode.test.mcp.yml │ │ ├── get-latest-error.full-mode.test.mcp.yml │ │ ├── get-latest-info.full-mode.test.mcp.yml │ │ ├── get-latest-job-log-files.full-mode.test.mcp.yml │ │ ├── get-latest-warn.full-mode.test.mcp.yml │ │ ├── get-log-file-contents.full-mode.test.mcp.yml │ │ ├── get-sfcc-class-documentation.docs-only.test.mcp.yml │ │ ├── get-sfcc-class-documentation.full-mode.test.mcp.yml │ │ ├── get-sfcc-class-info.docs-only.test.mcp.yml │ │ ├── get-sfcc-class-info.full-mode.test.mcp.yml │ │ ├── get-sfra-categories.docs-only.test.mcp.yml │ │ ├── get-sfra-categories.full-mode.test.mcp.yml │ │ ├── get-sfra-document.docs-only.test.mcp.yml │ │ ├── get-sfra-document.full-mode.test.mcp.yml │ │ ├── get-sfra-documents-by-category.docs-only.test.mcp.yml │ │ ├── get-sfra-documents-by-category.full-mode.test.mcp.yml │ │ ├── get-system-object-definition.docs-only.test.mcp.yml │ │ ├── get-system-object-definition.full-mode.test.mcp.yml │ │ ├── get-system-object-definitions.docs-only.test.mcp.yml │ │ ├── get-system-object-definitions.full-mode.test.mcp.yml │ │ ├── list-log-files.full-mode.test.mcp.yml │ │ ├── list-sfcc-classes.docs-only.test.mcp.yml │ │ ├── list-sfcc-classes.full-mode.test.mcp.yml │ │ ├── search-best-practices.docs-only.test.mcp.yml │ │ ├── search-best-practices.full-mode.test.mcp.yml │ │ ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml │ │ ├── search-custom-object-attribute-definitions.test.mcp.yml │ │ ├── search-job-logs-by-name.full-mode.test.mcp.yml │ │ ├── search-job-logs.full-mode.test.mcp.yml │ │ ├── search-logs.full-mode.test.mcp.yml │ │ ├── search-sfcc-classes.docs-only.test.mcp.yml │ │ ├── search-sfcc-classes.full-mode.test.mcp.yml │ │ ├── search-sfcc-methods.docs-only.test.mcp.yml │ │ ├── search-sfcc-methods.full-mode.test.mcp.yml │ │ ├── search-sfra-documentation.docs-only.test.mcp.yml │ │ ├── search-sfra-documentation.full-mode.test.mcp.yml │ │ ├── search-site-preferences.docs-only.test.mcp.yml │ │ ├── search-site-preferences.full-mode.test.mcp.yml │ │ ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml │ │ ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml │ │ ├── search-system-object-attribute-groups.docs-only.test.mcp.yml │ │ ├── search-system-object-attribute-groups.full-mode.test.mcp.yml │ │ ├── summarize-logs.full-mode.test.mcp.yml │ │ ├── tools.docs-only.test.mcp.yml │ │ └── tools.full-mode.test.mcp.yml │ ├── oauth-token.test.ts │ ├── ocapi-auth-client.test.ts │ ├── ocapi-client.test.ts │ ├── path-service.test.ts │ ├── query-builder.test.ts │ ├── referenced-types-extractor.test.ts │ ├── servers │ │ ├── sfcc-mock-server │ │ │ ├── mock-data │ │ │ │ └── ocapi │ │ │ │ ├── code-versions.json │ │ │ │ ├── custom-object-attributes-customapi.json │ │ │ │ ├── custom-object-attributes-globalsettings.json │ │ │ │ ├── custom-object-attributes-versionhistory.json │ │ │ │ ├── site-preferences-ccv.json │ │ │ │ ├── site-preferences-fastforward.json │ │ │ │ ├── site-preferences-sfra.json │ │ │ │ ├── site-preferences-storefront.json │ │ │ │ ├── site-preferences-system.json │ │ │ │ ├── system-object-attribute-groups-campaign.json │ │ │ │ ├── system-object-attribute-groups-category.json │ │ │ │ ├── system-object-attribute-groups-order.json │ │ │ │ ├── system-object-attribute-groups-product.json │ │ │ │ ├── system-object-attribute-groups-sitepreferences.json │ │ │ │ ├── system-object-attributes-customeraddress.json │ │ │ │ ├── system-object-attributes-product-expanded.json │ │ │ │ ├── system-object-attributes-product.json │ │ │ │ ├── system-object-definition-category.json │ │ │ │ ├── system-object-definition-customer.json │ │ │ │ ├── system-object-definition-customeraddress.json │ │ │ │ ├── system-object-definition-order.json │ │ │ │ ├── system-object-definition-product.json │ │ │ │ ├── system-object-definitions-old.json │ │ │ │ └── system-object-definitions.json │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ ├── scripts │ │ │ │ └── setup-logs.js │ │ │ ├── server.js │ │ │ └── src │ │ │ ├── app.js │ │ │ ├── config │ │ │ │ └── server-config.js │ │ │ ├── middleware │ │ │ │ ├── auth.js │ │ │ │ ├── cors.js │ │ │ │ └── logging.js │ │ │ ├── routes │ │ │ │ ├── ocapi │ │ │ │ │ ├── code-versions-handler.js │ │ │ │ │ ├── oauth-handler.js │ │ │ │ │ ├── ocapi-error-utils.js │ │ │ │ │ ├── ocapi-utils.js │ │ │ │ │ ├── site-preferences-handler.js │ │ │ │ │ └── system-objects-handler.js │ │ │ │ ├── ocapi.js │ │ │ │ └── webdav.js │ │ │ └── utils │ │ │ ├── mock-data-loader.js │ │ │ └── webdav-xml.js │ │ └── sfcc-mock-server-manager.ts │ ├── sfcc-mock-server.test.ts │ ├── site-preferences-client.test.ts │ ├── system-objects-client.test.ts │ ├── utils.test.ts │ ├── validation-helpers.test.ts │ └── validator.test.ts ├── tsconfig.json └── tsconfig.test.json ``` # Files -------------------------------------------------------------------------------- /tests/servers/sfcc-mock-server/mock-data/ocapi/system-object-attributes-customeraddress.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "_v": "23.2", 3 | "_type": "object_attribute_definition_search_result", 4 | "count": 15, 5 | "hits": [ 6 | { 7 | "_type": "object_attribute_definition", 8 | "_resource_state": "3270518feb2ba23c77355a1690a5a9916acb509aa181e533b529de4abe2969f8", 9 | "id": "ID", 10 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/ID" 11 | }, 12 | { 13 | "_type": "object_attribute_definition", 14 | "_resource_state": "3459bc3f84b37b9391714b05bbd8dedad7cac8edd3c243de0f0092549144240d", 15 | "id": "UUID", 16 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/UUID" 17 | }, 18 | { 19 | "_type": "object_attribute_definition", 20 | "_resource_state": "45f36d21db7d180fb27087e13eec59e80562f51472378c4293284da7550787ee", 21 | "id": "address1", 22 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/address1" 23 | }, 24 | { 25 | "_type": "object_attribute_definition", 26 | "_resource_state": "29d08491c3d2e65146b65fcfe44a64bf8ae7b538543d11d5bf6924c28965d9a0", 27 | "id": "address2", 28 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/address2" 29 | }, 30 | { 31 | "_type": "object_attribute_definition", 32 | "_resource_state": "2cce8462628d664cf70c247d7d1cddd1f7dce24cd0e294db28162cdb62d8c291", 33 | "id": "city", 34 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/city" 35 | }, 36 | { 37 | "_type": "object_attribute_definition", 38 | "_resource_state": "b15c7929905e11c4e1bf96a1de9c24f97645d5653c0a78efe916a3e1876be2ad", 39 | "id": "companyName", 40 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/companyName" 41 | }, 42 | { 43 | "_type": "object_attribute_definition", 44 | "_resource_state": "c0eb64a92268d13fa32777eaec7f824dc5db27088a2d133442bd081e11480b0b", 45 | "id": "countryCode", 46 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/countryCode" 47 | }, 48 | { 49 | "_type": "object_attribute_definition", 50 | "_resource_state": "f85a590a52c5d04bc7b61a4fc841d059e01e6dd2325761cf6d368a35b4b9b36b", 51 | "id": "creationDate", 52 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/creationDate" 53 | }, 54 | { 55 | "_type": "object_attribute_definition", 56 | "_resource_state": "5aa6c1f0af128dde7fa233ffa45187322f56d095a81a3348edcc8b0a21a0109a", 57 | "id": "firstName", 58 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/firstName" 59 | }, 60 | { 61 | "_type": "object_attribute_definition", 62 | "_resource_state": "fe691db5c3021705fcf0b30de48afa4eeb8172bd80846f830bb77eae9a0469bd", 63 | "id": "jobTitle", 64 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/jobTitle" 65 | }, 66 | { 67 | "_type": "object_attribute_definition", 68 | "_resource_state": "c404f51befa8a2a01b9775107d28b8067cebb1218bcaa135b616e8257a041e9e", 69 | "id": "lastModified", 70 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/lastModified" 71 | }, 72 | { 73 | "_type": "object_attribute_definition", 74 | "_resource_state": "84205a32eaaed93d867d8425d65347144f7ae376af1a45802602640e7c99e9c6", 75 | "id": "lastName", 76 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/lastName" 77 | }, 78 | { 79 | "_type": "object_attribute_definition", 80 | "_resource_state": "be89fc4879cca7a9fa426cac2e82a2d8829a11e0b4a59028482cb98cdf2d4567", 81 | "id": "phone", 82 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/phone" 83 | }, 84 | { 85 | "_type": "object_attribute_definition", 86 | "_resource_state": "4c78d7cb9d9e36a4cb69794ec547c3df032f12ff757ec716683913c6fe69feea", 87 | "id": "phone_country", 88 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/phone_country" 89 | }, 90 | { 91 | "_type": "object_attribute_definition", 92 | "_resource_state": "e61daf9d3e2beae465b19f3d6d46bd184bbc6d56b94bf5866b17311b06e6d51b", 93 | "id": "postBox", 94 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/CustomerAddress/attribute_definitions/postBox" 95 | } 96 | ], 97 | "next": { 98 | "_type": "result_page", 99 | "count": 15, 100 | "start": 15 101 | }, 102 | "query": { 103 | "match_all_query": { 104 | "_type": "match_all_query" 105 | } 106 | }, 107 | "start": 0, 108 | "total": 23 109 | } ``` -------------------------------------------------------------------------------- /docs/dw_svc/ServiceDefinition.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.svc 2 | 3 | # Class ServiceDefinition 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.svc.ServiceDefinition 9 | 10 | ## Description 11 | 12 | Base class of Service Definitions. A service definition represents configuration that is shared across all Service instances. 13 | 14 | ## Properties 15 | 16 | ### configuration 17 | 18 | **Type:** ServiceConfig (Read Only) 19 | 20 | The Service Configuration stored in the database. 21 | 22 | ### mock 23 | 24 | **Type:** boolean 25 | 26 | The status of whether mock mode is enabled for all instances of this definition. 27 | 28 | ### serviceName 29 | 30 | **Type:** String (Read Only) 31 | 32 | The name of this service. 33 | 34 | ### throwOnError 35 | 36 | **Type:** boolean 37 | 38 | The status of whether the shared throwOnError flag is set. 39 | 40 | ## Constructor Summary 41 | 42 | ## Method Summary 43 | 44 | ### configure 45 | 46 | **Signature:** `configure(config : Object) : ServiceDefinition` 47 | 48 | Register a callback to handle custom portions of the service. 49 | 50 | ### getConfiguration 51 | 52 | **Signature:** `getConfiguration() : ServiceConfig` 53 | 54 | Returns the Service Configuration stored in the database. 55 | 56 | ### getServiceName 57 | 58 | **Signature:** `getServiceName() : String` 59 | 60 | Returns the name of this service. 61 | 62 | ### isMock 63 | 64 | **Signature:** `isMock() : boolean` 65 | 66 | Returns the status of whether mock mode is enabled for all instances of this definition. 67 | 68 | ### isThrowOnError 69 | 70 | **Signature:** `isThrowOnError() : boolean` 71 | 72 | Returns the status of whether the shared throwOnError flag is set. 73 | 74 | ### setMock 75 | 76 | **Signature:** `setMock() : ServiceDefinition` 77 | 78 | Sets the mock mode for all Service instances that use this definition. 79 | 80 | ### setThrowOnError 81 | 82 | **Signature:** `setThrowOnError() : ServiceDefinition` 83 | 84 | Sets the throwOnError flag to true for all Service instances that use this definition. 85 | 86 | ## Method Detail 87 | 88 | ## Method Details 89 | 90 | ### configure 91 | 92 | **Signature:** `configure(config : Object) : ServiceDefinition` 93 | 94 | **Description:** Register a callback to handle custom portions of the service. This callback may declare multiple methods: { initServiceClient: function() { // Create and return the internal service client object. // This is usually optional, except in the case of SOAP services. }, // svc is the call-specific Service instance. For example, it may be an HTTPService or FTPService. // params are the arguments passed to the call method (if any). createRequest: function(svc:Service, params) { // Perform any required call-time configuration. // Optionally return a Service-specific object }, // svc is the call-specific Service instance. // arg is the output of createRequest. execute: function(svc:Service, arg:Object) { // Execute the service call and return a result // This method is not used by default for HTTP-related services unless executeOverride is set. }, // Use the execute function if it is present. This is only required to use the functionality with HTTP services. executeOverride: true, // svc is the call-specific Service instance. // response is the output of execute. parseResponse: function(svc:Service, response: Object) { // Process the response object as needed. // The return value of this method will be the return value of the outer call method. }, // svc is the call-specific Service instance. // arg is the output of createRequest. mockCall: function(svc:Service, arg:Object) { // This method takes the place of the 'execute' phase when mocking is enabled. // Note initServiceClient, createRequest, and parseResponse still invoked. }, // svc is the call-specific Service instance. // params are the arguments passed to the call method (if any). mockFull: function(svc:Service, params) { // This method takes the place of the entire service call when mocking is enabled. // No other callbacks are invoked. The output of this method becomes the output of call. } } 95 | 96 | **Parameters:** 97 | 98 | - `config`: Callback object. 99 | 100 | **Returns:** 101 | 102 | this 103 | 104 | --- 105 | 106 | ### getConfiguration 107 | 108 | **Signature:** `getConfiguration() : ServiceConfig` 109 | 110 | **Description:** Returns the Service Configuration stored in the database. 111 | 112 | **Returns:** 113 | 114 | Service Configuration. 115 | 116 | --- 117 | 118 | ### getServiceName 119 | 120 | **Signature:** `getServiceName() : String` 121 | 122 | **Description:** Returns the name of this service. 123 | 124 | **Returns:** 125 | 126 | Service name. 127 | 128 | --- 129 | 130 | ### isMock 131 | 132 | **Signature:** `isMock() : boolean` 133 | 134 | **Description:** Returns the status of whether mock mode is enabled for all instances of this definition. 135 | 136 | **Returns:** 137 | 138 | true for mock mode, false otherwise. 139 | 140 | --- 141 | 142 | ### isThrowOnError 143 | 144 | **Signature:** `isThrowOnError() : boolean` 145 | 146 | **Description:** Returns the status of whether the shared throwOnError flag is set. 147 | 148 | **Returns:** 149 | 150 | throwOnError flag. 151 | 152 | --- 153 | 154 | ### setMock 155 | 156 | **Signature:** `setMock() : ServiceDefinition` 157 | 158 | **Description:** Sets the mock mode for all Service instances that use this definition. 159 | 160 | **Returns:** 161 | 162 | this Service Definition. 163 | 164 | --- 165 | 166 | ### setThrowOnError 167 | 168 | **Signature:** `setThrowOnError() : ServiceDefinition` 169 | 170 | **Description:** Sets the throwOnError flag to true for all Service instances that use this definition. 171 | 172 | **Returns:** 173 | 174 | this Service Definition. 175 | 176 | --- ``` -------------------------------------------------------------------------------- /docs-site/components/ConfigBuilder.tsx: -------------------------------------------------------------------------------- ```typescript 1 | import React from 'react'; 2 | import CodeBlock from './CodeBlock'; 3 | 4 | interface FieldState { 5 | hostname: string; 6 | username: string; 7 | password: string; 8 | clientId: string; 9 | clientSecret: string; 10 | codeVersion: string; 11 | siteId: string; 12 | minimal: boolean; 13 | } 14 | 15 | const initial: FieldState = { 16 | hostname: 'dev01-sandbox.us01.dx.commercecloud.salesforce.com', 17 | username: 'your-username', 18 | password: 'your-password', 19 | clientId: '', 20 | clientSecret: '', 21 | codeVersion: 'version1', 22 | siteId: 'RefArch', 23 | minimal: true 24 | }; 25 | 26 | const labelCls = 'block text-xs font-semibold uppercase tracking-wide text-gray-600 mb-1'; 27 | const inputCls = 'w-full rounded-lg border border-gray-300 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 px-3 py-2 text-sm bg-white'; 28 | 29 | const pillBase = 'px-3 py-1.5 rounded-full text-xs font-medium transition border flex items-center gap-1'; 30 | 31 | export const ConfigBuilder: React.FC = () => { 32 | const [state, setState] = React.useState<FieldState>(initial); 33 | 34 | const toggleMinimal = () => setState(s => ({ ...s, minimal: !s.minimal })); 35 | 36 | const json = React.useMemo(() => { 37 | const base: Record<string, string> = { 38 | hostname: state.hostname, 39 | username: state.username, 40 | password: state.password 41 | }; 42 | if (!state.minimal) { 43 | if (state.clientId) base['client-id'] = state.clientId; 44 | if (state.clientSecret) base['client-secret'] = state.clientSecret; 45 | if (state.codeVersion) base['code-version'] = state.codeVersion; 46 | if (state.siteId) base['site-id'] = state.siteId; 47 | } 48 | return JSON.stringify(base, null, 2); 49 | }, [state]); 50 | 51 | const update = (k: keyof FieldState) => (e: React.ChangeEvent<HTMLInputElement>) => setState(s => ({ ...s, [k]: e.target.value })); 52 | 53 | return ( 54 | <div className="space-y-6"> 55 | <div className="flex flex-wrap gap-3 items-center"> 56 | <button onClick={toggleMinimal} className={`${pillBase} ${state.minimal ? 'bg-blue-600 text-white border-blue-600 shadow' : 'bg-white text-gray-700 border-gray-200 hover:border-blue-400'}`} 57 | aria-pressed={state.minimal}> 58 | {state.minimal ? 'Minimal Config' : 'Show Minimal'} 59 | </button> 60 | <button onClick={toggleMinimal} className={`${pillBase} ${!state.minimal ? 'bg-purple-600 text-white border-purple-600 shadow' : 'bg-white text-gray-700 border-gray-200 hover:border-purple-400'}`} 61 | aria-pressed={!state.minimal}> 62 | {!state.minimal ? 'Advanced Config' : 'Show Advanced'} 63 | </button> 64 | <span className="text-xs text-gray-500">Toggle to include OAuth + code/site fields</span> 65 | </div> 66 | 67 | <div className="grid md:grid-cols-2 gap-6"> 68 | <div className="space-y-4"> 69 | <div> 70 | <label className={labelCls}>Hostname *</label> 71 | <input value={state.hostname} onChange={update('hostname')} className={inputCls} /> 72 | </div> 73 | <div className="grid grid-cols-2 gap-4"> 74 | <div> 75 | <label className={labelCls}>Username *</label> 76 | <input value={state.username} onChange={update('username')} className={inputCls} /> 77 | </div> 78 | <div> 79 | <label className={labelCls}>Password *</label> 80 | <input type="password" value={state.password} onChange={update('password')} className={inputCls} /> 81 | </div> 82 | </div> 83 | {!state.minimal && ( 84 | <> 85 | <div className="grid grid-cols-2 gap-4"> 86 | <div> 87 | <label className={labelCls}>Client ID</label> 88 | <input value={state.clientId} onChange={update('clientId')} className={inputCls} /> 89 | </div> 90 | <div> 91 | <label className={labelCls}>Client Secret</label> 92 | <input type="password" value={state.clientSecret} onChange={update('clientSecret')} className={inputCls} /> 93 | </div> 94 | </div> 95 | <div className="grid grid-cols-2 gap-4"> 96 | <div> 97 | <label className={labelCls}>Code Version</label> 98 | <input value={state.codeVersion} onChange={update('codeVersion')} className={inputCls} /> 99 | </div> 100 | <div> 101 | <label className={labelCls}>Site ID</label> 102 | <input value={state.siteId} onChange={update('siteId')} className={inputCls} /> 103 | </div> 104 | </div> 105 | </> 106 | )} 107 | <p className="text-[11px] text-gray-500">* Required for WebDAV + log tools. Client credentials unlock Data API features.</p> 108 | </div> 109 | <div> 110 | <CodeBlock language="json" code={json} /> 111 | <p className="text-xs text-gray-500 -mt-4">Copy & save as <code className="font-mono">dw.json</code> then run with <code className="font-mono">--dw-json ./dw.json</code></p> 112 | </div> 113 | </div> 114 | </div> 115 | ); 116 | }; 117 | 118 | export default ConfigBuilder; 119 | ``` -------------------------------------------------------------------------------- /docs/dw_catalog/SearchRefinementValue.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.catalog 2 | 3 | # Class SearchRefinementValue 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.catalog.SearchRefinementValue 9 | 10 | ## Description 11 | 12 | Represents the value of a product or content search refinement. 13 | 14 | ## Properties 15 | 16 | ### description 17 | 18 | **Type:** String (Read Only) 19 | 20 | The optional refinement value description in the current locale. 21 | 22 | ### displayValue 23 | 24 | **Type:** String (Read Only) 25 | 26 | The refinement display value. For attribute refinements, this is 27 | the appropriate display value based on optional value display names 28 | within the object attribute definition. If no display name is defined, 29 | the value itself is returned. For category refinements, this is the 30 | display name of the category in the current locale. For price 31 | refinements, this is a string representation of the range appropriate for 32 | display. 33 | 34 | ### hitCount 35 | 36 | **Type:** Number (Read Only) 37 | 38 | The hit count value. 39 | 40 | ### ID 41 | 42 | **Type:** String (Read Only) 43 | 44 | The refinement value's ID. For attribute refinements, this will 45 | be the ID of the corresponding 46 | ObjectAttributeDefinition. This ID is included in the 47 | querystring parameter names returned by the URL-generating methods of 48 | SearchModel. For price and category refinements, this 49 | value will be empty. 50 | 51 | ### presentationID 52 | 53 | **Type:** String (Read Only) 54 | 55 | The optional presentation ID associated with this refinement 56 | value. The presentation ID can be used, for example, to associate an ID 57 | with an HTML widget. 58 | 59 | ### value 60 | 61 | **Type:** String (Read Only) 62 | 63 | The refinement value. For attribute refinements, this is the 64 | attribute value if the refinement values are unbucketed, or the bucket 65 | display name if the values are bucketed. This value is included in the 66 | querystring parameter values returned by the URL-generating methods of 67 | SearchModel. For price refinements, the value will be 68 | a string representation of the price range lower bound. For category 69 | refinements, the value will be a category ID. 70 | 71 | ## Constructor Summary 72 | 73 | ## Method Summary 74 | 75 | ### getDescription 76 | 77 | **Signature:** `getDescription() : String` 78 | 79 | Returns the optional refinement value description in the current locale. 80 | 81 | ### getDisplayValue 82 | 83 | **Signature:** `getDisplayValue() : String` 84 | 85 | Returns the refinement display value. 86 | 87 | ### getHitCount 88 | 89 | **Signature:** `getHitCount() : Number` 90 | 91 | Returns the hit count value. 92 | 93 | ### getID 94 | 95 | **Signature:** `getID() : String` 96 | 97 | Returns the refinement value's ID. 98 | 99 | ### getPresentationID 100 | 101 | **Signature:** `getPresentationID() : String` 102 | 103 | Returns the optional presentation ID associated with this refinement value. 104 | 105 | ### getValue 106 | 107 | **Signature:** `getValue() : String` 108 | 109 | Returns the refinement value. 110 | 111 | ## Method Detail 112 | 113 | ## Method Details 114 | 115 | ### getDescription 116 | 117 | **Signature:** `getDescription() : String` 118 | 119 | **Description:** Returns the optional refinement value description in the current locale. 120 | 121 | **Returns:** 122 | 123 | the optional refinement value description in the current locale, or null if none is defined. 124 | 125 | --- 126 | 127 | ### getDisplayValue 128 | 129 | **Signature:** `getDisplayValue() : String` 130 | 131 | **Description:** Returns the refinement display value. For attribute refinements, this is the appropriate display value based on optional value display names within the object attribute definition. If no display name is defined, the value itself is returned. For category refinements, this is the display name of the category in the current locale. For price refinements, this is a string representation of the range appropriate for display. 132 | 133 | **Returns:** 134 | 135 | the refinement display value in the current locale. 136 | 137 | --- 138 | 139 | ### getHitCount 140 | 141 | **Signature:** `getHitCount() : Number` 142 | 143 | **Description:** Returns the hit count value. 144 | 145 | **Returns:** 146 | 147 | the hit count value. 148 | 149 | --- 150 | 151 | ### getID 152 | 153 | **Signature:** `getID() : String` 154 | 155 | **Description:** Returns the refinement value's ID. For attribute refinements, this will be the ID of the corresponding ObjectAttributeDefinition. This ID is included in the querystring parameter names returned by the URL-generating methods of SearchModel. For price and category refinements, this value will be empty. 156 | 157 | **Returns:** 158 | 159 | the refinement value's ID. 160 | 161 | --- 162 | 163 | ### getPresentationID 164 | 165 | **Signature:** `getPresentationID() : String` 166 | 167 | **Description:** Returns the optional presentation ID associated with this refinement value. The presentation ID can be used, for example, to associate an ID with an HTML widget. 168 | 169 | **Returns:** 170 | 171 | the presentation ID, or null if none is defined. 172 | 173 | --- 174 | 175 | ### getValue 176 | 177 | **Signature:** `getValue() : String` 178 | 179 | **Description:** Returns the refinement value. For attribute refinements, this is the attribute value if the refinement values are unbucketed, or the bucket display name if the values are bucketed. This value is included in the querystring parameter values returned by the URL-generating methods of SearchModel. For price refinements, the value will be a string representation of the price range lower bound. For category refinements, the value will be a category ID. 180 | 181 | **Returns:** 182 | 183 | the refinement value. 184 | 185 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/summarize-logs.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | --- 2 | description: "Test summarize_logs tool in full mode" 3 | tests: 4 | # Core functionality - comprehensive structure validation 5 | - it: "should retrieve comprehensive log summary with complete structure" 6 | request: 7 | jsonrpc: "2.0" 8 | id: "summarize-comprehensive" 9 | method: "tools/call" 10 | params: 11 | name: "summarize_logs" 12 | arguments: {} 13 | expect: 14 | response: 15 | jsonrpc: "2.0" 16 | id: "summarize-comprehensive" 17 | result: 18 | content: 19 | match:arrayElements: 20 | type: "text" 21 | text: "match:regex:Log Summary for \\d{8}:[\\s\\S]*📊 Counts:[\\s\\S]*- Errors: \\d+[\\s\\S]*- Warnings: \\d+[\\s\\S]*- Info: \\d+[\\s\\S]*- Debug: \\d+[\\s\\S]*📁 Log Files \\(\\d+\\):[\\s\\S]*🔥 Key Issues:" 22 | isError: false 23 | stderr: "toBeEmpty" 24 | performance: 25 | maxResponseTime: "3000ms" 26 | 27 | # Basic successful response validation 28 | - it: "should return standard MCP response format" 29 | request: 30 | jsonrpc: "2.0" 31 | id: "summarize-format" 32 | method: "tools/call" 33 | params: 34 | name: "summarize_logs" 35 | arguments: {} 36 | expect: 37 | response: 38 | jsonrpc: "2.0" 39 | id: "summarize-format" 40 | result: 41 | content: "match:arrayLength:1" 42 | isError: false 43 | stderr: "toBeEmpty" 44 | 45 | # Date parameter tests - focused on key scenarios 46 | - it: "should handle specific valid date parameter" 47 | request: 48 | jsonrpc: "2.0" 49 | id: "summarize-specific-date" 50 | method: "tools/call" 51 | params: 52 | name: "summarize_logs" 53 | arguments: 54 | date: "20250921" 55 | expect: 56 | response: 57 | jsonrpc: "2.0" 58 | id: "summarize-specific-date" 59 | result: 60 | content: 61 | match:arrayElements: 62 | type: "text" 63 | text: "match:regex:Log Summary for 20250921:|No log files found for date 20250921" 64 | isError: false 65 | stderr: "toBeEmpty" 66 | 67 | - it: "should handle no available logs gracefully" 68 | request: 69 | jsonrpc: "2.0" 70 | id: "summarize-no-logs" 71 | method: "tools/call" 72 | params: 73 | name: "summarize_logs" 74 | arguments: 75 | date: "20220101" 76 | expect: 77 | response: 78 | jsonrpc: "2.0" 79 | id: "summarize-no-logs" 80 | result: 81 | content: 82 | match:arrayElements: 83 | type: "text" 84 | text: "match:contains:No log files found for date 20220101" 85 | isError: false 86 | stderr: "toBeEmpty" 87 | 88 | # Edge cases - simplified and consolidated 89 | - it: "should handle invalid date formats gracefully" 90 | request: 91 | jsonrpc: "2.0" 92 | id: "summarize-invalid-date" 93 | method: "tools/call" 94 | params: 95 | name: "summarize_logs" 96 | arguments: 97 | date: "invalid-date" 98 | expect: 99 | response: 100 | jsonrpc: "2.0" 101 | id: "summarize-invalid-date" 102 | result: 103 | content: 104 | match:arrayElements: 105 | type: "text" 106 | text: "match:contains:No log files found for date invalid-date" 107 | isError: false 108 | stderr: "toBeEmpty" 109 | 110 | # YAML-specific pattern tests - what YAML does better than Node.js 111 | - it: "should validate emoji patterns and structure markers" 112 | request: 113 | jsonrpc: "2.0" 114 | id: "summarize-patterns" 115 | method: "tools/call" 116 | params: 117 | name: "summarize_logs" 118 | arguments: {} 119 | expect: 120 | response: 121 | jsonrpc: "2.0" 122 | id: "summarize-patterns" 123 | result: 124 | content: 125 | match:arrayElements: 126 | type: "text" 127 | text: "match:regex:📊.*📁.*🔥" 128 | isError: false 129 | stderr: "toBeEmpty" 130 | 131 | # Performance test - single focused scenario 132 | - it: "should complete log summary analysis within reasonable time for health monitoring" 133 | request: 134 | jsonrpc: "2.0" 135 | id: "summarize-performance" 136 | method: "tools/call" 137 | params: 138 | name: "summarize_logs" 139 | arguments: {} 140 | expect: 141 | response: 142 | jsonrpc: "2.0" 143 | id: "summarize-performance" 144 | result: 145 | content: 146 | match:arrayElements: 147 | type: "text" 148 | text: "match:type:string" 149 | isError: false 150 | stderr: "toBeEmpty" 151 | performance: 152 | maxResponseTime: "2500ms" # Stricter for critical health monitoring 153 | 154 | # Date format validation - specific YAML strength 155 | - it: "should use consistent YYYYMMDD date format in responses" 156 | request: 157 | jsonrpc: "2.0" 158 | id: "summarize-date-format" 159 | method: "tools/call" 160 | params: 161 | name: "summarize_logs" 162 | arguments: {} 163 | expect: 164 | response: 165 | jsonrpc: "2.0" 166 | id: "summarize-date-format" 167 | result: 168 | content: 169 | match:arrayElements: 170 | type: "text" 171 | text: "match:regex:Log Summary for \\d{8}:|No log files found for date \\d{8}" 172 | isError: false 173 | stderr: "toBeEmpty" 174 | ``` -------------------------------------------------------------------------------- /docs/dw_suggest/Suggestions.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.suggest 2 | 3 | # Class Suggestions 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.suggest.Suggestions 9 | 10 | ## Description 11 | 12 | This is the base class for suggestions containers. For each type of items, a sub class provides methods to access the actual items. See the sub classes for more specific information. 13 | 14 | ## Properties 15 | 16 | ### searchPhraseSuggestions 17 | 18 | **Type:** SearchPhraseSuggestions (Read Only) 19 | 20 | The suggested search phrases that are associated to this suggestions. 21 | 22 | In contrast to the suggested items, the suggested phrases contains the corrected and 23 | completed versions of the original search phrase. 24 | 25 | ### suggestedPhrases 26 | 27 | **Type:** Iterator (Read Only) 28 | 29 | A list of SuggestedPhrase objects that relates to the 30 | user input search phrase. 31 | 32 | ### suggestedTerms 33 | 34 | **Type:** Iterator (Read Only) 35 | 36 | A list of SuggestedTerms objects. Each of the returned 37 | instances represents a set of terms suggested for a particular single term 38 | of the user input search phrase. 39 | 40 | ## Constructor Summary 41 | 42 | ## Method Summary 43 | 44 | ### getSearchPhraseSuggestions 45 | 46 | **Signature:** `getSearchPhraseSuggestions() : SearchPhraseSuggestions` 47 | 48 | Returns the suggested search phrases that are associated to this suggestions. 49 | 50 | ### getSuggestedPhrases 51 | 52 | **Signature:** `getSuggestedPhrases() : Iterator` 53 | 54 | Returns a list of SuggestedPhrase objects that relates to the user input search phrase. 55 | 56 | ### getSuggestedTerms 57 | 58 | **Signature:** `getSuggestedTerms() : Iterator` 59 | 60 | Returns a list of SuggestedTerms objects. 61 | 62 | ### hasSuggestedPhrases 63 | 64 | **Signature:** `hasSuggestedPhrases() : boolean` 65 | 66 | Returns whether this suggestions container has any suggested phrases. 67 | 68 | ### hasSuggestedTerms 69 | 70 | **Signature:** `hasSuggestedTerms() : boolean` 71 | 72 | Returns whether this suggestions container has any suggested terms. 73 | 74 | ### hasSuggestions 75 | 76 | **Signature:** `hasSuggestions() : boolean` 77 | 78 | Returns whether this suggestions container has any suggested items, i.e. 79 | 80 | ## Method Detail 81 | 82 | ## Method Details 83 | 84 | ### getSearchPhraseSuggestions 85 | 86 | **Signature:** `getSearchPhraseSuggestions() : SearchPhraseSuggestions` 87 | 88 | **Description:** Returns the suggested search phrases that are associated to this suggestions. In contrast to the suggested items, the suggested phrases contains the corrected and completed versions of the original search phrase. 89 | 90 | **Returns:** 91 | 92 | the suggested search phrases for this suggestions 93 | 94 | --- 95 | 96 | ### getSuggestedPhrases 97 | 98 | **Signature:** `getSuggestedPhrases() : Iterator` 99 | 100 | **Description:** Returns a list of SuggestedPhrase objects that relates to the user input search phrase. 101 | 102 | **Deprecated:** 103 | 104 | Please use method getSearchPhraseSuggestions() to obtain the suggested search phrases. 105 | 106 | **Returns:** 107 | 108 | a list of SuggestedPhrases 109 | 110 | **See Also:** 111 | 112 | hasSuggestedPhrases() 113 | 114 | --- 115 | 116 | ### getSuggestedTerms 117 | 118 | **Signature:** `getSuggestedTerms() : Iterator` 119 | 120 | **Description:** Returns a list of SuggestedTerms objects. Each of the returned instances represents a set of terms suggested for a particular single term of the user input search phrase. 121 | 122 | **Deprecated:** 123 | 124 | Please use method getSearchPhraseSuggestions() to obtain the suggested search phrases. 125 | 126 | **Returns:** 127 | 128 | a list of SuggestedTerms for each term of the user input search phrase 129 | 130 | --- 131 | 132 | ### hasSuggestedPhrases 133 | 134 | **Signature:** `hasSuggestedPhrases() : boolean` 135 | 136 | **Description:** Returns whether this suggestions container has any suggested phrases. Note that this method only looks for suggested phrases. It does not account for suggested terms or suggested objects. In other words, even if there are suggested terms or objects, this method will return false if this suggestions container has no phrases. 137 | 138 | **Deprecated:** 139 | 140 | Please use method getSearchPhraseSuggestions() to obtain the suggested search phrases. 141 | 142 | **Returns:** 143 | 144 | true only if there are phrases available 145 | 146 | --- 147 | 148 | ### hasSuggestedTerms 149 | 150 | **Signature:** `hasSuggestedTerms() : boolean` 151 | 152 | **Description:** Returns whether this suggestions container has any suggested terms. Note that this method checks suggested terms only, but not suggested phrases or suggested objects. 153 | 154 | **Deprecated:** 155 | 156 | Please use method getSearchPhraseSuggestions() to obtain the suggested search phrases. 157 | 158 | **Returns:** 159 | 160 | true only if there are terms available 161 | 162 | --- 163 | 164 | ### hasSuggestions 165 | 166 | **Signature:** `hasSuggestions() : boolean` 167 | 168 | **Description:** Returns whether this suggestions container has any suggested items, i.e. products. Note that this method only looks for concrete suggested items. It does not account for suggested terms. In other words, even if there are suggested terms, this method will return false if no matching items, like products or categories, were found for the suggested terms. To find out whether there are suggested terms and how they match with respect to the original search phrase, one can use getSuggestedTerms() to obtain a list of SuggestedTerms. 169 | 170 | **Returns:** 171 | 172 | true only if there are items found using the suggested terms 173 | 174 | **See Also:** 175 | 176 | getSuggestedTerms() 177 | SuggestedTerms.isEmpty() 178 | 179 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/get-latest-error.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | --- 2 | description: "Test get_latest_error tool in full mode (focused YAML tests - complex scenarios covered in Node.js)" 3 | tests: 4 | # Basic functionality tests 5 | - it: "should retrieve error messages with default parameters" 6 | request: 7 | jsonrpc: "2.0" 8 | id: "error-default" 9 | method: "tools/call" 10 | params: 11 | name: "get_latest_error" 12 | arguments: {} 13 | expect: 14 | response: 15 | jsonrpc: "2.0" 16 | id: "error-default" 17 | result: 18 | content: 19 | match:arrayElements: 20 | type: "text" 21 | text: "match:contains:Latest 10 error messages" 22 | isError: false 23 | stderr: "toBeEmpty" 24 | performance: 25 | maxResponseTime: "2000ms" 26 | 27 | - it: "should respect limit parameter" 28 | request: 29 | jsonrpc: "2.0" 30 | id: "error-limit" 31 | method: "tools/call" 32 | params: 33 | name: "get_latest_error" 34 | arguments: 35 | limit: 3 36 | expect: 37 | response: 38 | jsonrpc: "2.0" 39 | id: "error-limit" 40 | result: 41 | content: 42 | match:arrayElements: 43 | type: "text" 44 | text: "match:contains:Latest 3 error messages" 45 | isError: false 46 | stderr: "toBeEmpty" 47 | performance: 48 | maxResponseTime: "2000ms" 49 | 50 | # Basic content validation (detailed validation in Node.js tests) 51 | - it: "should include basic SFCC log structure elements" 52 | request: 53 | jsonrpc: "2.0" 54 | id: "error-structure" 55 | method: "tools/call" 56 | params: 57 | name: "get_latest_error" 58 | arguments: 59 | limit: 2 60 | expect: 61 | response: 62 | jsonrpc: "2.0" 63 | id: "error-structure" 64 | result: 65 | content: 66 | match:arrayElements: 67 | match:partial: 68 | text: "match:regex:error-blade-[\\d]{8}-[\\d]{6}\\.log[\\s\\S]*ERROR[\\s\\S]*GMT" 69 | isError: false 70 | stderr: "toBeEmpty" 71 | 72 | # Parameter validation tests (core error cases) 73 | - it: "should reject string limit parameter" 74 | request: 75 | jsonrpc: "2.0" 76 | id: "error-string-limit" 77 | method: "tools/call" 78 | params: 79 | name: "get_latest_error" 80 | arguments: 81 | limit: "5" 82 | expect: 83 | response: 84 | jsonrpc: "2.0" 85 | id: "error-string-limit" 86 | result: 87 | content: 88 | match:arrayElements: 89 | type: "text" 90 | text: "match:contains:Invalid limit '5'" 91 | isError: true 92 | stderr: "toBeEmpty" 93 | 94 | - it: "should reject zero limit parameter" 95 | request: 96 | jsonrpc: "2.0" 97 | id: "error-zero-limit" 98 | method: "tools/call" 99 | params: 100 | name: "get_latest_error" 101 | arguments: 102 | limit: 0 103 | expect: 104 | response: 105 | jsonrpc: "2.0" 106 | id: "error-zero-limit" 107 | result: 108 | content: 109 | match:arrayElements: 110 | match:partial: 111 | text: "match:contains:Invalid limit '0'" 112 | isError: true 113 | stderr: "toBeEmpty" 114 | 115 | - it: "should reject negative limit parameter" 116 | request: 117 | jsonrpc: "2.0" 118 | id: "error-negative-limit" 119 | method: "tools/call" 120 | params: 121 | name: "get_latest_error" 122 | arguments: 123 | limit: -5 124 | expect: 125 | response: 126 | jsonrpc: "2.0" 127 | id: "error-negative-limit" 128 | result: 129 | content: 130 | match:arrayElements: 131 | match:partial: 132 | text: "match:contains:Invalid limit" 133 | isError: true 134 | stderr: "toBeEmpty" 135 | 136 | # Date parameter basic validation 137 | - it: "should handle valid date parameter" 138 | request: 139 | jsonrpc: "2.0" 140 | id: "error-valid-date" 141 | method: "tools/call" 142 | params: 143 | name: "get_latest_error" 144 | arguments: 145 | date: "20240101" 146 | limit: 1 147 | expect: 148 | response: 149 | jsonrpc: "2.0" 150 | id: "error-valid-date" 151 | result: 152 | content: "match:type:array" 153 | isError: false 154 | stderr: "toBeEmpty" 155 | 156 | # Performance validation (basic) 157 | - it: "should respond quickly for small limits" 158 | request: 159 | jsonrpc: "2.0" 160 | id: "error-perf-small" 161 | method: "tools/call" 162 | params: 163 | name: "get_latest_error" 164 | arguments: 165 | limit: 1 166 | expect: 167 | response: 168 | jsonrpc: "2.0" 169 | id: "error-perf-small" 170 | result: 171 | content: "match:type:array" 172 | isError: false 173 | stderr: "toBeEmpty" 174 | performance: 175 | maxResponseTime: "1500ms" 176 | 177 | # Response structure consistency 178 | - it: "should return consistent MCP response structure" 179 | request: 180 | jsonrpc: "2.0" 181 | id: "error-mcp-structure" 182 | method: "tools/call" 183 | params: 184 | name: "get_latest_error" 185 | arguments: 186 | limit: 1 187 | expect: 188 | response: 189 | jsonrpc: "2.0" 190 | id: "error-mcp-structure" 191 | result: 192 | match:partial: 193 | content: "match:type:array" 194 | isError: "match:type:boolean" 195 | stderr: "toBeEmpty" 196 | ``` -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yml: -------------------------------------------------------------------------------- ```yaml 1 | name: ✨ Feature Request 2 | description: Suggest a new feature or enhancement for the SFCC Development MCP Server 3 | title: "[Feature]: " 4 | labels: ["enhancement", "needs-triage"] 5 | assignees: [] 6 | body: 7 | - type: markdown 8 | attributes: 9 | value: | 10 | Thanks for suggesting a new feature! Please provide detailed information to help us understand and evaluate your request. 11 | 12 | - type: checkboxes 13 | id: terms 14 | attributes: 15 | label: Pre-submission Checklist 16 | description: Please confirm you have completed these steps before submitting the feature request. 17 | options: 18 | - label: I have searched existing issues and discussions to ensure this feature hasn't been requested already 19 | required: true 20 | - label: I have reviewed the roadmap and documentation to confirm this feature doesn't already exist 21 | required: true 22 | - label: This feature aligns with the project's goals of improving SFCC development workflows 23 | required: true 24 | 25 | - type: dropdown 26 | id: feature-category 27 | attributes: 28 | label: Feature Category 29 | description: Which category does this feature request fall into? 30 | options: 31 | - New MCP Tool 32 | - SFCC API Integration Enhancement 33 | - Documentation/Best Practices 34 | - Authentication/Security 35 | - Performance/Caching 36 | - Configuration/Setup 37 | - Developer Experience 38 | - Testing/Quality Assurance 39 | - Other 40 | validations: 41 | required: true 42 | 43 | - type: textarea 44 | id: problem-statement 45 | attributes: 46 | label: Problem Statement 47 | description: What problem does this feature solve? What pain point are you experiencing? 48 | placeholder: Describe the current limitation or challenge you're facing in SFCC development... 49 | validations: 50 | required: true 51 | 52 | - type: textarea 53 | id: proposed-solution 54 | attributes: 55 | label: Proposed Solution 56 | description: Describe your ideal solution to this problem. 57 | placeholder: Explain how you envision this feature working... 58 | validations: 59 | required: true 60 | 61 | - type: textarea 62 | id: use-cases 63 | attributes: 64 | label: Use Cases 65 | description: Provide specific examples of how this feature would be used. 66 | placeholder: | 67 | 1. As a developer, I want to... so that... 68 | 2. When working on cartridge development, I need to... 69 | 3. During debugging sessions, it would help if... 70 | validations: 71 | required: true 72 | 73 | - type: dropdown 74 | id: target-mode 75 | attributes: 76 | label: Target Operating Mode 77 | description: Which operating mode should this feature support? 78 | multiple: true 79 | options: 80 | - Documentation-only mode 81 | - Full mode (with SFCC credentials) 82 | - Both modes 83 | - New mode (please specify in additional context) 84 | validations: 85 | required: true 86 | 87 | - type: dropdown 88 | id: priority 89 | attributes: 90 | label: Priority Level 91 | description: How would you rate the priority of this feature? 92 | options: 93 | - Critical - Blocking my work 94 | - High - Would significantly improve my workflow 95 | - Medium - Nice to have improvement 96 | - Low - Minor enhancement 97 | validations: 98 | required: true 99 | 100 | - type: textarea 101 | id: alternatives 102 | attributes: 103 | label: Alternative Solutions 104 | description: Have you considered any alternative approaches or workarounds? 105 | placeholder: Describe any workarounds you're currently using or other solutions you've considered... 106 | 107 | - type: textarea 108 | id: implementation-ideas 109 | attributes: 110 | label: Implementation Ideas (Optional) 111 | description: If you have ideas about how this could be implemented, please share them. 112 | placeholder: | 113 | - Could be implemented as a new tool in the clients/ directory 114 | - Might require changes to the authentication flow 115 | - Would need new SFCC API endpoints... 116 | 117 | - type: dropdown 118 | id: sfcc-apis 119 | attributes: 120 | label: SFCC APIs Involved 121 | description: Which SFCC APIs would this feature likely interact with? 122 | multiple: true 123 | options: 124 | - OCAPI (Open Commerce API) 125 | - SCAPI (Shopper API) 126 | - WebDAV 127 | - SFCC Logs 128 | - System Object Definitions 129 | - Site Preferences 130 | - Custom Objects 131 | - Not sure 132 | - Not applicable 133 | 134 | - type: textarea 135 | id: additional-context 136 | attributes: 137 | label: Additional Context 138 | description: Any other context, mockups, examples, or references that would help understand this feature request. 139 | 140 | - type: checkboxes 141 | id: contribution 142 | attributes: 143 | label: Contribution Intent 144 | description: Are you interested in contributing to this feature? 145 | options: 146 | - label: I'm willing to help implement this feature 147 | required: false 148 | - label: I can help with testing and validation 149 | required: false 150 | - label: I can provide domain expertise or consultation 151 | required: false 152 | ``` -------------------------------------------------------------------------------- /docs/dw_util/SeekableIterator.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.util 2 | 3 | # Class SeekableIterator 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.util.Iterator 9 | - dw.util.SeekableIterator 10 | 11 | ## Description 12 | 13 | A special Iterator, which is returned by the system to iterate through large sets of data. The iterator supports seeking forward to a random position. This is a typical action when paging forward in a result set. The Iterator is primarily returned from search operations. Starting with API version 10.6, these iterators can only be iterated once to avoid possible memory problems for really large result sets. Putting them into the pipeline dictionary and trying to loop them multiple times is no longer possible because this would require buffering the iterated elements internally. Prior to 10.6, and for all customers still running API version 10.4 (compatibility mode), SeekableIterator instances stored in the pipeline dictionary could be iterated multiple times (for example, by several loop nodes). 14 | 15 | ## Properties 16 | 17 | ### count 18 | 19 | **Type:** Number (Read Only) 20 | 21 | The total element count for this iterator. The 22 | method returns -1, if the total count is not known. 23 | 24 | ## Constructor Summary 25 | 26 | ## Method Summary 27 | 28 | ### asList 29 | 30 | **Signature:** `asList(start : Number, size : Number) : List` 31 | 32 | Returns a list representing a subsequence within the iterator. 33 | 34 | ### close 35 | 36 | **Signature:** `close() : void` 37 | 38 | Closes all system resources associated with this iterator. 39 | 40 | ### first 41 | 42 | **Signature:** `first() : Object` 43 | 44 | Returns the first element of this iterator and closes it. 45 | 46 | ### forward 47 | 48 | **Signature:** `forward(n : Number) : void` 49 | 50 | Seeks forward by the given number of elements. 51 | 52 | ### forward 53 | 54 | **Signature:** `forward(n : Number, size : Number) : void` 55 | 56 | Seeks forward by the given number of elements and limits the iteration to the given number of elements. 57 | 58 | ### getCount 59 | 60 | **Signature:** `getCount() : Number` 61 | 62 | Returns the total element count for this iterator. 63 | 64 | ### hasNext 65 | 66 | **Signature:** `hasNext() : boolean` 67 | 68 | Indicates if there are more elements. 69 | 70 | ### next 71 | 72 | **Signature:** `next() : Object` 73 | 74 | Returns the next element from the Iterator. 75 | 76 | ## Method Detail 77 | 78 | ## Method Details 79 | 80 | ### asList 81 | 82 | **Signature:** `asList(start : Number, size : Number) : List` 83 | 84 | **Description:** Returns a list representing a subsequence within the iterator. The underlying system resources of the iterator will be closed at the end. The start position must be 0 or a positive number. 85 | 86 | **Parameters:** 87 | 88 | - `start`: the position from which to start the subsequence. 89 | - `size`: the number of items to collect. 90 | 91 | **Returns:** 92 | 93 | the list containing the subsequence. 94 | 95 | --- 96 | 97 | ### close 98 | 99 | **Signature:** `close() : void` 100 | 101 | **Description:** Closes all system resources associated with this iterator. Calling this method is strongly recommended if not all elements of this iterator are retrieved. This will allow the system to release system resources immediately. The SeekableIterator is closed automatically if all elements are retrieved. Then calling method close() is optional. 102 | 103 | --- 104 | 105 | ### first 106 | 107 | **Signature:** `first() : Object` 108 | 109 | **Description:** Returns the first element of this iterator and closes it. If the iterator does not contain another element null is returned. If any of the methods next(), forward(int) or forward(int,int) have been called before null is returned. This method is useful if only the first element of an iterator is needed. A possible example for the use of first() is: OrderMgr.queryOrders("queryString", "sortString", args).first() 110 | 111 | **Returns:** 112 | 113 | the first element of an iterator and closes the iterator or returns null if the iterator doesn't have another element or the methods next(), forward(int) or forward(int,int) have already been called. 114 | 115 | --- 116 | 117 | ### forward 118 | 119 | **Signature:** `forward(n : Number) : void` 120 | 121 | **Description:** Seeks forward by the given number of elements. The number of seek steps must be 0 or a positive number. 122 | 123 | **Parameters:** 124 | 125 | - `n`: the number of elements to seek forward. 126 | 127 | --- 128 | 129 | ### forward 130 | 131 | **Signature:** `forward(n : Number, size : Number) : void` 132 | 133 | **Description:** Seeks forward by the given number of elements and limits the iteration to the given number of elements. The method is typically used to position and trim an iterator for paging. The getCount() method will still return the total count of the underlying data collection. 134 | 135 | **Parameters:** 136 | 137 | - `n`: the number of elements to seek forward. 138 | - `size`: the maximum number of elements return from the iterator 139 | 140 | --- 141 | 142 | ### getCount 143 | 144 | **Signature:** `getCount() : Number` 145 | 146 | **Description:** Returns the total element count for this iterator. The method returns -1, if the total count is not known. 147 | 148 | **Returns:** 149 | 150 | the total element count for this iterator or -1. 151 | 152 | --- 153 | 154 | ### hasNext 155 | 156 | **Signature:** `hasNext() : boolean` 157 | 158 | **Description:** Indicates if there are more elements. 159 | 160 | **Returns:** 161 | 162 | true if there are more elements, false otherwise. 163 | 164 | --- 165 | 166 | ### next 167 | 168 | **Signature:** `next() : Object` 169 | 170 | **Description:** Returns the next element from the Iterator. 171 | 172 | **Returns:** 173 | 174 | the next element from the Iterator. 175 | 176 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/get-latest-warn.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | --- 2 | description: "Test get_latest_warn tool in full mode - focused on MCP response validation" 3 | tests: 4 | # Core functionality validation 5 | - it: "should retrieve latest warn messages with default parameters" 6 | request: 7 | jsonrpc: "2.0" 8 | id: "warn-default" 9 | method: "tools/call" 10 | params: 11 | name: "get_latest_warn" 12 | arguments: {} 13 | expect: 14 | response: 15 | jsonrpc: "2.0" 16 | id: "warn-default" 17 | result: 18 | content: 19 | match:arrayElements: 20 | type: "text" 21 | text: "match:contains:Latest 10 warn messages" 22 | isError: false 23 | stderr: "toBeEmpty" 24 | performance: 25 | maxResponseTime: "2000ms" 26 | 27 | - it: "should respect limit parameter" 28 | request: 29 | jsonrpc: "2.0" 30 | id: "warn-limit" 31 | method: "tools/call" 32 | params: 33 | name: "get_latest_warn" 34 | arguments: 35 | limit: 3 36 | expect: 37 | response: 38 | jsonrpc: "2.0" 39 | id: "warn-limit" 40 | result: 41 | content: 42 | match:arrayElements: 43 | match:partial: 44 | text: "match:regex:Latest 3 warn messages[\\s\\S]*warn-blade-[\\d]{8}-[\\d]{6}\\.log[\\s\\S]*WARN[\\s\\S]*GMT" 45 | isError: false 46 | stderr: "toBeEmpty" 47 | performance: 48 | maxResponseTime: "2000ms" 49 | 50 | # Core log structure validation in one comprehensive test 51 | - it: "should contain proper SFCC log structure elements" 52 | request: 53 | jsonrpc: "2.0" 54 | id: "warn-structure" 55 | method: "tools/call" 56 | params: 57 | name: "get_latest_warn" 58 | arguments: 59 | limit: 2 60 | expect: 61 | response: 62 | jsonrpc: "2.0" 63 | id: "warn-structure" 64 | result: 65 | content: 66 | match:arrayElements: 67 | match:partial: 68 | # Validates: log filename, timestamp, WARN level, Sites info, separators in one test 69 | text: "match:regex:warn-blade-[\\d]{8}-[\\d]{6}\\.log[\\s\\S]*[\\d]{4}-[\\d]{2}-[\\d]{2} [\\d]{2}:[\\d]{2}:[\\d]{2}\\.[\\d]{3} GMT[\\s\\S]*WARN PipelineCallServlet[\\s\\S]*Sites-[\\s\\S]*---" 70 | isError: false 71 | stderr: "toBeEmpty" 72 | 73 | # Error handling validation (key validation patterns) 74 | - it: "should handle string limit parameter with proper error message" 75 | request: 76 | jsonrpc: "2.0" 77 | id: "warn-string-limit" 78 | method: "tools/call" 79 | params: 80 | name: "get_latest_warn" 81 | arguments: 82 | limit: "5" 83 | expect: 84 | response: 85 | jsonrpc: "2.0" 86 | id: "warn-string-limit" 87 | result: 88 | content: 89 | match:arrayElements: 90 | type: "text" 91 | text: "match:regex:Error: Invalid limit '5'[\\s\\S]*Must be a valid number" 92 | isError: true 93 | stderr: "toBeEmpty" 94 | 95 | - it: "should handle zero limit with proper error message" 96 | request: 97 | jsonrpc: "2.0" 98 | id: "warn-zero-limit" 99 | method: "tools/call" 100 | params: 101 | name: "get_latest_warn" 102 | arguments: 103 | limit: 0 104 | expect: 105 | response: 106 | jsonrpc: "2.0" 107 | id: "warn-zero-limit" 108 | result: 109 | content: 110 | match:arrayElements: 111 | type: "text" 112 | text: "match:regex:Error: Invalid limit '0'[\\s\\S]*Must be between 1 and 1000" 113 | isError: true 114 | stderr: "toBeEmpty" 115 | 116 | - it: "should handle negative limit with proper error message" 117 | request: 118 | jsonrpc: "2.0" 119 | id: "warn-negative-limit" 120 | method: "tools/call" 121 | params: 122 | name: "get_latest_warn" 123 | arguments: 124 | limit: -5 125 | expect: 126 | response: 127 | jsonrpc: "2.0" 128 | id: "warn-negative-limit" 129 | result: 130 | content: 131 | match:arrayElements: 132 | type: "text" 133 | text: "match:contains:Error: Invalid limit '-5'" 134 | isError: true 135 | stderr: "toBeEmpty" 136 | 137 | # Edge case - large limit handling 138 | - it: "should handle large limit values appropriately" 139 | request: 140 | jsonrpc: "2.0" 141 | id: "warn-large-limit" 142 | method: "tools/call" 143 | params: 144 | name: "get_latest_warn" 145 | arguments: 146 | limit: 50 147 | expect: 148 | response: 149 | jsonrpc: "2.0" 150 | id: "warn-large-limit" 151 | result: 152 | content: 153 | match:arrayElements: 154 | type: "text" 155 | text: "match:contains:Latest 50 warn messages" 156 | isError: false 157 | stderr: "toBeEmpty" 158 | performance: 159 | maxResponseTime: "3000ms" 160 | 161 | # Date parameter edge case 162 | - it: "should handle invalid date format gracefully" 163 | request: 164 | jsonrpc: "2.0" 165 | id: "warn-invalid-date" 166 | method: "tools/call" 167 | params: 168 | name: "get_latest_warn" 169 | arguments: 170 | date: "invalid-date" 171 | limit: 1 172 | expect: 173 | response: 174 | jsonrpc: "2.0" 175 | id: "warn-invalid-date" 176 | result: 177 | content: 178 | match:arrayElements: 179 | type: "text" 180 | text: "match:type:string" 181 | isError: false 182 | stderr: "toBeEmpty" 183 | ``` -------------------------------------------------------------------------------- /src/tool-configs/job-log-tool-config.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { GenericToolSpec, ToolExecutionContext } from '../core/handlers/base-handler.js'; 2 | import { ToolArguments } from '../core/handlers/base-handler.js'; 3 | import { LogToolValidators } from '../utils/log-tool-utils.js'; 4 | import { ValidationHelpers, CommonValidations } from '../core/handlers/validation-helpers.js'; 5 | import { JobLogToolName, getLimit } from '../utils/log-tool-constants.js'; 6 | import { JobLogValidators, JobLogFormatters } from '../utils/job-log-utils.js'; 7 | import { SFCCLogClient } from '../clients/log-client.js'; 8 | 9 | /** 10 | * Configuration for job log tools 11 | * Maps each tool to its validation, execution, and messaging logic 12 | */ 13 | export const JOB_LOG_TOOL_CONFIG: Record<JobLogToolName, GenericToolSpec<ToolArguments, any>> = { 14 | get_latest_job_log_files: { 15 | defaults: (args: ToolArguments) => ({ 16 | limit: getLimit(args.limit as number, 'jobFiles'), 17 | }), 18 | validate: (args: ToolArguments, toolName: string) => 19 | LogToolValidators.validateLimit(args.limit as number, toolName), 20 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 21 | const client = context.logClient as SFCCLogClient; 22 | return client.getLatestJobLogFiles(args.limit as number); 23 | }, 24 | logMessage: (args: ToolArguments) => JobLogFormatters.formatJobLogMessage('Fetching latest job log files', { 25 | limit: args.limit as number, 26 | }), 27 | }, 28 | 29 | search_job_logs_by_name: { 30 | defaults: (args: ToolArguments) => ({ 31 | limit: getLimit(args.limit as number, 'jobFiles'), 32 | }), 33 | validate: (args: ToolArguments, toolName: string) => { 34 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName); 35 | LogToolValidators.validateLimit(args.limit as number, toolName); 36 | }, 37 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 38 | const client = context.logClient as SFCCLogClient; 39 | return client.searchJobLogsByName(args.jobName as string, args.limit as number); 40 | }, 41 | logMessage: (args: ToolArguments) => JobLogFormatters.formatJobLogMessage('Searching job logs by name', { 42 | jobName: args.jobName as string, 43 | limit: args.limit as number, 44 | }), 45 | }, 46 | 47 | get_job_log_entries: { 48 | defaults: (args: ToolArguments) => ({ 49 | level: args.level ?? 'all', 50 | limit: getLimit(args.limit as number, 'jobEntries'), 51 | }), 52 | validate: (args: ToolArguments, toolName: string) => { 53 | JobLogValidators.validateJobLogLevel(args.level as string, toolName); 54 | LogToolValidators.validateLimit(args.limit as number, toolName); 55 | }, 56 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 57 | const client = context.logClient as SFCCLogClient; 58 | return client.getJobLogEntries( 59 | args.level as any, 60 | args.limit as number, 61 | args.jobName as string, 62 | ); 63 | }, 64 | logMessage: (args: ToolArguments) => JobLogFormatters.formatJobLogMessage('Fetching job log entries', { 65 | level: args.level as string, 66 | limit: args.limit as number, 67 | jobName: args.jobName as string, 68 | }), 69 | }, 70 | 71 | search_job_logs: { 72 | defaults: (args: ToolArguments) => ({ 73 | level: args.level ?? 'all', 74 | limit: getLimit(args.limit as number, 'jobSearch'), 75 | }), 76 | validate: (args: ToolArguments, toolName: string) => { 77 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('pattern'), toolName); 78 | JobLogValidators.validateJobLogLevel(args.level as string, toolName); 79 | LogToolValidators.validateLimit(args.limit as number, toolName); 80 | // Validate optional jobName parameter - must be string if provided 81 | if (args.jobName !== undefined) { 82 | ValidationHelpers.validateArguments(args, CommonValidations.optionalField( 83 | 'jobName', 84 | 'string', 85 | (value: string) => typeof value === 'string' && value.trim().length > 0, 86 | 'jobName must be a non-empty string', 87 | ), toolName); 88 | } 89 | }, 90 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 91 | const client = context.logClient as SFCCLogClient; 92 | return client.searchJobLogs( 93 | args.pattern as string, 94 | args.level as any, 95 | args.limit as number, 96 | args.jobName as string, 97 | ); 98 | }, 99 | logMessage: (args: ToolArguments) => JobLogFormatters.formatJobLogMessage('Searching job logs', { 100 | pattern: args.pattern as string, 101 | level: args.level as string, 102 | limit: args.limit as number, 103 | jobName: args.jobName as string, 104 | }), 105 | }, 106 | 107 | get_job_execution_summary: { 108 | defaults: (args: ToolArguments) => args, 109 | validate: (args: ToolArguments, toolName: string) => { 110 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('jobName'), toolName); 111 | }, 112 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 113 | const client = context.logClient as SFCCLogClient; 114 | return client.getJobExecutionSummary(args.jobName as string); 115 | }, 116 | logMessage: (args: ToolArguments) => `Getting job execution summary for: ${args.jobName as string}`, 117 | }, 118 | }; 119 | ``` -------------------------------------------------------------------------------- /docs/dw_extensions.payments/SalesforcePayPalOrder.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.extensions.payments 2 | 3 | # Class SalesforcePayPalOrder 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.extensions.payments.SalesforcePayPalOrder 9 | 10 | ## Description 11 | 12 | Salesforce Payments representation of a PayPal order object. See Salesforce Payments documentation for how to gain access and configure it for use on your sites. A PayPal order is automatically created when a shopper is ready to pay for items in their basket. It becomes completed when the shopper provides information to the payment provider that is acceptable to authorize payment for a given amount. 13 | 14 | ## Constants 15 | 16 | ### TYPE_PAYPAL 17 | 18 | **Type:** String = "paypal" 19 | 20 | Represents the PayPal funding source. 21 | 22 | ### TYPE_VENMO 23 | 24 | **Type:** String = "venmo" 25 | 26 | Represents the Venmo funding source. 27 | 28 | ## Properties 29 | 30 | ### amount 31 | 32 | **Type:** Money (Read Only) 33 | 34 | The amount of this PayPal order. 35 | 36 | ### captureID 37 | 38 | **Type:** String (Read Only) 39 | 40 | The ID of the capture against this order, or null if not available. 41 | 42 | ### completed 43 | 44 | **Type:** boolean (Read Only) 45 | 46 | Returns true if this PayPal order has been completed, or false if not. 47 | 48 | ### ID 49 | 50 | **Type:** String (Read Only) 51 | 52 | The identifier of this PayPal order. 53 | 54 | ### payer 55 | 56 | **Type:** SalesforcePayPalOrderPayer (Read Only) 57 | 58 | The payer information for this PayPal order, or null if not known. 59 | 60 | ### shipping 61 | 62 | **Type:** SalesforcePayPalOrderAddress (Read Only) 63 | 64 | The shipping address for this PayPal order, or null if not known. 65 | 66 | ## Constructor Summary 67 | 68 | ## Method Summary 69 | 70 | ### getAmount 71 | 72 | **Signature:** `getAmount() : Money` 73 | 74 | Returns the amount of this PayPal order. 75 | 76 | ### getCaptureID 77 | 78 | **Signature:** `getCaptureID() : String` 79 | 80 | Returns the ID of the capture against this order, or null if not available. 81 | 82 | ### getID 83 | 84 | **Signature:** `getID() : String` 85 | 86 | Returns the identifier of this PayPal order. 87 | 88 | ### getPayer 89 | 90 | **Signature:** `getPayer() : SalesforcePayPalOrderPayer` 91 | 92 | Returns the payer information for this PayPal order, or null if not known. 93 | 94 | ### getPaymentDetails 95 | 96 | **Signature:** `getPaymentDetails(paymentInstrument : OrderPaymentInstrument) : SalesforcePaymentDetails` 97 | 98 | Returns the details to the Salesforce Payments payment for this PayPal order, using the given payment instrument. 99 | 100 | ### getPaymentInstrument 101 | 102 | **Signature:** `getPaymentInstrument(basket : Basket) : OrderPaymentInstrument` 103 | 104 | Returns the payment instrument for this PayPal order in the given basket, or null if the given basket has none. 105 | 106 | ### getPaymentInstrument 107 | 108 | **Signature:** `getPaymentInstrument(order : Order) : OrderPaymentInstrument` 109 | 110 | Returns the payment instrument for this PayPal order in the given order, or null if the given order has none. 111 | 112 | ### getShipping 113 | 114 | **Signature:** `getShipping() : SalesforcePayPalOrderAddress` 115 | 116 | Returns the shipping address for this PayPal order, or null if not known. 117 | 118 | ### isCompleted 119 | 120 | **Signature:** `isCompleted() : boolean` 121 | 122 | Returns true if this PayPal order has been completed, or false if not. 123 | 124 | ## Method Detail 125 | 126 | ## Method Details 127 | 128 | ### getAmount 129 | 130 | **Signature:** `getAmount() : Money` 131 | 132 | **Description:** Returns the amount of this PayPal order. 133 | 134 | **Returns:** 135 | 136 | PayPal order amount 137 | 138 | --- 139 | 140 | ### getCaptureID 141 | 142 | **Signature:** `getCaptureID() : String` 143 | 144 | **Description:** Returns the ID of the capture against this order, or null if not available. 145 | 146 | **Returns:** 147 | 148 | PayPal order capture identifier 149 | 150 | --- 151 | 152 | ### getID 153 | 154 | **Signature:** `getID() : String` 155 | 156 | **Description:** Returns the identifier of this PayPal order. 157 | 158 | **Returns:** 159 | 160 | PayPal order identifier 161 | 162 | --- 163 | 164 | ### getPayer 165 | 166 | **Signature:** `getPayer() : SalesforcePayPalOrderPayer` 167 | 168 | **Description:** Returns the payer information for this PayPal order, or null if not known. 169 | 170 | **Returns:** 171 | 172 | order payer information 173 | 174 | --- 175 | 176 | ### getPaymentDetails 177 | 178 | **Signature:** `getPaymentDetails(paymentInstrument : OrderPaymentInstrument) : SalesforcePaymentDetails` 179 | 180 | **Description:** Returns the details to the Salesforce Payments payment for this PayPal order, using the given payment instrument. 181 | 182 | **Parameters:** 183 | 184 | - `paymentInstrument`: payment instrument 185 | 186 | **Returns:** 187 | 188 | The payment details 189 | 190 | --- 191 | 192 | ### getPaymentInstrument 193 | 194 | **Signature:** `getPaymentInstrument(basket : Basket) : OrderPaymentInstrument` 195 | 196 | **Description:** Returns the payment instrument for this PayPal order in the given basket, or null if the given basket has none. 197 | 198 | **Parameters:** 199 | 200 | - `basket`: basket 201 | 202 | **Returns:** 203 | 204 | basket payment instrument 205 | 206 | --- 207 | 208 | ### getPaymentInstrument 209 | 210 | **Signature:** `getPaymentInstrument(order : Order) : OrderPaymentInstrument` 211 | 212 | **Description:** Returns the payment instrument for this PayPal order in the given order, or null if the given order has none. 213 | 214 | **Parameters:** 215 | 216 | - `order`: order 217 | 218 | **Returns:** 219 | 220 | order payment instrument 221 | 222 | --- 223 | 224 | ### getShipping 225 | 226 | **Signature:** `getShipping() : SalesforcePayPalOrderAddress` 227 | 228 | **Description:** Returns the shipping address for this PayPal order, or null if not known. 229 | 230 | **Returns:** 231 | 232 | order shipping address 233 | 234 | --- 235 | 236 | ### isCompleted 237 | 238 | **Signature:** `isCompleted() : boolean` 239 | 240 | **Description:** Returns true if this PayPal order has been completed, or false if not. 241 | 242 | **Returns:** 243 | 244 | true if this PayPal order has been completed 245 | 246 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/get-latest-debug.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | --- 2 | # Optimized YAML tests for get_latest_debug tool - focuses on MCP protocol compliance and basic functionality 3 | # Complex content validation, performance testing, and detailed parameter validation are handled in the programmatic tests 4 | # These tests primarily validate aegis testing framework integration and basic MCP responses 5 | description: "Test get_latest_debug tool in full mode - Basic MCP protocol and parameter validation" 6 | tests: 7 | # ======================================== 8 | # MCP PROTOCOL COMPLIANCE 9 | # ======================================== 10 | 11 | - it: "should return valid MCP response structure with default parameters" 12 | request: 13 | jsonrpc: "2.0" 14 | id: "debug-default" 15 | method: "tools/call" 16 | params: 17 | name: "get_latest_debug" 18 | arguments: {} 19 | expect: 20 | response: 21 | jsonrpc: "2.0" 22 | id: "debug-default" 23 | result: 24 | content: 25 | match:arrayElements: 26 | match:partial: 27 | type: "text" 28 | text: "match:type:string" 29 | isError: "match:type:boolean" 30 | stderr: "toBeEmpty" 31 | performance: 32 | maxResponseTime: "2000ms" 33 | 34 | - it: "should contain expected content structure for default limit" 35 | request: 36 | jsonrpc: "2.0" 37 | id: "debug-content" 38 | method: "tools/call" 39 | params: 40 | name: "get_latest_debug" 41 | arguments: {} 42 | expect: 43 | response: 44 | jsonrpc: "2.0" 45 | id: "debug-content" 46 | result: 47 | content: 48 | match:arrayElements: 49 | type: "text" 50 | text: "match:contains:Latest 10 debug messages" 51 | isError: false 52 | stderr: "toBeEmpty" 53 | 54 | # ======================================== 55 | # PARAMETER VALIDATION 56 | # ======================================== 57 | 58 | - it: "should respect limit parameter" 59 | request: 60 | jsonrpc: "2.0" 61 | id: "debug-limit" 62 | method: "tools/call" 63 | params: 64 | name: "get_latest_debug" 65 | arguments: 66 | limit: 3 67 | expect: 68 | response: 69 | jsonrpc: "2.0" 70 | id: "debug-limit" 71 | result: 72 | content: 73 | match:arrayElements: 74 | type: "text" 75 | text: "match:contains:Latest 3 debug messages" 76 | isError: false 77 | stderr: "toBeEmpty" 78 | 79 | - it: "should handle date parameter" 80 | request: 81 | jsonrpc: "2.0" 82 | id: "debug-date" 83 | method: "tools/call" 84 | params: 85 | name: "get_latest_debug" 86 | arguments: 87 | date: "20240101" 88 | limit: 2 89 | expect: 90 | response: 91 | jsonrpc: "2.0" 92 | id: "debug-date" 93 | result: 94 | content: 95 | match:arrayElements: 96 | type: "text" 97 | text: "match:type:string" 98 | isError: false 99 | stderr: "toBeEmpty" 100 | 101 | # ======================================== 102 | # ERROR HANDLING 103 | # ======================================== 104 | 105 | - it: "should reject invalid string limit parameter" 106 | request: 107 | jsonrpc: "2.0" 108 | id: "debug-string-limit" 109 | method: "tools/call" 110 | params: 111 | name: "get_latest_debug" 112 | arguments: 113 | limit: "5" 114 | expect: 115 | response: 116 | jsonrpc: "2.0" 117 | id: "debug-string-limit" 118 | result: 119 | content: 120 | match:arrayElements: 121 | type: "text" 122 | text: "match:contains:Invalid limit '5' for get_latest_debug. Must be a valid number" 123 | isError: true 124 | stderr: "toBeEmpty" 125 | 126 | - it: "should reject zero limit parameter" 127 | request: 128 | jsonrpc: "2.0" 129 | id: "debug-zero-limit" 130 | method: "tools/call" 131 | params: 132 | name: "get_latest_debug" 133 | arguments: 134 | limit: 0 135 | expect: 136 | response: 137 | jsonrpc: "2.0" 138 | id: "debug-zero-limit" 139 | result: 140 | content: 141 | match:arrayElements: 142 | type: "text" 143 | text: "match:contains:Invalid limit '0'" 144 | isError: true 145 | stderr: "toBeEmpty" 146 | 147 | # ======================================== 148 | # BASIC CONTENT VALIDATION 149 | # ======================================== 150 | 151 | - it: "should include basic SFCC log elements" 152 | request: 153 | jsonrpc: "2.0" 154 | id: "debug-basic-content" 155 | method: "tools/call" 156 | params: 157 | name: "get_latest_debug" 158 | arguments: 159 | limit: 2 160 | expect: 161 | response: 162 | jsonrpc: "2.0" 163 | id: "debug-basic-content" 164 | result: 165 | content: 166 | match:arrayElements: 167 | match:partial: 168 | text: "match:contains:DEBUG" 169 | isError: false 170 | stderr: "toBeEmpty" 171 | 172 | - it: "should include log file names in response" 173 | request: 174 | jsonrpc: "2.0" 175 | id: "debug-filenames" 176 | method: "tools/call" 177 | params: 178 | name: "get_latest_debug" 179 | arguments: 180 | limit: 1 181 | expect: 182 | response: 183 | jsonrpc: "2.0" 184 | id: "debug-filenames" 185 | result: 186 | content: 187 | match:arrayElements: 188 | match:partial: 189 | text: "match:contains:debug-blade-" 190 | isError: false 191 | stderr: "toBeEmpty" 192 | ``` -------------------------------------------------------------------------------- /docs/dw_web/FormElement.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.web 2 | 3 | # Class FormElement 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.web.FormElement 9 | 10 | ## Description 11 | 12 | Represents a form element. 13 | 14 | ## Properties 15 | 16 | ### dynamicHtmlName 17 | 18 | **Type:** String (Read Only) 19 | 20 | A dynamic html name for the field. It can be used to suppress any autocompletion 21 | support from a browser, e.g. for credit card related fields. It can be also 22 | used for a unique form name, if one form is used multiple times in a page. 23 | 24 | ### formId 25 | 26 | **Type:** String (Read Only) 27 | 28 | The ID of the form element. The is is unique within the parent 29 | element of the form. 30 | 31 | ### htmlName 32 | 33 | **Type:** String (Read Only) 34 | 35 | The global unique name of the field, which can be used as name 36 | in the html form. For radio buttons this name is not unique. 37 | 38 | ### parent 39 | 40 | **Type:** FormElement (Read Only) 41 | 42 | The parent within the form. 43 | 44 | ### valid 45 | 46 | **Type:** boolean (Read Only) 47 | 48 | Identifies if this element and all its children elements are 49 | valid. A form element, which was not submitted in the last 50 | request is always valid. 51 | 52 | ### validationResult 53 | 54 | **Type:** FormElementValidationResult (Read Only) 55 | 56 | Provides a combined view on the validation status as per isValid() and getError(). In 57 | addition it also provides the data as returned by the validation in case a validation 58 | script was used. 59 | 60 | ## Constructor Summary 61 | 62 | ## Method Summary 63 | 64 | ### clearFormElement 65 | 66 | **Signature:** `clearFormElement() : void` 67 | 68 | This method clears the whole form. 69 | 70 | ### getDynamicHtmlName 71 | 72 | **Signature:** `getDynamicHtmlName() : String` 73 | 74 | Returns a dynamic html name for the field. 75 | 76 | ### getFormId 77 | 78 | **Signature:** `getFormId() : String` 79 | 80 | The ID of the form element. 81 | 82 | ### getHtmlName 83 | 84 | **Signature:** `getHtmlName() : String` 85 | 86 | Returns the global unique name of the field, which can be used as name in the html form. 87 | 88 | ### getParent 89 | 90 | **Signature:** `getParent() : FormElement` 91 | 92 | The parent within the form. 93 | 94 | ### getValidationResult 95 | 96 | **Signature:** `getValidationResult() : FormElementValidationResult` 97 | 98 | Provides a combined view on the validation status as per isValid() and getError(). 99 | 100 | ### invalidateFormElement 101 | 102 | **Signature:** `invalidateFormElement() : void` 103 | 104 | The method can be called to explicitly invalidate a form element. 105 | 106 | ### invalidateFormElement 107 | 108 | **Signature:** `invalidateFormElement(error : String) : void` 109 | 110 | The method can be called to explicitly invalidate a field. 111 | 112 | ### isValid 113 | 114 | **Signature:** `isValid() : boolean` 115 | 116 | Identifies if this element and all its children elements are valid. 117 | 118 | ## Method Detail 119 | 120 | ## Method Details 121 | 122 | ### clearFormElement 123 | 124 | **Signature:** `clearFormElement() : void` 125 | 126 | **Description:** This method clears the whole form. After clearing a form it contains no value or the default value, is not bound to any business object and has the status of being valid. 127 | 128 | --- 129 | 130 | ### getDynamicHtmlName 131 | 132 | **Signature:** `getDynamicHtmlName() : String` 133 | 134 | **Description:** Returns a dynamic html name for the field. It can be used to suppress any autocompletion support from a browser, e.g. for credit card related fields. It can be also used for a unique form name, if one form is used multiple times in a page. 135 | 136 | **Returns:** 137 | 138 | a dynamic html name. 139 | 140 | --- 141 | 142 | ### getFormId 143 | 144 | **Signature:** `getFormId() : String` 145 | 146 | **Description:** The ID of the form element. The is is unique within the parent element of the form. 147 | 148 | **Returns:** 149 | 150 | the ID of the form. 151 | 152 | --- 153 | 154 | ### getHtmlName 155 | 156 | **Signature:** `getHtmlName() : String` 157 | 158 | **Description:** Returns the global unique name of the field, which can be used as name in the html form. For radio buttons this name is not unique. 159 | 160 | **Returns:** 161 | 162 | the global unique name of the field. 163 | 164 | --- 165 | 166 | ### getParent 167 | 168 | **Signature:** `getParent() : FormElement` 169 | 170 | **Description:** The parent within the form. 171 | 172 | **Returns:** 173 | 174 | the parent within the form. 175 | 176 | --- 177 | 178 | ### getValidationResult 179 | 180 | **Signature:** `getValidationResult() : FormElementValidationResult` 181 | 182 | **Description:** Provides a combined view on the validation status as per isValid() and getError(). In addition it also provides the data as returned by the validation in case a validation script was used. 183 | 184 | **Returns:** 185 | 186 | the validation status (valid, error, data) 187 | 188 | --- 189 | 190 | ### invalidateFormElement 191 | 192 | **Signature:** `invalidateFormElement() : void` 193 | 194 | **Description:** The method can be called to explicitly invalidate a form element. The error text will be set to the one of two possible preconfigured custom error messages associated with the form definition. The "value-error" message will be used for FormField instances and "form-error" will be used for FormGroup instances. 195 | 196 | --- 197 | 198 | ### invalidateFormElement 199 | 200 | **Signature:** `invalidateFormElement(error : String) : void` 201 | 202 | **Description:** The method can be called to explicitly invalidate a field. The error text is set to the given error message. 203 | 204 | **Parameters:** 205 | 206 | - `error`: the error text to use. 207 | 208 | --- 209 | 210 | ### isValid 211 | 212 | **Signature:** `isValid() : boolean` 213 | 214 | **Description:** Identifies if this element and all its children elements are valid. A form element, which was not submitted in the last request is always valid. 215 | 216 | **Returns:** 217 | 218 | true if this element and all its children elements are valid, false otherwise. 219 | 220 | --- ``` -------------------------------------------------------------------------------- /docs/dw_crypto/WeakMac.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.crypto 2 | 3 | # Class WeakMac 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.crypto.WeakMac 9 | 10 | ## Description 11 | 12 | This API provides access to Deprecated algorithms. See Mac for full documentation. WeakMac is simply a drop-in replacement that only supports deprecated algorithms. This is helpful when you need to deal with weak algorithms for backward compatibility purposes, but Mac should always be used for new development and for anything intended to be secure. This class provides the functionality of a "Message Authentication Code" (MAC) algorithm. A MAC provides a way to check the integrity of information transmitted over or stored in an unreliable medium, based on a secret key. Typically, message authentication codes are used between two parties that share a secret key in order to validate information transmitted between these parties. A MAC mechanism that is based on cryptographic hash functions is referred to as HMAC. HMAC can be used with any cryptographic hash function, e.g., SHA256, in combination with a secret shared key. HMAC is specified in RFC 2104. Note: this class handles sensitive security-related data. Pay special attention to PCI DSS v3. requirements 2, 4, and 12. 13 | 14 | ## Constants 15 | 16 | ### HMAC_MD5 17 | 18 | **Type:** String = "HmacMD5" 19 | 20 | Constant representing the HMAC-MD5 keyed-hashing algorithm as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997). This algorithm uses as MD5 cryptographic hash function. This algorithm is obsolete. Do not use it for any sensitive data 21 | 22 | ### HMAC_SHA_1 23 | 24 | **Type:** String = "HmacSHA1" 25 | 26 | Constant representing the HmacSHA1 algorithms as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997) with SHA-1 as the message digest algorithm. This algorithm is obsolete. Do not use it for any sensitive data 27 | 28 | ## Properties 29 | 30 | ## Constructor Summary 31 | 32 | WeakMac(algorithm : String) Construct a Mac encryption instance with the specified algorithm name. 33 | 34 | ## Method Summary 35 | 36 | ### digest 37 | 38 | **Signature:** `digest(input : String, key : String) : Bytes` 39 | 40 | Computes the hash value for the passed string input using the passed secret key. 41 | 42 | ### digest 43 | 44 | **Signature:** `digest(input : String, key : Bytes) : Bytes` 45 | 46 | Computes the hash value for the passed string input using the passed secret key. 47 | 48 | ### digest 49 | 50 | **Signature:** `digest(input : Bytes, key : Bytes) : Bytes` 51 | 52 | Computes the hash value for the passed bytes input using the passed secret key. 53 | 54 | ## Constructor Detail 55 | 56 | ## Method Detail 57 | 58 | ## Method Details 59 | 60 | ### digest 61 | 62 | **Signature:** `digest(input : String, key : String) : Bytes` 63 | 64 | **Description:** Computes the hash value for the passed string input using the passed secret key. Given input and the given key will be first converted with UTF-8 encoding into a byte array. The resulting hash is typically converted with base64 back into a string. 65 | 66 | **Parameters:** 67 | 68 | - `input`: A string to calculate a RFC 2104 compliant HMAC hash value for. 69 | - `key`: The secret key ready for use with the algorithm. The key's format depends on the chosen algorithm and the keys are assumed to be correctly formulated for the algorithm used, for example that the lengths are correct. Keys are not checked for validity. Only such keys that have no key parameters associated with them. 70 | 71 | **Returns:** 72 | 73 | The resulting hash value as bytes. 74 | 75 | **Throws:** 76 | 77 | IllegalArgumentException - if algorithm is not null and the specified algorithm name is not supported. 78 | 79 | --- 80 | 81 | ### digest 82 | 83 | **Signature:** `digest(input : String, key : Bytes) : Bytes` 84 | 85 | **Description:** Computes the hash value for the passed string input using the passed secret key. Given input will be first converted with UTF-8 encoding into a byte array. The resulting hash is typically converted with base64 back into a string. 86 | 87 | **Parameters:** 88 | 89 | - `input`: A string to calculate a RFC 2104 compliant HMAC hash value for. 90 | - `key`: The secret key as bytes ready for use with the algorithm. The key's format depends on the chosen algorithm and the keys are assumed to be correctly formulated for the algorithm used, for example that the lengths are correct. Keys are not checked for validity. Only such keys that have no key parameters associated with them. 91 | 92 | **Returns:** 93 | 94 | The resulting hash value as bytes. 95 | 96 | **Throws:** 97 | 98 | IllegalArgumentException - if algorithm is not null and the specified algorithm name is not supported. 99 | 100 | --- 101 | 102 | ### digest 103 | 104 | **Signature:** `digest(input : Bytes, key : Bytes) : Bytes` 105 | 106 | **Description:** Computes the hash value for the passed bytes input using the passed secret key. 107 | 108 | **Parameters:** 109 | 110 | - `input`: The bytes to calculate a RFC 2104 compliant HMAC hash value. 111 | - `key`: The secret key as byte array ready for use with the algorithm. The key's format depends on the chosen algorithm and the keys are assumed to be correctly formulated for the algorithm used, for example that the lengths are correct. Keys are not checked for validity. Only such keys that have no key parameters associated with them. 112 | 113 | **Returns:** 114 | 115 | The resulting hash value as bytes. 116 | 117 | **Throws:** 118 | 119 | IllegalArgumentException - if algorithm is not null and the specified algorithm name is not supported. 120 | 121 | --- ``` -------------------------------------------------------------------------------- /docs/dw_web/Resource.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.web 2 | 3 | # Class Resource 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.web.Resource 9 | 10 | ## Description 11 | 12 | Library class which provides methods for retrieving messages from properties resource bundles which contain locale-specific strings. When your program needs a locale-specific String, it loads it from the resource bundle that is appropriate for the user's current locale. In this way, the program code is largely independent of the user's locale. In Commerce Cloud Digital, resources are associated with the templates of a cartridge. These bundles consist of properties files with a common name defined in the template/resources directory of a site cartridge. For example: templates/resources/message.properties templates/resources/message_en.properties templates/resources/message_en_US.properties templates/resources/message_de_DE.properties Resource bundle lookup generally follows the same rules as the Java ResourceBundle class, where the locale used for lookup is based on the current request. See method javadoc for additional details. Properties resource files are assumed to use the UTF-8 character encoding. Unicode escape sequences are also supported. 13 | 14 | ## Constructor Summary 15 | 16 | ## Method Summary 17 | 18 | ### msg 19 | 20 | **Signature:** `static msg(key : String) : String` 21 | 22 | Returns the message from the default properties resource bundle (base name "message") corresponding to the specified key and the request locale. 23 | 24 | ### msg 25 | 26 | **Signature:** `static msg(key : String, defaultMessage : String) : String` 27 | 28 | Returns the message from the default properties resource bundle (base name "message") corresponding to the specified key and the request locale. 29 | 30 | ### msg 31 | 32 | **Signature:** `static msg(key : String, bundleName : String, defaultMessage : String) : String` 33 | 34 | Returns the message from the specified properties resource bundle. 35 | 36 | ### msgf 37 | 38 | **Signature:** `static msgf(key : String, bundleName : String, defaultMessage : String, args : Object...) : String` 39 | 40 | Returns the message from the specified properties resource bundle, with the provided arguments substituted for the message argument placeholders (specified using the Java MessageFormat approach). 41 | 42 | ## Method Detail 43 | 44 | ## Method Details 45 | 46 | ### msg 47 | 48 | **Signature:** `static msg(key : String) : String` 49 | 50 | **Description:** Returns the message from the default properties resource bundle (base name "message") corresponding to the specified key and the request locale. This method is equivalent to msg(String, null). 51 | 52 | **Parameters:** 53 | 54 | - `key`: resource bundle message key 55 | 56 | **Returns:** 57 | 58 | the resource bundle message or the key itself if no message is defined. 59 | 60 | **See Also:** 61 | 62 | msg(String, String) 63 | 64 | --- 65 | 66 | ### msg 67 | 68 | **Signature:** `static msg(key : String, defaultMessage : String) : String` 69 | 70 | **Description:** Returns the message from the default properties resource bundle (base name "message") corresponding to the specified key and the request locale. If no message for the key is found, returns the default message if it is not null, otherwise returns the key itself. This method is equivalent to msg(key, null, defaultMessage). 71 | 72 | **Parameters:** 73 | 74 | - `key`: resource bundle message key 75 | - `defaultMessage`: default message to return if no message corresponding to the key is found 76 | 77 | **Returns:** 78 | 79 | the resource bundle message or default message 80 | 81 | **See Also:** 82 | 83 | msg(String, String, String) 84 | 85 | --- 86 | 87 | ### msg 88 | 89 | **Signature:** `static msg(key : String, bundleName : String, defaultMessage : String) : String` 90 | 91 | **Description:** Returns the message from the specified properties resource bundle. The resource bundle is located by iterating the site cartridges and looking for a bundle with the specified name in the cartridge template/resources directory. If it finds a bundle, it tries to return a message from the bundle using standard Java ResourceBundle logic. If a message is found in that cartridge's bundle, it is returned, otherwise, the next cartridge is examined. The method throws an exception if the key is null. 92 | 93 | **Parameters:** 94 | 95 | - `key`: resource bundle message key 96 | - `bundleName`: base bundle name, if null, default bundle name, "message", is used 97 | - `defaultMessage`: default message to return if no message corresponding to the key is found and defaultMessage is not null 98 | 99 | **Returns:** 100 | 101 | the resource bundle message or default message 102 | 103 | --- 104 | 105 | ### msgf 106 | 107 | **Signature:** `static msgf(key : String, bundleName : String, defaultMessage : String, args : Object...) : String` 108 | 109 | **Description:** Returns the message from the specified properties resource bundle, with the provided arguments substituted for the message argument placeholders (specified using the Java MessageFormat approach). If null is passed for the varargs argument, this method is equivalent to msg(key, bundleName, defaultMessage). 110 | 111 | **Parameters:** 112 | 113 | - `key`: resource bundle message key 114 | - `bundleName`: base bundle name, if null, default bundle name, "message", is used 115 | - `defaultMessage`: default message to return if no message corresponding to the key is found and defaultMessage is not null 116 | - `args`: optional list of arguments or a collection, which are included into the result string 117 | 118 | **Returns:** 119 | 120 | the resource bundle message or default message 121 | 122 | **See Also:** 123 | 124 | msg(String, String, String) 125 | 126 | --- ``` -------------------------------------------------------------------------------- /docs/dw_crypto/JWS.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.crypto 2 | 3 | # Class JWS 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.crypto.JWS 9 | 10 | ## Description 11 | 12 | This class represents a JSON Web Signature (JWS) object. 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 | ### algorithm 17 | 18 | **Type:** String (Read Only) 19 | 20 | Get the algorithm (alg) from the header. 21 | 22 | ### header 23 | 24 | **Type:** JWSHeader (Read Only) 25 | 26 | Get a copy of the JWS header. 27 | 28 | ### headerMap 29 | 30 | **Type:** Map (Read Only) 31 | 32 | Get a copy of the JWS header as a Map. 33 | 34 | ### payload 35 | 36 | **Type:** String (Read Only) 37 | 38 | Get the payload from this object. 39 | 40 | This is available even if the signature has not been verified. 41 | 42 | ## Constructor Summary 43 | 44 | JWS(header : JWSHeader, payload : String) Construct a new JWS for signing. 45 | 46 | JWS(header : JWSHeader, payload : Bytes) Construct a new JWS for signing. 47 | 48 | ## Method Summary 49 | 50 | ### getAlgorithm 51 | 52 | **Signature:** `getAlgorithm() : String` 53 | 54 | Get the algorithm (alg) from the header. 55 | 56 | ### getHeader 57 | 58 | **Signature:** `getHeader() : JWSHeader` 59 | 60 | Get a copy of the JWS header. 61 | 62 | ### getHeaderMap 63 | 64 | **Signature:** `getHeaderMap() : Map` 65 | 66 | Get a copy of the JWS header as a Map. 67 | 68 | ### getPayload 69 | 70 | **Signature:** `getPayload() : String` 71 | 72 | Get the payload from this object. 73 | 74 | ### parse 75 | 76 | **Signature:** `static parse(jws : String) : JWS` 77 | 78 | Parse a JSON Web Signature (JWS) object from its compact serialization format. 79 | 80 | ### parse 81 | 82 | **Signature:** `static parse(jws : String, payload : String) : JWS` 83 | 84 | Parse a JSON Web Signature (JWS) object from its compact serialization format. 85 | 86 | ### parse 87 | 88 | **Signature:** `static parse(jws : String, payload : Bytes) : JWS` 89 | 90 | Parse a JSON Web Signature (JWS) object from its compact serialization format. 91 | 92 | ### serialize 93 | 94 | **Signature:** `serialize(detachPayload : boolean) : String` 95 | 96 | Get this JWS in compact serialization form. 97 | 98 | ### sign 99 | 100 | **Signature:** `sign(keyRef : KeyRef) : void` 101 | 102 | Sign the payload using the given private key. 103 | 104 | ### verify 105 | 106 | **Signature:** `verify(certificateRef : CertificateRef) : boolean` 107 | 108 | Verifies the signature of the payload. 109 | 110 | ## Constructor Detail 111 | 112 | ## Method Detail 113 | 114 | ## Method Details 115 | 116 | ### getAlgorithm 117 | 118 | **Signature:** `getAlgorithm() : String` 119 | 120 | **Description:** Get the algorithm (alg) from the header. 121 | 122 | **Returns:** 123 | 124 | Value of the algorithm or null if missing. 125 | 126 | --- 127 | 128 | ### getHeader 129 | 130 | **Signature:** `getHeader() : JWSHeader` 131 | 132 | **Description:** Get a copy of the JWS header. 133 | 134 | **Returns:** 135 | 136 | Copy of the JWS header. 137 | 138 | --- 139 | 140 | ### getHeaderMap 141 | 142 | **Signature:** `getHeaderMap() : Map` 143 | 144 | **Description:** Get a copy of the JWS header as a Map. 145 | 146 | **Returns:** 147 | 148 | Copy of the JWS header. 149 | 150 | --- 151 | 152 | ### getPayload 153 | 154 | **Signature:** `getPayload() : String` 155 | 156 | **Description:** Get the payload from this object. This is available even if the signature has not been verified. 157 | 158 | **Returns:** 159 | 160 | UTF-8 encoded payload. 161 | 162 | --- 163 | 164 | ### parse 165 | 166 | **Signature:** `static parse(jws : String) : JWS` 167 | 168 | **Description:** Parse a JSON Web Signature (JWS) object from its compact serialization format. 169 | 170 | **Parameters:** 171 | 172 | - `jws`: JWS in compact serialization format. 173 | 174 | **Returns:** 175 | 176 | JWS object. 177 | 178 | --- 179 | 180 | ### parse 181 | 182 | **Signature:** `static parse(jws : String, payload : String) : JWS` 183 | 184 | **Description:** Parse a JSON Web Signature (JWS) object from its compact serialization format. 185 | 186 | **Parameters:** 187 | 188 | - `jws`: JWS without a payload in compact serialization format. 189 | - `payload`: Detached payload 190 | 191 | **Returns:** 192 | 193 | JWS object. 194 | 195 | --- 196 | 197 | ### parse 198 | 199 | **Signature:** `static parse(jws : String, payload : Bytes) : JWS` 200 | 201 | **Description:** Parse a JSON Web Signature (JWS) object from its compact serialization format. 202 | 203 | **Parameters:** 204 | 205 | - `jws`: JWS without a payload in compact serialization format. 206 | - `payload`: Detached payload 207 | 208 | **Returns:** 209 | 210 | JWS object. 211 | 212 | --- 213 | 214 | ### serialize 215 | 216 | **Signature:** `serialize(detachPayload : boolean) : String` 217 | 218 | **Description:** Get this JWS in compact serialization form. 219 | 220 | **Parameters:** 221 | 222 | - `detachPayload`: true for a detached payload compliant with RFC-7797, or false to serialize the payload too. 223 | 224 | **Returns:** 225 | 226 | Compact serialized object. 227 | 228 | --- 229 | 230 | ### sign 231 | 232 | **Signature:** `sign(keyRef : KeyRef) : void` 233 | 234 | **Description:** Sign the payload using the given private key. The key type and size must match the algorithm given in the JWS header. 235 | 236 | **Parameters:** 237 | 238 | - `keyRef`: Reference to the private key. 239 | 240 | **Throws:** 241 | 242 | Exception - if there is an error while signing the payload. 243 | 244 | --- 245 | 246 | ### verify 247 | 248 | **Signature:** `verify(certificateRef : CertificateRef) : boolean` 249 | 250 | **Description:** Verifies the signature of the payload. If the x5c header parameter is present, then that certificate chain will be used to verify the signature and the given certificateRef must be its root certificate. If this parameter is not present then the given certificateRef will be used to directly verify the signature. The following algorithms are supported: ES256 ES256K ES384 ES512 RS256 RS384 RS512 PS256 PS384 PS512 251 | 252 | **Parameters:** 253 | 254 | - `certificateRef`: Reference to the certificate to use for verification. 255 | 256 | **Returns:** 257 | 258 | a boolean indicating success (true) or failure (false). 259 | 260 | **Throws:** 261 | 262 | Exception - if there is an error while processing the certificate (for example if the x5c is not signed by the given certificate) or the algorithm is unsupported. 263 | 264 | --- ``` -------------------------------------------------------------------------------- /docs/sfra/request.md: -------------------------------------------------------------------------------- ```markdown 1 | # Class Request 2 | 3 | ## Inheritance Hierarchy 4 | 5 | - Object 6 | - sfra.models.Request 7 | 8 | ## Description 9 | 10 | The SFRA Request object is a local wrapper around the global request object that provides enhanced functionality for SFRA (Storefront Reference Architecture) applications. This class translates the global request, customer, and session objects into a more convenient local interface with additional properties and methods. The Request object automatically handles currency setting based on locale, provides easy access to form data and query parameters, and includes customer information in a normalized format. It serves as the primary interface for accessing request-related data in SFRA controllers and provides a consistent API across different types of requests (GET, POST, PUT, etc.). 11 | 12 | ## Properties 13 | 14 | ### httpMethod 15 | 16 | **Type:** String (Read Only) 17 | 18 | The HTTP method of the request (GET, POST, PUT, DELETE, etc.). 19 | 20 | ### host 21 | 22 | **Type:** String (Read Only) 23 | 24 | The HTTP host header value from the request. 25 | 26 | ### path 27 | 28 | **Type:** String (Read Only) 29 | 30 | The HTTP path portion of the request URL. 31 | 32 | ### httpHeaders 33 | 34 | **Type:** Object (Read Only) 35 | 36 | Collection of HTTP headers from the request. 37 | 38 | ### https 39 | 40 | **Type:** Boolean (Read Only) 41 | 42 | Indicates whether the request was made over HTTPS. 43 | 44 | ### includeRequest 45 | 46 | **Type:** Boolean (Read Only) 47 | 48 | Indicates whether this is an include request (remote include). 49 | 50 | ### session 51 | 52 | **Type:** Object (Read Only) 53 | 54 | Local session object containing privacy cache, currency information, and click stream data. 55 | 56 | ### httpParameterMap 57 | 58 | **Type:** dw.web.HttpParameterMap (Read Only) 59 | 60 | The raw HTTP parameter map from the global request object. 61 | 62 | ### querystring 63 | 64 | **Type:** QueryString (Read Only) 65 | 66 | Parsed query string parameters as a QueryString object. 67 | 68 | ### form 69 | 70 | **Type:** Object (Read Only) 71 | 72 | Normalized form data from the HTTP parameter map, excluding query string parameters. 73 | 74 | ### body 75 | 76 | **Type:** String (Read Only) 77 | 78 | The request body as a string for POST and PUT requests. 79 | 80 | ### geolocation 81 | 82 | **Type:** Object (Read Only) 83 | 84 | Geolocation information including country code, latitude, and longitude. 85 | 86 | ### currentCustomer 87 | 88 | **Type:** Object (Read Only) 89 | 90 | Local customer object containing profile, address book, and wallet information. 91 | 92 | ### locale 93 | 94 | **Type:** Object (Read Only) 95 | 96 | Current locale information including currency details. 97 | 98 | ### remoteAddress 99 | 100 | **Type:** String (Read Only) 101 | 102 | The remote IP address of the client making the request. 103 | 104 | ### referer 105 | 106 | **Type:** String (Read Only) 107 | 108 | The HTTP referer header value. 109 | 110 | ### pageMetaData 111 | 112 | **Type:** Object (Read Only) 113 | 114 | Page metadata object for managing SEO-related information. 115 | 116 | ## Constructor Summary 117 | 118 | ### Request 119 | 120 | **Signature:** `Request(request, customer, session)` 121 | 122 | Creates a new SFRA Request object from global request, customer, and session objects. 123 | 124 | **Parameters:** 125 | - `request` (Object) - Global request object 126 | - `customer` (dw.customer.Customer) - Global customer object 127 | - `session` (dw.system.Session) - Global session object 128 | 129 | ## Method Summary 130 | 131 | ### setLocale 132 | 133 | **Signature:** `setLocale(localeID) : Boolean` 134 | 135 | Sets the locale for the current request. 136 | 137 | **Parameters:** 138 | - `localeID` (String) - The locale ID to set 139 | 140 | **Returns:** 141 | - Boolean indicating success of locale setting 142 | 143 | ## Method Detail 144 | 145 | ### setLocale 146 | 147 | **Signature:** `setLocale(localeID) : Boolean` 148 | 149 | **Description:** Sets the locale for the current request and returns whether the operation was successful. 150 | 151 | **Parameters:** 152 | - `localeID` (String) - The locale identifier (e.g., "en_US", "fr_FR") 153 | 154 | **Returns:** 155 | Boolean value indicating whether the locale was successfully set. 156 | 157 | ## Property Details 158 | 159 | ### session 160 | 161 | **Type:** Object (Read Only) 162 | 163 | **Description:** Provides access to session-related information including: 164 | 165 | - `privacyCache` - Simple cache for session privacy data 166 | - `raw` - Reference to the original session object 167 | - `currency` - Current currency information with code, digits, name, and symbol 168 | - `setCurrency(value)` - Method to update session currency 169 | - `clickStream` - Click stream data with clicks array, first/last clicks, and partial flag 170 | 171 | ### currentCustomer 172 | 173 | **Type:** Object (Read Only) 174 | 175 | **Description:** Normalized customer object containing: 176 | 177 | **For Authenticated Customers:** 178 | - `profile` - Customer profile with name, email, phone, and customer number 179 | - `addressBook` - Address book with preferred address and addresses array 180 | - `wallet` - Payment instruments collection 181 | - `raw` - Reference to original customer object 182 | 183 | **For Unauthenticated Customers:** 184 | - `credentials` - Username information 185 | - `raw` - Reference to original customer object 186 | 187 | ### geolocation 188 | 189 | **Type:** Object (Read Only) 190 | 191 | **Description:** Geographic location information: 192 | - `countryCode` - Two-letter country code 193 | - `latitude` - Geographic latitude coordinate 194 | - `longitude` - Geographic longitude coordinate 195 | 196 | ### pageMetaData 197 | 198 | **Type:** Object (Read Only) 199 | 200 | **Description:** SEO and page metadata management: 201 | - `title` - Page title 202 | - `description` - Page description 203 | - `keywords` - Page keywords 204 | - `pageMetaTags` - Collection of meta tags 205 | - `addPageMetaTags(pageMetaTags)` - Method to add meta tags 206 | - `setTitle(title)` - Method to set page title 207 | - `setDescription(description)` - Method to set page description 208 | - `setKeywords(keywords)` - Method to set page keywords 209 | 210 | --- 211 | ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/get-latest-job-log-files.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | --- 2 | description: "Test get_latest_job_log_files tool in full mode - Optimized for YAML/Aegis testing" 3 | tests: 4 | # Core functionality test with comprehensive content validation 5 | - it: "should retrieve job log files with complete format validation" 6 | request: 7 | jsonrpc: "2.0" 8 | id: "job-files-complete" 9 | method: "tools/call" 10 | params: 11 | name: "get_latest_job_log_files" 12 | arguments: 13 | limit: 1 14 | expect: 15 | response: 16 | jsonrpc: "2.0" 17 | id: "job-files-complete" 18 | result: 19 | content: 20 | match:arrayElements: 21 | type: "text" 22 | # Response is JSON-encoded, so match the quoted content with escaped newlines 23 | text: "match:regex:\"Found 1 job logs:[\\s\\S]*🔧 Job: [A-Za-z]+[\\s\\S]*ID: [0-9]+[\\s\\S]*File: Job-[A-Za-z]+-[0-9]+\\.log[\\s\\S]*Modified: [A-Za-z]{3}, [0-9]{2} [A-Za-z]{3} [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} GMT[\\s\\S]*Size: [0-9]+\\.[0-9]+ [A-Z]B\"" 24 | isError: false 25 | stderr: "toBeEmpty" 26 | performance: 27 | maxResponseTime: "2000ms" 28 | 29 | # Test default behavior (no limit parameter) 30 | - it: "should retrieve job log files with default parameters" 31 | request: 32 | jsonrpc: "2.0" 33 | id: "job-files-default" 34 | method: "tools/call" 35 | params: 36 | name: "get_latest_job_log_files" 37 | arguments: {} 38 | expect: 39 | response: 40 | jsonrpc: "2.0" 41 | id: "job-files-default" 42 | result: 43 | content: 44 | match:arrayElements: 45 | type: "text" 46 | text: "match:contains:Found" 47 | isError: false 48 | stderr: "toBeEmpty" 49 | performance: 50 | maxResponseTime: "2000ms" 51 | 52 | # Test limit parameter functionality 53 | - it: "should respect limit parameter" 54 | request: 55 | jsonrpc: "2.0" 56 | id: "job-files-limit" 57 | method: "tools/call" 58 | params: 59 | name: "get_latest_job_log_files" 60 | arguments: 61 | limit: 5 62 | expect: 63 | response: 64 | jsonrpc: "2.0" 65 | id: "job-files-limit" 66 | result: 67 | content: 68 | match:arrayElements: 69 | type: "text" 70 | text: "match:contains:job logs:" 71 | isError: false 72 | stderr: "toBeEmpty" 73 | performance: 74 | maxResponseTime: "2000ms" 75 | 76 | # Response structure validation 77 | - it: "should return proper MCP response structure" 78 | request: 79 | jsonrpc: "2.0" 80 | id: "job-files-structure" 81 | method: "tools/call" 82 | params: 83 | name: "get_latest_job_log_files" 84 | arguments: 85 | limit: 1 86 | expect: 87 | response: 88 | jsonrpc: "2.0" 89 | id: "job-files-structure" 90 | result: 91 | content: "match:type:array" 92 | isError: "match:type:boolean" 93 | stderr: "toBeEmpty" 94 | 95 | # Error handling: zero limit 96 | - it: "should reject zero limit parameter" 97 | request: 98 | jsonrpc: "2.0" 99 | id: "job-files-zero-limit" 100 | method: "tools/call" 101 | params: 102 | name: "get_latest_job_log_files" 103 | arguments: 104 | limit: 0 105 | expect: 106 | response: 107 | jsonrpc: "2.0" 108 | id: "job-files-zero-limit" 109 | result: 110 | content: 111 | match:arrayElements: 112 | type: "text" 113 | text: "match:contains:Invalid limit '0' for tool" 114 | isError: true 115 | stderr: "toBeEmpty" 116 | performance: 117 | maxResponseTime: "1000ms" 118 | 119 | # Error handling: negative limit 120 | - it: "should reject negative limit parameter" 121 | request: 122 | jsonrpc: "2.0" 123 | id: "job-files-negative-limit" 124 | method: "tools/call" 125 | params: 126 | name: "get_latest_job_log_files" 127 | arguments: 128 | limit: -1 129 | expect: 130 | response: 131 | jsonrpc: "2.0" 132 | id: "job-files-negative-limit" 133 | result: 134 | content: 135 | match:arrayElements: 136 | type: "text" 137 | text: "match:contains:Invalid limit '-1' for tool" 138 | isError: true 139 | stderr: "toBeEmpty" 140 | performance: 141 | maxResponseTime: "1000ms" 142 | 143 | # Error handling: invalid limit type 144 | - it: "should reject invalid limit parameter type" 145 | request: 146 | jsonrpc: "2.0" 147 | id: "job-files-invalid-limit" 148 | method: "tools/call" 149 | params: 150 | name: "get_latest_job_log_files" 151 | arguments: 152 | limit: "invalid" 153 | expect: 154 | response: 155 | jsonrpc: "2.0" 156 | id: "job-files-invalid-limit" 157 | result: 158 | content: 159 | match:arrayElements: 160 | type: "text" 161 | text: "match:contains:Invalid limit 'invalid' for tool. Must be a valid number" 162 | isError: true 163 | stderr: "toBeEmpty" 164 | performance: 165 | maxResponseTime: "1000ms" 166 | 167 | # Performance validation for successful operations 168 | - it: "should meet performance requirements for successful operations" 169 | request: 170 | jsonrpc: "2.0" 171 | id: "job-files-performance" 172 | method: "tools/call" 173 | params: 174 | name: "get_latest_job_log_files" 175 | arguments: 176 | limit: 10 177 | expect: 178 | response: 179 | jsonrpc: "2.0" 180 | id: "job-files-performance" 181 | result: 182 | content: 183 | match:arrayElements: 184 | type: "text" 185 | text: "match:type:string" 186 | isError: false 187 | stderr: "toBeEmpty" 188 | performance: 189 | maxResponseTime: "2000ms" 190 | ``` -------------------------------------------------------------------------------- /docs/dw_system/StatusItem.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.system 2 | 3 | # Class StatusItem 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.system.StatusItem 9 | 10 | ## Description 11 | 12 | A StatusItem holds all the status information. Multi StatusItems are bundled together into a Status. 13 | 14 | ## Properties 15 | 16 | ### code 17 | 18 | **Type:** String 19 | 20 | The status code is the unique identifier for the message and can be used by 21 | client programs to check for a specific status and to generate a localized 22 | message. 23 | 24 | ### details 25 | 26 | **Type:** Map (Read Only) 27 | 28 | The optional details for this StatusItem. 29 | 30 | ### error 31 | 32 | **Type:** boolean (Read Only) 33 | 34 | Returns whether this Status Item represents and error. 35 | 36 | ### message 37 | 38 | **Type:** String 39 | 40 | The default human readable message for this Status. 41 | 42 | Note: Custom code and client programs must not use this message to identify 43 | a specific status. The getCode() must be used for that purpose. The actual 44 | message can change from release to release. 45 | 46 | ### parameters 47 | 48 | **Type:** List 49 | 50 | The parameters to construct a custom message. 51 | 52 | ### status 53 | 54 | **Type:** Number 55 | 56 | The status. 57 | 58 | ## Constructor Summary 59 | 60 | StatusItem() Constructs a new OK StatusItem. 61 | 62 | StatusItem(status : Number) Constructs a new StatusItem with the given status. 63 | 64 | StatusItem(status : Number, code : String) Constructs a new StatusItem with the given status and code. 65 | 66 | StatusItem(status : Number, code : String, message : String, parameters : Object...) Constructs a new StatusItem with the given values. 67 | 68 | ## Method Summary 69 | 70 | ### addDetail 71 | 72 | **Signature:** `addDetail(key : String, value : Object) : void` 73 | 74 | Add an additional detail to this StatusItem. 75 | 76 | ### getCode 77 | 78 | **Signature:** `getCode() : String` 79 | 80 | The status code is the unique identifier for the message and can be used by client programs to check for a specific status and to generate a localized message. 81 | 82 | ### getDetails 83 | 84 | **Signature:** `getDetails() : Map` 85 | 86 | Returns the optional details for this StatusItem. 87 | 88 | ### getMessage 89 | 90 | **Signature:** `getMessage() : String` 91 | 92 | Returns the default human readable message for this Status. 93 | 94 | ### getParameters 95 | 96 | **Signature:** `getParameters() : List` 97 | 98 | Returns the parameters to construct a custom message. 99 | 100 | ### getStatus 101 | 102 | **Signature:** `getStatus() : Number` 103 | 104 | Returns the status. 105 | 106 | ### isError 107 | 108 | **Signature:** `isError() : boolean` 109 | 110 | Returns whether this Status Item represents and error. 111 | 112 | ### setCode 113 | 114 | **Signature:** `setCode(code : String) : void` 115 | 116 | Method to set the status code. 117 | 118 | ### setMessage 119 | 120 | **Signature:** `setMessage(message : String) : void` 121 | 122 | Sets the default human readable message for this Status. 123 | 124 | ### setParameters 125 | 126 | **Signature:** `setParameters(parameters : Object...) : void` 127 | 128 | Sets the parameters for a custom message. 129 | 130 | ### setStatus 131 | 132 | **Signature:** `setStatus(status : Number) : void` 133 | 134 | Set the status. 135 | 136 | ## Constructor Detail 137 | 138 | ## Method Detail 139 | 140 | ## Method Details 141 | 142 | ### addDetail 143 | 144 | **Signature:** `addDetail(key : String, value : Object) : void` 145 | 146 | **Description:** Add an additional detail to this StatusItem. 147 | 148 | **Parameters:** 149 | 150 | - `key`: the key for the detail. 151 | - `value`: the detail value. 152 | 153 | --- 154 | 155 | ### getCode 156 | 157 | **Signature:** `getCode() : String` 158 | 159 | **Description:** The status code is the unique identifier for the message and can be used by client programs to check for a specific status and to generate a localized message. 160 | 161 | **Returns:** 162 | 163 | the status code. 164 | 165 | --- 166 | 167 | ### getDetails 168 | 169 | **Signature:** `getDetails() : Map` 170 | 171 | **Description:** Returns the optional details for this StatusItem. 172 | 173 | **Returns:** 174 | 175 | the optional details for this StatusItem. 176 | 177 | --- 178 | 179 | ### getMessage 180 | 181 | **Signature:** `getMessage() : String` 182 | 183 | **Description:** Returns the default human readable message for this Status. Note: Custom code and client programs must not use this message to identify a specific status. The getCode() must be used for that purpose. The actual message can change from release to release. 184 | 185 | **Returns:** 186 | 187 | the default human readable message for this Status. 188 | 189 | --- 190 | 191 | ### getParameters 192 | 193 | **Signature:** `getParameters() : List` 194 | 195 | **Description:** Returns the parameters to construct a custom message. 196 | 197 | **Returns:** 198 | 199 | the parameters to construct a custom message. 200 | 201 | --- 202 | 203 | ### getStatus 204 | 205 | **Signature:** `getStatus() : Number` 206 | 207 | **Description:** Returns the status. 208 | 209 | **Returns:** 210 | 211 | either Status.OK or Status.ERROR. 212 | 213 | --- 214 | 215 | ### isError 216 | 217 | **Signature:** `isError() : boolean` 218 | 219 | **Description:** Returns whether this Status Item represents and error. 220 | 221 | **Returns:** 222 | 223 | true is this item represents an error, false otherwise. 224 | 225 | --- 226 | 227 | ### setCode 228 | 229 | **Signature:** `setCode(code : String) : void` 230 | 231 | **Description:** Method to set the status code. The status code is the unique identifier for the message and can be used by client programs to check for a specific status and to generate a localized message. 232 | 233 | **Parameters:** 234 | 235 | - `code`: the status code. 236 | 237 | --- 238 | 239 | ### setMessage 240 | 241 | **Signature:** `setMessage(message : String) : void` 242 | 243 | **Description:** Sets the default human readable message for this Status. 244 | 245 | **Parameters:** 246 | 247 | - `message`: the default human readable message for this Status. 248 | 249 | --- 250 | 251 | ### setParameters 252 | 253 | **Signature:** `setParameters(parameters : Object...) : void` 254 | 255 | **Description:** Sets the parameters for a custom message. 256 | 257 | **Parameters:** 258 | 259 | - `parameters`: the parameters for a custom message. 260 | 261 | --- 262 | 263 | ### setStatus 264 | 265 | **Signature:** `setStatus(status : Number) : void` 266 | 267 | **Description:** Set the status. 268 | 269 | **Parameters:** 270 | 271 | - `status`: either Status.OK or Status.ERROR. 272 | 273 | --- ``` -------------------------------------------------------------------------------- /docs/dw_catalog/PriceBookMgr.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.catalog 2 | 3 | # Class PriceBookMgr 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.catalog.PriceBookMgr 9 | 10 | ## Description 11 | 12 | Price book manager provides methods to access price books. 13 | 14 | ## Properties 15 | 16 | ### allPriceBooks 17 | 18 | **Type:** Collection (Read Only) 19 | 20 | All price books defined for the organization. 21 | 22 | ### applicablePriceBooks 23 | 24 | **Type:** Collection 25 | 26 | A collection of price books that are set in the user session. 27 | 28 | ### sitePriceBooks 29 | 30 | **Type:** Collection (Read Only) 31 | 32 | All price books assigned to the current site. 33 | Please note that this doesn't include parent price books not assigned to the site, but considered by the price 34 | lookup. 35 | 36 | ## Constructor Summary 37 | 38 | ## Method Summary 39 | 40 | ### assignPriceBookToSite 41 | 42 | **Signature:** `static assignPriceBookToSite(priceBook : PriceBook, siteId : String) : boolean` 43 | 44 | Assign a price book to a site. 45 | 46 | ### getAllPriceBooks 47 | 48 | **Signature:** `static getAllPriceBooks() : Collection` 49 | 50 | Returns all price books defined for the organization. 51 | 52 | ### getApplicablePriceBooks 53 | 54 | **Signature:** `static getApplicablePriceBooks() : Collection` 55 | 56 | Returns a collection of price books that are set in the user session. 57 | 58 | ### getPriceBook 59 | 60 | **Signature:** `static getPriceBook(priceBookID : String) : PriceBook` 61 | 62 | Returns the price book of the current organization matching the specified ID. 63 | 64 | ### getSitePriceBooks 65 | 66 | **Signature:** `static getSitePriceBooks() : Collection` 67 | 68 | Returns all price books assigned to the current site. 69 | 70 | ### setApplicablePriceBooks 71 | 72 | **Signature:** `static setApplicablePriceBooks(priceBooks : PriceBook...) : void` 73 | 74 | Sets one or more price books to be considered by the product price lookup. 75 | 76 | ### unassignPriceBookFromAllSites 77 | 78 | **Signature:** `static unassignPriceBookFromAllSites(priceBook : PriceBook) : boolean` 79 | 80 | Unassign a price book from all sites. 81 | 82 | ### unassignPriceBookFromSite 83 | 84 | **Signature:** `static unassignPriceBookFromSite(priceBook : PriceBook, siteId : String) : boolean` 85 | 86 | Unassign a price book from a site. 87 | 88 | ## Method Detail 89 | 90 | ## Method Details 91 | 92 | ### assignPriceBookToSite 93 | 94 | **Signature:** `static assignPriceBookToSite(priceBook : PriceBook, siteId : String) : boolean` 95 | 96 | **Description:** Assign a price book to a site. This requires a transaction, see Transaction.wrap(Function) 97 | 98 | **Parameters:** 99 | 100 | - `priceBook`: price book to be assigned 101 | - `siteId`: id of the site to be assigned to, such as 'SiteGenesis'. The site has to be a storefront site. 102 | 103 | **Returns:** 104 | 105 | true if price book is assigned to site. Throws an exception if price book doesn't exist or site doesn't exist or site is not a storefront site. 106 | 107 | --- 108 | 109 | ### getAllPriceBooks 110 | 111 | **Signature:** `static getAllPriceBooks() : Collection` 112 | 113 | **Description:** Returns all price books defined for the organization. 114 | 115 | **Returns:** 116 | 117 | All price books of the organization. 118 | 119 | --- 120 | 121 | ### getApplicablePriceBooks 122 | 123 | **Signature:** `static getApplicablePriceBooks() : Collection` 124 | 125 | **Description:** Returns a collection of price books that are set in the user session. 126 | 127 | **Returns:** 128 | 129 | Collection of applicable price books set in the session. 130 | 131 | --- 132 | 133 | ### getPriceBook 134 | 135 | **Signature:** `static getPriceBook(priceBookID : String) : PriceBook` 136 | 137 | **Description:** Returns the price book of the current organization matching the specified ID. 138 | 139 | **Parameters:** 140 | 141 | - `priceBookID`: The price book id. 142 | 143 | **Returns:** 144 | 145 | Price book or null of not found 146 | 147 | --- 148 | 149 | ### getSitePriceBooks 150 | 151 | **Signature:** `static getSitePriceBooks() : Collection` 152 | 153 | **Description:** Returns all price books assigned to the current site. Please note that this doesn't include parent price books not assigned to the site, but considered by the price lookup. 154 | 155 | **Returns:** 156 | 157 | All price books assigned to the current site. 158 | 159 | --- 160 | 161 | ### setApplicablePriceBooks 162 | 163 | **Signature:** `static setApplicablePriceBooks(priceBooks : PriceBook...) : void` 164 | 165 | **Description:** Sets one or more price books to be considered by the product price lookup. The information is stored in the user session. If no price book is set in the user session, all active and valid price books assigned to the site are used for the price lookup. If price books are set, only those price books are considered by the price lookup. Note that the system does not assure that a price book set by this API is assigned to the current site. 166 | 167 | **Parameters:** 168 | 169 | - `priceBooks`: The price books that are set in the session as applicable price books. 170 | 171 | --- 172 | 173 | ### unassignPriceBookFromAllSites 174 | 175 | **Signature:** `static unassignPriceBookFromAllSites(priceBook : PriceBook) : boolean` 176 | 177 | **Description:** Unassign a price book from all sites. This requires a transaction, see Transaction.wrap(Function) 178 | 179 | **Parameters:** 180 | 181 | - `priceBook`: price book to be unassigned 182 | 183 | **Returns:** 184 | 185 | true if price book is unassigned from all sites. Throws an exception if price book doesn't exist 186 | 187 | --- 188 | 189 | ### unassignPriceBookFromSite 190 | 191 | **Signature:** `static unassignPriceBookFromSite(priceBook : PriceBook, siteId : String) : boolean` 192 | 193 | **Description:** Unassign a price book from a site. This requires a transaction, see Transaction.wrap(Function) 194 | 195 | **Parameters:** 196 | 197 | - `priceBook`: price book to be unassigned 198 | - `siteId`: id of the site to be unassigned from, such as 'SiteGenesis'. The site has to be a storefront site. 199 | 200 | **Returns:** 201 | 202 | true if price book is unassigned from site. Throws an exception if price book doesn't exist or site doesn't exist or site is not a storefront site. 203 | 204 | --- ``` -------------------------------------------------------------------------------- /docs/dw_crypto/Mac.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.crypto 2 | 3 | # Class Mac 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.crypto.Mac 9 | 10 | ## Description 11 | 12 | This class provides the functionality of a "Message Authentication Code" (MAC) algorithm. A MAC provides a way to check the integrity of information transmitted over or stored in an unreliable medium, based on a secret key. Typically, message authentication codes are used between two parties that share a secret key in order to validate information transmitted between these parties. A MAC mechanism that is based on cryptographic hash functions is referred to as HMAC. HMAC can be used with any cryptographic hash function, e.g., SHA256, in combination with a secret shared key. HMAC is specified in RFC 2104. Note: this class handles sensitive security-related data. Pay special attention to PCI DSS v3. requirements 2, 4, and 12. 13 | 14 | ## Constants 15 | 16 | ### HMAC_MD5 17 | 18 | **Type:** String = "HmacMD5" 19 | 20 | Constant representing the HMAC-MD5 keyed-hashing algorithm as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997). This algorithm uses as MD5 cryptographic hash function. 21 | 22 | ### HMAC_SHA_1 23 | 24 | **Type:** String = "HmacSHA1" 25 | 26 | Constant representing the HmacSHA1 algorithms as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997) with SHA-1 as the message digest algorithm. 27 | 28 | ### HMAC_SHA_256 29 | 30 | **Type:** String = "HmacSHA256" 31 | 32 | Constant representing the HmacSHA256 algorithms as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997) with SHA-256 as the message digest algorithm. 33 | 34 | ### HMAC_SHA_384 35 | 36 | **Type:** String = "HmacSHA384" 37 | 38 | Constant representing the HmacSHA384 algorithms as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997) with SHA-384 as the message digest algorithm. 39 | 40 | ### HMAC_SHA_512 41 | 42 | **Type:** String = "HmacSHA512" 43 | 44 | Constant representing the HmacSHA512 algorithms as defined in RFC 2104 "HMAC: Keyed-Hashing for Message Authentication" (February 1997) with SHA-512 as the message digest algorithm. 45 | 46 | ## Properties 47 | 48 | ## Constructor Summary 49 | 50 | Mac(algorithm : String) Construct a Mac encryption instance with the specified algorithm name. 51 | 52 | ## Method Summary 53 | 54 | ### digest 55 | 56 | **Signature:** `digest(input : String, key : String) : Bytes` 57 | 58 | Computes the hash value for the passed string input using the passed secret key. 59 | 60 | ### digest 61 | 62 | **Signature:** `digest(input : String, key : Bytes) : Bytes` 63 | 64 | Computes the hash value for the passed string input using the passed secret key. 65 | 66 | ### digest 67 | 68 | **Signature:** `digest(input : Bytes, key : Bytes) : Bytes` 69 | 70 | Computes the hash value for the passed bytes input using the passed secret key. 71 | 72 | ## Constructor Detail 73 | 74 | ## Method Detail 75 | 76 | ## Method Details 77 | 78 | ### digest 79 | 80 | **Signature:** `digest(input : String, key : String) : Bytes` 81 | 82 | **Description:** Computes the hash value for the passed string input using the passed secret key. Given input and the given key will be first converted with UTF-8 encoding into a byte array. The resulting hash is typically converted with base64 back into a string. 83 | 84 | **Parameters:** 85 | 86 | - `input`: A string to calculate a RFC 2104 compliant HMAC hash value for. 87 | - `key`: The secret key ready for use with the algorithm. The key's format depends on the chosen algorithm and the keys are assumed to be correctly formulated for the algorithm used, for example that the lengths are correct. Keys are not checked for validity. Only such keys that have no key parameters associated with them. 88 | 89 | **Returns:** 90 | 91 | The resulting hash value as bytes. 92 | 93 | **Throws:** 94 | 95 | IllegalArgumentException - if algorithm is not null and the specified algorithm name is not supported. 96 | 97 | --- 98 | 99 | ### digest 100 | 101 | **Signature:** `digest(input : String, key : Bytes) : Bytes` 102 | 103 | **Description:** Computes the hash value for the passed string input using the passed secret key. Given input will be first converted with UTF-8 encoding into a byte array. The resulting hash is typically converted with base64 back into a string. 104 | 105 | **Parameters:** 106 | 107 | - `input`: A string to calculate a RFC 2104 compliant HMAC hash value for. 108 | - `key`: The secret key as bytes ready for use with the algorithm. The key's format depends on the chosen algorithm and the keys are assumed to be correctly formulated for the algorithm used, for example that the lengths are correct. Keys are not checked for validity. Only such keys that have no key parameters associated with them. 109 | 110 | **Returns:** 111 | 112 | The resulting hash value as bytes. 113 | 114 | **Throws:** 115 | 116 | IllegalArgumentException - if algorithm is not null and the specified algorithm name is not supported. 117 | 118 | --- 119 | 120 | ### digest 121 | 122 | **Signature:** `digest(input : Bytes, key : Bytes) : Bytes` 123 | 124 | **Description:** Computes the hash value for the passed bytes input using the passed secret key. 125 | 126 | **Parameters:** 127 | 128 | - `input`: The bytes to calculate a RFC 2104 compliant HMAC hash value. 129 | - `key`: The secret key as byte array ready for use with the algorithm. The key's format depends on the chosen algorithm and the keys are assumed to be correctly formulated for the algorithm used, for example that the lengths are correct. Keys are not checked for validity. Only such keys that have no key parameters associated with them. 130 | 131 | **Returns:** 132 | 133 | The resulting hash value as bytes. 134 | 135 | **Throws:** 136 | 137 | IllegalArgumentException - if algorithm is not null and the specified algorithm name is not supported. 138 | 139 | --- ``` -------------------------------------------------------------------------------- /tests/servers/sfcc-mock-server/mock-data/ocapi/site-preferences-system.json: -------------------------------------------------------------------------------- ```json 1 | { 2 | "_v": "23.2", 3 | "_type": "preference_value_search_result", 4 | "count": 3, 5 | "hits": [ 6 | { 7 | "_type": "preference_value", 8 | "attribute_definition": { 9 | "_type": "object_attribute_definition", 10 | "_resource_state": "system1-resource-state", 11 | "creation_date": "2024-01-15T10:30:00.000Z", 12 | "description": { 13 | "default": "Global system configuration for payment processing" 14 | }, 15 | "display_name": { 16 | "default": "System Payment Gateway URL" 17 | }, 18 | "effective_id": "c_systemPaymentGatewayUrl", 19 | "externally_defined": false, 20 | "externally_managed": false, 21 | "id": "systemPaymentGatewayUrl", 22 | "key": false, 23 | "last_modified": "2024-01-15T10:30:00.000Z", 24 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/SitePreferences/attribute_definitions/systemPaymentGatewayUrl", 25 | "localizable": false, 26 | "mandatory": true, 27 | "multi_value_type": false, 28 | "order_required": false, 29 | "queryable": false, 30 | "read_only": false, 31 | "requires_encoding": false, 32 | "searchable": false, 33 | "set_value_type": false, 34 | "site_specific": true, 35 | "system": false, 36 | "value_type": "string", 37 | "visible": true 38 | }, 39 | "description": { 40 | "default": "Global system configuration for payment processing" 41 | }, 42 | "display_name": { 43 | "default": "System Payment Gateway URL" 44 | }, 45 | "id": "systemPaymentGatewayUrl", 46 | "site_values": { 47 | "RefArch": "https://payments.example.com/api", 48 | "RefArchGlobal": "https://payments-global.example.com/api", 49 | "pxl_1": null, 50 | "pxl_2": null, 51 | "pxl_3": null, 52 | "pxl_4": null, 53 | "pxl_5": null, 54 | "pxl_6": null 55 | }, 56 | "value_type": "string" 57 | }, 58 | { 59 | "_type": "preference_value", 60 | "attribute_definition": { 61 | "_type": "object_attribute_definition", 62 | "_resource_state": "system2-resource-state", 63 | "creation_date": "2024-01-15T10:30:00.000Z", 64 | "description": { 65 | "default": "Enable debug logging for system operations" 66 | }, 67 | "display_name": { 68 | "default": "System Debug Enabled" 69 | }, 70 | "effective_id": "c_systemDebugEnabled", 71 | "externally_defined": false, 72 | "externally_managed": false, 73 | "id": "systemDebugEnabled", 74 | "key": false, 75 | "last_modified": "2024-01-15T10:30:00.000Z", 76 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/SitePreferences/attribute_definitions/systemDebugEnabled", 77 | "localizable": false, 78 | "mandatory": false, 79 | "multi_value_type": false, 80 | "order_required": false, 81 | "queryable": false, 82 | "read_only": false, 83 | "requires_encoding": false, 84 | "searchable": false, 85 | "set_value_type": false, 86 | "site_specific": true, 87 | "system": false, 88 | "value_type": "boolean", 89 | "visible": true 90 | }, 91 | "description": { 92 | "default": "Enable debug logging for system operations" 93 | }, 94 | "display_name": { 95 | "default": "System Debug Enabled" 96 | }, 97 | "id": "systemDebugEnabled", 98 | "site_values": { 99 | "RefArch": false, 100 | "RefArchGlobal": true, 101 | "pxl_1": null, 102 | "pxl_2": null, 103 | "pxl_3": null, 104 | "pxl_4": null, 105 | "pxl_5": null, 106 | "pxl_6": null 107 | }, 108 | "value_type": "boolean" 109 | }, 110 | { 111 | "_type": "preference_value", 112 | "attribute_definition": { 113 | "_type": "object_attribute_definition", 114 | "_resource_state": "system3-resource-state", 115 | "creation_date": "2024-01-15T10:30:00.000Z", 116 | "description": { 117 | "default": "Maximum number of concurrent system operations" 118 | }, 119 | "display_name": { 120 | "default": "System Max Concurrent Operations" 121 | }, 122 | "effective_id": "c_systemMaxConcurrentOps", 123 | "externally_defined": false, 124 | "externally_managed": false, 125 | "id": "systemMaxConcurrentOps", 126 | "key": false, 127 | "last_modified": "2024-01-15T10:30:00.000Z", 128 | "link": "https://localhost:3000/s/-/dw/data/v23_2/system_object_definitions/SitePreferences/attribute_definitions/systemMaxConcurrentOps", 129 | "localizable": false, 130 | "mandatory": false, 131 | "multi_value_type": false, 132 | "order_required": false, 133 | "queryable": false, 134 | "read_only": false, 135 | "requires_encoding": false, 136 | "searchable": false, 137 | "set_value_type": false, 138 | "site_specific": false, 139 | "system": false, 140 | "value_type": "int", 141 | "visible": true 142 | }, 143 | "description": { 144 | "default": "Maximum number of concurrent system operations" 145 | }, 146 | "display_name": { 147 | "default": "System Max Concurrent Operations" 148 | }, 149 | "id": "systemMaxConcurrentOps", 150 | "site_values": { 151 | "RefArch": 10, 152 | "RefArchGlobal": 50, 153 | "pxl_1": null, 154 | "pxl_2": null, 155 | "pxl_3": null, 156 | "pxl_4": null, 157 | "pxl_5": null, 158 | "pxl_6": null 159 | }, 160 | "value_type": "int" 161 | } 162 | ], 163 | "query": { 164 | "match_all_query": { 165 | "_type": "match_all_query" 166 | } 167 | }, 168 | "select": "(**)", 169 | "start": 0, 170 | "total": 3 171 | } ```