This is page 11 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 -------------------------------------------------------------------------------- /docs/dw_order/GiftCertificateMgr.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.order 2 | 3 | # Class GiftCertificateMgr 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.order.GiftCertificateMgr 9 | 10 | ## Description 11 | 12 | The GiftCertificateMgr class contains a set of static methods for interacting with GiftCertificates. 13 | 14 | ## Constants 15 | 16 | ### GC_ERROR_DISABLED 17 | 18 | **Type:** String = "GIFTCERTIFICATE-100" 19 | 20 | Indicates that an error occurred because the Gift Certificate is currently disabled. 21 | 22 | ### GC_ERROR_INSUFFICIENT_BALANCE 23 | 24 | **Type:** String = "GIFTCERTIFICATE-110" 25 | 26 | Indicates that an error occurred because the Gift Certificate does not have a sufficient balance to perform the requested operation. 27 | 28 | ### GC_ERROR_INVALID_AMOUNT 29 | 30 | **Type:** String = "GIFTCERTIFICATE-140" 31 | 32 | Indicates that an error occurred because the Gift Certificate Amount was not valid. 33 | 34 | ### GC_ERROR_INVALID_CODE 35 | 36 | **Type:** String = "GIFTCERTIFICATE-150" 37 | 38 | Indicates that an error occurred because the Gift Certificate ID was not valid. 39 | 40 | ### GC_ERROR_PENDING 41 | 42 | **Type:** String = "GIFTCERTIFICATE-130" 43 | 44 | Indicates that an error occurred because the Gift Certificate has been fully redeemed. 45 | 46 | ### GC_ERROR_REDEEMED 47 | 48 | **Type:** String = "GIFTCERTIFICATE-120" 49 | 50 | Indicates that an error occurred because the Gift Certificate has been fully redeemed. 51 | 52 | ## Properties 53 | 54 | ## Constructor Summary 55 | 56 | ## Method Summary 57 | 58 | ### createGiftCertificate 59 | 60 | **Signature:** `static createGiftCertificate(amount : Number, code : String) : GiftCertificate` 61 | 62 | Creates a Gift Certificate. 63 | 64 | ### createGiftCertificate 65 | 66 | **Signature:** `static createGiftCertificate(amount : Number) : GiftCertificate` 67 | 68 | Creates a Gift Certificate. 69 | 70 | ### getGiftCertificate 71 | 72 | **Signature:** `static getGiftCertificate(giftCertificateCode : String) : GiftCertificate` 73 | 74 | Returns the Gift Certificate identified by the specified gift certificate code. 75 | 76 | ### getGiftCertificateByCode 77 | 78 | **Signature:** `static getGiftCertificateByCode(giftCertificateCode : String) : GiftCertificate` 79 | 80 | Returns the Gift Certificate identified by the specified gift certificate code. 81 | 82 | ### getGiftCertificateByMerchantID 83 | 84 | **Signature:** `static getGiftCertificateByMerchantID(merchantID : String) : GiftCertificate` 85 | 86 | Returns the Gift Certificate identified by the specified merchant ID. 87 | 88 | ### redeemGiftCertificate 89 | 90 | **Signature:** `static redeemGiftCertificate(paymentInstrument : OrderPaymentInstrument) : Status` 91 | 92 | Redeems an amount from a Gift Certificate. 93 | 94 | ## Method Detail 95 | 96 | ## Method Details 97 | 98 | ### createGiftCertificate 99 | 100 | **Signature:** `static createGiftCertificate(amount : Number, code : String) : GiftCertificate` 101 | 102 | **Description:** Creates a Gift Certificate. If a non-empty Gift Certificate code is specified, the code will be used to create the Gift Certificate. Be aware that this code must be unique for the current site. If it is not unique, the Gift Certificate will not be created. 103 | 104 | **Parameters:** 105 | 106 | - `amount`: the amount of the gift certificate. Must not be negative or zero. 107 | - `code`: the code for the new gift certificate. If parameter is null or empty , the system will assign a code to the new gift certificate. 108 | 109 | **Returns:** 110 | 111 | the newly created Gift Certificate. 112 | 113 | --- 114 | 115 | ### createGiftCertificate 116 | 117 | **Signature:** `static createGiftCertificate(amount : Number) : GiftCertificate` 118 | 119 | **Description:** Creates a Gift Certificate. The system will assign a code to the new Gift Certificate. 120 | 121 | **Parameters:** 122 | 123 | - `amount`: the amount of the gift certificate. Must not be negative or zero. 124 | 125 | **Returns:** 126 | 127 | the newly created Gift Certificate. 128 | 129 | --- 130 | 131 | ### getGiftCertificate 132 | 133 | **Signature:** `static getGiftCertificate(giftCertificateCode : String) : GiftCertificate` 134 | 135 | **Description:** Returns the Gift Certificate identified by the specified gift certificate code. 136 | 137 | **Deprecated:** 138 | 139 | Use getGiftCertificateByCode(String) 140 | 141 | **Parameters:** 142 | 143 | - `giftCertificateCode`: to identify the Gift Certificate. 144 | 145 | **Returns:** 146 | 147 | the Gift Certificate identified by the specified code or null. 148 | 149 | --- 150 | 151 | ### getGiftCertificateByCode 152 | 153 | **Signature:** `static getGiftCertificateByCode(giftCertificateCode : String) : GiftCertificate` 154 | 155 | **Description:** Returns the Gift Certificate identified by the specified gift certificate code. 156 | 157 | **Parameters:** 158 | 159 | - `giftCertificateCode`: to identify the Gift Certificate. 160 | 161 | **Returns:** 162 | 163 | the Gift Certificate identified by the specified code or null. 164 | 165 | --- 166 | 167 | ### getGiftCertificateByMerchantID 168 | 169 | **Signature:** `static getGiftCertificateByMerchantID(merchantID : String) : GiftCertificate` 170 | 171 | **Description:** Returns the Gift Certificate identified by the specified merchant ID. 172 | 173 | **Parameters:** 174 | 175 | - `merchantID`: to identify the Gift Certificate. 176 | 177 | **Returns:** 178 | 179 | the Gift Certificate identified by the specified merchant ID or null. 180 | 181 | --- 182 | 183 | ### redeemGiftCertificate 184 | 185 | **Signature:** `static redeemGiftCertificate(paymentInstrument : OrderPaymentInstrument) : Status` 186 | 187 | **Description:** Redeems an amount from a Gift Certificate. The Gift Certificate ID is specified in the OrderPaymentInstrument and the amount specified in the PaymentTransaction associated with the OrderPaymentInstrument. If the PaymentTransaction.getTransactionID() is not null, the value returned by this method is used as the 'Order Number' for the redemption transaction. The 'Order Number' is visible via the Business Manager. 188 | 189 | **Parameters:** 190 | 191 | - `paymentInstrument`: the OrderPaymentInstrument containing the ID of the Gift Certificate to redeem, and the amount of the redemption. 192 | 193 | **Returns:** 194 | 195 | the status of the redemption operation. 196 | 197 | --- ``` -------------------------------------------------------------------------------- /docs/dw_svc/Result.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.svc 2 | 3 | # Class Result 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.svc.Result 9 | 10 | ## Description 11 | 12 | Represents the result of a service call. 13 | 14 | ## Constants 15 | 16 | ### ERROR 17 | 18 | **Type:** String = "ERROR" 19 | 20 | Status indicating a general service error. 21 | 22 | ### OK 23 | 24 | **Type:** String = "OK" 25 | 26 | Status indicating a successful service call. 27 | 28 | ### SERVICE_UNAVAILABLE 29 | 30 | **Type:** String = "SERVICE_UNAVAILABLE" 31 | 32 | Status indicating the service is unavailable. This includes timeouts, rate limits, and remote server issues. 33 | 34 | ### UNAVAILABLE_CIRCUIT_BROKEN 35 | 36 | **Type:** String = "CIRCUIT_BROKEN" 37 | 38 | Unavailable reason: No call was made because the circuit breaker prevented it. 39 | 40 | ### UNAVAILABLE_CONFIG_PROBLEM 41 | 42 | **Type:** String = "CONFIG_PROBLEM" 43 | 44 | Unavailable reason: No call was made because the service was not configured correctly. 45 | 46 | ### UNAVAILABLE_DISABLED 47 | 48 | **Type:** String = "DISABLED" 49 | 50 | Unavailable reason: No call was made because the service is disabled. 51 | 52 | ### UNAVAILABLE_RATE_LIMITED 53 | 54 | **Type:** String = "RATE_LIMITED" 55 | 56 | Unavailable reason: No call was made because the rate limit was hit. 57 | 58 | ### UNAVAILABLE_TIMEOUT 59 | 60 | **Type:** String = "TIMEOUT" 61 | 62 | Unavailable reason: A real call was made but a timeout occurred. 63 | 64 | ## Properties 65 | 66 | ### error 67 | 68 | **Type:** Number (Read Only) 69 | 70 | An error-specific code if applicable. For example, this is the HTTP response code for an 71 | HTTPService. 72 | 73 | ### errorMessage 74 | 75 | **Type:** String (Read Only) 76 | 77 | An error message on a non-OK status. 78 | 79 | ### mockResult 80 | 81 | **Type:** boolean (Read Only) 82 | 83 | The status of whether the response is the result of a "mock" service call. 84 | 85 | ### msg 86 | 87 | **Type:** String (Read Only) 88 | 89 | An extra error message on failure (if any). 90 | 91 | ### object 92 | 93 | **Type:** Object (Read Only) 94 | 95 | The actual object returned by the service when the status is OK. 96 | 97 | ### ok 98 | 99 | **Type:** boolean (Read Only) 100 | 101 | The status of whether the service call was successful. 102 | 103 | ### status 104 | 105 | **Type:** String (Read Only) 106 | 107 | The status. This is "OK" on success. Failure codes include "ERROR" and "SERVICE_UNAVAILABLE". 108 | 109 | If the status is "SERVICE_UNAVAILABLE", then the unavailableReason is guaranteed to be non-null. 110 | 111 | ### unavailableReason 112 | 113 | **Type:** String (Read Only) 114 | 115 | The reason the status is SERVICE_UNAVAILABLE. 116 | 117 | ## Constructor Summary 118 | 119 | Result() Constructs a new result instance. 120 | 121 | ## Method Summary 122 | 123 | ### getError 124 | 125 | **Signature:** `getError() : Number` 126 | 127 | Returns an error-specific code if applicable. 128 | 129 | ### getErrorMessage 130 | 131 | **Signature:** `getErrorMessage() : String` 132 | 133 | Returns an error message on a non-OK status. 134 | 135 | ### getMsg 136 | 137 | **Signature:** `getMsg() : String` 138 | 139 | Returns an extra error message on failure (if any). 140 | 141 | ### getObject 142 | 143 | **Signature:** `getObject() : Object` 144 | 145 | Returns the actual object returned by the service when the status is OK. 146 | 147 | ### getStatus 148 | 149 | **Signature:** `getStatus() : String` 150 | 151 | Returns the status. 152 | 153 | ### getUnavailableReason 154 | 155 | **Signature:** `getUnavailableReason() : String` 156 | 157 | Returns the reason the status is SERVICE_UNAVAILABLE. 158 | 159 | ### isMockResult 160 | 161 | **Signature:** `isMockResult() : boolean` 162 | 163 | Returns the status of whether the response is the result of a "mock" service call. 164 | 165 | ### isOk 166 | 167 | **Signature:** `isOk() : boolean` 168 | 169 | Returns the status of whether the service call was successful. 170 | 171 | ### toString 172 | 173 | **Signature:** `toString() : String` 174 | 175 | Returns a string representation of the result. 176 | 177 | ## Constructor Detail 178 | 179 | ## Method Detail 180 | 181 | ## Method Details 182 | 183 | ### getError 184 | 185 | **Signature:** `getError() : Number` 186 | 187 | **Description:** Returns an error-specific code if applicable. For example, this is the HTTP response code for an HTTPService. 188 | 189 | **Returns:** 190 | 191 | Error-specific code (if applicable). 192 | 193 | --- 194 | 195 | ### getErrorMessage 196 | 197 | **Signature:** `getErrorMessage() : String` 198 | 199 | **Description:** Returns an error message on a non-OK status. 200 | 201 | **Returns:** 202 | 203 | Error message. 204 | 205 | --- 206 | 207 | ### getMsg 208 | 209 | **Signature:** `getMsg() : String` 210 | 211 | **Description:** Returns an extra error message on failure (if any). 212 | 213 | **Returns:** 214 | 215 | Error message, or null. 216 | 217 | --- 218 | 219 | ### getObject 220 | 221 | **Signature:** `getObject() : Object` 222 | 223 | **Description:** Returns the actual object returned by the service when the status is OK. 224 | 225 | **Returns:** 226 | 227 | Object returned by the service. 228 | 229 | --- 230 | 231 | ### getStatus 232 | 233 | **Signature:** `getStatus() : String` 234 | 235 | **Description:** Returns the status. This is "OK" on success. Failure codes include "ERROR" and "SERVICE_UNAVAILABLE". If the status is "SERVICE_UNAVAILABLE", then the unavailableReason is guaranteed to be non-null. 236 | 237 | **Returns:** 238 | 239 | Status code. 240 | 241 | **See Also:** 242 | 243 | OK 244 | ERROR 245 | SERVICE_UNAVAILABLE 246 | 247 | --- 248 | 249 | ### getUnavailableReason 250 | 251 | **Signature:** `getUnavailableReason() : String` 252 | 253 | **Description:** Returns the reason the status is SERVICE_UNAVAILABLE. 254 | 255 | **Returns:** 256 | 257 | Unavailable reason code, or null if the status is not SERVICE_UNAVAILABLE. 258 | 259 | **See Also:** 260 | 261 | UNAVAILABLE_TIMEOUT 262 | UNAVAILABLE_CIRCUIT_BROKEN 263 | UNAVAILABLE_RATE_LIMITED 264 | UNAVAILABLE_DISABLED 265 | UNAVAILABLE_CONFIG_PROBLEM 266 | 267 | --- 268 | 269 | ### isMockResult 270 | 271 | **Signature:** `isMockResult() : boolean` 272 | 273 | **Description:** Returns the status of whether the response is the result of a "mock" service call. 274 | 275 | **Returns:** 276 | 277 | true if this was a mock service call, false otherwise. 278 | 279 | --- 280 | 281 | ### isOk 282 | 283 | **Signature:** `isOk() : boolean` 284 | 285 | **Description:** Returns the status of whether the service call was successful. 286 | 287 | **Returns:** 288 | 289 | true on success, false otherwise. 290 | 291 | --- 292 | 293 | ### toString 294 | 295 | **Signature:** `toString() : String` 296 | 297 | **Description:** Returns a string representation of the result. 298 | 299 | **Returns:** 300 | 301 | a string representation of the result. 302 | 303 | --- ``` -------------------------------------------------------------------------------- /docs/dw_system/Log.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.system 2 | 3 | # Class Log 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.system.Log 9 | 10 | ## Description 11 | 12 | A log4j like logger instance. To obtain such an instance, use the Logger.getRootLogger() or Logger.getLogger(String) or Logger.getLogger(String, String) methods. 13 | 14 | ## Properties 15 | 16 | ### debugEnabled 17 | 18 | **Type:** boolean (Read Only) 19 | 20 | This method returns true if debug logging is enabled for this logging instance. 21 | 22 | ### errorEnabled 23 | 24 | **Type:** boolean (Read Only) 25 | 26 | This method returns true if error logging is enabled for this logging instance. 27 | 28 | ### infoEnabled 29 | 30 | **Type:** boolean (Read Only) 31 | 32 | This method returns true if information logging is enabled for this logging instance. 33 | 34 | ### NDC 35 | 36 | **Type:** LogNDC (Read Only) 37 | 38 | The Nested Diagnostic Context for this script call. 39 | 40 | ### warnEnabled 41 | 42 | **Type:** boolean (Read Only) 43 | 44 | This method returns true if warning logging is enabled for this logging instance. 45 | 46 | ## Constructor Summary 47 | 48 | ## Method Summary 49 | 50 | ### debug 51 | 52 | **Signature:** `debug(msg : String, args : Object...) : void` 53 | 54 | The method reports an debug level message. 55 | 56 | ### error 57 | 58 | **Signature:** `error(msg : String, args : Object...) : void` 59 | 60 | The method reports an error level message. 61 | 62 | ### fatal 63 | 64 | **Signature:** `fatal(msg : String, args : Object...) : void` 65 | 66 | The method reports an warning level message. 67 | 68 | ### getNDC 69 | 70 | **Signature:** `static getNDC() : LogNDC` 71 | 72 | Returns the Nested Diagnostic Context for this script call. 73 | 74 | ### info 75 | 76 | **Signature:** `info(msg : String, args : Object...) : void` 77 | 78 | The method reports an information level message. 79 | 80 | ### isDebugEnabled 81 | 82 | **Signature:** `isDebugEnabled() : boolean` 83 | 84 | This method returns true if debug logging is enabled for this logging instance. 85 | 86 | ### isErrorEnabled 87 | 88 | **Signature:** `isErrorEnabled() : boolean` 89 | 90 | This method returns true if error logging is enabled for this logging instance. 91 | 92 | ### isInfoEnabled 93 | 94 | **Signature:** `isInfoEnabled() : boolean` 95 | 96 | This method returns true if information logging is enabled for this logging instance. 97 | 98 | ### isWarnEnabled 99 | 100 | **Signature:** `isWarnEnabled() : boolean` 101 | 102 | This method returns true if warning logging is enabled for this logging instance. 103 | 104 | ### warn 105 | 106 | **Signature:** `warn(msg : String, args : Object...) : void` 107 | 108 | The method reports an warning level message. 109 | 110 | ## Method Detail 111 | 112 | ## Method Details 113 | 114 | ### debug 115 | 116 | **Signature:** `debug(msg : String, args : Object...) : void` 117 | 118 | **Description:** The method reports an debug level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 119 | 120 | **Parameters:** 121 | 122 | - `msg`: the message to log. 123 | - `args`: the arguments to insert into the message. 124 | 125 | --- 126 | 127 | ### error 128 | 129 | **Signature:** `error(msg : String, args : Object...) : void` 130 | 131 | **Description:** The method reports an error level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 132 | 133 | **Parameters:** 134 | 135 | - `msg`: the message to log. 136 | - `args`: the arguments to insert into the message. 137 | 138 | --- 139 | 140 | ### fatal 141 | 142 | **Signature:** `fatal(msg : String, args : Object...) : void` 143 | 144 | **Description:** The method reports an warning level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. Note: Fatal log messages are always enabled and optionally send via E-Mail. 145 | 146 | **Parameters:** 147 | 148 | - `msg`: the message to log. 149 | - `args`: the arguments to insert into the message. 150 | 151 | --- 152 | 153 | ### getNDC 154 | 155 | **Signature:** `static getNDC() : LogNDC` 156 | 157 | **Description:** Returns the Nested Diagnostic Context for this script call. 158 | 159 | **Returns:** 160 | 161 | the nested diagnostic context 162 | 163 | --- 164 | 165 | ### info 166 | 167 | **Signature:** `info(msg : String, args : Object...) : void` 168 | 169 | **Description:** The method reports an information level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 170 | 171 | **Parameters:** 172 | 173 | - `msg`: the message to log. 174 | - `args`: the arguments to insert into the message. 175 | 176 | --- 177 | 178 | ### isDebugEnabled 179 | 180 | **Signature:** `isDebugEnabled() : boolean` 181 | 182 | **Description:** This method returns true if debug logging is enabled for this logging instance. 183 | 184 | **Returns:** 185 | 186 | true if logging of debug messages is enabled, false otherwise. 187 | 188 | --- 189 | 190 | ### isErrorEnabled 191 | 192 | **Signature:** `isErrorEnabled() : boolean` 193 | 194 | **Description:** This method returns true if error logging is enabled for this logging instance. 195 | 196 | **Returns:** 197 | 198 | true if logging of error messages is enabled, false otherwise. 199 | 200 | --- 201 | 202 | ### isInfoEnabled 203 | 204 | **Signature:** `isInfoEnabled() : boolean` 205 | 206 | **Description:** This method returns true if information logging is enabled for this logging instance. 207 | 208 | **Returns:** 209 | 210 | true if logging of information messages is enabled, false otherwise. 211 | 212 | --- 213 | 214 | ### isWarnEnabled 215 | 216 | **Signature:** `isWarnEnabled() : boolean` 217 | 218 | **Description:** This method returns true if warning logging is enabled for this logging instance. 219 | 220 | **Returns:** 221 | 222 | true if logging of warning messages is enabled, false otherwise. 223 | 224 | --- 225 | 226 | ### warn 227 | 228 | **Signature:** `warn(msg : String, args : Object...) : void` 229 | 230 | **Description:** The method reports an warning level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 231 | 232 | **Parameters:** 233 | 234 | - `msg`: the message to log. 235 | - `args`: the arguments to insert into the message. 236 | 237 | --- ``` -------------------------------------------------------------------------------- /docs/dw_order/ShippingMethod.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.order 2 | 3 | # Class ShippingMethod 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.object.PersistentObject 9 | - dw.object.ExtensibleObject 10 | - dw.order.ShippingMethod 11 | 12 | ## Description 13 | 14 | ShippingMethod represents how the shipment will be shipped. 15 | 16 | ## Properties 17 | 18 | ### baseMethod 19 | 20 | **Type:** ShippingMethod (Read Only) 21 | 22 | The base shipping method or null if undefined. 23 | 24 | ### currencyCode 25 | 26 | **Type:** String (Read Only) 27 | 28 | The currency code associated with the shipping method 29 | 30 | ### customerGroups 31 | 32 | **Type:** Collection (Read Only) 33 | 34 | The customer groups assigned to the shipping method. 35 | Assigned ids that do not belong to an existing customer group are ignored. 36 | 37 | ### defaultMethod 38 | 39 | **Type:** boolean (Read Only) 40 | 41 | Returns 'true' if the shipping method is marked as 'default' for the current session's currency. 42 | Otherwise 'false' is returned. 43 | 44 | ### dependentMethods 45 | 46 | **Type:** Collection (Read Only) 47 | 48 | The dependent shipping methods of this shipping method, 49 | regardless of the online status of the methods. 50 | Dependent shipping methods have this method as their base method. 51 | 52 | ### description 53 | 54 | **Type:** String (Read Only) 55 | 56 | The description of the shipping method as specified in the current locale or 57 | null if it could not be found. 58 | 59 | ### displayName 60 | 61 | **Type:** String (Read Only) 62 | 63 | The display name of the shipping method in the current locale or 64 | null if it could not be found. 65 | 66 | ### ID 67 | 68 | **Type:** String (Read Only) 69 | 70 | The ID of the shipping method. 71 | 72 | ### online 73 | 74 | **Type:** boolean (Read Only) 75 | 76 | Returns true if shipping method is online, false otherwise 77 | 78 | ### taxClassID 79 | 80 | **Type:** String (Read Only) 81 | 82 | The tax class id of the shipping method. 83 | 84 | ## Constructor Summary 85 | 86 | ## Method Summary 87 | 88 | ### getBaseMethod 89 | 90 | **Signature:** `getBaseMethod() : ShippingMethod` 91 | 92 | Returns the base shipping method or null if undefined. 93 | 94 | ### getCurrencyCode 95 | 96 | **Signature:** `getCurrencyCode() : String` 97 | 98 | Returns the currency code associated with the shipping method 99 | 100 | ### getCustomerGroups 101 | 102 | **Signature:** `getCustomerGroups() : Collection` 103 | 104 | Returns the customer groups assigned to the shipping method. 105 | 106 | ### getDependentMethods 107 | 108 | **Signature:** `getDependentMethods() : Collection` 109 | 110 | Returns the dependent shipping methods of this shipping method, regardless of the online status of the methods. 111 | 112 | ### getDescription 113 | 114 | **Signature:** `getDescription() : String` 115 | 116 | Returns the description of the shipping method as specified in the current locale or null if it could not be found. 117 | 118 | ### getDisplayName 119 | 120 | **Signature:** `getDisplayName() : String` 121 | 122 | Returns the display name of the shipping method in the current locale or null if it could not be found. 123 | 124 | ### getID 125 | 126 | **Signature:** `getID() : String` 127 | 128 | Returns the ID of the shipping method. 129 | 130 | ### getTaxClassID 131 | 132 | **Signature:** `getTaxClassID() : String` 133 | 134 | Returns the tax class id of the shipping method. 135 | 136 | ### isDefaultMethod 137 | 138 | **Signature:** `isDefaultMethod() : boolean` 139 | 140 | Returns 'true' if the shipping method is marked as 'default' for the current session's currency. 141 | 142 | ### isOnline 143 | 144 | **Signature:** `isOnline() : boolean` 145 | 146 | Returns true if shipping method is online, false otherwise 147 | 148 | ## Method Detail 149 | 150 | ## Method Details 151 | 152 | ### getBaseMethod 153 | 154 | **Signature:** `getBaseMethod() : ShippingMethod` 155 | 156 | **Description:** Returns the base shipping method or null if undefined. 157 | 158 | **Returns:** 159 | 160 | Base shipping method 161 | 162 | --- 163 | 164 | ### getCurrencyCode 165 | 166 | **Signature:** `getCurrencyCode() : String` 167 | 168 | **Description:** Returns the currency code associated with the shipping method 169 | 170 | **Returns:** 171 | 172 | currency code 173 | 174 | --- 175 | 176 | ### getCustomerGroups 177 | 178 | **Signature:** `getCustomerGroups() : Collection` 179 | 180 | **Description:** Returns the customer groups assigned to the shipping method. Assigned ids that do not belong to an existing customer group are ignored. 181 | 182 | **Returns:** 183 | 184 | customer groups 185 | 186 | --- 187 | 188 | ### getDependentMethods 189 | 190 | **Signature:** `getDependentMethods() : Collection` 191 | 192 | **Description:** Returns the dependent shipping methods of this shipping method, regardless of the online status of the methods. Dependent shipping methods have this method as their base method. 193 | 194 | **Returns:** 195 | 196 | Dependent shipping methods 197 | 198 | --- 199 | 200 | ### getDescription 201 | 202 | **Signature:** `getDescription() : String` 203 | 204 | **Description:** Returns the description of the shipping method as specified in the current locale or null if it could not be found. 205 | 206 | **Returns:** 207 | 208 | he description of the shipping method as specified in the current locale or null if it could not be found. 209 | 210 | --- 211 | 212 | ### getDisplayName 213 | 214 | **Signature:** `getDisplayName() : String` 215 | 216 | **Description:** Returns the display name of the shipping method in the current locale or null if it could not be found. 217 | 218 | **Returns:** 219 | 220 | the display name of the shipping method or null if it could not be found. 221 | 222 | --- 223 | 224 | ### getID 225 | 226 | **Signature:** `getID() : String` 227 | 228 | **Description:** Returns the ID of the shipping method. 229 | 230 | **Returns:** 231 | 232 | the ID of the shipping method. 233 | 234 | --- 235 | 236 | ### getTaxClassID 237 | 238 | **Signature:** `getTaxClassID() : String` 239 | 240 | **Description:** Returns the tax class id of the shipping method. 241 | 242 | **Returns:** 243 | 244 | the tax class id of the shipping method. 245 | 246 | --- 247 | 248 | ### isDefaultMethod 249 | 250 | **Signature:** `isDefaultMethod() : boolean` 251 | 252 | **Description:** Returns 'true' if the shipping method is marked as 'default' for the current session's currency. Otherwise 'false' is returned. 253 | 254 | **Returns:** 255 | 256 | 'true' if it is the default shipping method of the site 257 | 258 | --- 259 | 260 | ### isOnline 261 | 262 | **Signature:** `isOnline() : boolean` 263 | 264 | **Description:** Returns true if shipping method is online, false otherwise 265 | 266 | --- ``` -------------------------------------------------------------------------------- /docs/dw_order/TrackingInfo.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.order 2 | 3 | # Class TrackingInfo 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.object.Extensible 9 | - dw.order.TrackingInfo 10 | 11 | ## Description 12 | 13 | Provides basic information about a tracking info. An instance is identified by an ID and can be referenced from n ShippingOrderItems using TrackingRefs. This also allows one ShippingOrderItem to be associated with n TrackingInfo. 14 | 15 | ## Properties 16 | 17 | ### carrier 18 | 19 | **Type:** String 20 | 21 | Get the Carrier. 22 | 23 | ### carrierService 24 | 25 | **Type:** String 26 | 27 | Get the service(ship method) of the used carrier. 28 | 29 | ### ID 30 | 31 | **Type:** String (Read Only) 32 | 33 | Get the mandatory identifier for this tracking information. The id allows the tracking information to be referenced from 34 | TrackingRefs. To support short shipping a shipping-order-item can manage a list of 35 | TrackingRefs, each with an optional quantity value allowing individual items to ship in multiple 36 | parcels with known item quantity in each. 37 | 38 | ### shipDate 39 | 40 | **Type:** Date 41 | 42 | Get the ship date. 43 | 44 | ### shippingOrder 45 | 46 | **Type:** ShippingOrder (Read Only) 47 | 48 | Gets the shipping order. 49 | 50 | ### trackingNumber 51 | 52 | **Type:** String 53 | 54 | Get the tracking number. 55 | 56 | ### trackingRefs 57 | 58 | **Type:** Collection (Read Only) 59 | 60 | Gets the tracking refs (shipping order items) which are assigned to this tracking info. 61 | 62 | ### warehouseID 63 | 64 | **Type:** String 65 | 66 | Get the id of the shipping warehouse. 67 | 68 | ## Constructor Summary 69 | 70 | ## Method Summary 71 | 72 | ### getCarrier 73 | 74 | **Signature:** `getCarrier() : String` 75 | 76 | Get the Carrier. 77 | 78 | ### getCarrierService 79 | 80 | **Signature:** `getCarrierService() : String` 81 | 82 | Get the service(ship method) of the used carrier. 83 | 84 | ### getID 85 | 86 | **Signature:** `getID() : String` 87 | 88 | Get the mandatory identifier for this tracking information. 89 | 90 | ### getShipDate 91 | 92 | **Signature:** `getShipDate() : Date` 93 | 94 | Get the ship date. 95 | 96 | ### getShippingOrder 97 | 98 | **Signature:** `getShippingOrder() : ShippingOrder` 99 | 100 | Gets the shipping order. 101 | 102 | ### getTrackingNumber 103 | 104 | **Signature:** `getTrackingNumber() : String` 105 | 106 | Get the tracking number. 107 | 108 | ### getTrackingRefs 109 | 110 | **Signature:** `getTrackingRefs() : Collection` 111 | 112 | Gets the tracking refs (shipping order items) which are assigned to this tracking info. 113 | 114 | ### getWarehouseID 115 | 116 | **Signature:** `getWarehouseID() : String` 117 | 118 | Get the id of the shipping warehouse. 119 | 120 | ### setCarrier 121 | 122 | **Signature:** `setCarrier(carrier : String) : void` 123 | 124 | Set the Carrier. 125 | 126 | ### setCarrierService 127 | 128 | **Signature:** `setCarrierService(carrierService : String) : void` 129 | 130 | Set the service(ship method) of the used carrier. 131 | 132 | ### setShipDate 133 | 134 | **Signature:** `setShipDate(shipDate : Date) : void` 135 | 136 | Set the ship date. 137 | 138 | ### setTrackingNumber 139 | 140 | **Signature:** `setTrackingNumber(trackingNumber : String) : void` 141 | 142 | Set the TrackingNumber. 143 | 144 | ### setWarehouseID 145 | 146 | **Signature:** `setWarehouseID(warehouseID : String) : void` 147 | 148 | Set the id of the shipping warehouse. 149 | 150 | ## Method Detail 151 | 152 | ## Method Details 153 | 154 | ### getCarrier 155 | 156 | **Signature:** `getCarrier() : String` 157 | 158 | **Description:** Get the Carrier. 159 | 160 | **Returns:** 161 | 162 | the Carrier 163 | 164 | --- 165 | 166 | ### getCarrierService 167 | 168 | **Signature:** `getCarrierService() : String` 169 | 170 | **Description:** Get the service(ship method) of the used carrier. 171 | 172 | **Returns:** 173 | 174 | the carrier service (ship method) 175 | 176 | --- 177 | 178 | ### getID 179 | 180 | **Signature:** `getID() : String` 181 | 182 | **Description:** Get the mandatory identifier for this tracking information. The id allows the tracking information to be referenced from TrackingRefs. To support short shipping a shipping-order-item can manage a list of TrackingRefs, each with an optional quantity value allowing individual items to ship in multiple parcels with known item quantity in each. 183 | 184 | **Returns:** 185 | 186 | the id 187 | 188 | **See Also:** 189 | 190 | ShippingOrder.addTrackingInfo(String) 191 | 192 | --- 193 | 194 | ### getShipDate 195 | 196 | **Signature:** `getShipDate() : Date` 197 | 198 | **Description:** Get the ship date. 199 | 200 | **Returns:** 201 | 202 | the ship date 203 | 204 | --- 205 | 206 | ### getShippingOrder 207 | 208 | **Signature:** `getShippingOrder() : ShippingOrder` 209 | 210 | **Description:** Gets the shipping order. 211 | 212 | **Returns:** 213 | 214 | the shipping order 215 | 216 | --- 217 | 218 | ### getTrackingNumber 219 | 220 | **Signature:** `getTrackingNumber() : String` 221 | 222 | **Description:** Get the tracking number. 223 | 224 | **Returns:** 225 | 226 | the TrackingNumber 227 | 228 | --- 229 | 230 | ### getTrackingRefs 231 | 232 | **Signature:** `getTrackingRefs() : Collection` 233 | 234 | **Description:** Gets the tracking refs (shipping order items) which are assigned to this tracking info. 235 | 236 | **Returns:** 237 | 238 | the tracking refs (shipping order items) which are assigned to this tracking info. 239 | 240 | --- 241 | 242 | ### getWarehouseID 243 | 244 | **Signature:** `getWarehouseID() : String` 245 | 246 | **Description:** Get the id of the shipping warehouse. 247 | 248 | **Returns:** 249 | 250 | the id of the shipping warehouse 251 | 252 | --- 253 | 254 | ### setCarrier 255 | 256 | **Signature:** `setCarrier(carrier : String) : void` 257 | 258 | **Description:** Set the Carrier. 259 | 260 | **Parameters:** 261 | 262 | - `carrier`: the Carrier 263 | 264 | --- 265 | 266 | ### setCarrierService 267 | 268 | **Signature:** `setCarrierService(carrierService : String) : void` 269 | 270 | **Description:** Set the service(ship method) of the used carrier. 271 | 272 | **Parameters:** 273 | 274 | - `carrierService`: the carrier service, eg. the ship method 275 | 276 | --- 277 | 278 | ### setShipDate 279 | 280 | **Signature:** `setShipDate(shipDate : Date) : void` 281 | 282 | **Description:** Set the ship date. 283 | 284 | **Parameters:** 285 | 286 | - `shipDate`: the ship date 287 | 288 | --- 289 | 290 | ### setTrackingNumber 291 | 292 | **Signature:** `setTrackingNumber(trackingNumber : String) : void` 293 | 294 | **Description:** Set the TrackingNumber. 295 | 296 | **Parameters:** 297 | 298 | - `trackingNumber`: the TrackingNumber 299 | 300 | --- 301 | 302 | ### setWarehouseID 303 | 304 | **Signature:** `setWarehouseID(warehouseID : String) : void` 305 | 306 | **Description:** Set the id of the shipping warehouse. 307 | 308 | **Parameters:** 309 | 310 | - `warehouseID`: the id of the shipping warehouse 311 | 312 | --- ``` -------------------------------------------------------------------------------- /docs/sfra/totals.md: -------------------------------------------------------------------------------- ```markdown 1 | # SFRA Totals Model 2 | 3 | ## Overview 4 | 5 | The Totals model represents comprehensive pricing and discount information for a basket or order in SFRA applications. It provides formatted monetary values, discount calculations, and tax information for checkout and order display. 6 | 7 | ## Constructor 8 | 9 | ```javascript 10 | function totals(lineItemContainer) 11 | ``` 12 | 13 | Creates a Totals model instance with comprehensive pricing information from a line item container. 14 | 15 | ### Parameters 16 | 17 | - `lineItemContainer` (dw.order.LineItemCtnr) - Current user's basket or order 18 | 19 | ## Properties 20 | 21 | ### subTotal 22 | **Type:** string 23 | 24 | Formatted subtotal of merchandise before taxes and shipping. 25 | 26 | ### totalShippingCost 27 | **Type:** string 28 | 29 | Formatted total shipping cost. 30 | 31 | ### grandTotal 32 | **Type:** string 33 | 34 | Formatted grand total including all items, taxes, shipping, and discounts. 35 | 36 | ### totalTax 37 | **Type:** string 38 | 39 | Formatted total tax amount. 40 | 41 | ### discounts 42 | **Type:** Array<Object> 43 | 44 | Array of discount objects including promotions and coupons. Each discount contains: 45 | 46 | **For Promotions:** 47 | - `UUID` (string) - Unique identifier 48 | - `lineItemText` (string) - Display text for the discount 49 | - `price` (string) - Formatted discount amount 50 | - `type` (string) - Always 'promotion' 51 | - `callOutMsg` (string) - Promotion callout message 52 | 53 | **For Coupons:** 54 | - `UUID` (string) - Unique identifier 55 | - `type` (string) - Always 'coupon' 56 | - `couponCode` (string) - The coupon code 57 | - `applied` (boolean) - Whether the coupon is applied 58 | - `valid` (boolean) - Whether the coupon is valid 59 | - `relationship` (Array) - Array of related price adjustments with callout messages 60 | 61 | ### discountsHtml 62 | **Type:** string 63 | 64 | HTML-formatted string of all discounts for display purposes. 65 | 66 | ### orderLevelDiscountTotal 67 | **Type:** Object 68 | 69 | Order-level discount information containing: 70 | - `value` (number) - Raw discount value 71 | - `formatted` (string) - Formatted discount amount 72 | 73 | ### shippingLevelDiscountTotal 74 | **Type:** Object 75 | 76 | Shipping-level discount information containing: 77 | - `value` (number) - Raw discount value 78 | - `formatted` (string) - Formatted discount amount 79 | 80 | ## Helper Functions 81 | 82 | ### getTotals(total) 83 | Formats a money total for display, handling unavailable totals. 84 | 85 | **Parameters:** 86 | - `total` (dw.value.Money) - Total price value 87 | 88 | **Returns:** string - Formatted money value or '-' if unavailable 89 | 90 | ### getOrderLevelDiscountTotal(lineItemContainer) 91 | Calculates order-level discount by comparing totals with and without order discounts. 92 | 93 | **Parameters:** 94 | - `lineItemContainer` (dw.order.LineItemCtnr) - Basket or order container 95 | 96 | **Returns:** Object - Order discount value and formatted amount 97 | 98 | ### getShippingLevelDiscountTotal(lineItemContainer) 99 | Calculates shipping-level discount by comparing shipping totals. 100 | 101 | **Parameters:** 102 | - `lineItemContainer` (dw.order.LineItemCtnr) - Basket or order container 103 | 104 | **Returns:** Object - Shipping discount value and formatted amount 105 | 106 | ### createDiscountObject(collection, discounts) 107 | Adds promotion discounts to a discounts object. 108 | 109 | **Parameters:** 110 | - `collection` (dw.util.Collection) - Collection of price adjustments 111 | - `discounts` (Object) - Existing discounts object 112 | 113 | **Returns:** Object - Updated discounts object 114 | 115 | ### getDiscounts(lineItemContainer) 116 | Creates a comprehensive array of all discounts including promotions and coupons. 117 | 118 | **Parameters:** 119 | - `lineItemContainer` (dw.order.LineItemCtnr) - Basket or order container 120 | 121 | **Returns:** Array<Object> - Array of discount objects 122 | 123 | ## Usage Example 124 | 125 | ```javascript 126 | var totals = require('*/cartridge/models/totals'); 127 | var BasketMgr = require('dw/order/BasketMgr'); 128 | 129 | var currentBasket = BasketMgr.getCurrentBasket(); 130 | var totalsModel = new totals(currentBasket); 131 | 132 | // Access formatted totals 133 | console.log(totalsModel.subTotal); // "$149.99" 134 | console.log(totalsModel.totalShippingCost); // "$9.95" 135 | console.log(totalsModel.grandTotal); // "$159.94" 136 | console.log(totalsModel.totalTax); // "$12.00" 137 | 138 | // Access discount information 139 | totalsModel.discounts.forEach(function(discount) { 140 | if (discount.type === 'promotion') { 141 | console.log('Promotion: ' + discount.lineItemText + ' - ' + discount.price); 142 | } else if (discount.type === 'coupon') { 143 | console.log('Coupon: ' + discount.couponCode + ' (applied: ' + discount.applied + ')'); 144 | } 145 | }); 146 | 147 | // Check for order-level discounts 148 | if (totalsModel.orderLevelDiscountTotal.value > 0) { 149 | console.log('Order discount: ' + totalsModel.orderLevelDiscountTotal.formatted); 150 | } 151 | ``` 152 | 153 | ## Discount Types 154 | 155 | The model handles different types of discounts: 156 | 157 | ### Promotions 158 | - Automatic promotional discounts 159 | - Include callout messages for display 160 | - Based on business rules and conditions 161 | 162 | ### Coupons 163 | - Customer-entered coupon codes 164 | - Include the coupon code for reference 165 | - May have usage restrictions 166 | 167 | ## HTML Formatting 168 | 169 | The `discountsHtml` property provides ready-to-use HTML formatting for discount display, using templates to ensure consistent presentation across the application. 170 | 171 | ## Notes 172 | 173 | - All monetary values are properly formatted for display 174 | - Handles unavailable totals gracefully with fallback formatting 175 | - Separates order-level and shipping-level discounts 176 | - Provides both individual discount details and aggregate totals 177 | - Compatible with both baskets and completed orders 178 | - Includes comprehensive tax calculation information 179 | 180 | ## Related Models 181 | 182 | - **Cart Model** - Uses totals for cart display 183 | - **Order Model** - Uses totals for order information 184 | - **Checkout Models** - Use totals throughout checkout process 185 | ``` -------------------------------------------------------------------------------- /tests/servers/sfcc-mock-server/src/app.js: -------------------------------------------------------------------------------- ```javascript 1 | /** 2 | * Express Application Setup 3 | * 4 | * Main Express application configuration with middleware setup and route registration. 5 | * Follows modular architecture with clean separation of concerns. 6 | */ 7 | 8 | const express = require('express'); 9 | const { createCorsMiddleware } = require('./middleware/cors'); 10 | const { createRequestLogger, createResponseLogger, createErrorLogger } = require('./middleware/logging'); 11 | const AuthenticationManager = require('./middleware/auth'); 12 | const WebDAVRouteHandler = require('./routes/webdav'); 13 | const OCAPIRouteHandler = require('./routes/ocapi'); 14 | 15 | class SFCCMockApp { 16 | constructor(config) { 17 | this.config = config; 18 | this.app = express(); 19 | this.authManager = new AuthenticationManager(config); 20 | this.setupMiddleware(); 21 | this.setupRoutes(); 22 | this.setupErrorHandling(); 23 | } 24 | 25 | setupMiddleware() { 26 | // CORS middleware (if enabled) 27 | if (this.config.features.cors) { 28 | this.app.use(createCorsMiddleware()); 29 | } 30 | 31 | // Body parsing middleware 32 | this.app.use(express.json({ limit: '10mb' })); 33 | this.app.use(express.urlencoded({ extended: true, limit: '10mb' })); 34 | 35 | // Logging middleware (if enabled) 36 | if (this.config.features.logging) { 37 | this.app.use(createRequestLogger(this.config.isDevMode)); 38 | this.app.use(createResponseLogger(this.config.isDevMode)); 39 | } 40 | 41 | // Custom method support for WebDAV 42 | this.app.use((req, res, next) => { 43 | // Add support for PROPFIND method 44 | if (req.headers['content-length'] === '0' && req.method === 'POST') { 45 | // Check if this might be a PROPFIND disguised as POST 46 | const contentType = req.headers['content-type']; 47 | if (!contentType || contentType.includes('application/xml')) { 48 | req.method = 'PROPFIND'; 49 | } 50 | } 51 | next(); 52 | }); 53 | } 54 | 55 | setupRoutes() { 56 | // Health check endpoint 57 | this.app.get('/health', (req, res) => { 58 | const summary = this.config.getSummary(); 59 | res.json({ 60 | status: 'ok', 61 | message: 'SFCC Mock Server is running', 62 | timestamp: new Date().toISOString(), 63 | config: summary 64 | }); 65 | }); 66 | 67 | // Server info endpoint 68 | this.app.get('/info', (req, res) => { 69 | const summary = this.config.getSummary(); 70 | res.json({ 71 | name: 'SFCC Mock Server', 72 | version: '1.0.0', 73 | description: 'Unified WebDAV and OCAPI mock server for SFCC development', 74 | config: summary 75 | }); 76 | }); 77 | 78 | // WebDAV routes (if enabled) 79 | if (this.config.features.webdav) { 80 | const webdavHandler = new WebDAVRouteHandler(this.config); 81 | this.app.use(webdavHandler.getRouter()); 82 | 83 | if (this.config.isDevMode) { 84 | console.log('✅ WebDAV routes enabled'); 85 | } 86 | } 87 | 88 | // OCAPI routes (if enabled) 89 | if (this.config.features.ocapi) { 90 | const ocapiHandler = new OCAPIRouteHandler(this.config, this.authManager); 91 | this.app.use(ocapiHandler.getRouter()); 92 | 93 | if (this.config.isDevMode) { 94 | console.log('✅ OCAPI routes enabled'); 95 | } 96 | } 97 | 98 | // Catch-all for undefined routes 99 | this.app.use('*', (req, res) => { 100 | res.status(404).json({ 101 | error: 'Not Found', 102 | message: `Route ${req.method} ${req.originalUrl} not found`, 103 | timestamp: new Date().toISOString(), 104 | availableEndpoints: this.getAvailableEndpoints() 105 | }); 106 | }); 107 | } 108 | 109 | setupErrorHandling() { 110 | // Error logging middleware 111 | this.app.use(createErrorLogger()); 112 | 113 | // Final error handler 114 | this.app.use((err, req, res, next) => { 115 | // Prevent header already sent errors 116 | if (res.headersSent) { 117 | return next(err); 118 | } 119 | 120 | const statusCode = err.statusCode || err.status || 500; 121 | const message = err.message || 'Internal Server Error'; 122 | 123 | res.status(statusCode).json({ 124 | error: 'Server Error', 125 | message: message, 126 | timestamp: new Date().toISOString(), 127 | ...(this.config.isDevMode && { stack: err.stack }) 128 | }); 129 | }); 130 | } 131 | 132 | getAvailableEndpoints() { 133 | const baseUrl = this.config.getServerUrl(); 134 | const endpoints = { 135 | health: `${baseUrl}/health`, 136 | info: `${baseUrl}/info` 137 | }; 138 | 139 | if (this.config.features.webdav) { 140 | endpoints.webdav = { 141 | logs: this.config.getWebdavLogsUrl(), 142 | directLogs: `${baseUrl}/Logs/` 143 | }; 144 | } 145 | 146 | if (this.config.features.ocapi) { 147 | const ocapiBase = this.config.getOcapiBaseUrl(); 148 | endpoints.ocapi = { 149 | oauth: `${baseUrl}/dw/oauth2/access_token`, 150 | systemObjects: `${ocapiBase}/system_object_definitions`, 151 | codeVersions: `${ocapiBase}/code_versions` 152 | }; 153 | } 154 | 155 | return endpoints; 156 | } 157 | 158 | getExpressApp() { 159 | return this.app; 160 | } 161 | 162 | getAuthManager() { 163 | return this.authManager; 164 | } 165 | } 166 | 167 | module.exports = SFCCMockApp; ``` -------------------------------------------------------------------------------- /src/utils/validator.ts: -------------------------------------------------------------------------------- ```typescript 1 | /** 2 | * Validation Utilities 3 | * 4 | * This module provides validation functions for SFCC API parameters and inputs. 5 | * It includes common validation patterns used across different API clients. 6 | */ 7 | 8 | /** 9 | * Custom validation error class 10 | */ 11 | export class ValidationError extends Error { 12 | constructor(message: string) { 13 | super(message); 14 | this.name = 'ValidationError'; 15 | } 16 | } 17 | 18 | /** 19 | * Valid instance types for SFCC site preferences 20 | */ 21 | const VALID_INSTANCE_TYPES = ['staging', 'development', 'sandbox', 'production'] as const; 22 | export type InstanceType = typeof VALID_INSTANCE_TYPES[number]; 23 | 24 | /** 25 | * Validation utility class 26 | */ 27 | export class Validator { 28 | /** 29 | * Validate that required fields are present and not empty 30 | */ 31 | static validateRequired(params: Record<string, any>, requiredFields: string[]): void { 32 | const missingFields: string[] = []; 33 | 34 | for (const field of requiredFields) { 35 | const value = params[field]; 36 | if (value === undefined || value === null || (typeof value === 'string' && value.trim().length === 0)) { 37 | missingFields.push(field); 38 | } 39 | } 40 | 41 | if (missingFields.length > 0) { 42 | throw new ValidationError(`Required fields are missing or empty: ${missingFields.join(', ')}`); 43 | } 44 | } 45 | 46 | /** 47 | * Validate instance type for site preferences 48 | */ 49 | static validateInstanceType(instanceType: string): InstanceType { 50 | if (!VALID_INSTANCE_TYPES.includes(instanceType as InstanceType)) { 51 | throw new ValidationError( 52 | `Invalid instance type '${instanceType}'. Must be one of: ${VALID_INSTANCE_TYPES.join(', ')}`, 53 | ); 54 | } 55 | return instanceType as InstanceType; 56 | } 57 | 58 | /** 59 | * Validate that a string is not empty 60 | */ 61 | static validateNotEmpty(value: string, fieldName: string): void { 62 | if (!value || value.trim().length === 0) { 63 | throw new ValidationError(`${fieldName} cannot be empty`); 64 | } 65 | } 66 | 67 | /** 68 | * Validate that a value is a positive number 69 | */ 70 | static validatePositiveNumber(value: number, fieldName: string): void { 71 | if (value < 0) { 72 | throw new ValidationError(`${fieldName} must be a positive number`); 73 | } 74 | } 75 | 76 | /** 77 | * Validate object type for system objects 78 | */ 79 | static validateObjectType(objectType: string): void { 80 | Validator.validateNotEmpty(objectType, 'objectType'); 81 | 82 | // Basic validation - could be extended with specific object type patterns 83 | if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(objectType)) { 84 | throw new ValidationError( 85 | `Invalid object type '${objectType}'. Must start with a letter and contain only letters, numbers, and underscores.`, 86 | ); 87 | } 88 | } 89 | 90 | /** 91 | * Validate search request structure 92 | */ 93 | static validateSearchRequest(searchRequest: any): void { 94 | if (!searchRequest || typeof searchRequest !== 'object') { 95 | throw new ValidationError('Search request must be a valid object'); 96 | } 97 | 98 | // Validate query structure if present 99 | if (searchRequest.query) { 100 | const query = searchRequest.query; 101 | 102 | // Check that at least one query type is specified 103 | const queryTypes = ['text_query', 'term_query', 'filtered_query', 'bool_query', 'match_all_query']; 104 | const hasValidQuery = queryTypes.some(type => query[type]); 105 | 106 | if (!hasValidQuery) { 107 | throw new ValidationError( 108 | `Search query must contain at least one of: ${queryTypes.join(', ')}`, 109 | ); 110 | } 111 | 112 | // Validate text_query structure 113 | if (query.text_query) { 114 | const textQuery = query.text_query; 115 | if (!textQuery.fields || !Array.isArray(textQuery.fields) || textQuery.fields.length === 0) { 116 | throw new ValidationError('text_query.fields must be a non-empty array'); 117 | } 118 | if (!textQuery.search_phrase || typeof textQuery.search_phrase !== 'string') { 119 | throw new ValidationError('text_query.search_phrase must be a non-empty string'); 120 | } 121 | } 122 | 123 | // Validate term_query structure 124 | if (query.term_query) { 125 | const termQuery = query.term_query; 126 | if (!termQuery.fields || !Array.isArray(termQuery.fields) || termQuery.fields.length === 0) { 127 | throw new ValidationError('term_query.fields must be a non-empty array'); 128 | } 129 | if (!termQuery.operator || typeof termQuery.operator !== 'string') { 130 | throw new ValidationError('term_query.operator must be a non-empty string'); 131 | } 132 | if (!termQuery.values || !Array.isArray(termQuery.values) || termQuery.values.length === 0) { 133 | throw new ValidationError('term_query.values must be a non-empty array'); 134 | } 135 | } 136 | } 137 | 138 | // Validate sorts structure if present 139 | if (searchRequest.sorts) { 140 | if (!Array.isArray(searchRequest.sorts)) { 141 | throw new ValidationError('sorts must be an array'); 142 | } 143 | 144 | searchRequest.sorts.forEach((sort: any, index: number) => { 145 | if (!sort.field || typeof sort.field !== 'string') { 146 | throw new ValidationError(`sorts[${index}].field must be a non-empty string`); 147 | } 148 | if (sort.sort_order && !['asc', 'desc'].includes(sort.sort_order)) { 149 | throw new ValidationError(`sorts[${index}].sort_order must be either 'asc' or 'desc'`); 150 | } 151 | }); 152 | } 153 | 154 | // Validate pagination parameters 155 | if (searchRequest.start !== undefined) { 156 | Validator.validatePositiveNumber(searchRequest.start, 'start'); 157 | } 158 | if (searchRequest.count !== undefined) { 159 | Validator.validatePositiveNumber(searchRequest.count, 'count'); 160 | } 161 | } 162 | } 163 | ``` -------------------------------------------------------------------------------- /src/tool-configs/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, LogMessageFormatter } from '../utils/log-tool-utils.js'; 4 | import { ValidationHelpers, CommonValidations } from '../core/handlers/validation-helpers.js'; 5 | import { LogToolName, getLimit } from '../utils/log-tool-constants.js'; 6 | import { SFCCLogClient } from '../clients/log-client.js'; 7 | 8 | /** 9 | * Configuration for standard log tools 10 | * Maps each tool to its validation, execution, and messaging logic 11 | */ 12 | export const LOG_TOOL_CONFIG: Record<LogToolName, GenericToolSpec<ToolArguments, any>> = { 13 | get_latest_error: { 14 | defaults: (args: ToolArguments) => ({ 15 | limit: getLimit(args.limit as number, 'latest'), 16 | }), 17 | validate: (args: ToolArguments) => LogToolValidators.validateLimit(args.limit as number, 'get_latest_error'), 18 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 19 | const client = context.logClient as SFCCLogClient; 20 | return client.getLatestLogs('error', args.limit as number, args.date as string); 21 | }, 22 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatLatestLogs('error', args.limit as number, args.date as string), 23 | }, 24 | 25 | get_latest_warn: { 26 | defaults: (args: ToolArguments) => ({ 27 | limit: getLimit(args.limit as number, 'latest'), 28 | }), 29 | validate: (args: ToolArguments) => LogToolValidators.validateLimit(args.limit as number, 'get_latest_warn'), 30 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 31 | const client = context.logClient as SFCCLogClient; 32 | return client.getLatestLogs('warn', args.limit as number, args.date as string); 33 | }, 34 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatLatestLogs('warn', args.limit as number, args.date as string), 35 | }, 36 | 37 | get_latest_info: { 38 | defaults: (args: ToolArguments) => ({ 39 | limit: getLimit(args.limit as number, 'latest'), 40 | }), 41 | validate: (args: ToolArguments) => LogToolValidators.validateLimit(args.limit as number, 'get_latest_info'), 42 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 43 | const client = context.logClient as SFCCLogClient; 44 | return client.getLatestLogs('info', args.limit as number, args.date as string); 45 | }, 46 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatLatestLogs('info', args.limit as number, args.date as string), 47 | }, 48 | 49 | get_latest_debug: { 50 | defaults: (args: ToolArguments) => ({ 51 | limit: getLimit(args.limit as number, 'latest'), 52 | }), 53 | validate: (args: ToolArguments) => LogToolValidators.validateLimit(args.limit as number, 'get_latest_debug'), 54 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 55 | const client = context.logClient as SFCCLogClient; 56 | return client.getLatestLogs('debug', args.limit as number, args.date as string); 57 | }, 58 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatLatestLogs('debug', args.limit as number, args.date as string), 59 | }, 60 | 61 | summarize_logs: { 62 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 63 | const client = context.logClient as SFCCLogClient; 64 | return client.summarizeLogs(args.date as string); 65 | }, 66 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatSummarizeLogs(args.date as string), 67 | }, 68 | 69 | search_logs: { 70 | defaults: (args: ToolArguments) => ({ 71 | limit: getLimit(args.limit as number, 'search'), 72 | }), 73 | validate: (args: ToolArguments, toolName: string) => { 74 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('pattern'), toolName); 75 | LogToolValidators.validateLimit(args.limit as number, toolName); 76 | if (args.logLevel) { 77 | LogToolValidators.validateLogLevel(args.logLevel as string, toolName); 78 | } 79 | }, 80 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 81 | const client = context.logClient as SFCCLogClient; 82 | return client.searchLogs( 83 | args.pattern as string, 84 | args.logLevel as any, 85 | args.limit as number, 86 | args.date as string, 87 | ); 88 | }, 89 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatSearchLogs( 90 | args.pattern as string, 91 | args.logLevel as string, 92 | args.limit as number, 93 | args.date as string, 94 | ), 95 | }, 96 | 97 | list_log_files: { 98 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 99 | const client = context.logClient as SFCCLogClient; 100 | return client.listLogFiles(); 101 | }, 102 | logMessage: () => LogMessageFormatter.formatListLogFiles(), 103 | }, 104 | 105 | get_log_file_contents: { 106 | validate: (args: ToolArguments, toolName: string) => { 107 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('filename'), toolName); 108 | LogToolValidators.validateFilename(args.filename as string, toolName); 109 | LogToolValidators.validateMaxBytes(args.maxBytes as number, toolName); 110 | }, 111 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 112 | const client = context.logClient as SFCCLogClient; 113 | return client.getLogFileContents( 114 | args.filename as string, 115 | args.maxBytes as number, 116 | args.tailOnly as boolean, 117 | ); 118 | }, 119 | logMessage: (args: ToolArguments) => LogMessageFormatter.formatGetLogFileContents( 120 | args.filename as string, 121 | args.maxBytes as number, 122 | args.tailOnly as boolean, 123 | ), 124 | }, 125 | }; 126 | ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/search-logs.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | --- 2 | description: "Test search_logs tool in full mode - Aegis framework validation" 3 | tests: 4 | # Core Aegis framework tests - basic functionality 5 | - it: "should search for patterns with matches and proper response structure" 6 | request: 7 | jsonrpc: "2.0" 8 | id: "search-basic" 9 | method: "tools/call" 10 | params: 11 | name: "search_logs" 12 | arguments: 13 | pattern: "INFO" 14 | limit: 2 15 | expect: 16 | response: 17 | jsonrpc: "2.0" 18 | id: "search-basic" 19 | result: 20 | content: 21 | match:arrayElements: 22 | match:partial: 23 | type: "text" 24 | text: "match:regex:Found \\d+ matches for" 25 | isError: false 26 | stderr: "toBeEmpty" 27 | performance: 28 | maxResponseTime: "1500ms" 29 | 30 | - it: "should handle no matches gracefully" 31 | request: 32 | jsonrpc: "2.0" 33 | id: "search-no-matches" 34 | method: "tools/call" 35 | params: 36 | name: "search_logs" 37 | arguments: 38 | pattern: "nonexistentpattern123456789" 39 | expect: 40 | response: 41 | jsonrpc: "2.0" 42 | id: "search-no-matches" 43 | result: 44 | content: 45 | match:arrayElements: 46 | match:partial: 47 | type: "text" 48 | text: "match:regex:No matches found for.*nonexistentpattern123456789" 49 | isError: false 50 | stderr: "toBeEmpty" 51 | performance: 52 | maxResponseTime: "1000ms" 53 | 54 | # Error handling validation 55 | - it: "should reject empty pattern with proper error response" 56 | request: 57 | jsonrpc: "2.0" 58 | id: "search-empty-pattern" 59 | method: "tools/call" 60 | params: 61 | name: "search_logs" 62 | arguments: 63 | pattern: "" 64 | expect: 65 | response: 66 | jsonrpc: "2.0" 67 | id: "search-empty-pattern" 68 | result: 69 | content: 70 | match:arrayElements: 71 | match:partial: 72 | type: "text" 73 | text: "match:contains:pattern must be a non-empty string" 74 | isError: true 75 | stderr: "toBeEmpty" 76 | performance: 77 | maxResponseTime: "800ms" 78 | 79 | - it: "should reject invalid log level with proper error response" 80 | request: 81 | jsonrpc: "2.0" 82 | id: "search-invalid-level" 83 | method: "tools/call" 84 | params: 85 | name: "search_logs" 86 | arguments: 87 | pattern: "INFO" 88 | logLevel: "invalid_level" 89 | expect: 90 | response: 91 | jsonrpc: "2.0" 92 | id: "search-invalid-level" 93 | result: 94 | content: 95 | match:arrayElements: 96 | match:partial: 97 | type: "text" 98 | text: "match:contains:Invalid log level" 99 | isError: true 100 | stderr: "toBeEmpty" 101 | performance: 102 | maxResponseTime: "800ms" 103 | 104 | # Parameter validation tests 105 | - it: "should validate limit parameter bounds" 106 | request: 107 | jsonrpc: "2.0" 108 | id: "search-invalid-limit" 109 | method: "tools/call" 110 | params: 111 | name: "search_logs" 112 | arguments: 113 | pattern: "INFO" 114 | limit: 0 115 | expect: 116 | response: 117 | jsonrpc: "2.0" 118 | id: "search-invalid-limit" 119 | result: 120 | content: 121 | match:arrayElements: 122 | match:partial: 123 | type: "text" 124 | text: "match:contains:Invalid limit" 125 | isError: true 126 | stderr: "toBeEmpty" 127 | performance: 128 | maxResponseTime: "800ms" 129 | 130 | # Content structure validation - key patterns for Aegis testing 131 | - it: "should return properly structured log entries with SFCC patterns" 132 | request: 133 | jsonrpc: "2.0" 134 | id: "search-content-structure" 135 | method: "tools/call" 136 | params: 137 | name: "search_logs" 138 | arguments: 139 | pattern: "SystemJobThread" 140 | limit: 1 141 | expect: 142 | response: 143 | jsonrpc: "2.0" 144 | id: "search-content-structure" 145 | result: 146 | content: 147 | match:arrayElements: 148 | match:partial: 149 | type: "text" 150 | text: "match:regex:(Found \\d+ matches|No matches found)" 151 | isError: false 152 | stderr: "toBeEmpty" 153 | performance: 154 | maxResponseTime: "1500ms" 155 | 156 | # Parameter combination test - ensures Aegis handles multiple params 157 | - it: "should handle combined parameters correctly" 158 | request: 159 | jsonrpc: "2.0" 160 | id: "search-combined-params" 161 | method: "tools/call" 162 | params: 163 | name: "search_logs" 164 | arguments: 165 | pattern: "Sites" 166 | logLevel: "info" 167 | limit: 3 168 | expect: 169 | response: 170 | jsonrpc: "2.0" 171 | id: "search-combined-params" 172 | result: 173 | content: 174 | match:arrayElements: 175 | match:partial: 176 | type: "text" 177 | text: "match:type:string" 178 | isError: false 179 | stderr: "toBeEmpty" 180 | performance: 181 | maxResponseTime: "1500ms" 182 | 183 | # Performance validation - basic SLA testing 184 | - it: "should handle larger result sets within reasonable time" 185 | request: 186 | jsonrpc: "2.0" 187 | id: "search-performance" 188 | method: "tools/call" 189 | params: 190 | name: "search_logs" 191 | arguments: 192 | pattern: "INFO" 193 | limit: 20 194 | expect: 195 | response: 196 | jsonrpc: "2.0" 197 | id: "search-performance" 198 | result: 199 | content: 200 | match:arrayElements: 201 | match:partial: 202 | type: "text" 203 | text: "match:type:string" 204 | isError: false 205 | stderr: "toBeEmpty" 206 | performance: 207 | maxResponseTime: "2000ms" ``` -------------------------------------------------------------------------------- /docs/dw_catalog/ProductVariationAttributeValue.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.catalog 2 | 3 | # Class ProductVariationAttributeValue 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.catalog.ProductVariationAttributeValue 9 | 10 | ## Description 11 | 12 | Represents a product variation attribute 13 | 14 | ## Properties 15 | 16 | ### description 17 | 18 | **Type:** String (Read Only) 19 | 20 | The description of the product variation attribute value in the current locale. 21 | 22 | ### displayValue 23 | 24 | **Type:** String (Read Only) 25 | 26 | The display value for the product variation attribute value, which can be used in the 27 | user interface. 28 | 29 | ### ID 30 | 31 | **Type:** String (Read Only) 32 | 33 | The ID of the product variation attribute value. 34 | 35 | ### value 36 | 37 | **Type:** Object (Read Only) 38 | 39 | The value for the product variation attribute value. 40 | 41 | ## Constructor Summary 42 | 43 | ## Method Summary 44 | 45 | ### equals 46 | 47 | **Signature:** `equals(obj : Object) : boolean` 48 | 49 | Returns true if the specified object is equal to this object. 50 | 51 | ### getDescription 52 | 53 | **Signature:** `getDescription() : String` 54 | 55 | Returns the description of the product variation attribute value in the current locale. 56 | 57 | ### getDisplayValue 58 | 59 | **Signature:** `getDisplayValue() : String` 60 | 61 | Returns the display value for the product variation attribute value, which can be used in the user interface. 62 | 63 | ### getID 64 | 65 | **Signature:** `getID() : String` 66 | 67 | Returns the ID of the product variation attribute value. 68 | 69 | ### getImage 70 | 71 | **Signature:** `getImage(viewtype : String, index : Number) : MediaFile` 72 | 73 | The method calls getImages(String) and returns the image at the specific index. 74 | 75 | ### getImage 76 | 77 | **Signature:** `getImage(viewtype : String) : MediaFile` 78 | 79 | The method calls getImages(String) and returns the first image of the list. 80 | 81 | ### getImages 82 | 83 | **Signature:** `getImages(viewtype : String) : List` 84 | 85 | Returns all images that match the given view type and have the variant value of this value, which is typically the 'color' attribute. 86 | 87 | ### getValue 88 | 89 | **Signature:** `getValue() : Object` 90 | 91 | Returns the value for the product variation attribute value. 92 | 93 | ### hashCode 94 | 95 | **Signature:** `hashCode() : Number` 96 | 97 | Calculates the hash code for a product variation attribute value. 98 | 99 | ## Method Detail 100 | 101 | ## Method Details 102 | 103 | ### equals 104 | 105 | **Signature:** `equals(obj : Object) : boolean` 106 | 107 | **Description:** Returns true if the specified object is equal to this object. 108 | 109 | **Parameters:** 110 | 111 | - `obj`: the object to test. 112 | 113 | **Returns:** 114 | 115 | true if the specified object is equal to this object. 116 | 117 | --- 118 | 119 | ### getDescription 120 | 121 | **Signature:** `getDescription() : String` 122 | 123 | **Description:** Returns the description of the product variation attribute value in the current locale. 124 | 125 | **Returns:** 126 | 127 | the description of the product variation attribute value in the current locale, or null if it wasn't found. 128 | 129 | --- 130 | 131 | ### getDisplayValue 132 | 133 | **Signature:** `getDisplayValue() : String` 134 | 135 | **Description:** Returns the display value for the product variation attribute value, which can be used in the user interface. 136 | 137 | **Returns:** 138 | 139 | the display value for the product variation attribute value, which can be used in the user interface. 140 | 141 | --- 142 | 143 | ### getID 144 | 145 | **Signature:** `getID() : String` 146 | 147 | **Description:** Returns the ID of the product variation attribute value. 148 | 149 | **Returns:** 150 | 151 | the ID of the product variation attribute value. 152 | 153 | --- 154 | 155 | ### getImage 156 | 157 | **Signature:** `getImage(viewtype : String, index : Number) : MediaFile` 158 | 159 | **Description:** The method calls getImages(String) and returns the image at the specific index. If images are defined for this view type and variant, but not for specified index, the method returns null. If no images are defined for this variant and specified view type, the image at the specified index of the master product images is returned. If no master product image for specified index is defined, the method returns null. 160 | 161 | **Parameters:** 162 | 163 | - `viewtype`: the view type annotated to image 164 | - `index`: the index number of the image within image list 165 | 166 | **Returns:** 167 | 168 | the MediaFile or null 169 | 170 | **Throws:** 171 | 172 | NullArgumentException - if viewtype is null 173 | 174 | --- 175 | 176 | ### getImage 177 | 178 | **Signature:** `getImage(viewtype : String) : MediaFile` 179 | 180 | **Description:** The method calls getImages(String) and returns the first image of the list. The method is specifically built for handling color swatches in an apparel site. If no images are defined for this variant and specified view type, then the first image of the master product images for that view type is returned. If no master product images are defined, the method returns null. 181 | 182 | **Parameters:** 183 | 184 | - `viewtype`: the view type annotated to image 185 | 186 | **Returns:** 187 | 188 | the MediaFile or null 189 | 190 | **Throws:** 191 | 192 | NullArgumentException - if viewtype is null 193 | 194 | --- 195 | 196 | ### getImages 197 | 198 | **Signature:** `getImages(viewtype : String) : List` 199 | 200 | **Description:** Returns all images that match the given view type and have the variant value of this value, which is typically the 'color' attribute. The images are returned in the order of their index number ascending. If no images are defined for this variant, then the images of the master for that view type are returned. 201 | 202 | **Parameters:** 203 | 204 | - `viewtype`: the view type annotated to images 205 | 206 | **Returns:** 207 | 208 | a list of MediaFile objects, possibly empty 209 | 210 | **Throws:** 211 | 212 | NullArgumentException - if viewtype is null 213 | 214 | --- 215 | 216 | ### getValue 217 | 218 | **Signature:** `getValue() : Object` 219 | 220 | **Description:** Returns the value for the product variation attribute value. 221 | 222 | **Returns:** 223 | 224 | the value for the product variation attribute value. 225 | 226 | --- 227 | 228 | ### hashCode 229 | 230 | **Signature:** `hashCode() : Number` 231 | 232 | **Description:** Calculates the hash code for a product variation attribute value. 233 | 234 | **Returns:** 235 | 236 | the hash code for a product variation attribute value. 237 | 238 | --- ``` -------------------------------------------------------------------------------- /src/config/dw-json-loader.ts: -------------------------------------------------------------------------------- ```typescript 1 | /** 2 | * Configuration loader for SFCC MCP Server 3 | * 4 | * This module handles secure loading and validation of dw.json files 5 | * with comprehensive security checks for file access. 6 | */ 7 | 8 | import { readFileSync, existsSync, statSync } from 'fs'; 9 | import { resolve, basename, extname } from 'path'; 10 | import { DwJsonConfig } from '../types/types.js'; 11 | 12 | /** 13 | * Validates that a file path is safe to access and prevents path traversal attacks 14 | * 15 | * @param filePath - The file path to validate 16 | * @returns The validated and resolved path 17 | * @throws Error if the path is unsafe 18 | */ 19 | function validateSecurePath(filePath: string): string { 20 | // Prevent null bytes and other dangerous characters 21 | if (filePath.includes('\0') || filePath.includes('\x00')) { 22 | throw new Error('Invalid characters in file path'); 23 | } 24 | 25 | // Prevent excessively long paths that could cause DoS 26 | if (filePath.length > 1000) { 27 | throw new Error('File path too long'); 28 | } 29 | 30 | // Check if file extension is allowed (only .json files) 31 | const ext = extname(filePath).toLowerCase(); 32 | if (ext !== '.json') { 33 | throw new Error('Only .json files are allowed'); 34 | } 35 | 36 | // Normalize the path to prevent path traversal 37 | const resolvedPath = resolve(filePath); 38 | 39 | // Additional check: ensure the resolved path still ends with .json 40 | // This prevents attacks like "file.json/../../../etc/passwd" 41 | if (!resolvedPath.toLowerCase().endsWith('.json')) { 42 | throw new Error('Invalid file path'); 43 | } 44 | 45 | // Prevent access to system directories (additional security layer) 46 | // Allow CI workspace paths like /home/runner/work/ but block sensitive system paths 47 | const dangerousPaths = ['/etc/', '/proc/', '/sys/', '/dev/', '/root/']; 48 | const lowerPath = resolvedPath.toLowerCase(); 49 | 50 | // Check for dangerous system paths 51 | if (dangerousPaths.some(dangerous => lowerPath.includes(dangerous))) { 52 | throw new Error('Access to system directories not allowed'); 53 | } 54 | 55 | // Block /home/ but allow CI workspace paths (/home/runner/work/) 56 | if (lowerPath.includes('/home/') && !lowerPath.includes('/home/runner/work/')) { 57 | throw new Error('Access to system directories not allowed'); 58 | } 59 | 60 | return resolvedPath; 61 | } 62 | 63 | /** 64 | * Validates file size to prevent reading excessively large files 65 | * 66 | * @param filePath - The file path to check 67 | * @throws Error if file is too large 68 | */ 69 | function validateFileSize(filePath: string): void { 70 | try { 71 | const stats = statSync(filePath); 72 | const maxSize = 1024 * 1024; // 1MB limit for config files 73 | 74 | if (stats.size > maxSize) { 75 | throw new Error('Configuration file too large'); 76 | } 77 | } catch (error) { 78 | if (error instanceof Error && error.message === 'Configuration file too large') { 79 | throw error; 80 | } 81 | // Don't expose detailed file system errors 82 | throw new Error('Unable to access configuration file'); 83 | } 84 | } 85 | 86 | /** 87 | * Validates the content of a dw.json configuration 88 | * 89 | * @param dwConfig - The parsed dw.json configuration 90 | * @throws Error if required fields are missing or invalid 91 | */ 92 | function validateDwJsonContent(dwConfig: DwJsonConfig): void { 93 | // Validate required fields 94 | if (!dwConfig.hostname || !dwConfig.username || !dwConfig.password) { 95 | throw new Error('Configuration file must contain hostname, username, and password fields'); 96 | } 97 | 98 | // Additional validation for hostname format (trim whitespace first) 99 | const trimmedHostname = dwConfig.hostname.trim(); 100 | if (!trimmedHostname?.match(/^[a-zA-Z0-9.-]+(?::[0-9]+)?$/)) { 101 | throw new Error('Invalid hostname format in configuration'); 102 | } 103 | } 104 | 105 | /** 106 | * Securely loads and parses a dw.json file with comprehensive validation 107 | * 108 | * This function handles all security aspects of file loading including path validation, 109 | * file size checks, and content validation. It returns the raw parsed JSON without 110 | * any transformation to SFCCConfig format. 111 | * 112 | * @param dwJsonPath - Path to the dw.json file 113 | * @returns Parsed and validated dw.json configuration 114 | * @throws Error if file doesn't exist, is invalid, or fails security checks 115 | */ 116 | export function loadSecureDwJson(dwJsonPath: string): DwJsonConfig { 117 | let resolvedPath: string; 118 | 119 | try { 120 | // Validate and secure the path 121 | resolvedPath = validateSecurePath(dwJsonPath); 122 | } catch (error) { 123 | throw new Error( 124 | `Invalid file path: ${error instanceof Error ? error.message : 'Unknown error'}`, 125 | ); 126 | } 127 | 128 | if (!existsSync(resolvedPath)) { 129 | // Don't expose the full path in error messages for security 130 | throw new Error(`Configuration file not found: ${basename(dwJsonPath)}`); 131 | } 132 | 133 | // Validate file size before reading 134 | try { 135 | validateFileSize(resolvedPath); 136 | } catch (error) { 137 | throw new Error( 138 | `File validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 139 | ); 140 | } 141 | 142 | try { 143 | const dwJsonContent = readFileSync(resolvedPath, 'utf-8'); 144 | 145 | // Additional validation: ensure the content is not empty and doesn't contain suspicious patterns 146 | if (!dwJsonContent.trim()) { 147 | throw new Error('Configuration file is empty'); 148 | } 149 | 150 | // Basic check for potential binary content (null bytes) 151 | if (dwJsonContent.includes('\0')) { 152 | throw new Error('Configuration file contains invalid content'); 153 | } 154 | 155 | const dwConfig: DwJsonConfig = JSON.parse(dwJsonContent); 156 | 157 | // Validate the parsed configuration 158 | validateDwJsonContent(dwConfig); 159 | 160 | return dwConfig; 161 | } catch (error) { 162 | if (error instanceof SyntaxError) { 163 | throw new Error(`Invalid JSON in configuration file: ${error.message}`); 164 | } 165 | throw error; 166 | } 167 | } 168 | ``` -------------------------------------------------------------------------------- /docs/dw_util/Map.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.util 2 | 3 | # Class Map 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.util.Map 9 | 10 | ## Description 11 | 12 | Represents a Map of objects. 13 | 14 | ## Properties 15 | 16 | ### empty 17 | 18 | **Type:** boolean (Read Only) 19 | 20 | Identifies if this map is empty. 21 | 22 | ### length 23 | 24 | **Type:** Number (Read Only) 25 | 26 | The size of the map. This is a bean attribute method and 27 | supports the access to the collections 28 | length similar to a ECMA array, such as 'products.length'. 29 | 30 | ## Constructor Summary 31 | 32 | ## Method Summary 33 | 34 | ### clear 35 | 36 | **Signature:** `clear() : void` 37 | 38 | Clears the map of all objects. 39 | 40 | ### containsKey 41 | 42 | **Signature:** `containsKey(key : Object) : boolean` 43 | 44 | Identifies if this map contains an element identfied by the specified key. 45 | 46 | ### containsValue 47 | 48 | **Signature:** `containsValue(value : Object) : boolean` 49 | 50 | Identifies if this map contains an element identfied by the specified value. 51 | 52 | ### entrySet 53 | 54 | **Signature:** `entrySet() : Set` 55 | 56 | Returns a set of the map's entries. 57 | 58 | ### get 59 | 60 | **Signature:** `get(key : Object) : Object` 61 | 62 | Returns the object associated with the key or null. 63 | 64 | ### getLength 65 | 66 | **Signature:** `getLength() : Number` 67 | 68 | REturns the size of the map. 69 | 70 | ### isEmpty 71 | 72 | **Signature:** `isEmpty() : boolean` 73 | 74 | Identifies if this map is empty. 75 | 76 | ### keySet 77 | 78 | **Signature:** `keySet() : Set` 79 | 80 | Returns a set of the map's keys. 81 | 82 | ### put 83 | 84 | **Signature:** `put(key : Object, value : Object) : Object` 85 | 86 | Puts the specified value into the map using the specified key to identify it. 87 | 88 | ### putAll 89 | 90 | **Signature:** `putAll(other : Map) : void` 91 | 92 | Copies all of the objects inside the specified map into this map. 93 | 94 | ### remove 95 | 96 | **Signature:** `remove(key : Object) : Object` 97 | 98 | Removes the object from the map that is identified by the key. 99 | 100 | ### size 101 | 102 | **Signature:** `size() : Number` 103 | 104 | Returns the size of the map. 105 | 106 | ### values 107 | 108 | **Signature:** `values() : Collection` 109 | 110 | Returns a collection of the values contained in this map. 111 | 112 | ### values 113 | 114 | **Signature:** `values() : Collection` 115 | 116 | Returns a collection of the values contained in this map. 117 | 118 | ## Method Detail 119 | 120 | ## Method Details 121 | 122 | ### clear 123 | 124 | **Signature:** `clear() : void` 125 | 126 | **Description:** Clears the map of all objects. 127 | 128 | --- 129 | 130 | ### containsKey 131 | 132 | **Signature:** `containsKey(key : Object) : boolean` 133 | 134 | **Description:** Identifies if this map contains an element identfied by the specified key. 135 | 136 | **Parameters:** 137 | 138 | - `key`: the key to use. 139 | 140 | **Returns:** 141 | 142 | true if this map contains an element whose key is equal to the specified key. 143 | 144 | --- 145 | 146 | ### containsValue 147 | 148 | **Signature:** `containsValue(value : Object) : boolean` 149 | 150 | **Description:** Identifies if this map contains an element identfied by the specified value. 151 | 152 | **Parameters:** 153 | 154 | - `value`: the value to use. 155 | 156 | **Returns:** 157 | 158 | true if this map contains an element whose value is equal to the specified value. 159 | 160 | --- 161 | 162 | ### entrySet 163 | 164 | **Signature:** `entrySet() : Set` 165 | 166 | **Description:** Returns a set of the map's entries. The returned set is actually a view to the entries of this map. 167 | 168 | **Returns:** 169 | 170 | a set of the map's entries. 171 | 172 | --- 173 | 174 | ### get 175 | 176 | **Signature:** `get(key : Object) : Object` 177 | 178 | **Description:** Returns the object associated with the key or null. 179 | 180 | **Parameters:** 181 | 182 | - `key`: the key to use. 183 | 184 | **Returns:** 185 | 186 | the object associated with the key or null. 187 | 188 | --- 189 | 190 | ### getLength 191 | 192 | **Signature:** `getLength() : Number` 193 | 194 | **Description:** REturns the size of the map. This is a bean attribute method and supports the access to the collections length similar to a ECMA array, such as 'products.length'. 195 | 196 | **Returns:** 197 | 198 | the number of objects in the map. 199 | 200 | --- 201 | 202 | ### isEmpty 203 | 204 | **Signature:** `isEmpty() : boolean` 205 | 206 | **Description:** Identifies if this map is empty. 207 | 208 | **Returns:** 209 | 210 | true if the map is empty, false otherwise. 211 | 212 | --- 213 | 214 | ### keySet 215 | 216 | **Signature:** `keySet() : Set` 217 | 218 | **Description:** Returns a set of the map's keys. The returned set is actually a view to the keys of this map. 219 | 220 | **Returns:** 221 | 222 | a set of the map's keys. 223 | 224 | --- 225 | 226 | ### put 227 | 228 | **Signature:** `put(key : Object, value : Object) : Object` 229 | 230 | **Description:** Puts the specified value into the map using the specified key to identify it. 231 | 232 | **Parameters:** 233 | 234 | - `key`: the key to use to identify the value. 235 | - `value`: the object to put into the map. 236 | 237 | **Returns:** 238 | 239 | previous value associated with specified key, or null if there was no mapping for key. 240 | 241 | --- 242 | 243 | ### putAll 244 | 245 | **Signature:** `putAll(other : Map) : void` 246 | 247 | **Description:** Copies all of the objects inside the specified map into this map. 248 | 249 | **Parameters:** 250 | 251 | - `other`: the map whose contents are copied into this map. 252 | 253 | --- 254 | 255 | ### remove 256 | 257 | **Signature:** `remove(key : Object) : Object` 258 | 259 | **Description:** Removes the object from the map that is identified by the key. 260 | 261 | **Parameters:** 262 | 263 | - `key`: the key that identifies the object to remove. 264 | 265 | **Returns:** 266 | 267 | the removed object or null. 268 | 269 | --- 270 | 271 | ### size 272 | 273 | **Signature:** `size() : Number` 274 | 275 | **Description:** Returns the size of the map. 276 | 277 | **Returns:** 278 | 279 | the number of objects in the map. 280 | 281 | --- 282 | 283 | ### values 284 | 285 | **Signature:** `values() : Collection` 286 | 287 | **Description:** Returns a collection of the values contained in this map. 288 | 289 | **API Versioned:** 290 | 291 | No longer available as of version 16.1. Returns an independent modifiable collection holding all values. 292 | 293 | **Returns:** 294 | 295 | a collection of the values contained in this map 296 | 297 | --- 298 | 299 | ### values 300 | 301 | **Signature:** `values() : Collection` 302 | 303 | **Description:** Returns a collection of the values contained in this map. 304 | 305 | **API Versioned:** 306 | 307 | From version 16.1. Returns a view on the values of this map like keySet() and entrySet() do. Former version returned a shallow copy of this. 308 | 309 | **Returns:** 310 | 311 | a collection of the values contained in this map 312 | 313 | --- ``` -------------------------------------------------------------------------------- /docs/dw_campaign/Discount.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.campaign 2 | 3 | # Class Discount 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.campaign.Discount 9 | 10 | ## Description 11 | 12 | Superclass of all specific discount classes. 13 | 14 | ## Constants 15 | 16 | ### TYPE_AMOUNT 17 | 18 | **Type:** String = "AMOUNT" 19 | 20 | Constant representing discounts of type amount. 21 | 22 | ### TYPE_BONUS 23 | 24 | **Type:** String = "BONUS" 25 | 26 | Constant representing discounts of type bonus. 27 | 28 | ### TYPE_BONUS_CHOICE 29 | 30 | **Type:** String = "BONUS_CHOICE" 31 | 32 | Constant representing discounts of type bonus choice. 33 | 34 | ### TYPE_FIXED_PRICE 35 | 36 | **Type:** String = "FIXED_PRICE" 37 | 38 | Constant representing discounts of type fixed-price. 39 | 40 | ### TYPE_FIXED_PRICE_SHIPPING 41 | 42 | **Type:** String = "FIXED_PRICE_SHIPPING" 43 | 44 | Constant representing discounts of type fixed price shipping. 45 | 46 | ### TYPE_FREE 47 | 48 | **Type:** String = "FREE" 49 | 50 | Constant representing discounts of type free. 51 | 52 | ### TYPE_FREE_SHIPPING 53 | 54 | **Type:** String = "FREE_SHIPPING" 55 | 56 | Constant representing discounts of type free shipping. 57 | 58 | ### TYPE_PERCENTAGE 59 | 60 | **Type:** String = "PERCENTAGE" 61 | 62 | Constant representing discounts of type percentage. 63 | 64 | ### TYPE_PERCENTAGE_OFF_OPTIONS 65 | 66 | **Type:** String = "PERCENTAGE_OFF_OPTIONS" 67 | 68 | Constant representing discounts of type percent off options. 69 | 70 | ### TYPE_PRICEBOOK_PRICE 71 | 72 | **Type:** String = "PRICE_BOOK_PRICE" 73 | 74 | Constant representing discounts of type price book price. 75 | 76 | ### TYPE_TOTAL_FIXED_PRICE 77 | 78 | **Type:** String = "TOTAL_FIXED_PRICE" 79 | 80 | Constant representing discounts of type total fixed price. 81 | 82 | ## Properties 83 | 84 | ### itemPromotionTiers 85 | 86 | **Type:** Map (Read Only) 87 | 88 | The tier index by quantity Id of Product promotion. ProductLineItems may have more than one quantity, but 89 | not all items of that SKU may have received the same tier of promotion. Each quantity of the ProductLineItem is 90 | indexed from 1 to n, where n is the quantity of the ProductLineItem, and this method returns a mapping from that 91 | quantity index to the index of tier of the promotion that item received. For more information about tier indexes, 92 | see getPromotionTier() method. 93 | 94 | ### promotion 95 | 96 | **Type:** Promotion (Read Only) 97 | 98 | The promotion this discount is based on. 99 | 100 | ### promotionTier 101 | 102 | **Type:** Number (Read Only) 103 | 104 | The tier index for promotion at order level or bonus product. 105 | Promotion tiers are always evaluated in the order of the highest threshold (e.g. quantity, or amount) 106 | to the lowest threshold. The tier that is evaluated first (i.e. the highest quantity or amount) is indexed as 0, 107 | the next tier 1, etc. The lowest tier will have index n - 1, where n is the total number of tiers. 108 | 109 | ### quantity 110 | 111 | **Type:** Number (Read Only) 112 | 113 | The quantity of the discount. This quantity specifies how often 114 | this discount applies to its target object. For example, a 10% off 115 | discount with quantity 2 associated to a product line item with 116 | quantity 3 is applied to two items of the product line item. 117 | Discounts of order and shipping promotions, and bonus discounts 118 | have a fix quantity of 1. 119 | 120 | ### type 121 | 122 | **Type:** String (Read Only) 123 | 124 | The type of the discount. 125 | 126 | ## Constructor Summary 127 | 128 | ## Method Summary 129 | 130 | ### getItemPromotionTiers 131 | 132 | **Signature:** `getItemPromotionTiers() : Map` 133 | 134 | Returns the tier index by quantity Id of Product promotion. 135 | 136 | ### getPromotion 137 | 138 | **Signature:** `getPromotion() : Promotion` 139 | 140 | Returns the promotion this discount is based on. 141 | 142 | ### getPromotionTier 143 | 144 | **Signature:** `getPromotionTier() : Number` 145 | 146 | Returns the tier index for promotion at order level or bonus product. 147 | 148 | ### getQuantity 149 | 150 | **Signature:** `getQuantity() : Number` 151 | 152 | Returns the quantity of the discount. 153 | 154 | ### getType 155 | 156 | **Signature:** `getType() : String` 157 | 158 | Returns the type of the discount. 159 | 160 | ## Method Detail 161 | 162 | ## Method Details 163 | 164 | ### getItemPromotionTiers 165 | 166 | **Signature:** `getItemPromotionTiers() : Map` 167 | 168 | **Description:** Returns the tier index by quantity Id of Product promotion. ProductLineItems may have more than one quantity, but not all items of that SKU may have received the same tier of promotion. Each quantity of the ProductLineItem is indexed from 1 to n, where n is the quantity of the ProductLineItem, and this method returns a mapping from that quantity index to the index of tier of the promotion that item received. For more information about tier indexes, see getPromotionTier() method. 169 | 170 | **Returns:** 171 | 172 | Map of Tier index by quantity Id or empty map 173 | 174 | **See Also:** 175 | 176 | getPromotionTier() 177 | 178 | --- 179 | 180 | ### getPromotion 181 | 182 | **Signature:** `getPromotion() : Promotion` 183 | 184 | **Description:** Returns the promotion this discount is based on. 185 | 186 | **Returns:** 187 | 188 | Promotion related to this discount 189 | 190 | --- 191 | 192 | ### getPromotionTier 193 | 194 | **Signature:** `getPromotionTier() : Number` 195 | 196 | **Description:** Returns the tier index for promotion at order level or bonus product. Promotion tiers are always evaluated in the order of the highest threshold (e.g. quantity, or amount) to the lowest threshold. The tier that is evaluated first (i.e. the highest quantity or amount) is indexed as 0, the next tier 1, etc. The lowest tier will have index n - 1, where n is the total number of tiers. 197 | 198 | **Returns:** 199 | 200 | Tier index or null 201 | 202 | --- 203 | 204 | ### getQuantity 205 | 206 | **Signature:** `getQuantity() : Number` 207 | 208 | **Description:** Returns the quantity of the discount. This quantity specifies how often this discount applies to its target object. For example, a 10% off discount with quantity 2 associated to a product line item with quantity 3 is applied to two items of the product line item. Discounts of order and shipping promotions, and bonus discounts have a fix quantity of 1. 209 | 210 | **Returns:** 211 | 212 | Discount quantity 213 | 214 | --- 215 | 216 | ### getType 217 | 218 | **Signature:** `getType() : String` 219 | 220 | **Description:** Returns the type of the discount. 221 | 222 | **Returns:** 223 | 224 | Discount type 225 | 226 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/search-system-object-attribute-definitions.docs-only.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | # ================================================================================== 2 | # SFCC MCP Server - search_system_object_attribute_definitions Tool YAML Tests (Docs-Only Mode) 3 | # Validates that system object search tools are NOT available in docs-only mode 4 | # This tool requires SFCC credentials and should not be available without them 5 | # 6 | # Quick Test Commands: 7 | # aegis "tests/mcp/yaml/search-system-object-attribute-definitions.docs-only.test.mcp.yml" --config "aegis.config.docs-only.json" --verbose 8 | # aegis query search_system_object_attribute_definitions '{"objectType": "Product", "searchRequest": {"query": {"match_all_query": {}}}}' --config "aegis.config.docs-only.json" 9 | # ================================================================================== 10 | 11 | description: "search_system_object_attribute_definitions tool docs-only mode tests - Tool unavailability validation" 12 | 13 | tests: 14 | # ================================================================================== 15 | # TOOL UNAVAILABILITY IN DOCS-ONLY MODE 16 | # ================================================================================== 17 | - it: "should NOT list search_system_object_attribute_definitions tool in docs-only mode" 18 | request: 19 | jsonrpc: "2.0" 20 | id: "tool-not-available-docs" 21 | method: "tools/list" 22 | params: {} 23 | expect: 24 | response: 25 | jsonrpc: "2.0" 26 | id: "tool-not-available-docs" 27 | result: 28 | tools: 29 | match:arrayElements: 30 | match:partial: 31 | name: "match:type:string" 32 | description: "match:type:string" 33 | match:extractField: "tools.*.name" 34 | value: "match:not:arrayContains:search_system_object_attribute_definitions" 35 | stderr: "toBeEmpty" 36 | 37 | # ================================================================================== 38 | # AUTHENTICATION ERROR TESTS (Tool Can Be Called But Returns Error) 39 | # ================================================================================== 40 | - it: "should return authentication error when calling search_system_object_attribute_definitions in docs-only mode" 41 | request: 42 | jsonrpc: "2.0" 43 | id: "auth-error-product" 44 | method: "tools/call" 45 | params: 46 | name: "search_system_object_attribute_definitions" 47 | arguments: 48 | objectType: "Product" 49 | searchRequest: 50 | query: 51 | match_all_query: {} 52 | expect: 53 | response: 54 | jsonrpc: "2.0" 55 | id: "auth-error-product" 56 | result: 57 | content: 58 | - type: "text" 59 | text: "match:contains:OCAPI client not configured" 60 | isError: true 61 | performance: 62 | maxResponseTime: "500ms" 63 | stderr: "toBeEmpty" 64 | 65 | - it: "should return authentication error for text query search requests" 66 | request: 67 | jsonrpc: "2.0" 68 | id: "auth-error-text-query" 69 | method: "tools/call" 70 | params: 71 | name: "search_system_object_attribute_definitions" 72 | arguments: 73 | objectType: "Customer" 74 | searchRequest: 75 | query: 76 | text_query: 77 | fields: ["id", "display_name"] 78 | search_phrase: "test" 79 | expect: 80 | response: 81 | jsonrpc: "2.0" 82 | id: "auth-error-text-query" 83 | result: 84 | content: 85 | - type: "text" 86 | text: "match:contains:credentials are provided" 87 | isError: true 88 | performance: 89 | maxResponseTime: "500ms" 90 | stderr: "toBeEmpty" 91 | 92 | - it: "should return authentication error for term query requests" 93 | request: 94 | jsonrpc: "2.0" 95 | id: "auth-error-term-query" 96 | method: "tools/call" 97 | params: 98 | name: "search_system_object_attribute_definitions" 99 | arguments: 100 | objectType: "Order" 101 | searchRequest: 102 | query: 103 | term_query: 104 | fields: ["value_type"] 105 | operator: "is" 106 | values: ["string"] 107 | expect: 108 | response: 109 | jsonrpc: "2.0" 110 | id: "auth-error-term-query" 111 | result: 112 | content: 113 | - type: "text" 114 | text: "match:contains:full mode" 115 | isError: true 116 | performance: 117 | maxResponseTime: "500ms" 118 | stderr: "toBeEmpty" 119 | 120 | - it: "should handle malformed parameters with same authentication error" 121 | request: 122 | jsonrpc: "2.0" 123 | id: "auth-error-malformed" 124 | method: "tools/call" 125 | params: 126 | name: "search_system_object_attribute_definitions" 127 | arguments: 128 | invalidParam: "test" 129 | expect: 130 | response: 131 | jsonrpc: "2.0" 132 | id: "auth-error-malformed" 133 | result: 134 | content: 135 | - type: "text" 136 | text: "match:contains:OCAPI client not configured" 137 | isError: true 138 | performance: 139 | maxResponseTime: "500ms" 140 | stderr: "toBeEmpty" 141 | 142 | # ================================================================================== 143 | # CONSISTENT ERROR RESPONSE VALIDATION 144 | # ================================================================================== 145 | - it: "should consistently return isError: true for all docs-only calls" 146 | request: 147 | jsonrpc: "2.0" 148 | id: "consistent-error-flag" 149 | method: "tools/call" 150 | params: 151 | name: "search_system_object_attribute_definitions" 152 | arguments: 153 | objectType: "Site" 154 | searchRequest: 155 | query: 156 | match_all_query: {} 157 | expect: 158 | response: 159 | jsonrpc: "2.0" 160 | id: "consistent-error-flag" 161 | result: 162 | content: 163 | - type: "text" 164 | text: "match:type:string" 165 | isError: true 166 | performance: 167 | maxResponseTime: "500ms" 168 | stderr: "toBeEmpty" ``` -------------------------------------------------------------------------------- /docs/sfra/stores.md: -------------------------------------------------------------------------------- ```markdown 1 | # SFRA Stores Model 2 | 3 | ## Overview 4 | 5 | The Stores model represents a collection of store locations in SFRA applications. It provides store locator functionality, map integration capabilities, and formatted store information for display in store finder interfaces. 6 | 7 | ## Constructor 8 | 9 | ```javascript 10 | function stores(storesResultsObject, searchKey, searchRadius, actionUrl, apiKey) 11 | ``` 12 | 13 | Creates a Stores model instance with store collection and search parameters. 14 | 15 | ### Parameters 16 | 17 | - `storesResultsObject` (dw.util.Set) - A set of dw.catalog.Store objects 18 | - `searchKey` (Object) - What the user searched by (location or postal code) 19 | - `searchRadius` (number) - The radius used in the search 20 | - `actionUrl` (dw.web.URL) - A relative URL for the search action 21 | - `apiKey` (string) - The Google Maps API key that is set in site preferences 22 | 23 | ## Properties 24 | 25 | ### stores 26 | **Type:** Array<StoreModel> 27 | 28 | Array of individual store models, each containing complete store information including location, contact details, and hours. 29 | 30 | ### searchKey 31 | **Type:** Object 32 | 33 | The search term or location used to find the stores (e.g., ZIP code, address, city). 34 | 35 | ### radius 36 | **Type:** number 37 | 38 | The search radius in miles/kilometers used to limit store results. 39 | 40 | ### actionUrl 41 | **Type:** dw.web.URL 42 | 43 | A relative URL for the search action. 44 | 45 | ### googleMapsApi 46 | **Type:** string | null 47 | 48 | URL for Google Maps API integration, or null if no API key is configured. 49 | 50 | ### radiusOptions 51 | **Type:** Array<number> 52 | 53 | Array of available radius options: [15, 30, 50, 100, 300]. 54 | 55 | ### storesResultsHtml 56 | **Type:** string | null 57 | 58 | HTML-formatted string of store results for display, or null if no stores found. 59 | 60 | ### locations 61 | **Type:** string 62 | 63 | JSON stringified array of location objects optimized for map display. Each location contains: 64 | - `name` (string) - Store name 65 | - `latitude` (number) - Geographic latitude 66 | - `longitude` (number) - Geographic longitude 67 | - `infoWindowHtml` (string) - Rendered HTML for map info windows 68 | 69 | ## Helper Functions 70 | 71 | ### createStoresObject(storesObject) 72 | Converts a set of store objects into an array of StoreModel instances. 73 | 74 | **Parameters:** 75 | - `storesObject` (dw.util.Set) - Set of dw.catalog.Store objects 76 | 77 | **Returns:** Array<StoreModel> - Array of formatted store models 78 | 79 | ### createGeoLocationObject(storesObject) 80 | Creates location objects with coordinates and rendered info window HTML for map display. 81 | 82 | **Parameters:** 83 | - `storesObject` (dw.util.Set) - Set of dw.catalog.Store objects 84 | 85 | **Returns:** Array<Object> - Array of location objects with map data 86 | 87 | ### getGoogleMapsApi(apiKey) 88 | Constructs Google Maps API URL if API key is available. 89 | 90 | **Parameters:** 91 | - `apiKey` (string) - Google Maps API key 92 | 93 | **Returns:** string | null - Complete API URL or null if no key 94 | 95 | ## Usage Example 96 | 97 | ```javascript 98 | var stores = require('*/cartridge/models/stores'); 99 | var storeHelpers = require('*/cartridge/scripts/helpers/storeHelpers'); 100 | 101 | // Search for stores 102 | var searchResults = storeHelpers.findStores('10001', 25); 103 | var apiKey = Site.getCurrent().getCustomPreferenceValue('googleMapsApiKey'); 104 | var actionUrl = URLUtils.url('Stores-FindStores'); 105 | 106 | var storesModel = new stores( 107 | searchResults.stores, 108 | '10001', 109 | 25, 110 | actionUrl, 111 | apiKey 112 | ); 113 | 114 | // Access store collection 115 | console.log('Found ' + storesModel.stores.length + ' stores'); 116 | console.log('Search: ' + storesModel.searchKey + ' within ' + storesModel.radius + ' miles'); 117 | 118 | // Parse JSON locations for map 119 | var locations = JSON.parse(storesModel.locations); 120 | 121 | // Iterate through stores 122 | storesModel.stores.forEach(function(store) { 123 | console.log(store.name + ' - ' + store.city); 124 | }); 125 | 126 | // Use for map integration 127 | if (storesModel.googleMapsApi) { 128 | // Load Google Maps with locations 129 | var locations = JSON.parse(storesModel.locations); 130 | locations.forEach(function(location) { 131 | // Add markers to map using latitude/longitude 132 | // Use infoWindowHtml for marker popups 133 | }); 134 | } 135 | 136 | // Display pre-rendered HTML results 137 | if (storesModel.storesResultsHtml) { 138 | // Use the pre-rendered HTML for store display 139 | } 140 | ``` 141 | 142 | ## Map Integration 143 | 144 | The model provides comprehensive mapping support: 145 | 146 | ### Google Maps Integration 147 | - **googleMapsApi** - Ready-to-use API URL 148 | - **locations** - JSON string of coordinates with info windows (needs parsing) 149 | - **infoWindowHtml** - Pre-rendered HTML for map popups 150 | 151 | ### Location Data Structure 152 | Each location object (after JSON parsing) includes: 153 | - Geographic coordinates for marker placement 154 | - Store name for marker labels 155 | - Rendered HTML content for info windows 156 | 157 | ## Search Context 158 | 159 | The model preserves search context: 160 | - **searchKey** - Original search term for reference 161 | - **radius** - Search distance for display and refinement 162 | - **actionUrl** - URL for additional search actions 163 | - **radiusOptions** - Available radius choices for refinement 164 | - Enables search result pagination and refinement 165 | 166 | ## Template Integration 167 | 168 | Info windows use the `storeLocator/storeInfoWindow` template: 169 | - Consistent store information display 170 | - Customizable popup content 171 | - Integrated with SFRA template system 172 | 173 | ## Notes 174 | 175 | - Converts SFCC store objects to structured models 176 | - Provides map-ready coordinate data as JSON string 177 | - Includes pre-rendered HTML for info windows and store results 178 | - Supports Google Maps API integration 179 | - Maintains search context for user reference 180 | - Includes predefined radius options for search refinement 181 | - Handles missing API keys gracefully 182 | - Optimized for store locator interfaces 183 | - Uses storeHelpers.createStoresResultsHtml for consistent display 184 | 185 | ## Related Models 186 | 187 | - **StoreModel** - Individual store representation 188 | - **Search Models** - May include store search results 189 | - **Address Models** - Similar location structure 190 | - **Product Models** - May include store availability 191 | ``` -------------------------------------------------------------------------------- /docs/dw_customer/CustomerPaymentInstrument.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.customer 2 | 3 | # Class CustomerPaymentInstrument 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.object.PersistentObject 9 | - dw.object.ExtensibleObject 10 | - dw.customer.EncryptedObject 11 | - dw.order.PaymentInstrument 12 | - dw.customer.CustomerPaymentInstrument 13 | 14 | ## Description 15 | 16 | Represents any payment instrument stored in the customers profile, such as credit card or bank transfer. The object defines standard methods for credit card payment, and can be extended by attributes appropriate for other payment methods. 17 | 18 | ## Properties 19 | 20 | ### bankAccountDriversLicense 21 | 22 | **Type:** String (Read Only) 23 | 24 | The driver's license number of the bank account number 25 | if the calling context meets the following criteria: 26 | 27 | 28 | If the method call happens in the context of a storefront request and 29 | the current customer is registered and authenticated, and the payment 30 | instrument is associated to the profile of the current customer, and 31 | the current protocol is HTTPS 32 | 33 | 34 | Otherwise, the method returns the masked driver's license number of the bank account. 35 | 36 | Note: this method handles sensitive financial and card holder data. 37 | Pay special attention to PCI DSS v3. requirements 1, 3, 7, and 9. 38 | 39 | ### bankAccountNumber 40 | 41 | **Type:** String (Read Only) 42 | 43 | The bank account number if the calling context meets 44 | the following criteria: 45 | 46 | 47 | If the method call happens in the context of a storefront request, 48 | the current customer is registered and authenticated, the payment 49 | instrument is associated to the profile of the current customer, and 50 | the current protocol is HTTPS 51 | 52 | 53 | Otherwise, the method returns the masked bank account number. 54 | 55 | Note: this method handles sensitive financial and card holder data. 56 | Pay special attention to PCI DSS v3. requirements 1, 3, 7, and 9. 57 | 58 | ### creditCardNumber 59 | 60 | **Type:** String (Read Only) 61 | 62 | The decrypted credit card number if the calling context meets 63 | the following criteria: 64 | 65 | 66 | If the method call happens in the context of a storefront request, 67 | the current customer is registered and authenticated, the payment 68 | instrument is associated to the profile of the current customer, and 69 | the current protocol is HTTPS. 70 | 71 | 72 | Otherwise, the method returns the masked credit card number. 73 | 74 | Note: this method handles sensitive financial and card holder data. 75 | Pay special attention to PCI DSS v3. requirements 1, 3, 7, and 9. 76 | 77 | ## Constructor Summary 78 | 79 | ## Method Summary 80 | 81 | ### getBankAccountDriversLicense 82 | 83 | **Signature:** `getBankAccountDriversLicense() : String` 84 | 85 | Returns the driver's license number of the bank account number if the calling context meets the following criteria: If the method call happens in the context of a storefront request and the current customer is registered and authenticated, and the payment instrument is associated to the profile of the current customer, and the current protocol is HTTPS Otherwise, the method returns the masked driver's license number of the bank account. 86 | 87 | ### getBankAccountNumber 88 | 89 | **Signature:** `getBankAccountNumber() : String` 90 | 91 | Returns the bank account number if the calling context meets the following criteria: If the method call happens in the context of a storefront request, the current customer is registered and authenticated, the payment instrument is associated to the profile of the current customer, and the current protocol is HTTPS Otherwise, the method returns the masked bank account number. 92 | 93 | ### getCreditCardNumber 94 | 95 | **Signature:** `getCreditCardNumber() : String` 96 | 97 | Returns the decrypted credit card number if the calling context meets the following criteria: If the method call happens in the context of a storefront request, the current customer is registered and authenticated, the payment instrument is associated to the profile of the current customer, and the current protocol is HTTPS. 98 | 99 | ## Method Detail 100 | 101 | ## Method Details 102 | 103 | ### getBankAccountDriversLicense 104 | 105 | **Signature:** `getBankAccountDriversLicense() : String` 106 | 107 | **Description:** Returns the driver's license number of the bank account number if the calling context meets the following criteria: If the method call happens in the context of a storefront request and the current customer is registered and authenticated, and the payment instrument is associated to the profile of the current customer, and the current protocol is HTTPS Otherwise, the method returns the masked driver's license number of the bank account. Note: this method handles sensitive financial and card holder data. Pay special attention to PCI DSS v3. requirements 1, 3, 7, and 9. 108 | 109 | --- 110 | 111 | ### getBankAccountNumber 112 | 113 | **Signature:** `getBankAccountNumber() : String` 114 | 115 | **Description:** Returns the bank account number if the calling context meets the following criteria: If the method call happens in the context of a storefront request, the current customer is registered and authenticated, the payment instrument is associated to the profile of the current customer, and the current protocol is HTTPS Otherwise, the method returns the masked bank account number. Note: this method handles sensitive financial and card holder data. Pay special attention to PCI DSS v3. requirements 1, 3, 7, and 9. 116 | 117 | --- 118 | 119 | ### getCreditCardNumber 120 | 121 | **Signature:** `getCreditCardNumber() : String` 122 | 123 | **Description:** Returns the decrypted credit card number if the calling context meets the following criteria: If the method call happens in the context of a storefront request, the current customer is registered and authenticated, the payment instrument is associated to the profile of the current customer, and the current protocol is HTTPS. Otherwise, the method returns the masked credit card number. Note: this method handles sensitive financial and card holder data. Pay special attention to PCI DSS v3. requirements 1, 3, 7, and 9. 124 | 125 | --- ``` -------------------------------------------------------------------------------- /docs/dw_system/Logger.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.system 2 | 3 | # Class Logger 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.system.Logger 9 | 10 | ## Description 11 | 12 | The Logger class provides logging utility methods. 13 | 14 | ## Properties 15 | 16 | ### debugEnabled 17 | 18 | **Type:** boolean (Read Only) 19 | 20 | This method returns true if debug logging is enabled. 21 | 22 | ### errorEnabled 23 | 24 | **Type:** boolean (Read Only) 25 | 26 | This method returns true if error logging is enabled. 27 | 28 | ### infoEnabled 29 | 30 | **Type:** boolean (Read Only) 31 | 32 | This method returns true if info logging is enabled. 33 | 34 | ### rootLogger 35 | 36 | **Type:** Log (Read Only) 37 | 38 | The root logger object. 39 | 40 | ### warnEnabled 41 | 42 | **Type:** boolean (Read Only) 43 | 44 | This method returns true if warning logging is enabled. 45 | 46 | ## Constructor Summary 47 | 48 | ## Method Summary 49 | 50 | ### debug 51 | 52 | **Signature:** `static debug(msg : String, args : Object...) : void` 53 | 54 | The method reports an debug level message. 55 | 56 | ### error 57 | 58 | **Signature:** `static error(msg : String, args : Object...) : void` 59 | 60 | The method reports an error level message. 61 | 62 | ### getLogger 63 | 64 | **Signature:** `static getLogger(category : String) : Log` 65 | 66 | Returns the logger object for the given category. 67 | 68 | ### getLogger 69 | 70 | **Signature:** `static getLogger(fileNamePrefix : String, category : String) : Log` 71 | 72 | Returns the logger object for the given file name prefix and category. 73 | 74 | ### getRootLogger 75 | 76 | **Signature:** `static getRootLogger() : Log` 77 | 78 | Returns the root logger object. 79 | 80 | ### info 81 | 82 | **Signature:** `static info(msg : String, args : Object...) : void` 83 | 84 | The method reports an information level message. 85 | 86 | ### isDebugEnabled 87 | 88 | **Signature:** `static isDebugEnabled() : boolean` 89 | 90 | This method returns true if debug logging is enabled. 91 | 92 | ### isErrorEnabled 93 | 94 | **Signature:** `static isErrorEnabled() : boolean` 95 | 96 | This method returns true if error logging is enabled. 97 | 98 | ### isInfoEnabled 99 | 100 | **Signature:** `static isInfoEnabled() : boolean` 101 | 102 | This method returns true if info logging is enabled. 103 | 104 | ### isWarnEnabled 105 | 106 | **Signature:** `static isWarnEnabled() : boolean` 107 | 108 | This method returns true if warning logging is enabled. 109 | 110 | ### warn 111 | 112 | **Signature:** `static warn(msg : String, args : Object...) : void` 113 | 114 | The method reports an warning level message. 115 | 116 | ## Method Detail 117 | 118 | ## Method Details 119 | 120 | ### debug 121 | 122 | **Signature:** `static debug(msg : String, args : Object...) : void` 123 | 124 | **Description:** The method reports an debug level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 125 | 126 | **Parameters:** 127 | 128 | - `msg`: the message to log. 129 | - `args`: the arguments to insert into the message. 130 | 131 | --- 132 | 133 | ### error 134 | 135 | **Signature:** `static error(msg : String, args : Object...) : void` 136 | 137 | **Description:** The method reports an error level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 138 | 139 | **Parameters:** 140 | 141 | - `msg`: the message to log. 142 | - `args`: the arguments to insert into the message. 143 | 144 | --- 145 | 146 | ### getLogger 147 | 148 | **Signature:** `static getLogger(category : String) : Log` 149 | 150 | **Description:** Returns the logger object for the given category. 151 | 152 | **Parameters:** 153 | 154 | - `category`: - the category to get the logger for 155 | 156 | **Returns:** 157 | 158 | the logger object for the given category. 159 | 160 | --- 161 | 162 | ### getLogger 163 | 164 | **Signature:** `static getLogger(fileNamePrefix : String, category : String) : Log` 165 | 166 | **Description:** Returns the logger object for the given file name prefix and category. Throws an exception if maximum number of custom log files per day has already been obtained. 167 | 168 | **Parameters:** 169 | 170 | - `fileNamePrefix`: - the file name prefix to identify the logger must not be null or an empty string, must be at least 3 characters long, can contain characters a-z A-Z 0-9 '-' '_' only, can have up to 25 characters must not start or end with '-' or '_' can only start or end with a-z A-Z 0-9 171 | - `category`: - the category to get the logger for, must not be null 172 | 173 | **Returns:** 174 | 175 | the logger object for the given category. 176 | 177 | --- 178 | 179 | ### getRootLogger 180 | 181 | **Signature:** `static getRootLogger() : Log` 182 | 183 | **Description:** Returns the root logger object. 184 | 185 | **Returns:** 186 | 187 | the root logger object. 188 | 189 | --- 190 | 191 | ### info 192 | 193 | **Signature:** `static info(msg : String, args : Object...) : void` 194 | 195 | **Description:** The method reports an information level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 196 | 197 | **Parameters:** 198 | 199 | - `msg`: the message to log. 200 | - `args`: the arguments to insert into the message. 201 | 202 | --- 203 | 204 | ### isDebugEnabled 205 | 206 | **Signature:** `static isDebugEnabled() : boolean` 207 | 208 | **Description:** This method returns true if debug logging is enabled. 209 | 210 | **Returns:** 211 | 212 | true if logging of debug messages is enabled, false otherwise. 213 | 214 | --- 215 | 216 | ### isErrorEnabled 217 | 218 | **Signature:** `static isErrorEnabled() : boolean` 219 | 220 | **Description:** This method returns true if error logging is enabled. 221 | 222 | **Returns:** 223 | 224 | true if logging of error messages is enabled, false otherwise. 225 | 226 | --- 227 | 228 | ### isInfoEnabled 229 | 230 | **Signature:** `static isInfoEnabled() : boolean` 231 | 232 | **Description:** This method returns true if info logging is enabled. 233 | 234 | **Returns:** 235 | 236 | true if logging of info messages is enabled, false otherwise. 237 | 238 | --- 239 | 240 | ### isWarnEnabled 241 | 242 | **Signature:** `static isWarnEnabled() : boolean` 243 | 244 | **Description:** This method returns true if warning logging is enabled. 245 | 246 | **Returns:** 247 | 248 | true if logging of warn messages is enabled, false otherwise. 249 | 250 | --- 251 | 252 | ### warn 253 | 254 | **Signature:** `static warn(msg : String, args : Object...) : void` 255 | 256 | **Description:** The method reports an warning level message. Arguments can be embedded into the message, e.g. like "Failure {0} in {1}". The method implements the Java MessageFormat.format() syntax. 257 | 258 | **Parameters:** 259 | 260 | - `msg`: the message to log. 261 | - `args`: the arguments to insert into the message. 262 | 263 | --- ``` -------------------------------------------------------------------------------- /docs/dw_order/ShippingMgr.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.order 2 | 3 | # Class ShippingMgr 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.order.ShippingMgr 9 | 10 | ## Description 11 | 12 | Provides methods to access the shipping information. 13 | 14 | ## Properties 15 | 16 | ### allShippingMethods 17 | 18 | **Type:** Collection (Read Only) 19 | 20 | The active shipping methods of the current site applicable to the session currency and current customer group. 21 | 22 | ### defaultShippingMethod 23 | 24 | **Type:** ShippingMethod (Read Only) 25 | 26 | The default shipping method of the current site applicable to the session currency. 27 | 28 | Does an additional check if there is a base method and if their currencies are 29 | the same. Returns NULL if the two currencies are different. 30 | 31 | ## Constructor Summary 32 | 33 | ## Method Summary 34 | 35 | ### applyShippingCost 36 | 37 | **Signature:** `static applyShippingCost(lineItemCtnr : LineItemCtnr) : void` 38 | 39 | Applies product and shipment-level shipping cost to the specified line item container. 40 | 41 | ### getAllShippingMethods 42 | 43 | **Signature:** `static getAllShippingMethods() : Collection` 44 | 45 | Returns the active shipping methods of the current site applicable to the session currency and current customer group. 46 | 47 | ### getDefaultShippingMethod 48 | 49 | **Signature:** `static getDefaultShippingMethod() : ShippingMethod` 50 | 51 | Returns the default shipping method of the current site applicable to the session currency. 52 | 53 | ### getProductShippingModel 54 | 55 | **Signature:** `static getProductShippingModel(product : Product) : ProductShippingModel` 56 | 57 | Returns the shipping model for the specified product. 58 | 59 | ### getShipmentShippingModel 60 | 61 | **Signature:** `static getShipmentShippingModel(shipment : Shipment) : ShipmentShippingModel` 62 | 63 | Returns the shipping model for the specified shipment. 64 | 65 | ### getShippingCost 66 | 67 | **Signature:** `static getShippingCost(shippingMethod : ShippingMethod, orderValue : Money) : Money` 68 | 69 | Returns the shipping cost amount for the specified shipping method and the specified order value. 70 | 71 | ## Method Detail 72 | 73 | ## Method Details 74 | 75 | ### applyShippingCost 76 | 77 | **Signature:** `static applyShippingCost(lineItemCtnr : LineItemCtnr) : void` 78 | 79 | **Description:** Applies product and shipment-level shipping cost to the specified line item container. For each product line item in the specified line item container, a product shipping line item is created if product-level shipping cost is defined for the product. If no product-level shipping cost is defined for the product, an existing product shipping line item is removed. For each shipment in the specified line item container, shipment-level shipping cost is calculated. This cost is determined based on the merchandise total of the shipment after all product and order discounts. Only products without or with surcharge product-specific shipping cost count towards this merchandise total. Products with fixed product-specific shipping cost don't count towards the merchandise total used to calculate shipment-level shipping cost. The calculated shipping cost is set at the standard shipping line item of the shipment. If 'net' taxation is configured for the site, the merchandise total before tax is used. If 'gross' taxation is configured for the site, the merchandise total after tax is used. If no shipping method is set for a shipment, neither product nor shipment-level shipping cost can be calculated. In this case, the amount of the standard shipment shipping line item will be set to N/A, and shipping line items of product line items in this shipment will be removed from the line item container. Special cases for product-level shipping cost: if a product is member of multiple shipping cost groups, the lowest shipping cost takes precedence if fixed and surcharge shipping cost is defined for a product, the fixed cost takes precedence shipping cost defined for a master product is also defined for all variants of this master shipping cost is not applied to bundled product line items or options line items 80 | 81 | **Parameters:** 82 | 83 | - `lineItemCtnr`: the line item container to use. 84 | 85 | --- 86 | 87 | ### getAllShippingMethods 88 | 89 | **Signature:** `static getAllShippingMethods() : Collection` 90 | 91 | **Description:** Returns the active shipping methods of the current site applicable to the session currency and current customer group. 92 | 93 | **Returns:** 94 | 95 | the active shipping methods of the current site applicable to the session currency and current customer group. 96 | 97 | --- 98 | 99 | ### getDefaultShippingMethod 100 | 101 | **Signature:** `static getDefaultShippingMethod() : ShippingMethod` 102 | 103 | **Description:** Returns the default shipping method of the current site applicable to the session currency. Does an additional check if there is a base method and if their currencies are the same. Returns NULL if the two currencies are different. 104 | 105 | **Returns:** 106 | 107 | the default shipping method of the current site applicable to the session currency or null. 108 | 109 | --- 110 | 111 | ### getProductShippingModel 112 | 113 | **Signature:** `static getProductShippingModel(product : Product) : ProductShippingModel` 114 | 115 | **Description:** Returns the shipping model for the specified product. 116 | 117 | **Parameters:** 118 | 119 | - `product`: Product 120 | 121 | **Returns:** 122 | 123 | Shipping model for specified product 124 | 125 | --- 126 | 127 | ### getShipmentShippingModel 128 | 129 | **Signature:** `static getShipmentShippingModel(shipment : Shipment) : ShipmentShippingModel` 130 | 131 | **Description:** Returns the shipping model for the specified shipment. 132 | 133 | **Parameters:** 134 | 135 | - `shipment`: the shipment to use. 136 | 137 | **Returns:** 138 | 139 | Shipping model for specified product 140 | 141 | --- 142 | 143 | ### getShippingCost 144 | 145 | **Signature:** `static getShippingCost(shippingMethod : ShippingMethod, orderValue : Money) : Money` 146 | 147 | **Description:** Returns the shipping cost amount for the specified shipping method and the specified order value. If shipping cost cannot be calculated for any reason, Money.NA is returned. 148 | 149 | **Parameters:** 150 | 151 | - `shippingMethod`: Selected shipping method 152 | - `orderValue`: Order value 153 | 154 | **Returns:** 155 | 156 | Shipping cost 157 | 158 | --- ``` -------------------------------------------------------------------------------- /docs/dw_web/HttpParameterMap.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.web 2 | 3 | # Class HttpParameterMap 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.web.HttpParameterMap 9 | 10 | ## Description 11 | 12 | A map of HTTP parameters. 13 | 14 | ## Properties 15 | 16 | ### parameterCount 17 | 18 | **Type:** Number (Read Only) 19 | 20 | The number of paramters in this http parameter map. 21 | 22 | ### parameterNames 23 | 24 | **Type:** Set (Read Only) 25 | 26 | A collection of all parameter names. 27 | 28 | ### requestBodyAsString 29 | 30 | **Type:** String (Read Only) 31 | 32 | The HTTP request body as string (e.g. useful for XML posts). A body 33 | is only returned if the request is a POST or PUT request and was not send 34 | with "application/x-www-form-urlencoded" encoding. If the request was send 35 | with that encoding it is interpreted as form data and the body will be empty. 36 | 37 | ## Constructor Summary 38 | 39 | ## Method Summary 40 | 41 | ### get 42 | 43 | **Signature:** `get(name : Object) : HttpParameter` 44 | 45 | Returns the http parameter for the given key or an empty http parameter, if no parameter is defined for that key. 46 | 47 | ### getParameterCount 48 | 49 | **Signature:** `getParameterCount() : Number` 50 | 51 | Returns the number of paramters in this http parameter map. 52 | 53 | ### getParameterMap 54 | 55 | **Signature:** `getParameterMap(prefix : String) : HttpParameterMap` 56 | 57 | Returns a sub-map containing all parameters that start with the given prefix. 58 | 59 | ### getParameterNames 60 | 61 | **Signature:** `getParameterNames() : Set` 62 | 63 | Returns a collection of all parameter names. 64 | 65 | ### getRequestBodyAsString 66 | 67 | **Signature:** `getRequestBodyAsString() : String` 68 | 69 | Returns the HTTP request body as string (e.g. 70 | 71 | ### isParameterSubmitted 72 | 73 | **Signature:** `isParameterSubmitted(key : String) : boolean` 74 | 75 | Identifies if the parameter has been submitted. 76 | 77 | ### processMultipart 78 | 79 | **Signature:** `processMultipart(callback : Function) : LinkedHashMap` 80 | 81 | This method can be called to process a form submission for an HTML form with encoding type "multipart/form-data". 82 | 83 | ## Method Detail 84 | 85 | ## Method Details 86 | 87 | ### get 88 | 89 | **Signature:** `get(name : Object) : HttpParameter` 90 | 91 | **Description:** Returns the http parameter for the given key or an empty http parameter, if no parameter is defined for that key. An empty parameter returns false for the method isDefined(). 92 | 93 | **Parameters:** 94 | 95 | - `name`: the key whose associated http parameter is to be returned. 96 | 97 | **Returns:** 98 | 99 | the http parameter or an empty http parameter. 100 | 101 | --- 102 | 103 | ### getParameterCount 104 | 105 | **Signature:** `getParameterCount() : Number` 106 | 107 | **Description:** Returns the number of paramters in this http parameter map. 108 | 109 | **Returns:** 110 | 111 | the number parameters. 112 | 113 | --- 114 | 115 | ### getParameterMap 116 | 117 | **Signature:** `getParameterMap(prefix : String) : HttpParameterMap` 118 | 119 | **Description:** Returns a sub-map containing all parameters that start with the given prefix. The prefix will be removed from the parameter names in the returned sub-map. For example with the parameters "pre_P1" and "pre_p2" a call with "pre_" as parameter will return a HttpParameterMap containing "P1" and "P2". 120 | 121 | **Parameters:** 122 | 123 | - `prefix`: the prefix to use when creating the sub-map. 124 | 125 | **Returns:** 126 | 127 | the sub-map containing the target parameters. 128 | 129 | --- 130 | 131 | ### getParameterNames 132 | 133 | **Signature:** `getParameterNames() : Set` 134 | 135 | **Description:** Returns a collection of all parameter names. 136 | 137 | **Returns:** 138 | 139 | a set of all parameter names 140 | 141 | --- 142 | 143 | ### getRequestBodyAsString 144 | 145 | **Signature:** `getRequestBodyAsString() : String` 146 | 147 | **Description:** Returns the HTTP request body as string (e.g. useful for XML posts). A body is only returned if the request is a POST or PUT request and was not send with "application/x-www-form-urlencoded" encoding. If the request was send with that encoding it is interpreted as form data and the body will be empty. 148 | 149 | **Returns:** 150 | 151 | the http request body 152 | 153 | --- 154 | 155 | ### isParameterSubmitted 156 | 157 | **Signature:** `isParameterSubmitted(key : String) : boolean` 158 | 159 | **Description:** Identifies if the parameter has been submitted. 160 | 161 | **Parameters:** 162 | 163 | - `key`: the parameter to check. 164 | 165 | **Returns:** 166 | 167 | true if the parameter has been submitted, false otherwise. 168 | 169 | --- 170 | 171 | ### processMultipart 172 | 173 | **Signature:** `processMultipart(callback : Function) : LinkedHashMap` 174 | 175 | **Description:** This method can be called to process a form submission for an HTML form with encoding type "multipart/form-data". Such a form can have a mixture of "regular" HTML form fields and also file uploads. Form fields are available via get(Object) without calling this method. Uploaded files still need to be processed via the passed callback function. This callback function is called for each file upload part in the request. The parameters are the field name, the content type and the original file name. The function can return either a null, which means that the upload of this part should be skipped, or return a dw.io.File instance. If the file is an existing directory the system will automatically generate a unique file name. If the file is not an existing directory the uploaded content will be directly stored into that file. An existing file with the same name will be deleted. If the file can't be deleted for whatever reason, the upload is stored with a generated unique file name in the indicated directory. An automatically generated file name consists of the the prefix "upload", a time stamp, a unique id and the extension tmp. For example: "upload_20070114221535_bc7H1aOadI9qYaaacovPd3lqna.tmp". var params : HttpParameterMap = pdict.CurrentHttpParameterMap; // Get the file name from the first field. This is works because the // parameter map is updated before the file part is parsed. var files : LinkedHashMap = params.processMultipart( (function( field, ct, oname ){ return new File( File.IMPEX + "/" + params.firstField ); }) ); 176 | 177 | **Parameters:** 178 | 179 | - `callback`: a callback function, which takes the field name, content type and original file name as input 180 | 181 | **Returns:** 182 | 183 | a LinkedHashMap where the keys are the actual file names and the values are references to the File, or null if this is not a multipart request 184 | 185 | --- ``` -------------------------------------------------------------------------------- /docs/dw_web/FormGroup.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.web 2 | 3 | # Class FormGroup 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.web.FormElement 9 | - dw.web.FormGroup 10 | 11 | ## Description 12 | 13 | The class is the central class within the whole form handling. It is the container element for fields and other form elements. A form group can contain other forms, also called sub-forms. Access to the elements of a form is provided via an index based access or via an associative array access. For example, the field "firstname" can be accessed with the expression "myform.firstname". 14 | 15 | ## Properties 16 | 17 | ### childCount 18 | 19 | **Type:** Number (Read Only) 20 | 21 | The number of elements in the form. 22 | 23 | ### error 24 | 25 | **Type:** String (Read Only) 26 | 27 | A form-wide error message. If no error message 28 | is present the method returns null. 29 | 30 | ### object 31 | 32 | **Type:** Object (Read Only) 33 | 34 | The object that was bound to this form group. 35 | 36 | ### submittedAction 37 | 38 | **Type:** FormAction (Read Only) 39 | 40 | The action that was submitted with the last request. The action is 41 | set independent whether the form must be valid for this action. The method 42 | returns null if no action at all was submitted with the last request for this 43 | form group. 44 | 45 | ### triggeredAction 46 | 47 | **Type:** FormAction (Read Only) 48 | 49 | The action that was triggered with the last request. An action is 50 | only marked as triggered if the constraints regarding form validation are 51 | meet. The method returns null if no action was marked as triggered. 52 | 53 | ## Constructor Summary 54 | 55 | ## Method Summary 56 | 57 | ### accept 58 | 59 | **Signature:** `accept() : void` 60 | 61 | The method copies the value from a form into the object, which was previously bound to the form. 62 | 63 | ### copyFrom 64 | 65 | **Signature:** `copyFrom(obj : Object) : void` 66 | 67 | The method updates the form with the values from the given object. The method call is basically equivalent to the pipelet UpdateFormWithObject. The method not only copies the value, it also binds the object to the form. 68 | 69 | ### copyTo 70 | 71 | **Signature:** `copyTo(obj : Object) : void` 72 | 73 | The method updates the object with the values from the form. The method call is basically equivalent to the pipelet UpdateObjectWithForm. The method needs a submitted form. 74 | 75 | ### getChildCount 76 | 77 | **Signature:** `getChildCount() : Number` 78 | 79 | Returns the number of elements in the form. 80 | 81 | ### getError 82 | 83 | **Signature:** `getError() : String` 84 | 85 | Returns a form-wide error message. 86 | 87 | ### getObject 88 | 89 | **Signature:** `getObject() : Object` 90 | 91 | The object that was bound to this form group. 92 | 93 | ### getSubmittedAction 94 | 95 | **Signature:** `getSubmittedAction() : FormAction` 96 | 97 | Returns the action that was submitted with the last request. 98 | 99 | ### getTriggeredAction 100 | 101 | **Signature:** `getTriggeredAction() : FormAction` 102 | 103 | Returns the action that was triggered with the last request. 104 | 105 | ## Method Detail 106 | 107 | ## Method Details 108 | 109 | ### accept 110 | 111 | **Signature:** `accept() : void` 112 | 113 | **Description:** The method copies the value from a form into the object, which was previously bound to the form. The method is equivalent to the pipelet AcceptForm. This method is equivalent to the call formgroup.copyFrom( formgroup.object ). 114 | 115 | --- 116 | 117 | ### copyFrom 118 | 119 | **Signature:** `copyFrom(obj : Object) : void` 120 | 121 | **Description:** The method updates the form with the values from the given object. The method call is basically equivalent to the pipelet UpdateFormWithObject. The method not only copies the value, it also binds the object to the form. Binding means that the form keeps the information from which objects the values were taken. This can be used for two purposes: for lists it makes it easier in the code to find the associated object, for example in case of a related action, and it allows to copy back the values from the form into the object (see accept()). Because of this bind behavior, the operation is also sometimes called a bind-operation. 122 | 123 | **Parameters:** 124 | 125 | - `obj`: the object from, which the values are read 126 | 127 | --- 128 | 129 | ### copyTo 130 | 131 | **Signature:** `copyTo(obj : Object) : void` 132 | 133 | **Description:** The method updates the object with the values from the form. The method call is basically equivalent to the pipelet UpdateObjectWithForm. The method needs a submitted form. The copyTo call is delegated to the form fields. Each form field than checks if its value was submitted as part of the form: If this is true, the object gets updated with the form field value. If this is false, the object will not be updated. This is the reason why you cannot copy values from one object into another object by using copyFrom(Object) and copyTo(Object) within the same request (e.g. by one call to a script or controller). 134 | 135 | **Parameters:** 136 | 137 | - `obj`: the object, which is updated from the form 138 | 139 | --- 140 | 141 | ### getChildCount 142 | 143 | **Signature:** `getChildCount() : Number` 144 | 145 | **Description:** Returns the number of elements in the form. 146 | 147 | **Returns:** 148 | 149 | the number of elements in the form. 150 | 151 | --- 152 | 153 | ### getError 154 | 155 | **Signature:** `getError() : String` 156 | 157 | **Description:** Returns a form-wide error message. If no error message is present the method returns null. 158 | 159 | **Returns:** 160 | 161 | a form-wide error message or null. 162 | 163 | --- 164 | 165 | ### getObject 166 | 167 | **Signature:** `getObject() : Object` 168 | 169 | **Description:** The object that was bound to this form group. 170 | 171 | **Returns:** 172 | 173 | the bound object. 174 | 175 | --- 176 | 177 | ### getSubmittedAction 178 | 179 | **Signature:** `getSubmittedAction() : FormAction` 180 | 181 | **Description:** Returns the action that was submitted with the last request. The action is set independent whether the form must be valid for this action. The method returns null if no action at all was submitted with the last request for this form group. 182 | 183 | **Returns:** 184 | 185 | the action that was submitted with the last request or null. 186 | 187 | --- 188 | 189 | ### getTriggeredAction 190 | 191 | **Signature:** `getTriggeredAction() : FormAction` 192 | 193 | **Description:** Returns the action that was triggered with the last request. An action is only marked as triggered if the constraints regarding form validation are meet. The method returns null if no action was marked as triggered. 194 | 195 | **Returns:** 196 | 197 | the action that was triggered with the last request. 198 | 199 | --- ``` -------------------------------------------------------------------------------- /src/tool-configs/system-object-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 { ValidationHelpers, CommonValidations } from '../core/handlers/validation-helpers.js'; 4 | import { OCAPIClient } from '../clients/ocapi-client.js'; 5 | 6 | export const SYSTEM_OBJECT_TOOL_NAMES = [ 7 | 'get_system_object_definitions', 8 | 'get_system_object_definition', 9 | 'search_system_object_attribute_definitions', 10 | 'search_custom_object_attribute_definitions', 11 | 'search_site_preferences', 12 | 'search_system_object_attribute_groups', 13 | ] as const; 14 | 15 | export type SystemObjectToolName = typeof SYSTEM_OBJECT_TOOL_NAMES[number]; 16 | export const SYSTEM_OBJECT_TOOL_NAMES_SET = new Set<SystemObjectToolName>(SYSTEM_OBJECT_TOOL_NAMES); 17 | 18 | /** 19 | * Configuration for system object tools 20 | * Maps each tool to its validation, execution, and messaging logic 21 | */ 22 | export const SYSTEM_OBJECT_TOOL_CONFIG: Record<SystemObjectToolName, GenericToolSpec<ToolArguments, any>> = { 23 | get_system_object_definitions: { 24 | defaults: (args: ToolArguments) => args, 25 | validate: (_args: ToolArguments, _toolName: string) => { 26 | // No validation needed for list operation 27 | }, 28 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 29 | const client = context.ocapiClient as OCAPIClient; 30 | // Pass pagination parameters to the client 31 | const params = { 32 | start: args.start as number, 33 | count: args.count as number, 34 | select: args.select as string, 35 | }; 36 | // Remove undefined values to avoid sending them 37 | Object.keys(params).forEach(key => { 38 | if (params[key as keyof typeof params] === undefined) { 39 | delete params[key as keyof typeof params]; 40 | } 41 | }); 42 | return client.systemObjects.getSystemObjectDefinitions(Object.keys(params).length > 0 ? params : undefined); 43 | }, 44 | logMessage: (args: ToolArguments) => `Get system object definitions (start: ${args?.start ?? 0}, count: ${args?.count ?? 200})`, 45 | }, 46 | 47 | get_system_object_definition: { 48 | defaults: (args: ToolArguments) => args, 49 | validate: (args: ToolArguments, toolName: string) => { 50 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('objectType'), toolName); 51 | }, 52 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 53 | const client = context.ocapiClient as OCAPIClient; 54 | return client.systemObjects.getSystemObjectDefinition(args.objectType as string); 55 | }, 56 | logMessage: (args: ToolArguments) => `Get system object definition for ${args?.objectType}`, 57 | }, 58 | 59 | search_system_object_attribute_definitions: { 60 | defaults: (args: ToolArguments) => ({ 61 | ...args, 62 | searchRequest: args.searchRequest ?? { 63 | query: { match_all_query: {} }, 64 | select: '(**)', 65 | count: 200, 66 | }, 67 | }), 68 | validate: (args: ToolArguments, toolName: string) => { 69 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('objectType'), toolName); 70 | }, 71 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 72 | const client = context.ocapiClient as OCAPIClient; 73 | return client.systemObjects.searchSystemObjectAttributeDefinitions( 74 | args.objectType as string, 75 | args.searchRequest as any, 76 | ); 77 | }, 78 | logMessage: (args: ToolArguments) => `Search system object attributes for ${args?.objectType}`, 79 | }, 80 | 81 | search_custom_object_attribute_definitions: { 82 | defaults: (args: ToolArguments) => ({ 83 | ...args, 84 | searchRequest: args.searchRequest ?? { 85 | query: { match_all_query: {} }, 86 | count: 200, 87 | }, 88 | }), 89 | validate: (args: ToolArguments, toolName: string) => { 90 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('objectType'), toolName); 91 | }, 92 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 93 | const client = context.ocapiClient as OCAPIClient; 94 | return client.systemObjects.searchCustomObjectAttributeDefinitions( 95 | args.objectType as string, 96 | args.searchRequest as any, 97 | ); 98 | }, 99 | logMessage: (args: ToolArguments) => `Search custom object attributes for ${args?.objectType}`, 100 | }, 101 | 102 | search_site_preferences: { 103 | defaults: (args: ToolArguments) => ({ 104 | ...args, 105 | instanceType: args.instanceType ?? 'sandbox', 106 | searchRequest: args.searchRequest ?? { 107 | query: { match_all_query: {} }, 108 | count: 200, 109 | }, 110 | options: args.options ?? { expand: 'value' }, 111 | }), 112 | validate: (args: ToolArguments, toolName: string) => { 113 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('groupId'), toolName); 114 | }, 115 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 116 | const client = context.ocapiClient as OCAPIClient; 117 | return client.sitePreferences.searchSitePreferences( 118 | args.groupId as string, 119 | args.instanceType as string, 120 | args.searchRequest as any, 121 | args.options as any, 122 | ); 123 | }, 124 | logMessage: (args: ToolArguments) => `Search site preferences group ${args?.groupId}`, 125 | }, 126 | 127 | search_system_object_attribute_groups: { 128 | defaults: (args: ToolArguments) => ({ 129 | ...args, 130 | searchRequest: args.searchRequest ?? { 131 | query: { match_all_query: {} }, 132 | count: 200, 133 | }, 134 | }), 135 | validate: (args: ToolArguments, toolName: string) => { 136 | ValidationHelpers.validateArguments(args, CommonValidations.requiredString('objectType'), toolName); 137 | }, 138 | exec: async (args: ToolArguments, context: ToolExecutionContext) => { 139 | const client = context.ocapiClient as OCAPIClient; 140 | return client.systemObjects.searchSystemObjectAttributeGroups( 141 | args.objectType as string, 142 | args.searchRequest as any, 143 | ); 144 | }, 145 | logMessage: (args: ToolArguments) => `Search attribute groups for ${args?.objectType}`, 146 | }, 147 | }; 148 | ```