This is page 27 of 61. Use http://codebase.md/taurgis/sfcc-dev-mcp?lines=true&page={x} to view the full context. # Directory Structure ``` ├── .DS_Store ├── .github │ ├── dependabot.yml │ ├── instructions │ │ ├── mcp-node-tests.instructions.md │ │ └── mcp-yml-tests.instructions.md │ ├── ISSUE_TEMPLATE │ │ ├── bug_report.yml │ │ ├── config.yml │ │ ├── documentation.yml │ │ ├── feature_request.yml │ │ └── question.yml │ ├── PULL_REQUEST_TEMPLATE │ │ ├── bug_fix.md │ │ ├── documentation.md │ │ └── new_tool.md │ ├── pull_request_template.md │ └── workflows │ ├── ci.yml │ ├── deploy-pages.yml │ ├── publish.yml │ └── update-docs.yml ├── .gitignore ├── .husky │ └── pre-commit ├── aegis.config.docs-only.json ├── aegis.config.json ├── aegis.config.with-dw.json ├── AGENTS.md ├── ai-instructions │ ├── claude-desktop │ │ └── claude_custom_instructions.md │ ├── cursor │ │ └── .cursor │ │ └── rules │ │ ├── debugging-workflows.mdc │ │ ├── hooks-development.mdc │ │ ├── isml-templates.mdc │ │ ├── job-framework.mdc │ │ ├── performance-optimization.mdc │ │ ├── scapi-endpoints.mdc │ │ ├── security-patterns.mdc │ │ ├── sfcc-development.mdc │ │ ├── sfra-controllers.mdc │ │ ├── sfra-models.mdc │ │ ├── system-objects.mdc │ │ └── testing-patterns.mdc │ └── github-copilot │ └── copilot-instructions.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── docs │ ├── best-practices │ │ ├── cartridge_creation.md │ │ ├── isml_templates.md │ │ ├── job_framework.md │ │ ├── localserviceregistry.md │ │ ├── ocapi_hooks.md │ │ ├── performance.md │ │ ├── scapi_custom_endpoint.md │ │ ├── scapi_hooks.md │ │ ├── security.md │ │ ├── sfra_client_side_js.md │ │ ├── sfra_controllers.md │ │ ├── sfra_models.md │ │ └── sfra_scss.md │ ├── dw_campaign │ │ ├── ABTest.md │ │ ├── ABTestMgr.md │ │ ├── ABTestSegment.md │ │ ├── AmountDiscount.md │ │ ├── ApproachingDiscount.md │ │ ├── BonusChoiceDiscount.md │ │ ├── BonusDiscount.md │ │ ├── Campaign.md │ │ ├── CampaignMgr.md │ │ ├── CampaignStatusCodes.md │ │ ├── Coupon.md │ │ ├── CouponMgr.md │ │ ├── CouponRedemption.md │ │ ├── CouponStatusCodes.md │ │ ├── Discount.md │ │ ├── DiscountPlan.md │ │ ├── FixedPriceDiscount.md │ │ ├── FixedPriceShippingDiscount.md │ │ ├── FreeDiscount.md │ │ ├── FreeShippingDiscount.md │ │ ├── PercentageDiscount.md │ │ ├── PercentageOptionDiscount.md │ │ ├── PriceBookPriceDiscount.md │ │ ├── Promotion.md │ │ ├── PromotionMgr.md │ │ ├── PromotionPlan.md │ │ ├── SlotContent.md │ │ ├── SourceCodeGroup.md │ │ ├── SourceCodeInfo.md │ │ ├── SourceCodeStatusCodes.md │ │ └── TotalFixedPriceDiscount.md │ ├── dw_catalog │ │ ├── Catalog.md │ │ ├── CatalogMgr.md │ │ ├── Category.md │ │ ├── CategoryAssignment.md │ │ ├── CategoryLink.md │ │ ├── PriceBook.md │ │ ├── PriceBookMgr.md │ │ ├── Product.md │ │ ├── ProductActiveData.md │ │ ├── ProductAttributeModel.md │ │ ├── ProductAvailabilityLevels.md │ │ ├── ProductAvailabilityModel.md │ │ ├── ProductInventoryList.md │ │ ├── ProductInventoryMgr.md │ │ ├── ProductInventoryRecord.md │ │ ├── ProductLink.md │ │ ├── ProductMgr.md │ │ ├── ProductOption.md │ │ ├── ProductOptionModel.md │ │ ├── ProductOptionValue.md │ │ ├── ProductPriceInfo.md │ │ ├── ProductPriceModel.md │ │ ├── ProductPriceTable.md │ │ ├── ProductSearchHit.md │ │ ├── ProductSearchModel.md │ │ ├── ProductSearchRefinementDefinition.md │ │ ├── ProductSearchRefinements.md │ │ ├── ProductSearchRefinementValue.md │ │ ├── ProductVariationAttribute.md │ │ ├── ProductVariationAttributeValue.md │ │ ├── ProductVariationModel.md │ │ ├── Recommendation.md │ │ ├── SearchModel.md │ │ ├── SearchRefinementDefinition.md │ │ ├── SearchRefinements.md │ │ ├── SearchRefinementValue.md │ │ ├── SortingOption.md │ │ ├── SortingRule.md │ │ ├── Store.md │ │ ├── StoreGroup.md │ │ ├── StoreInventoryFilter.md │ │ ├── StoreInventoryFilterValue.md │ │ ├── StoreMgr.md │ │ ├── Variant.md │ │ └── VariationGroup.md │ ├── dw_content │ │ ├── Content.md │ │ ├── ContentMgr.md │ │ ├── ContentSearchModel.md │ │ ├── ContentSearchRefinementDefinition.md │ │ ├── ContentSearchRefinements.md │ │ ├── ContentSearchRefinementValue.md │ │ ├── Folder.md │ │ ├── Library.md │ │ ├── MarkupText.md │ │ └── MediaFile.md │ ├── dw_crypto │ │ ├── CertificateRef.md │ │ ├── CertificateUtils.md │ │ ├── Cipher.md │ │ ├── Encoding.md │ │ ├── JWE.md │ │ ├── JWEHeader.md │ │ ├── JWS.md │ │ ├── JWSHeader.md │ │ ├── KeyRef.md │ │ ├── Mac.md │ │ ├── MessageDigest.md │ │ ├── SecureRandom.md │ │ ├── Signature.md │ │ ├── WeakCipher.md │ │ ├── WeakMac.md │ │ ├── WeakMessageDigest.md │ │ ├── WeakSignature.md │ │ └── X509Certificate.md │ ├── dw_customer │ │ ├── AddressBook.md │ │ ├── AgentUserMgr.md │ │ ├── AgentUserStatusCodes.md │ │ ├── AuthenticationStatus.md │ │ ├── Credentials.md │ │ ├── Customer.md │ │ ├── CustomerActiveData.md │ │ ├── CustomerAddress.md │ │ ├── CustomerCDPData.md │ │ ├── CustomerContextMgr.md │ │ ├── CustomerGroup.md │ │ ├── CustomerList.md │ │ ├── CustomerMgr.md │ │ ├── CustomerPasswordConstraints.md │ │ ├── CustomerPaymentInstrument.md │ │ ├── CustomerStatusCodes.md │ │ ├── EncryptedObject.md │ │ ├── ExternalProfile.md │ │ ├── OrderHistory.md │ │ ├── ProductList.md │ │ ├── ProductListItem.md │ │ ├── ProductListItemPurchase.md │ │ ├── ProductListMgr.md │ │ ├── ProductListRegistrant.md │ │ ├── Profile.md │ │ └── Wallet.md │ ├── dw_extensions.applepay │ │ ├── ApplePayHookResult.md │ │ └── ApplePayHooks.md │ ├── dw_extensions.facebook │ │ ├── FacebookFeedHooks.md │ │ └── FacebookProduct.md │ ├── dw_extensions.paymentrequest │ │ ├── PaymentRequestHookResult.md │ │ └── PaymentRequestHooks.md │ ├── dw_extensions.payments │ │ ├── SalesforceBancontactPaymentDetails.md │ │ ├── SalesforceCardPaymentDetails.md │ │ ├── SalesforceEpsPaymentDetails.md │ │ ├── SalesforceIdealPaymentDetails.md │ │ ├── SalesforceKlarnaPaymentDetails.md │ │ ├── SalesforcePaymentDetails.md │ │ ├── SalesforcePaymentIntent.md │ │ ├── SalesforcePaymentMethod.md │ │ ├── SalesforcePaymentRequest.md │ │ ├── SalesforcePaymentsHooks.md │ │ ├── SalesforcePaymentsMgr.md │ │ ├── SalesforcePaymentsSiteConfiguration.md │ │ ├── SalesforcePayPalOrder.md │ │ ├── SalesforcePayPalOrderAddress.md │ │ ├── SalesforcePayPalOrderPayer.md │ │ ├── SalesforcePayPalPaymentDetails.md │ │ ├── SalesforceSepaDebitPaymentDetails.md │ │ └── SalesforceVenmoPaymentDetails.md │ ├── dw_extensions.pinterest │ │ ├── PinterestAvailability.md │ │ ├── PinterestFeedHooks.md │ │ ├── PinterestOrder.md │ │ ├── PinterestOrderHooks.md │ │ └── PinterestProduct.md │ ├── dw_io │ │ ├── CSVStreamReader.md │ │ ├── CSVStreamWriter.md │ │ ├── File.md │ │ ├── FileReader.md │ │ ├── FileWriter.md │ │ ├── InputStream.md │ │ ├── OutputStream.md │ │ ├── PrintWriter.md │ │ ├── RandomAccessFileReader.md │ │ ├── Reader.md │ │ ├── StringWriter.md │ │ ├── Writer.md │ │ ├── XMLIndentingStreamWriter.md │ │ ├── XMLStreamConstants.md │ │ ├── XMLStreamReader.md │ │ └── XMLStreamWriter.md │ ├── dw_job │ │ ├── JobExecution.md │ │ └── JobStepExecution.md │ ├── dw_net │ │ ├── FTPClient.md │ │ ├── FTPFileInfo.md │ │ ├── HTTPClient.md │ │ ├── HTTPRequestPart.md │ │ ├── Mail.md │ │ ├── SFTPClient.md │ │ ├── SFTPFileInfo.md │ │ ├── WebDAVClient.md │ │ └── WebDAVFileInfo.md │ ├── dw_object │ │ ├── ActiveData.md │ │ ├── CustomAttributes.md │ │ ├── CustomObject.md │ │ ├── CustomObjectMgr.md │ │ ├── Extensible.md │ │ ├── ExtensibleObject.md │ │ ├── Note.md │ │ ├── ObjectAttributeDefinition.md │ │ ├── ObjectAttributeGroup.md │ │ ├── ObjectAttributeValueDefinition.md │ │ ├── ObjectTypeDefinition.md │ │ ├── PersistentObject.md │ │ ├── SimpleExtensible.md │ │ └── SystemObjectMgr.md │ ├── dw_order │ │ ├── AbstractItem.md │ │ ├── AbstractItemCtnr.md │ │ ├── Appeasement.md │ │ ├── AppeasementItem.md │ │ ├── Basket.md │ │ ├── BasketMgr.md │ │ ├── BonusDiscountLineItem.md │ │ ├── CouponLineItem.md │ │ ├── CreateAgentBasketLimitExceededException.md │ │ ├── CreateBasketFromOrderException.md │ │ ├── CreateCouponLineItemException.md │ │ ├── CreateOrderException.md │ │ ├── CreateTemporaryBasketLimitExceededException.md │ │ ├── GiftCertificate.md │ │ ├── GiftCertificateLineItem.md │ │ ├── GiftCertificateMgr.md │ │ ├── GiftCertificateStatusCodes.md │ │ ├── Invoice.md │ │ ├── InvoiceItem.md │ │ ├── LineItem.md │ │ ├── LineItemCtnr.md │ │ ├── Order.md │ │ ├── OrderAddress.md │ │ ├── OrderItem.md │ │ ├── OrderMgr.md │ │ ├── OrderPaymentInstrument.md │ │ ├── OrderProcessStatusCodes.md │ │ ├── PaymentCard.md │ │ ├── PaymentInstrument.md │ │ ├── PaymentMethod.md │ │ ├── PaymentMgr.md │ │ ├── PaymentProcessor.md │ │ ├── PaymentStatusCodes.md │ │ ├── PaymentTransaction.md │ │ ├── PriceAdjustment.md │ │ ├── PriceAdjustmentLimitTypes.md │ │ ├── ProductLineItem.md │ │ ├── ProductShippingCost.md │ │ ├── ProductShippingLineItem.md │ │ ├── ProductShippingModel.md │ │ ├── Return.md │ │ ├── ReturnCase.md │ │ ├── ReturnCaseItem.md │ │ ├── ReturnItem.md │ │ ├── Shipment.md │ │ ├── ShipmentShippingCost.md │ │ ├── ShipmentShippingModel.md │ │ ├── ShippingLineItem.md │ │ ├── ShippingLocation.md │ │ ├── ShippingMethod.md │ │ ├── ShippingMgr.md │ │ ├── ShippingOrder.md │ │ ├── ShippingOrderItem.md │ │ ├── SumItem.md │ │ ├── TaxGroup.md │ │ ├── TaxItem.md │ │ ├── TaxMgr.md │ │ ├── TrackingInfo.md │ │ └── TrackingRef.md │ ├── dw_order.hooks │ │ ├── CalculateHooks.md │ │ ├── OrderHooks.md │ │ ├── PaymentHooks.md │ │ ├── ReturnHooks.md │ │ └── ShippingOrderHooks.md │ ├── dw_rpc │ │ ├── SOAPUtil.md │ │ ├── Stub.md │ │ └── WebReference.md │ ├── dw_suggest │ │ ├── BrandSuggestions.md │ │ ├── CategorySuggestions.md │ │ ├── ContentSuggestions.md │ │ ├── CustomSuggestions.md │ │ ├── ProductSuggestions.md │ │ ├── SearchPhraseSuggestions.md │ │ ├── SuggestedCategory.md │ │ ├── SuggestedContent.md │ │ ├── SuggestedPhrase.md │ │ ├── SuggestedProduct.md │ │ ├── SuggestedTerm.md │ │ ├── SuggestedTerms.md │ │ ├── Suggestions.md │ │ └── SuggestModel.md │ ├── dw_svc │ │ ├── FTPService.md │ │ ├── FTPServiceDefinition.md │ │ ├── HTTPFormService.md │ │ ├── HTTPFormServiceDefinition.md │ │ ├── HTTPService.md │ │ ├── HTTPServiceDefinition.md │ │ ├── LocalServiceRegistry.md │ │ ├── Result.md │ │ ├── Service.md │ │ ├── ServiceCallback.md │ │ ├── ServiceConfig.md │ │ ├── ServiceCredential.md │ │ ├── ServiceDefinition.md │ │ ├── ServiceProfile.md │ │ ├── ServiceRegistry.md │ │ ├── SOAPService.md │ │ └── SOAPServiceDefinition.md │ ├── dw_system │ │ ├── AgentUserStatusCodes.md │ │ ├── Cache.md │ │ ├── CacheMgr.md │ │ ├── HookMgr.md │ │ ├── InternalObject.md │ │ ├── JobProcessMonitor.md │ │ ├── Log.md │ │ ├── Logger.md │ │ ├── LogNDC.md │ │ ├── OrganizationPreferences.md │ │ ├── Pipeline.md │ │ ├── PipelineDictionary.md │ │ ├── RemoteInclude.md │ │ ├── Request.md │ │ ├── RequestHooks.md │ │ ├── Response.md │ │ ├── RESTErrorResponse.md │ │ ├── RESTResponseMgr.md │ │ ├── RESTSuccessResponse.md │ │ ├── SearchStatus.md │ │ ├── Session.md │ │ ├── Site.md │ │ ├── SitePreferences.md │ │ ├── Status.md │ │ ├── StatusItem.md │ │ ├── System.md │ │ └── Transaction.md │ ├── dw_util │ │ ├── ArrayList.md │ │ ├── Assert.md │ │ ├── BigInteger.md │ │ ├── Bytes.md │ │ ├── Calendar.md │ │ ├── Collection.md │ │ ├── Currency.md │ │ ├── DateUtils.md │ │ ├── Decimal.md │ │ ├── FilteringCollection.md │ │ ├── Geolocation.md │ │ ├── HashMap.md │ │ ├── HashSet.md │ │ ├── Iterator.md │ │ ├── LinkedHashMap.md │ │ ├── LinkedHashSet.md │ │ ├── List.md │ │ ├── Locale.md │ │ ├── Map.md │ │ ├── MapEntry.md │ │ ├── MappingKey.md │ │ ├── MappingMgr.md │ │ ├── PropertyComparator.md │ │ ├── SecureEncoder.md │ │ ├── SecureFilter.md │ │ ├── SeekableIterator.md │ │ ├── Set.md │ │ ├── SortedMap.md │ │ ├── SortedSet.md │ │ ├── StringUtils.md │ │ ├── Template.md │ │ └── UUIDUtils.md │ ├── dw_value │ │ ├── EnumValue.md │ │ ├── MimeEncodedText.md │ │ ├── Money.md │ │ └── Quantity.md │ ├── dw_web │ │ ├── ClickStream.md │ │ ├── ClickStreamEntry.md │ │ ├── Cookie.md │ │ ├── Cookies.md │ │ ├── CSRFProtection.md │ │ ├── Form.md │ │ ├── FormAction.md │ │ ├── FormElement.md │ │ ├── FormElementValidationResult.md │ │ ├── FormField.md │ │ ├── FormFieldOption.md │ │ ├── FormFieldOptions.md │ │ ├── FormGroup.md │ │ ├── FormList.md │ │ ├── FormListItem.md │ │ ├── Forms.md │ │ ├── HttpParameter.md │ │ ├── HttpParameterMap.md │ │ ├── LoopIterator.md │ │ ├── PageMetaData.md │ │ ├── PageMetaTag.md │ │ ├── PagingModel.md │ │ ├── Resource.md │ │ ├── URL.md │ │ ├── URLAction.md │ │ ├── URLParameter.md │ │ ├── URLRedirect.md │ │ ├── URLRedirectMgr.md │ │ └── URLUtils.md │ ├── sfra │ │ ├── account.md │ │ ├── address.md │ │ ├── billing.md │ │ ├── cart.md │ │ ├── categories.md │ │ ├── content.md │ │ ├── locale.md │ │ ├── order.md │ │ ├── payment.md │ │ ├── price-default.md │ │ ├── price-range.md │ │ ├── price-tiered.md │ │ ├── product-bundle.md │ │ ├── product-full.md │ │ ├── product-line-items.md │ │ ├── product-search.md │ │ ├── product-tile.md │ │ ├── querystring.md │ │ ├── render.md │ │ ├── request.md │ │ ├── response.md │ │ ├── server.md │ │ ├── shipping.md │ │ ├── store.md │ │ ├── stores.md │ │ └── totals.md │ └── TopLevel │ ├── APIException.md │ ├── arguments.md │ ├── Array.md │ ├── ArrayBuffer.md │ ├── BigInt.md │ ├── Boolean.md │ ├── ConversionError.md │ ├── DataView.md │ ├── Date.md │ ├── Error.md │ ├── ES6Iterator.md │ ├── EvalError.md │ ├── Fault.md │ ├── Float32Array.md │ ├── Float64Array.md │ ├── Function.md │ ├── Generator.md │ ├── global.md │ ├── Int16Array.md │ ├── Int32Array.md │ ├── Int8Array.md │ ├── InternalError.md │ ├── IOError.md │ ├── Iterable.md │ ├── Iterator.md │ ├── JSON.md │ ├── Map.md │ ├── Math.md │ ├── Module.md │ ├── Namespace.md │ ├── Number.md │ ├── Object.md │ ├── QName.md │ ├── RangeError.md │ ├── ReferenceError.md │ ├── RegExp.md │ ├── Set.md │ ├── StopIteration.md │ ├── String.md │ ├── Symbol.md │ ├── SyntaxError.md │ ├── SystemError.md │ ├── TypeError.md │ ├── Uint16Array.md │ ├── Uint32Array.md │ ├── Uint8Array.md │ ├── Uint8ClampedArray.md │ ├── URIError.md │ ├── WeakMap.md │ ├── WeakSet.md │ ├── XML.md │ ├── XMLList.md │ └── XMLStreamError.md ├── docs-site │ ├── .gitignore │ ├── App.tsx │ ├── components │ │ ├── Badge.tsx │ │ ├── BreadcrumbSchema.tsx │ │ ├── CodeBlock.tsx │ │ ├── Collapsible.tsx │ │ ├── ConfigBuilder.tsx │ │ ├── ConfigHero.tsx │ │ ├── ConfigModeTabs.tsx │ │ ├── icons.tsx │ │ ├── Layout.tsx │ │ ├── LightCodeContainer.tsx │ │ ├── NewcomerCTA.tsx │ │ ├── NextStepsStrip.tsx │ │ ├── OnThisPage.tsx │ │ ├── Search.tsx │ │ ├── SEO.tsx │ │ ├── Sidebar.tsx │ │ ├── StructuredData.tsx │ │ ├── ToolCard.tsx │ │ ├── ToolFilters.tsx │ │ ├── Typography.tsx │ │ └── VersionBadge.tsx │ ├── constants.tsx │ ├── index.html │ ├── main.tsx │ ├── metadata.json │ ├── package-lock.json │ ├── package.json │ ├── pages │ │ ├── AIInterfacesPage.tsx │ │ ├── ConfigurationPage.tsx │ │ ├── DevelopmentPage.tsx │ │ ├── ExamplesPage.tsx │ │ ├── FeaturesPage.tsx │ │ ├── HomePage.tsx │ │ ├── SecurityPage.tsx │ │ ├── ToolsPage.tsx │ │ └── TroubleshootingPage.tsx │ ├── postcss.config.js │ ├── public │ │ ├── .well-known │ │ │ └── security.txt │ │ ├── 404.html │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-512x512.png │ │ ├── apple-touch-icon.png │ │ ├── explain-product-pricing-methods-no-mcp.png │ │ ├── explain-product-pricing-methods.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon.ico │ │ ├── llms.txt │ │ ├── robots.txt │ │ ├── site.webmanifest │ │ └── sitemap.xml │ ├── README.md │ ├── scripts │ │ ├── generate-search-index.js │ │ ├── generate-sitemap.js │ │ └── search-dev.js │ ├── src │ │ └── styles │ │ ├── input.css │ │ └── prism-theme.css │ ├── tailwind.config.js │ ├── tsconfig.json │ ├── types.ts │ ├── utils │ │ ├── search.ts │ │ └── toolsData.ts │ └── vite.config.ts ├── eslint.config.js ├── jest.config.js ├── LICENSE ├── package-lock.json ├── package.json ├── README.md ├── scripts │ └── convert-docs.js ├── SECURITY.md ├── server.json ├── src │ ├── clients │ │ ├── base │ │ │ ├── http-client.ts │ │ │ ├── oauth-token.ts │ │ │ └── ocapi-auth-client.ts │ │ ├── best-practices-client.ts │ │ ├── cartridge-generation-client.ts │ │ ├── docs │ │ │ ├── class-content-parser.ts │ │ │ ├── class-name-resolver.ts │ │ │ ├── documentation-scanner.ts │ │ │ ├── index.ts │ │ │ └── referenced-types-extractor.ts │ │ ├── docs-client.ts │ │ ├── log-client.ts │ │ ├── logs │ │ │ ├── index.ts │ │ │ ├── log-analyzer.ts │ │ │ ├── log-client.ts │ │ │ ├── log-constants.ts │ │ │ ├── log-file-discovery.ts │ │ │ ├── log-file-reader.ts │ │ │ ├── log-formatter.ts │ │ │ ├── log-processor.ts │ │ │ ├── log-types.ts │ │ │ └── webdav-client-manager.ts │ │ ├── ocapi │ │ │ ├── code-versions-client.ts │ │ │ ├── site-preferences-client.ts │ │ │ └── system-objects-client.ts │ │ ├── ocapi-client.ts │ │ └── sfra-client.ts │ ├── config │ │ ├── configuration-factory.ts │ │ └── dw-json-loader.ts │ ├── core │ │ ├── handlers │ │ │ ├── abstract-log-tool-handler.ts │ │ │ ├── base-handler.ts │ │ │ ├── best-practices-handler.ts │ │ │ ├── cartridge-handler.ts │ │ │ ├── client-factory.ts │ │ │ ├── code-version-handler.ts │ │ │ ├── docs-handler.ts │ │ │ ├── job-log-handler.ts │ │ │ ├── job-log-tool-config.ts │ │ │ ├── log-handler.ts │ │ │ ├── log-tool-config.ts │ │ │ ├── sfra-handler.ts │ │ │ ├── system-object-handler.ts │ │ │ └── validation-helpers.ts │ │ ├── server.ts │ │ └── tool-definitions.ts │ ├── index.ts │ ├── main.ts │ ├── services │ │ ├── file-system-service.ts │ │ ├── index.ts │ │ └── path-service.ts │ ├── tool-configs │ │ ├── best-practices-tool-config.ts │ │ ├── cartridge-tool-config.ts │ │ ├── code-version-tool-config.ts │ │ ├── docs-tool-config.ts │ │ ├── job-log-tool-config.ts │ │ ├── log-tool-config.ts │ │ ├── sfra-tool-config.ts │ │ └── system-object-tool-config.ts │ ├── types │ │ └── types.ts │ └── utils │ ├── cache.ts │ ├── job-log-tool-config.ts │ ├── job-log-utils.ts │ ├── log-cache.ts │ ├── log-tool-config.ts │ ├── log-tool-constants.ts │ ├── log-tool-utils.ts │ ├── logger.ts │ ├── ocapi-url-builder.ts │ ├── path-resolver.ts │ ├── query-builder.ts │ ├── utils.ts │ └── validator.ts ├── tests │ ├── __mocks__ │ │ ├── docs-client.ts │ │ ├── src │ │ │ └── clients │ │ │ └── base │ │ │ └── http-client.js │ │ └── webdav.js │ ├── base-handler.test.ts │ ├── base-http-client.test.ts │ ├── best-practices-handler.test.ts │ ├── cache.test.ts │ ├── cartridge-handler.test.ts │ ├── class-content-parser.test.ts │ ├── class-name-resolver.test.ts │ ├── client-factory.test.ts │ ├── code-version-handler.test.ts │ ├── code-versions-client.test.ts │ ├── config.test.ts │ ├── configuration-factory.test.ts │ ├── docs-handler.test.ts │ ├── documentation-scanner.test.ts │ ├── file-system-service.test.ts │ ├── job-log-handler.test.ts │ ├── job-log-utils.test.ts │ ├── log-client.test.ts │ ├── log-handler.test.ts │ ├── log-processor.test.ts │ ├── logger.test.ts │ ├── mcp │ │ ├── AGENTS.md │ │ ├── node │ │ │ ├── activate-code-version-advanced.full-mode.programmatic.test.js │ │ │ ├── code-versions.full-mode.programmatic.test.js │ │ │ ├── generate-cartridge-structure.docs-only.programmatic.test.js │ │ │ ├── get-available-best-practice-guides.docs-only.programmatic.test.js │ │ │ ├── get-available-sfra-documents.programmatic.test.js │ │ │ ├── get-best-practice-guide.docs-only.programmatic.test.js │ │ │ ├── get-hook-reference.docs-only.programmatic.test.js │ │ │ ├── get-job-execution-summary.full-mode.programmatic.test.js │ │ │ ├── get-job-log-entries.full-mode.programmatic.test.js │ │ │ ├── get-latest-debug.full-mode.programmatic.test.js │ │ │ ├── get-latest-error.full-mode.programmatic.test.js │ │ │ ├── get-latest-info.full-mode.programmatic.test.js │ │ │ ├── get-latest-job-log-files.full-mode.programmatic.test.js │ │ │ ├── get-latest-warn.full-mode.programmatic.test.js │ │ │ ├── get-log-file-contents.full-mode.programmatic.test.js │ │ │ ├── get-sfcc-class-documentation.docs-only.programmatic.test.js │ │ │ ├── get-sfcc-class-info.docs-only.programmatic.test.js │ │ │ ├── get-sfra-categories.docs-only.programmatic.test.js │ │ │ ├── get-sfra-document.programmatic.test.js │ │ │ ├── get-sfra-documents-by-category.docs-only.programmatic.test.js │ │ │ ├── get-system-object-definition.full-mode.programmatic.test.js │ │ │ ├── get-system-object-definitions.docs-only.programmatic.test.js │ │ │ ├── get-system-object-definitions.full-mode.programmatic.test.js │ │ │ ├── list-log-files.full-mode.programmatic.test.js │ │ │ ├── list-sfcc-classes.docs-only.programmatic.test.js │ │ │ ├── search-best-practices.docs-only.programmatic.test.js │ │ │ ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js │ │ │ ├── search-job-logs-by-name.full-mode.programmatic.test.js │ │ │ ├── search-job-logs.full-mode.programmatic.test.js │ │ │ ├── search-logs.full-mode.programmatic.test.js │ │ │ ├── search-sfcc-classes.docs-only.programmatic.test.js │ │ │ ├── search-sfcc-methods.docs-only.programmatic.test.js │ │ │ ├── search-sfra-documentation.docs-only.programmatic.test.js │ │ │ ├── search-site-preferences.full-mode.programmatic.test.js │ │ │ ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js │ │ │ ├── search-system-object-attribute-groups.full-mode.programmatic.test.js │ │ │ ├── summarize-logs.full-mode.programmatic.test.js │ │ │ ├── tools.docs-only.programmatic.test.js │ │ │ └── tools.full-mode.programmatic.test.js │ │ ├── README.md │ │ ├── test-fixtures │ │ │ └── dw.json │ │ └── yaml │ │ ├── activate-code-version.docs-only.test.mcp.yml │ │ ├── activate-code-version.full-mode.test.mcp.yml │ │ ├── get_latest_error.test.mcp.yml │ │ ├── get-available-best-practice-guides.docs-only.test.mcp.yml │ │ ├── get-available-best-practice-guides.full-mode.test.mcp.yml │ │ ├── get-available-sfra-documents.docs-only.test.mcp.yml │ │ ├── get-available-sfra-documents.full-mode.test.mcp.yml │ │ ├── get-best-practice-guide.docs-only.test.mcp.yml │ │ ├── get-best-practice-guide.full-mode.test.mcp.yml │ │ ├── get-code-versions.docs-only.test.mcp.yml │ │ ├── get-code-versions.full-mode.test.mcp.yml │ │ ├── get-hook-reference.docs-only.test.mcp.yml │ │ ├── get-hook-reference.full-mode.test.mcp.yml │ │ ├── get-job-execution-summary.full-mode.test.mcp.yml │ │ ├── get-job-log-entries.full-mode.test.mcp.yml │ │ ├── get-latest-debug.full-mode.test.mcp.yml │ │ ├── get-latest-error.full-mode.test.mcp.yml │ │ ├── get-latest-info.full-mode.test.mcp.yml │ │ ├── get-latest-job-log-files.full-mode.test.mcp.yml │ │ ├── get-latest-warn.full-mode.test.mcp.yml │ │ ├── get-log-file-contents.full-mode.test.mcp.yml │ │ ├── get-sfcc-class-documentation.docs-only.test.mcp.yml │ │ ├── get-sfcc-class-documentation.full-mode.test.mcp.yml │ │ ├── get-sfcc-class-info.docs-only.test.mcp.yml │ │ ├── get-sfcc-class-info.full-mode.test.mcp.yml │ │ ├── get-sfra-categories.docs-only.test.mcp.yml │ │ ├── get-sfra-categories.full-mode.test.mcp.yml │ │ ├── get-sfra-document.docs-only.test.mcp.yml │ │ ├── get-sfra-document.full-mode.test.mcp.yml │ │ ├── get-sfra-documents-by-category.docs-only.test.mcp.yml │ │ ├── get-sfra-documents-by-category.full-mode.test.mcp.yml │ │ ├── get-system-object-definition.docs-only.test.mcp.yml │ │ ├── get-system-object-definition.full-mode.test.mcp.yml │ │ ├── get-system-object-definitions.docs-only.test.mcp.yml │ │ ├── get-system-object-definitions.full-mode.test.mcp.yml │ │ ├── list-log-files.full-mode.test.mcp.yml │ │ ├── list-sfcc-classes.docs-only.test.mcp.yml │ │ ├── list-sfcc-classes.full-mode.test.mcp.yml │ │ ├── search-best-practices.docs-only.test.mcp.yml │ │ ├── search-best-practices.full-mode.test.mcp.yml │ │ ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml │ │ ├── search-custom-object-attribute-definitions.test.mcp.yml │ │ ├── search-job-logs-by-name.full-mode.test.mcp.yml │ │ ├── search-job-logs.full-mode.test.mcp.yml │ │ ├── search-logs.full-mode.test.mcp.yml │ │ ├── search-sfcc-classes.docs-only.test.mcp.yml │ │ ├── search-sfcc-classes.full-mode.test.mcp.yml │ │ ├── search-sfcc-methods.docs-only.test.mcp.yml │ │ ├── search-sfcc-methods.full-mode.test.mcp.yml │ │ ├── search-sfra-documentation.docs-only.test.mcp.yml │ │ ├── search-sfra-documentation.full-mode.test.mcp.yml │ │ ├── search-site-preferences.docs-only.test.mcp.yml │ │ ├── search-site-preferences.full-mode.test.mcp.yml │ │ ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml │ │ ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml │ │ ├── search-system-object-attribute-groups.docs-only.test.mcp.yml │ │ ├── search-system-object-attribute-groups.full-mode.test.mcp.yml │ │ ├── summarize-logs.full-mode.test.mcp.yml │ │ ├── tools.docs-only.test.mcp.yml │ │ └── tools.full-mode.test.mcp.yml │ ├── oauth-token.test.ts │ ├── ocapi-auth-client.test.ts │ ├── ocapi-client.test.ts │ ├── path-service.test.ts │ ├── query-builder.test.ts │ ├── referenced-types-extractor.test.ts │ ├── servers │ │ ├── sfcc-mock-server │ │ │ ├── mock-data │ │ │ │ └── ocapi │ │ │ │ ├── code-versions.json │ │ │ │ ├── custom-object-attributes-customapi.json │ │ │ │ ├── custom-object-attributes-globalsettings.json │ │ │ │ ├── custom-object-attributes-versionhistory.json │ │ │ │ ├── site-preferences-ccv.json │ │ │ │ ├── site-preferences-fastforward.json │ │ │ │ ├── site-preferences-sfra.json │ │ │ │ ├── site-preferences-storefront.json │ │ │ │ ├── site-preferences-system.json │ │ │ │ ├── system-object-attribute-groups-campaign.json │ │ │ │ ├── system-object-attribute-groups-category.json │ │ │ │ ├── system-object-attribute-groups-order.json │ │ │ │ ├── system-object-attribute-groups-product.json │ │ │ │ ├── system-object-attribute-groups-sitepreferences.json │ │ │ │ ├── system-object-attributes-customeraddress.json │ │ │ │ ├── system-object-attributes-product-expanded.json │ │ │ │ ├── system-object-attributes-product.json │ │ │ │ ├── system-object-definition-category.json │ │ │ │ ├── system-object-definition-customer.json │ │ │ │ ├── system-object-definition-customeraddress.json │ │ │ │ ├── system-object-definition-order.json │ │ │ │ ├── system-object-definition-product.json │ │ │ │ ├── system-object-definitions-old.json │ │ │ │ └── system-object-definitions.json │ │ │ ├── package-lock.json │ │ │ ├── package.json │ │ │ ├── README.md │ │ │ ├── scripts │ │ │ │ └── setup-logs.js │ │ │ ├── server.js │ │ │ └── src │ │ │ ├── app.js │ │ │ ├── config │ │ │ │ └── server-config.js │ │ │ ├── middleware │ │ │ │ ├── auth.js │ │ │ │ ├── cors.js │ │ │ │ └── logging.js │ │ │ ├── routes │ │ │ │ ├── ocapi │ │ │ │ │ ├── code-versions-handler.js │ │ │ │ │ ├── oauth-handler.js │ │ │ │ │ ├── ocapi-error-utils.js │ │ │ │ │ ├── ocapi-utils.js │ │ │ │ │ ├── site-preferences-handler.js │ │ │ │ │ └── system-objects-handler.js │ │ │ │ ├── ocapi.js │ │ │ │ └── webdav.js │ │ │ └── utils │ │ │ ├── mock-data-loader.js │ │ │ └── webdav-xml.js │ │ └── sfcc-mock-server-manager.ts │ ├── sfcc-mock-server.test.ts │ ├── site-preferences-client.test.ts │ ├── system-objects-client.test.ts │ ├── utils.test.ts │ ├── validation-helpers.test.ts │ └── validator.test.ts ├── tsconfig.json └── tsconfig.test.json ``` # Files -------------------------------------------------------------------------------- /tests/mcp/yaml/get-sfra-documents-by-category.docs-only.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | # ================================================================================== 2 | # SFCC MCP Server - get_sfra_documents_by_category Tool YAML Tests (docs-only mode) 3 | # Tests SFRA document category filtering functionality with comprehensive validation 4 | # 5 | # Tool: get_sfra_documents_by_category 6 | # Purpose: Get SFRA documents filtered by category (core, product, order, customer, pricing, store, other) 7 | # Parameters: category (required) - Category to filter by 8 | # 9 | # Quick Test Commands: 10 | # aegis "tests/mcp/yaml/get-sfra-documents-by-category.docs-only.test.mcp.yml" --config "aegis.config.docs-only.json" --verbose 11 | # aegis "tests/mcp/yaml/get-sfra-documents-by-category.docs-only.test.mcp.yml" --config "aegis.config.docs-only.json" --debug --timing 12 | # aegis query get_sfra_documents_by_category '{"category": "core"}' --config "aegis.config.docs-only.json" 13 | # ================================================================================== 14 | description: "SFCC MCP Server - get_sfra_documents_by_category tool comprehensive tests" 15 | 16 | # ================================================================================== 17 | # SUCCESSFUL OPERATIONS - VALID CATEGORIES 18 | # ================================================================================== 19 | tests: 20 | - it: "should retrieve core SFRA documents with proper structure" 21 | request: 22 | jsonrpc: "2.0" 23 | id: "core-docs-1" 24 | method: "tools/call" 25 | params: 26 | name: "get_sfra_documents_by_category" 27 | arguments: 28 | category: "core" 29 | expect: 30 | response: 31 | jsonrpc: "2.0" 32 | id: "core-docs-1" 33 | result: 34 | content: 35 | - type: "text" 36 | text: "match:regex:\\[\\s*\\{[\\s\\S]*\\}\\s*\\]" # Valid JSON array structure 37 | isError: false 38 | performance: 39 | maxResponseTime: "500ms" 40 | stderr: "toBeEmpty" 41 | 42 | - it: "should return valid JSON array for core category" 43 | request: 44 | jsonrpc: "2.0" 45 | id: "core-json-1" 46 | method: "tools/call" 47 | params: 48 | name: "get_sfra_documents_by_category" 49 | arguments: 50 | category: "core" 51 | expect: 52 | response: 53 | jsonrpc: "2.0" 54 | id: "core-json-1" 55 | result: 56 | content: 57 | - type: "text" 58 | text: "match:contains:server" # Core category should contain server document 59 | isError: false 60 | stderr: "toBeEmpty" 61 | 62 | - it: "should include required document fields for core category" 63 | request: 64 | jsonrpc: "2.0" 65 | id: "core-fields-1" 66 | method: "tools/call" 67 | params: 68 | name: "get_sfra_documents_by_category" 69 | arguments: 70 | category: "core" 71 | expect: 72 | response: 73 | jsonrpc: "2.0" 74 | id: "core-fields-1" 75 | result: 76 | content: 77 | - type: "text" 78 | text: "match:regex:[\\s\\S]*name[\\s\\S]*title[\\s\\S]*description[\\s\\S]*type[\\s\\S]*category[\\s\\S]*filename" 79 | isError: false 80 | stderr: "toBeEmpty" 81 | 82 | - it: "should contain expected core documents" 83 | request: 84 | jsonrpc: "2.0" 85 | id: "core-content-1" 86 | method: "tools/call" 87 | params: 88 | name: "get_sfra_documents_by_category" 89 | arguments: 90 | category: "core" 91 | expect: 92 | response: 93 | jsonrpc: "2.0" 94 | id: "core-content-1" 95 | result: 96 | content: 97 | - type: "text" 98 | text: "match:regex:[\\s\\S]*querystring[\\s\\S]*render[\\s\\S]*request[\\s\\S]*response[\\s\\S]*server" # Core SFRA classes in alphabetical order 99 | isError: false 100 | stderr: "toBeEmpty" 101 | 102 | - it: "should retrieve product SFRA documents with proper structure" 103 | request: 104 | jsonrpc: "2.0" 105 | id: "product-docs-1" 106 | method: "tools/call" 107 | params: 108 | name: "get_sfra_documents_by_category" 109 | arguments: 110 | category: "product" 111 | expect: 112 | response: 113 | jsonrpc: "2.0" 114 | id: "product-docs-1" 115 | result: 116 | content: 117 | - type: "text" 118 | text: "match:regex:\\[\\s*\\{[\\s\\S]*\\}\\s*\\]" # Valid JSON array structure 119 | isError: false 120 | performance: 121 | maxResponseTime: "500ms" 122 | stderr: "toBeEmpty" 123 | 124 | - it: "should contain product model documents" 125 | request: 126 | jsonrpc: "2.0" 127 | id: "product-content-1" 128 | method: "tools/call" 129 | params: 130 | name: "get_sfra_documents_by_category" 131 | arguments: 132 | category: "product" 133 | expect: 134 | response: 135 | jsonrpc: "2.0" 136 | id: "product-content-1" 137 | result: 138 | content: 139 | - type: "text" 140 | text: "match:regex:[\\s\\S]*product-full[\\s\\S]*product-tile" # Product models 141 | isError: false 142 | stderr: "toBeEmpty" 143 | 144 | - it: "should retrieve order category documents" 145 | request: 146 | jsonrpc: "2.0" 147 | id: "order-docs-1" 148 | method: "tools/call" 149 | params: 150 | name: "get_sfra_documents_by_category" 151 | arguments: 152 | category: "order" 153 | expect: 154 | response: 155 | jsonrpc: "2.0" 156 | id: "order-docs-1" 157 | result: 158 | content: 159 | - type: "text" 160 | text: "match:regex:\\[[\\s\\S]*\\]" # Valid JSON array (may be empty) 161 | isError: false 162 | stderr: "toBeEmpty" 163 | 164 | - it: "should retrieve customer category documents" 165 | request: 166 | jsonrpc: "2.0" 167 | id: "customer-docs-1" 168 | method: "tools/call" 169 | params: 170 | name: "get_sfra_documents_by_category" 171 | arguments: 172 | category: "customer" 173 | expect: 174 | response: 175 | jsonrpc: "2.0" 176 | id: "customer-docs-1" 177 | result: 178 | content: 179 | - type: "text" 180 | text: "match:regex:\\[[\\s\\S]*\\]" # Valid JSON array 181 | isError: false 182 | stderr: "toBeEmpty" 183 | 184 | - it: "should retrieve pricing category documents" 185 | request: 186 | jsonrpc: "2.0" 187 | id: "pricing-docs-1" 188 | method: "tools/call" 189 | params: 190 | name: "get_sfra_documents_by_category" 191 | arguments: 192 | category: "pricing" 193 | expect: 194 | response: 195 | jsonrpc: "2.0" 196 | id: "pricing-docs-1" 197 | result: 198 | content: 199 | - type: "text" 200 | text: "match:regex:\\[[\\s\\S]*\\]" # Valid JSON array 201 | isError: false 202 | stderr: "toBeEmpty" 203 | 204 | - it: "should retrieve store category documents" 205 | request: 206 | jsonrpc: "2.0" 207 | id: "store-docs-1" 208 | method: "tools/call" 209 | params: 210 | name: "get_sfra_documents_by_category" 211 | arguments: 212 | category: "store" 213 | expect: 214 | response: 215 | jsonrpc: "2.0" 216 | id: "store-docs-1" 217 | result: 218 | content: 219 | - type: "text" 220 | text: "match:regex:\\[[\\s\\S]*\\]" # Valid JSON array 221 | isError: false 222 | stderr: "toBeEmpty" 223 | 224 | - it: "should retrieve other category documents" 225 | request: 226 | jsonrpc: "2.0" 227 | id: "other-docs-1" 228 | method: "tools/call" 229 | params: 230 | name: "get_sfra_documents_by_category" 231 | arguments: 232 | category: "other" 233 | expect: 234 | response: 235 | jsonrpc: "2.0" 236 | id: "other-docs-1" 237 | result: 238 | content: 239 | - type: "text" 240 | text: "match:regex:\\[[\\s\\S]*\\]" # Valid JSON array 241 | isError: false 242 | stderr: "toBeEmpty" 243 | 244 | # ================================================================================== 245 | # EDGE CASES - INVALID/EMPTY CATEGORIES 246 | # ================================================================================== 247 | 248 | - it: "should handle invalid category gracefully" 249 | request: 250 | jsonrpc: "2.0" 251 | id: "invalid-category-1" 252 | method: "tools/call" 253 | params: 254 | name: "get_sfra_documents_by_category" 255 | arguments: 256 | category: "invalid_category_xyz" 257 | expect: 258 | response: 259 | jsonrpc: "2.0" 260 | id: "invalid-category-1" 261 | result: 262 | content: 263 | - type: "text" 264 | text: "match:regex:^\\[\\s*\\]$" # Empty array for invalid category 265 | isError: false 266 | stderr: "toBeEmpty" 267 | 268 | - it: "should handle empty category gracefully" 269 | request: 270 | jsonrpc: "2.0" 271 | id: "empty-category-1" 272 | method: "tools/call" 273 | params: 274 | name: "get_sfra_documents_by_category" 275 | arguments: 276 | category: "" 277 | expect: 278 | response: 279 | jsonrpc: "2.0" 280 | id: "empty-category-1" 281 | result: 282 | content: 283 | - type: "text" 284 | text: "match:contains:Error" 285 | isError: true 286 | stderr: "toBeEmpty" 287 | 288 | # ================================================================================== 289 | # ERROR HANDLING - MISSING PARAMETERS 290 | # ================================================================================== 291 | 292 | - it: "should require category parameter" 293 | request: 294 | jsonrpc: "2.0" 295 | id: "missing-category-1" 296 | method: "tools/call" 297 | params: 298 | name: "get_sfra_documents_by_category" 299 | arguments: {} 300 | expect: 301 | response: 302 | jsonrpc: "2.0" 303 | id: "missing-category-1" 304 | result: 305 | content: 306 | - type: "text" 307 | text: "match:contains:category must be a non-empty string" 308 | isError: true 309 | stderr: "toBeEmpty" 310 | 311 | - it: "should handle null category parameter" 312 | request: 313 | jsonrpc: "2.0" 314 | id: "null-category-1" 315 | method: "tools/call" 316 | params: 317 | name: "get_sfra_documents_by_category" 318 | arguments: 319 | category: null 320 | expect: 321 | response: 322 | jsonrpc: "2.0" 323 | id: "null-category-1" 324 | result: 325 | content: 326 | - type: "text" 327 | text: "match:contains:Error" 328 | isError: true 329 | stderr: "toBeEmpty" 330 | 331 | # ================================================================================== 332 | # DATA VALIDATION - CONTENT STRUCTURE 333 | # ================================================================================== 334 | 335 | - it: "should return documents with valid category field in core" 336 | request: 337 | jsonrpc: "2.0" 338 | id: "category-field-1" 339 | method: "tools/call" 340 | params: 341 | name: "get_sfra_documents_by_category" 342 | arguments: 343 | category: "core" 344 | expect: 345 | response: 346 | jsonrpc: "2.0" 347 | id: "category-field-1" 348 | result: 349 | content: 350 | - type: "text" 351 | text: "match:regex:[\\s\\S]*category[\\s\\S]*:[\\s\\S]*core" # Category field should match request 352 | isError: false 353 | stderr: "toBeEmpty" 354 | 355 | - it: "should return documents with type field in product category" 356 | request: 357 | jsonrpc: "2.0" 358 | id: "type-field-1" 359 | method: "tools/call" 360 | params: 361 | name: "get_sfra_documents_by_category" 362 | arguments: 363 | category: "product" 364 | expect: 365 | response: 366 | jsonrpc: "2.0" 367 | id: "type-field-1" 368 | result: 369 | content: 370 | - type: "text" 371 | text: "match:regex:[\\s\\S]*type[\\s\\S]*:[\\s\\S]*(model|class|module)" # Valid type values 372 | isError: false 373 | stderr: "toBeEmpty" 374 | 375 | - it: "should return documents with filename field" 376 | request: 377 | jsonrpc: "2.0" 378 | id: "filename-field-1" 379 | method: "tools/call" 380 | params: 381 | name: "get_sfra_documents_by_category" 382 | arguments: 383 | category: "core" 384 | expect: 385 | response: 386 | jsonrpc: "2.0" 387 | id: "filename-field-1" 388 | result: 389 | content: 390 | - type: "text" 391 | text: "match:regex:[\\s\\S]*filename[\\s\\S]*:[\\s\\S]*\\.md" # Markdown filename 392 | isError: false 393 | stderr: "toBeEmpty" 394 | 395 | # ================================================================================== 396 | # PERFORMANCE VALIDATION 397 | # ================================================================================== 398 | 399 | - it: "should respond quickly for core category lookup" 400 | request: 401 | jsonrpc: "2.0" 402 | id: "perf-core-1" 403 | method: "tools/call" 404 | params: 405 | name: "get_sfra_documents_by_category" 406 | arguments: 407 | category: "core" 408 | expect: 409 | response: 410 | jsonrpc: "2.0" 411 | id: "perf-core-1" 412 | result: 413 | content: 414 | - type: "text" 415 | text: "match:type:string" 416 | isError: false 417 | performance: 418 | maxResponseTime: "300ms" # Fast metadata operation 419 | stderr: "toBeEmpty" 420 | 421 | - it: "should respond quickly for product category lookup" 422 | request: 423 | jsonrpc: "2.0" 424 | id: "perf-product-1" 425 | method: "tools/call" 426 | params: 427 | name: "get_sfra_documents_by_category" 428 | arguments: 429 | category: "product" 430 | expect: 431 | response: 432 | jsonrpc: "2.0" 433 | id: "perf-product-1" 434 | result: 435 | content: 436 | - type: "text" 437 | text: "match:type:string" 438 | isError: false 439 | performance: 440 | maxResponseTime: "300ms" # Fast metadata operation 441 | stderr: "toBeEmpty" 442 | 443 | - it: "should handle error cases quickly" 444 | request: 445 | jsonrpc: "2.0" 446 | id: "perf-error-1" 447 | method: "tools/call" 448 | params: 449 | name: "get_sfra_documents_by_category" 450 | arguments: 451 | category: "" 452 | expect: 453 | response: 454 | jsonrpc: "2.0" 455 | id: "perf-error-1" 456 | result: 457 | content: 458 | - type: "text" 459 | text: "match:contains:Error" 460 | isError: true 461 | performance: 462 | maxResponseTime: "200ms" # Error handling should be very fast 463 | stderr: "toBeEmpty" 464 | 465 | # ================================================================================== 466 | # CASE SENSITIVITY TESTING 467 | # ================================================================================== 468 | 469 | - it: "should handle uppercase category names" 470 | request: 471 | jsonrpc: "2.0" 472 | id: "case-upper-1" 473 | method: "tools/call" 474 | params: 475 | name: "get_sfra_documents_by_category" 476 | arguments: 477 | category: "CORE" 478 | expect: 479 | response: 480 | jsonrpc: "2.0" 481 | id: "case-upper-1" 482 | result: 483 | content: 484 | - type: "text" 485 | text: "match:regex:^\\[\\s*\\]$" # Expect empty array for case mismatch 486 | isError: false 487 | stderr: "toBeEmpty" 488 | 489 | - it: "should handle mixed case category names" 490 | request: 491 | jsonrpc: "2.0" 492 | id: "case-mixed-1" 493 | method: "tools/call" 494 | params: 495 | name: "get_sfra_documents_by_category" 496 | arguments: 497 | category: "Core" 498 | expect: 499 | response: 500 | jsonrpc: "2.0" 501 | id: "case-mixed-1" 502 | result: 503 | content: 504 | - type: "text" 505 | text: "match:regex:^\\[\\s*\\]$" # Expect empty array for case mismatch 506 | isError: false 507 | stderr: "toBeEmpty" 508 | ``` -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- ```markdown 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and versions follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | Release comparison links are provided at the bottom. Earlier patch releases on the same day may represent rapid iterations (e.g. architectural + documentation expansions). Dates are derived from git tag timestamps. 8 | 9 | ## [1.0.15] - 2025-10-03 10 | ### Added 11 | - **SFRA Best Practices Expansion**: 12 | - SFRA SCSS best practices guide with theming and override patterns 13 | - SFRA client-side JavaScript guide covering AJAX flows, validation, and accessibility 14 | - **OCAPI Select Parameter Support**: Comprehensive support for OCAPI select syntax to control response field selection 15 | - **System Object Pagination**: Added pagination support for system object definitions with configurable start/count parameters 16 | - **Chronological Log Sorting**: Enhanced log file sorting by last modification time for accurate recency ordering 17 | - **OCAPI Mock Server**: Complete OCAPI mock server implementation for testing with site preferences and system objects 18 | - **Documentation Site Enhancements**: 19 | - Vite React SSG migration for improved build performance and SSR capabilities 20 | - GitHub link integration in sidebar 21 | - Newcomer CTA component for better onboarding 22 | - Mobile web app capability with enhanced PWA support 23 | - Enhanced schema.org metadata for better SEO 24 | - **Performance Best Practices**: Added detailed SCAPI web-tier cache fundamentals, personalized cache keys, and script-level cache controls 25 | - **Custom Endpoint Caching**: Comprehensive caching strategies documentation for custom SCAPI endpoints with two-tier pattern examples 26 | 27 | ### Changed 28 | - **Testing Framework Migration**: Replaced Conductor with Aegis for MCP testing with improved declarative YAML patterns 29 | - **Documentation Modernization**: 30 | - Revamped documentation site with improved layout and readability 31 | - Consolidated agent instructions with enhanced clarity 32 | - Updated all Aegis usage examples to use `npx` commands 33 | - Added `-y` flag to npx commands in documentation 34 | - **Code Quality Improvements**: 35 | - Modularized OCAPI route handling for better maintainability 36 | - Centralized site date constants 37 | - Improved code block rendering with LightCodeContainer component 38 | - Enhanced sidebar header display 39 | - **Node.js Version Updates**: Updated Node.js versions and related documentation 40 | - **URL Structure**: Enforced trailing slashes for routes with consistent URL patterns 41 | - **AI Interface Enhancements**: Improved AI interface and configuration documentation 42 | 43 | ### Fixed 44 | - **SSR Hydration**: Fixed SSR hydration mismatch in OnThisPage component 45 | - **Hash Navigation**: Resolved hash navigation issues after search operations 46 | 47 | ### Documentation 48 | - **CSRF Middleware**: Clarified CSRF middleware usage patterns in SFRA 49 | - **Remote Include Architecture**: Added detailed explanation of remote include patterns for dynamic content 50 | - **Aegis Testing**: Comprehensive updates to Aegis testing documentation with best practices 51 | - **Performance Guidance**: Enhanced performance best practices with SCAPI-specific caching strategies 52 | 53 | ### Testing 54 | - **Comprehensive Test Coverage**: 55 | - OCAPI error handling and validation tests 56 | - Site preferences search tool tests 57 | - System object attribute search tests with complex query support 58 | - Full mode tests for object definitions and search logs 59 | - Comprehensive select parameter validation tests 60 | - MCP tool tests with Aegis framework 61 | - **Test Infrastructure**: 62 | - OCAPI test server setup integrated into CI/CD pipeline 63 | - Refactored tests to use centralized SFCC mock server 64 | - Enhanced test targeting and organization 65 | 66 | ### Dependencies 67 | - **GitHub Actions Updates**: 68 | - `actions/checkout` from 4 to 5 69 | - `actions/configure-pages` from 4 to 5 70 | - `actions/setup-node` from 4 to 5 71 | - `actions/upload-pages-artifact` from 3 to 4 72 | - `codecov/codecov-action` from 5.5.0 to 5.5.1 73 | - **Development Dependencies**: 74 | - `browserslist` from 4.25.2 to 4.26.2 75 | - `vite-react-ssg` to v0.8.9 76 | - Updated ESLint group packages 77 | - Updated `ts-jest` in Jest group 78 | 79 | ### Notes 80 | - Major testing infrastructure modernization with Aegis framework adoption 81 | - Significant documentation site improvements with SSG migration and enhanced UX 82 | - Expanded SFRA best practices coverage for complete development lifecycle 83 | - Enhanced OCAPI functionality with select parameter support and comprehensive mocking 84 | 85 | ## [1.0.14] - 2025-09-16 86 | ### Added 87 | - **SFCC Class Information Filtering**: Enhanced `get_sfcc_class_info` tool with comprehensive filtering capabilities including search parameter, inclusion/exclusion of descriptions, constants, properties, methods, and inheritance hierarchy. 88 | - **AI Response Comparison Modals**: Interactive modals on documentation site showing side-by-side comparison of AI responses with and without MCP server, including zoom functionality for detailed inspection. 89 | - **Documentation Site Enhancements**: 90 | - Examples page with practical usage scenarios and filtering demonstrations 91 | - Tools page documenting all available MCP tools 92 | - Features page highlighting key capabilities 93 | - Configuration documentation page with setup instructions 94 | - AI Instruction Files section for different AI platforms 95 | - LLMs documentation file for AI assistant integration 96 | - Troubleshooting page for common issues 97 | - Development and security documentation pages 98 | - **Homepage Value Proposition**: Enhanced homepage with clear value proposition and practical examples. 99 | - **Anchor Link Navigation**: Added IDs to documentation headers for direct linking. 100 | 101 | ### Changed 102 | - **Project Licensing**: Aligned to MIT License (replaced ISC LICENSE text, updated `package.json` license field). 103 | - **CI/CD Pipeline**: Enhanced with improved linting and security checks. 104 | - **Documentation Structure**: Comprehensive reorganization and expansion of documentation site structure. 105 | - **Code Examples**: Updated with full path references for better clarity. 106 | - **Configuration Examples**: Updated example configurations for better usability. 107 | - **UI/UX Polish**: Improved padding, layout adjustments, and site navigation structure. 108 | 109 | ### Fixed 110 | - **URL Fragment Handling**: Fixed URL-encoded hash fragment handling in documentation site. 111 | - **Workflow Deployment**: Corrected path issues for page deployment. 112 | - **Log Tool Validation**: Improved argument validation robustness for log analysis tools. 113 | 114 | ### Documentation 115 | - **AI Interface Setup**: Comprehensive guides for Claude Desktop, Cursor, and GitHub Copilot integration. 116 | - **Security Guidance**: Enhanced security considerations and best practices documentation. 117 | - **Troubleshooting**: Added comprehensive troubleshooting guide for common setup and usage issues. 118 | - **Development Workflow**: Detailed development guidelines and contribution instructions. 119 | 120 | ### Testing 121 | - **Enhanced Test Coverage**: 122 | - Comprehensive programmatic tests for SFCC class info filtering in documentation mode 123 | - Enhanced YAML-based MCP tests for class information tools 124 | - Job execution summary tests and job log analysis tests 125 | - Improved test setup reliability and CI stability 126 | 127 | ### Notes 128 | - Major documentation site expansion with React/Vite architecture 129 | - Enhanced developer experience with comprehensive filtering and search capabilities 130 | - Improved AI assistant integration with detailed setup guides for multiple platforms 131 | 132 | ## [1.0.13] - 2025-09-15 133 | ### Added 134 | - `engines` field in `package.json` enforcing Node >=18 and npm >=8. 135 | - Comprehensive architectural documentation (handler modularization, capability gating, services layer, log subsystem, tool-configs, caching). 136 | - Initial `CHANGELOG.md` introduction. 137 | 138 | ### Changed 139 | - Server reported version synchronized with `package.json`. 140 | - Development guide: migrated from legacy Jekyll instructions to Vite workflow; updated tool addition workflow for new handler architecture. 141 | 142 | ### Fixed 143 | - Removed references to non-existent config files (`config.ts`, `constants.ts`). 144 | - Corrected debug flag examples (`--debug` vs `--debug true`). 145 | - Escaping/format fixes in development guide code blocks. 146 | 147 | ### Notes 148 | - Pre-1.0.14 license mismatch (ISC vs MIT badge) resolved in 1.0.14. 149 | 150 | ## [1.0.12] - 2025-08-19 151 | ### Added 152 | - Code version management tools (listing & activation) with supporting documentation. 153 | - Cartridge generation enhancements: page layout & styling improvements; prevention of overwriting existing files. 154 | - Security and OCAPI configuration warnings; highlighted AI instruction files. 155 | - Additional SFRA model and best practice documentation (ISML decorators, LocalServiceRegistry, Auth examples, BM configuration guide). 156 | 157 | ### Changed 158 | - ESLint configuration (global vars, lint fix script), table styling, documentation site theme updates, repository URL in config, branch protection for deploy (restricted to main), improved instance type check. 159 | - Documentation structure reorganized (multiple passes consolidating guides, theme adjustments, layout evolution and subsequent refinements / reverts). 160 | 161 | ### Fixed 162 | - Removal of `resourceState` from activateCodeVersion request. 163 | 164 | ### Documentation 165 | - Large expansion of SFRA models, cartridge creation, ISML templates, decorators warnings, URL patterns, customer context, authentication flows, endpoint security guidance. 166 | 167 | ### Notes 168 | - Multiple rapid doc iterations (additions, reverts, restyles) before stabilization. 169 | 170 | ## [1.0.11] - 2025-08-15 171 | ### Added 172 | - SFCC development rules and SFRA controllers best practices guide. 173 | - AI interface instruction documentation. 174 | 175 | ### Changed 176 | - Refactored rule configurations; enhanced SFCC debugging workflows; streamlined documentation tools; removed improvement roadmap. 177 | 178 | ### Fixed 179 | - Log files now sorted by last modification for accurate recency ordering. 180 | 181 | ### Testing 182 | - Enhanced log client test coverage. 183 | 184 | ### Notes 185 | - Documentation emphasis on rule context explanation and operational clarity. 186 | 187 | ## [1.0.10] - 2025-08-15 188 | ### Added 189 | - Custom object attribute search capability. 190 | - Progressive development guide (subsequently refined) and job framework best practices. 191 | - Additional documentation: steptypes configuration, ISML templates, SCAPI custom endpoint guide, path parameter & search query usage clarifications, SFRA documentation support expansion. 192 | 193 | ### Changed 194 | - Auth examples refactored into appendix; logging improvements and build output cleanliness. 195 | 196 | ### Fixed 197 | - Reversal / clarification cycles for job framework status codes and default values (cleanup of earlier docs ambiguities). 198 | 199 | ### Notes 200 | - Foundation for expanded SCAPI / SFRA documentation just before rapid rule & controller additions in 1.0.11. 201 | 202 | ## [1.0.9-2] - 2025-08-13 203 | ### Changed 204 | - Enhanced release workflow (iteration on same-day release of 1.0.9). 205 | 206 | ## [1.0.9] - 2025-08-13 207 | ### Added 208 | - Initial modular handler & directory architecture groundwork: secure config loading, debug log support, documentation-only mode, system object exposure, site preferences & attribute search, OCAPI client integration. 209 | - CI workflow, caching layer for documentation, expanded class details, path resolver, pre-commit hooks, NPM publishing & Dependabot configuration, issue templates. 210 | 211 | ### Changed 212 | - Large-scale codebase reorganization (directory structure, authentication & logging refactors, configuration loading improvements, handler refactors, OAuth token management relocation, package metadata updates, JSON serialization, system object description refinements, server architecture refactor). 213 | - Log tool naming alignment & tool description clarity improvements. 214 | 215 | ### Fixed 216 | - File path security validation enhancements. 217 | 218 | ### Documentation 219 | - Extensive expansion: best practices (security, performance, cartridge creation), contributing guidelines, search tool description, quick setup, system object definitions, Copilot instructions, local dev focus clarification. 220 | 221 | ### Testing 222 | - Added Jest framework and early test coverage (config factory, OAuth token manager, log client, attribute definitions, best practices client). 223 | 224 | ### Notes 225 | - Represents the foundational public baseline preceding rapid feature layering in 1.0.10+. 226 | 227 | ## [1.0.8] - 2025-08-13 228 | ### Changed 229 | - Package version alignment & metadata updates; project structure and documentation improvements; Node version CI expansions. 230 | 231 | ### Added 232 | - Security & performance best practices guides, contributing guidelines, AI assistant integration guide, deprecation support, attribute definition search, site preferences search. 233 | 234 | ### Notes 235 | - Last pre-architecture refactor baseline before major handler and structural reorganization in 1.0.9. 236 | 237 | ## [1.0.2] - 2025-08-08 238 | ### Added 239 | - Debug logging capabilities, caching for documentation, expanded class details, initial SFCC MCP server feature set (system object & attribute tools, OCAPI integration, documentation retrieval). 240 | - Jest testing framework & initial unit tests. 241 | 242 | ### Changed 243 | - Centralized logging infrastructure; configuration logging & security tightening; authentication config refactors. 244 | 245 | ### Documentation 246 | - Cartridge creation guide, npx usage instructions, API docs, system object definitions resource. 247 | 248 | ### Notes 249 | - Early stabilization phase; intermediate patch releases between 1.0.2 and 1.0.8 consolidated here (internal iteration without tags not reconstructed individually). 250 | 251 | ## [1.0.0] - 2025-08-08 252 | ### Added 253 | - Initial commit introducing SFCC Dev MCP Server core (base server, tooling scaffolding, initial documentation framework). 254 | 255 | ### Notes 256 | - Foundation commit history includes scaffolding, early capability extensions, and initial architectural decisions. 257 | 258 | --- 259 | 260 | --- 261 | 262 | ### Future 263 | - Add automation for changelog validation in CI (ensure categories & links present). 264 | - Add script to generate comparison links automatically when tagging. 265 | - Potential provenance notes for security-impacting changes (e.g., file path validation hardening). 266 | 267 | --- 268 | 269 | ### Comparison Links 270 | [1.0.15]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.14...v1.0.15 271 | [1.0.14]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.13...v1.0.14 272 | [1.0.13]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.12...v1.0.13 273 | [1.0.12]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.11...v1.0.12 274 | [1.0.11]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.10...v1.0.11 275 | [1.0.10]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.9-2...v1.0.10 276 | [1.0.9-2]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.9...v1.0.9-2 277 | [1.0.9]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.8...v1.0.9 278 | [1.0.8]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.2...v1.0.8 279 | [1.0.2]: https://github.com/taurgis/sfcc-dev-mcp/compare/v1.0.0...v1.0.2 280 | [1.0.0]: https://github.com/taurgis/sfcc-dev-mcp/tree/v1.0.0 281 | 282 | ``` -------------------------------------------------------------------------------- /docs/dw_order/LineItem.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.order 2 | 3 | # Class LineItem 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.object.PersistentObject 9 | - dw.object.ExtensibleObject 10 | - dw.order.LineItem 11 | 12 | ## Description 13 | 14 | Common line item base class. 15 | 16 | ## Properties 17 | 18 | ### basePrice 19 | 20 | **Type:** Money 21 | 22 | The base price for the line item, which is the price of the unit before applying adjustments, in the 23 | purchase currency. The base price may be net or gross of tax depending on the configured taxation policy. 24 | 25 | ### grossPrice 26 | 27 | **Type:** Money 28 | 29 | The gross price for the line item, which is the price of the unit before applying adjustments, in the 30 | purchase currency, including tax. 31 | 32 | ### lineItemCtnr 33 | 34 | **Type:** LineItemCtnr (Read Only) 35 | 36 | The line item ctnr of the line item. 37 | 38 | ### lineItemText 39 | 40 | **Type:** String 41 | 42 | The display text for the line item. 43 | 44 | ### netPrice 45 | 46 | **Type:** Money 47 | 48 | The net price for the line item, which is the price of the unit before applying adjustments, in the 49 | purchase currency, excluding tax. 50 | 51 | ### price 52 | 53 | **Type:** Money (Read Only) 54 | 55 | Get the price of the line item. If the line item is based on net pricing then the net price is returned. If the 56 | line item is based on gross pricing then the gross price is returned. 57 | 58 | ### priceValue 59 | 60 | **Type:** Number 61 | 62 | Return the price amount for the line item. Same as getPrice().getValue(). 63 | 64 | ### tax 65 | 66 | **Type:** Money 67 | 68 | The tax for the line item, which is the tax of the unit before applying adjustments, in the purchase 69 | currency. 70 | 71 | ### taxBasis 72 | 73 | **Type:** Money (Read Only) 74 | 75 | Get the price used to calculate the tax for this line item. 76 | 77 | ### taxClassID 78 | 79 | **Type:** String 80 | 81 | The tax class ID for the line item or null if no tax class ID is associated with the line item. In the 82 | case where the tax class ID is null, you should use the default tax class ID. 83 | 84 | ### taxRate 85 | 86 | **Type:** Number 87 | 88 | The tax rate, which is the decimal tax rate to be applied to the product represented by this line item. A 89 | value of 0.175 represents a percentage of 17.5%. 90 | 91 | ## Constructor Summary 92 | 93 | ## Method Summary 94 | 95 | ### getBasePrice 96 | 97 | **Signature:** `getBasePrice() : Money` 98 | 99 | Returns the base price for the line item, which is the price of the unit before applying adjustments, in the purchase currency. 100 | 101 | ### getGrossPrice 102 | 103 | **Signature:** `getGrossPrice() : Money` 104 | 105 | Returns the gross price for the line item, which is the price of the unit before applying adjustments, in the purchase currency, including tax. 106 | 107 | ### getLineItemCtnr 108 | 109 | **Signature:** `getLineItemCtnr() : LineItemCtnr` 110 | 111 | Returns the line item ctnr of the line item. 112 | 113 | ### getLineItemText 114 | 115 | **Signature:** `getLineItemText() : String` 116 | 117 | Returns the display text for the line item. 118 | 119 | ### getNetPrice 120 | 121 | **Signature:** `getNetPrice() : Money` 122 | 123 | Returns the net price for the line item, which is the price of the unit before applying adjustments, in the purchase currency, excluding tax. 124 | 125 | ### getPrice 126 | 127 | **Signature:** `getPrice() : Money` 128 | 129 | Get the price of the line item. 130 | 131 | ### getPriceValue 132 | 133 | **Signature:** `getPriceValue() : Number` 134 | 135 | Return the price amount for the line item. 136 | 137 | ### getTax 138 | 139 | **Signature:** `getTax() : Money` 140 | 141 | Returns the tax for the line item, which is the tax of the unit before applying adjustments, in the purchase currency. 142 | 143 | ### getTaxBasis 144 | 145 | **Signature:** `getTaxBasis() : Money` 146 | 147 | Get the price used to calculate the tax for this line item. 148 | 149 | ### getTaxClassID 150 | 151 | **Signature:** `getTaxClassID() : String` 152 | 153 | Returns the tax class ID for the line item or null if no tax class ID is associated with the line item. 154 | 155 | ### getTaxRate 156 | 157 | **Signature:** `getTaxRate() : Number` 158 | 159 | Returns the tax rate, which is the decimal tax rate to be applied to the product represented by this line item. 160 | 161 | ### setBasePrice 162 | 163 | **Signature:** `setBasePrice(aValue : Money) : void` 164 | 165 | Sets the base price for the line item, which is the price of the unit before applying adjustments, in the purchase currency. 166 | 167 | ### setGrossPrice 168 | 169 | **Signature:** `setGrossPrice(aValue : Money) : void` 170 | 171 | Sets the gross price for the line item, which is the Price of the unit before applying adjustments, in the purchase currency, including tax. 172 | 173 | ### setLineItemText 174 | 175 | **Signature:** `setLineItemText(aText : String) : void` 176 | 177 | Sets the display text for the line item. 178 | 179 | ### setNetPrice 180 | 181 | **Signature:** `setNetPrice(aValue : Money) : void` 182 | 183 | Sets the value for the net price, which is the price of the unit before applying adjustments, in the purchase currency, excluding tax. 184 | 185 | ### setPriceValue 186 | 187 | **Signature:** `setPriceValue(value : Number) : void` 188 | 189 | Sets price attributes of the line item based on the current purchase currency and taxation policy. 190 | 191 | ### setTax 192 | 193 | **Signature:** `setTax(aValue : Money) : void` 194 | 195 | Sets the value for the tax of the line item, which is the the tax of the unit before applying adjustments, in the purchase currency. 196 | 197 | ### setTaxClassID 198 | 199 | **Signature:** `setTaxClassID(aValue : String) : void` 200 | 201 | Sets the tax class ID for the line item. 202 | 203 | ### setTaxRate 204 | 205 | **Signature:** `setTaxRate(taxRate : Number) : void` 206 | 207 | Sets the tax rate, which is the decimal tax rate to be applied to the product represented by this line item. 208 | 209 | ### updatePrice 210 | 211 | **Signature:** `updatePrice(price : Money) : void` 212 | 213 | Updates the price attributes of the line item based on the specified price. 214 | 215 | ### updateTax 216 | 217 | **Signature:** `updateTax(taxRate : Number) : void` 218 | 219 | Updates the tax-related attributes of the line item based on the specified tax rate, a tax basis determined by the system and the "Tax Rounding Mode" order preference. 220 | 221 | ### updateTax 222 | 223 | **Signature:** `updateTax(taxRate : Number, taxBasis : Money) : void` 224 | 225 | Updates the tax-related attributes of the line item based on the specified tax rate, the passed tax basis and the "Tax Rounding Mode" order preference. 226 | 227 | ### updateTaxAmount 228 | 229 | **Signature:** `updateTaxAmount(tax : Money) : void` 230 | 231 | Updates tax amount of the line item setting the provided value. 232 | 233 | ## Method Detail 234 | 235 | ## Method Details 236 | 237 | ### getBasePrice 238 | 239 | **Signature:** `getBasePrice() : Money` 240 | 241 | **Description:** Returns the base price for the line item, which is the price of the unit before applying adjustments, in the purchase currency. The base price may be net or gross of tax depending on the configured taxation policy. 242 | 243 | **Returns:** 244 | 245 | the base price for the line item. 246 | 247 | --- 248 | 249 | ### getGrossPrice 250 | 251 | **Signature:** `getGrossPrice() : Money` 252 | 253 | **Description:** Returns the gross price for the line item, which is the price of the unit before applying adjustments, in the purchase currency, including tax. 254 | 255 | **Returns:** 256 | 257 | the value of the gross price. 258 | 259 | --- 260 | 261 | ### getLineItemCtnr 262 | 263 | **Signature:** `getLineItemCtnr() : LineItemCtnr` 264 | 265 | **Description:** Returns the line item ctnr of the line item. 266 | 267 | **Returns:** 268 | 269 | Line item ctnr of the line item 270 | 271 | --- 272 | 273 | ### getLineItemText 274 | 275 | **Signature:** `getLineItemText() : String` 276 | 277 | **Description:** Returns the display text for the line item. 278 | 279 | **Returns:** 280 | 281 | the display text. 282 | 283 | --- 284 | 285 | ### getNetPrice 286 | 287 | **Signature:** `getNetPrice() : Money` 288 | 289 | **Description:** Returns the net price for the line item, which is the price of the unit before applying adjustments, in the purchase currency, excluding tax. 290 | 291 | **Returns:** 292 | 293 | the value for the net price. 294 | 295 | --- 296 | 297 | ### getPrice 298 | 299 | **Signature:** `getPrice() : Money` 300 | 301 | **Description:** Get the price of the line item. If the line item is based on net pricing then the net price is returned. If the line item is based on gross pricing then the gross price is returned. 302 | 303 | **Returns:** 304 | 305 | either the net or the gross price 306 | 307 | --- 308 | 309 | ### getPriceValue 310 | 311 | **Signature:** `getPriceValue() : Number` 312 | 313 | **Description:** Return the price amount for the line item. Same as getPrice().getValue(). 314 | 315 | **Returns:** 316 | 317 | the price for the line item 318 | 319 | --- 320 | 321 | ### getTax 322 | 323 | **Signature:** `getTax() : Money` 324 | 325 | **Description:** Returns the tax for the line item, which is the tax of the unit before applying adjustments, in the purchase currency. 326 | 327 | **Returns:** 328 | 329 | the tax for the line item. 330 | 331 | --- 332 | 333 | ### getTaxBasis 334 | 335 | **Signature:** `getTaxBasis() : Money` 336 | 337 | **Description:** Get the price used to calculate the tax for this line item. 338 | 339 | **Returns:** 340 | 341 | The tax basis used to calculate tax for this line item, or Money.NOT_AVAILABLE if tax has not been set for this line item yet. 342 | 343 | --- 344 | 345 | ### getTaxClassID 346 | 347 | **Signature:** `getTaxClassID() : String` 348 | 349 | **Description:** Returns the tax class ID for the line item or null if no tax class ID is associated with the line item. In the case where the tax class ID is null, you should use the default tax class ID. 350 | 351 | **Returns:** 352 | 353 | the tax class ID for the line item or null if no tax class ID is associated with the line item. 354 | 355 | **See Also:** 356 | 357 | TaxMgr.getDefaultTaxClassID() 358 | 359 | --- 360 | 361 | ### getTaxRate 362 | 363 | **Signature:** `getTaxRate() : Number` 364 | 365 | **Description:** Returns the tax rate, which is the decimal tax rate to be applied to the product represented by this line item. A value of 0.175 represents a percentage of 17.5%. 366 | 367 | **Returns:** 368 | 369 | the value of the tax rate. 370 | 371 | --- 372 | 373 | ### setBasePrice 374 | 375 | **Signature:** `setBasePrice(aValue : Money) : void` 376 | 377 | **Description:** Sets the base price for the line item, which is the price of the unit before applying adjustments, in the purchase currency. The base price may be net or gross of tax depending on the configured taxation policy. 378 | 379 | **Deprecated:** 380 | 381 | Use updatePrice(Money) instead. 382 | 383 | **Parameters:** 384 | 385 | - `aValue`: the new value of the base price. 386 | 387 | --- 388 | 389 | ### setGrossPrice 390 | 391 | **Signature:** `setGrossPrice(aValue : Money) : void` 392 | 393 | **Description:** Sets the gross price for the line item, which is the Price of the unit before applying adjustments, in the purchase currency, including tax. 394 | 395 | **Deprecated:** 396 | 397 | Use updatePrice(Money) which sets the base price and also the gross price if the line item is based on gross pricing. 398 | 399 | **Parameters:** 400 | 401 | - `aValue`: the new value of the attribute 402 | 403 | --- 404 | 405 | ### setLineItemText 406 | 407 | **Signature:** `setLineItemText(aText : String) : void` 408 | 409 | **Description:** Sets the display text for the line item. 410 | 411 | **Parameters:** 412 | 413 | - `aText`: line item text. 414 | 415 | --- 416 | 417 | ### setNetPrice 418 | 419 | **Signature:** `setNetPrice(aValue : Money) : void` 420 | 421 | **Description:** Sets the value for the net price, which is the price of the unit before applying adjustments, in the purchase currency, excluding tax. 422 | 423 | **Deprecated:** 424 | 425 | Use updatePrice(Money) which sets the base price and also the net price if the line item is based on net pricing. 426 | 427 | **Parameters:** 428 | 429 | - `aValue`: the new value for the net price 430 | 431 | --- 432 | 433 | ### setPriceValue 434 | 435 | **Signature:** `setPriceValue(value : Number) : void` 436 | 437 | **Description:** Sets price attributes of the line item based on the current purchase currency and taxation policy. The methods sets the 'basePrice' attribute of the line item. Additionally, it sets the 'netPrice' attribute of the line item if the current taxation policy is 'net', and the 'grossPrice' attribute, if the current taxation policy is 'gross'. If null is specified as value, the price attributes are reset to Money.NOT_AVAILABLE. 438 | 439 | **Parameters:** 440 | 441 | - `value`: Price value or null 442 | 443 | --- 444 | 445 | ### setTax 446 | 447 | **Signature:** `setTax(aValue : Money) : void` 448 | 449 | **Description:** Sets the value for the tax of the line item, which is the the tax of the unit before applying adjustments, in the purchase currency. 450 | 451 | **Parameters:** 452 | 453 | - `aValue`: the new value for the tax. 454 | 455 | --- 456 | 457 | ### setTaxClassID 458 | 459 | **Signature:** `setTaxClassID(aValue : String) : void` 460 | 461 | **Description:** Sets the tax class ID for the line item. 462 | 463 | **Parameters:** 464 | 465 | - `aValue`: the tax class ID for the line item. 466 | 467 | --- 468 | 469 | ### setTaxRate 470 | 471 | **Signature:** `setTaxRate(taxRate : Number) : void` 472 | 473 | **Description:** Sets the tax rate, which is the decimal tax rate to be applied to the product represented by this line item. A value of 0.175 represents a percentage of 17.5%. 474 | 475 | **Parameters:** 476 | 477 | - `taxRate`: the new value for the tax rate. 478 | 479 | --- 480 | 481 | ### updatePrice 482 | 483 | **Signature:** `updatePrice(price : Money) : void` 484 | 485 | **Description:** Updates the price attributes of the line item based on the specified price. The base price is set to the specified value. If the line item is based on net pricing then the net price attribute is set. If the line item is based on gross pricing then the gross price attribute is set. Whether or not a line item is based on net or gross pricing is a site-wide configuration parameter. 486 | 487 | **Deprecated:** 488 | 489 | Use setPriceValue(Number) instead. 490 | 491 | **Parameters:** 492 | 493 | - `price`: The price to use when performing the update. This price must not be null and must either be equal to NOT_AVAIALBLE or must have a currency code equal to that of the parent container. 494 | 495 | --- 496 | 497 | ### updateTax 498 | 499 | **Signature:** `updateTax(taxRate : Number) : void` 500 | 501 | **Description:** Updates the tax-related attributes of the line item based on the specified tax rate, a tax basis determined by the system and the "Tax Rounding Mode" order preference. This method sets the tax basis as an attribute, and is not affected by the previous value of this attribute. The value used as a basis depends on the type of line item this is and on the promotion preferences for the current site. If you tax products, shipping, and discounts based on price (default), then the tax basis will simply be equal to getPrice(). If you tax products and shipping only based on adjusted price, then the tax basis depends upon line item type as follows: ProductLineItem: basis equals ProductLineItem.getProratedPrice(). ShippingLineItem: basis equals ShippingLineItem.getAdjustedPrice(). ProductShippingLineItem: basis equals ProductShippingLineItem.getAdjustedPrice(). PriceAdjustment: basis equals 0.00. All other line item types: basis equals getPrice(). If null is passed as tax rate, tax-related attribute fields are set to N/A. 502 | 503 | **Parameters:** 504 | 505 | - `taxRate`: taxRate the tax rate to use or null. 506 | 507 | --- 508 | 509 | ### updateTax 510 | 511 | **Signature:** `updateTax(taxRate : Number, taxBasis : Money) : void` 512 | 513 | **Description:** Updates the tax-related attributes of the line item based on the specified tax rate, the passed tax basis and the "Tax Rounding Mode" order preference. If null is passed as tax rate or tax basis, tax-related attribute fields are set to N/A. 514 | 515 | **Parameters:** 516 | 517 | - `taxRate`: the tax rate to use or null. 518 | - `taxBasis`: the tax basis to use or null. 519 | 520 | --- 521 | 522 | ### updateTaxAmount 523 | 524 | **Signature:** `updateTaxAmount(tax : Money) : void` 525 | 526 | **Description:** Updates tax amount of the line item setting the provided value. Depending on the way how the tax is calculated (based on net or gross price), the corresponding gross or net price is updated accordingly. For tax calculation based on net price, the gross price is calculated by adding the tax to the net price. For tax calculation based on gross price, the net price is calculated by subtracting the tax from the gross price. If null is passed as tax amount, the item tax and resulting net or gross price are set to N/A. Note that tax rate is not calculated and it is not updated. 527 | 528 | **Parameters:** 529 | 530 | - `tax`: the tax amount of the line item to set 531 | 532 | --- ``` -------------------------------------------------------------------------------- /docs/dw_object/SystemObjectMgr.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.object 2 | 3 | # Class SystemObjectMgr 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.object.SystemObjectMgr 9 | 10 | ## Description 11 | 12 | Manager class which provides methods for querying of system objects with meta data using the Commerce Cloud Digital query language. See individual API methods for details on the query language. Note: Other manager classes such as CustomerMgr, ProductMgr, etc provide more specific and fine-grained querying methods that can not be achieved using the general query language. The following system object types are supported: GiftCertificate SourceCodeGroup Store ProductList Support for the following system object types is deprecated: Order Profile Use the search methods from CustomerMgr and OrderMgr, respectively for querying these types. To search for custom objects, use CustomObjectMgr. Note: this class allows access to sensitive information through operations that retrieve the Profile and Order objects. Pay attention to appropriate legal and regulatory requirements related to this data. 13 | 14 | ## Constructor Summary 15 | 16 | ## Method Summary 17 | 18 | ### describe 19 | 20 | **Signature:** `static describe(type : String) : ObjectTypeDefinition` 21 | 22 | Returns the object type definition for the given system object type. 23 | 24 | ### getAllSystemObjects 25 | 26 | **Signature:** `static getAllSystemObjects(type : String) : SeekableIterator` 27 | 28 | Returns all system objects of a specific type. 29 | 30 | ### querySystemObject 31 | 32 | **Signature:** `static querySystemObject(type : String, queryString : String, args : Object...) : PersistentObject` 33 | 34 | Searches for a single system object instance. 35 | 36 | ### querySystemObjects 37 | 38 | **Signature:** `static querySystemObjects(type : String, queryString : String, sortString : String, args : Object...) : SeekableIterator` 39 | 40 | Searches for system object instances. 41 | 42 | ### querySystemObjects 43 | 44 | **Signature:** `static querySystemObjects(type : String, queryAttributes : Map, sortString : String) : SeekableIterator` 45 | 46 | Searches for system object instances. 47 | 48 | ## Method Detail 49 | 50 | ## Method Details 51 | 52 | ### describe 53 | 54 | **Signature:** `static describe(type : String) : ObjectTypeDefinition` 55 | 56 | **Description:** Returns the object type definition for the given system object type. This method can be used for all system object types that are derived from ExtensibleObject. 57 | 58 | **Parameters:** 59 | 60 | - `type`: system object type whose type definition should be returned 61 | 62 | **Returns:** 63 | 64 | the matching object type definition or null in case no such type definition exists. 65 | 66 | --- 67 | 68 | ### getAllSystemObjects 69 | 70 | **Signature:** `static getAllSystemObjects(type : String) : SeekableIterator` 71 | 72 | **Description:** Returns all system objects of a specific type. The following system object types are supported: GiftCertificate Order Profile SourceCodeGroup Store ProductList The method throws an exception in case of another system type. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources. 73 | 74 | **Parameters:** 75 | 76 | - `type`: The name of the system object type. If a matching type definition cannot be found for the given type a MetaDataException will be thrown. 77 | 78 | **Returns:** 79 | 80 | SeekableIterator containing all system objects of a specific type. 81 | 82 | **See Also:** 83 | 84 | SeekableIterator.close() 85 | 86 | --- 87 | 88 | ### querySystemObject 89 | 90 | **Signature:** `static querySystemObject(type : String, queryString : String, args : Object...) : PersistentObject` 91 | 92 | **Description:** Searches for a single system object instance. The following system object types are supported: GiftCertificate Order Profile SourceCodeGroup Store ProductList The method throws an exception in case of another system type. The search can be configured using a simple query language, which provides most common filter and operator functionality. The identifier for an attribute to use in a query condition is always the ID of the attribute as defined in the type definition. For custom defined attributes the prefix custom is required in the search term (e.g. custom.color = {1}), while for system attributes no prefix is used (e.g. name = {4}). Supported attribute value types with sample expression values: String 'String', 'Str*', 'Strin?' Integer 1, 3E4 Number 1.0, 3.99E5 Date yyyy-MM-dd e.g. 2007-05-31 (Default TimeZone = UTC) DateTime yyyy-MM-dd'T'hh:mm:ss+Z e.g. 2007-05-31T00:00+Z (Z TimeZone = UTC) or 2007-05-31T00:00:00 Boolean true, false Email '[email protected]', '*@demandware.com' Set of String 'String', 'Str*', 'Strin?' Set of Integer 1, 3E4 Set of Number 1.0, 3.99E5 Enum of String 'String', 'Str*', 'Strin?' Enum of Integer 1, 3E4 The following types of attributes are not queryable: Image HTML Text Quantity Password Note, that some system attributes are not queryable by default regardless of the actual value type code. The following operators are supported in a condition: = Equals - All types; supports NULL value (thumbnail = NULL) != Not equals - All types; supports NULL value (thumbnail != NULL) < Less than - Integer, Number and Date types only > Greater than - Integer, Number and Date types only <= Less or equals than - Integer, Number and Date types only >= Greater or equals than - Integer, Number and Date types only LIKE Like - String types and Email only; use if leading or trailing wildcards will be used to support substring search(custom.country LIKE 'US*') ILIKE Caseindependent Like - String types and Email only, use to support case insensitive query (custom.country ILIKE 'usa'), does also support wildcards for substring matching Conditions can be combined using logical expressions 'AND', 'OR' and 'NOT' and nested using parenthesis e.g. gender = {1} AND (age >= {2} OR (NOT profession LIKE {3})). The query language provides a placeholder syntax to pass objects as additional search parameters. Each passed object is related to a placeholder in the query string. The placeholder must be an Integer that is surrounded by braces. The first Integer value must be '0', the second '1' and so on, e.g. querySystemObjects("sample", "age = {0} or creationDate >= {1}", 18, date) If there is more than one object matching the specified query criteria, the result is not deterministic. In order to retrieve a single object from a sorted result set it is recommended to use the following code: querySystemObjects("", "custom.myAttr asc", null).first(). The method first() returns only the next element and closes the iterator. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being processed. This will enable the cleanup of system resources. This method does not consider locale specific attributes. It returns all objects by checking the default non-localizable attributes. Any locale specific filtering after fetching the objects must be done by other custom code. Example: For store objects, such a locale specific filtering can be: Get the store objects using this method with non-localized attributes query. Access the store.getCustom("myattr"). It returns the localized value of the attribute. 93 | 94 | **Parameters:** 95 | 96 | - `type`: the system object type for the query. 97 | - `queryString`: the actual query. 98 | - `args`: optional parameters for the queryString. 99 | 100 | **Returns:** 101 | 102 | the system object defined by type which was found when executing the queryString. 103 | 104 | **See Also:** 105 | 106 | SeekableIterator.close() 107 | 108 | --- 109 | 110 | ### querySystemObjects 111 | 112 | **Signature:** `static querySystemObjects(type : String, queryString : String, sortString : String, args : Object...) : SeekableIterator` 113 | 114 | **Description:** Searches for system object instances. The following system object types are supported: GiftCertificate Order Profile SourceCodeGroup Store ProductList The method throws an exception in case of another system type. The search can be configured using a simple query language, which provides most common filter and operator functionality. The identifier for an attribute to use in a query condition is always the ID of the attribute as defined in the type definition. For custom defined attributes the prefix custom is required in the search term (e.g. custom.color = {1}), while for system attributes no prefix is used (e.g. name = {4}). Supported attribute value types with sample expression values: String 'String', 'Str*', 'Strin?' Integer 1, 3E4 Number 1.0, 3.99E5 Date yyyy-MM-dd e.g. 2007-05-31 (Default TimeZone = UTC) DateTime yyyy-MM-dd'T'hh:mm:ss+Z e.g. 2007-05-31T00:00+Z (Z TimeZone = UTC) or 2007-05-31T00:00:00 Boolean true, false Email '[email protected]', '*@demandware.com' Set of String 'String', 'Str*', 'Strin?' Set of Integer 1, 3E4 Set of Number 1.0, 3.99E5 Enum of String 'String', 'Str*', 'Strin?' Enum of Integer 1, 3E4 The following types of attributes are not queryable: Image HTML Text Quantity Password Note, that some system attributes are not queryable by default regardless of the actual value type code. The following operators are supported in a condition: = Equals - All types; supports NULL value (thumbnail = NULL) != Not equals - All types; supports NULL value (thumbnail != NULL) < Less than - Integer, Number and Date types only > Greater than - Integer, Number and Date types only <= Less or equals than - Integer, Number and Date types only >= Greater or equals than - Integer, Number and Date types only LIKE Like - String types and Email only; use if leading or trailing wildcards will be used to support substring search(custom.country LIKE 'US*') ILIKE Caseindependent Like - String types and Email only, use to support case insensitive query (custom.country ILIKE 'usa'), does also support wildcards for substring matching Conditions can be combined using logical expressions 'AND', 'OR' and 'NOT' and nested using parenthesis e.g. gender = {1} AND (age >= {2} OR (NOT profession LIKE {3})). The query language provides a placeholder syntax to pass objects as additional search parameters. Each passed object is related to a placeholder in the query string. The placeholder must be an Integer that is surrounded by braces. The first Integer value must be '0', the second '1' and so on, e.g. querySystemObjects("sample", "age = {0} or creationDate >= {1}", 18, date) The sorting parameter is optional and may contain a comma separated list of attribute names to sort by. Each sort attribute name may be followed by an optional sort direction specifier ('asc' | 'desc'). Default sorting directions is ascending, if no direction was specified. Example: age desc, name Please note that specifying a localized custom attribute as the sorting attribute is currently not supported. Sometimes it is desired to get all instances of specified type with a special sorting condition. This can be easily done by providing the 'type' of the system object and the 'sortString' in combination with an empty 'queryString', e.g. querySystemObjects("sample", "", "ID asc") It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources. This method does not consider locale specific attributes. It returns all objects by checking the default non-localizable attributes. Any locale specific filtering after fetching the objects must be done by other custom code. Example: For store objects, such a locale specific filtering can be: Get the store objects using this method with non-localized attributes query. Access the store.getCustom("myattr"). It returns the localized value of the attribute. 115 | 116 | **Parameters:** 117 | 118 | - `type`: the system object type for the query. 119 | - `queryString`: the actual query. 120 | - `sortString`: an optional sorting or null if no sorting is necessary. 121 | - `args`: optional parameters for the queryString. 122 | 123 | **Returns:** 124 | 125 | SeekableIterator containing the result set of the query. 126 | 127 | **See Also:** 128 | 129 | SeekableIterator.close() 130 | 131 | --- 132 | 133 | ### querySystemObjects 134 | 135 | **Signature:** `static querySystemObjects(type : String, queryAttributes : Map, sortString : String) : SeekableIterator` 136 | 137 | **Description:** Searches for system object instances. The following system object types are supported: GiftCertificate Order Profile SourceCodeGroup Store ProductList The method throws an exception in case of another system type. The search can be configured with a map, which key-value pairs are converted into a query expression. The key-value pairs are turned into a sequence of '=' or 'like' conditions, which are combined with AND statements. Example: A map with the key/value pairs: 'name'/'tom*', 'age'/66 will be converted as follows: "name like 'tom*' and age = 66" The identifier for an attribute to use in a query condition is always the ID of the attribute as defined in the type definition. For custom defined attributes the prefix custom is required in the search term (e.g. custom.color = {1}), while for system attributes no prefix is used (e.g. name = {4}). Supported attribute value types with sample expression values: String 'String', 'Str*', 'Strin?' Integer 1, 3E4 Number 1.0, 3.99E5 Date yyyy-MM-dd e.g. 2007-05-31 (Default TimeZone = UTC) DateTime yyyy-MM-dd'T'hh:mm:ss+Z e.g. 2007-05-31T00:00+Z (Z TimeZone = UTC) or 2007-05-31T00:00:00 Boolean true, false Email '[email protected]', '*@demandware.com' Set of String 'String', 'Str*', 'Strin?' Set of Integer 1, 3E4 Set of Number 1.0, 3.99E5 Enum of String 'String', 'Str*', 'Strin?' Enum of Integer 1, 3E4 The following types of attributes are not queryable: Image HTML Text Quantity Password Note, that some system attributes are not queryable by default regardless of the actual value type code. The sorting parameter is optional and may contain a comma separated list of attribute names to sort by. Each sort attribute name may be followed by an optional sort direction specifier ('asc' | 'desc'). Default sorting directions is ascending, if no direction was specified. Example: age desc, name Please note that specifying a localized custom attribute as the sorting attribute is currently not supported. It is strongly recommended to call close() on the returned SeekableIterator if not all of its elements are being retrieved. This will ensure the proper cleanup of system resources. This method does not consider locale specific attributes. It returns all objects by checking the default non-localizable attributes. Any locale specific filtering after fetching the objects must be done by other custom code. Example: For store objects, such a locale specific filtering can be: Get the store objects using this method with non-localized attributes query. Access the store.getCustom("myattr"). It returns the localized value of the attribute. 138 | 139 | **Parameters:** 140 | 141 | - `type`: the system object type for the query. 142 | - `queryAttributes`: key-value pairs, which define the query. 143 | - `sortString`: an optional sorting or null if no sorting is necessary. 144 | 145 | **Returns:** 146 | 147 | SeekableIterator containing the result set of the query. 148 | 149 | **See Also:** 150 | 151 | SeekableIterator.close() 152 | 153 | --- ``` -------------------------------------------------------------------------------- /docs/dw_extensions.applepay/ApplePayHooks.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.extensions.applepay 2 | 3 | # Class ApplePayHooks 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - dw.extensions.applepay.ApplePayHooks 8 | 9 | ## Description 10 | 11 | ApplePayHooks interface containing extension points for customizing Apple Pay. These hooks are executed in a transaction. The extension points (hook names), and the functions that are called by each extension point. A function must be defined inside a JavaScript source and must be exported. The script with the exported hook function must be located inside a site cartridge. Inside the site cartridge a 'package.json' file with a 'hooks' entry must exist. "hooks": "./hooks.json" The hooks entry links to a json file, relative to the 'package.json' file. This file lists all registered hooks inside the hooks property: "hooks": [ {"name": "dw.extensions.applepay.getRequest", "script": "./applepay.ds"} {"name": "dw.extensions.applepay.shippingContactSelected", "script": "./applepay.ds"} ] A hook entry has a 'name' and a 'script' property. The 'name' contains the extension point, the hook name. The 'script' contains the script relative to the hooks file, with the exported hook function. 12 | 13 | ## Constants 14 | 15 | ## Properties 16 | 17 | ## Constructor Summary 18 | 19 | ## Method Summary 20 | 21 | ### authorizeOrderPayment 22 | 23 | **Signature:** `authorizeOrderPayment(order : Order, event : Object) : Status` 24 | 25 | Called to authorize the Apple Pay payment for the order. 26 | 27 | ### cancel 28 | 29 | **Signature:** `cancel(basket : Basket) : ApplePayHookResult` 30 | 31 | Called after the Apple Pay payment sheet was canceled. 32 | 33 | ### createOrder 34 | 35 | **Signature:** `createOrder(basket : Basket, event : Object) : Order` 36 | 37 | Called after handling the given ApplePayPaymentAuthorizedEvent for the given basket. 38 | 39 | ### failOrder 40 | 41 | **Signature:** `failOrder(order : Order, status : Status) : ApplePayHookResult` 42 | 43 | Called after payment authorization is unsuccessful and the given Apple Pay order must be failed. 44 | 45 | ### getRequest 46 | 47 | **Signature:** `getRequest(basket : Basket, request : Object) : ApplePayHookResult` 48 | 49 | Called to get the Apple Pay JS PaymentRequest for the given basket. 50 | 51 | ### paymentMethodSelected 52 | 53 | **Signature:** `paymentMethodSelected(basket : Basket, event : Object, response : Object) : ApplePayHookResult` 54 | 55 | Called after handling the given ApplePayPaymentMethodSelectedEvent for the given basket. 56 | 57 | ### placeOrder 58 | 59 | **Signature:** `placeOrder(order : Order) : ApplePayHookResult` 60 | 61 | Called after payment has been authorized and the given Apple Pay order is ready to be placed. 62 | 63 | ### prepareBasket 64 | 65 | **Signature:** `prepareBasket(basket : Basket, parameters : Object) : ApplePayHookResult` 66 | 67 | Called to prepare the given basket for an Apple Pay checkout. 68 | 69 | ### shippingContactSelected 70 | 71 | **Signature:** `shippingContactSelected(basket : Basket, event : Object, response : Object) : ApplePayHookResult` 72 | 73 | Called after handling the given ApplePayShippingContactSelectedEvent for the given basket. 74 | 75 | ### shippingMethodSelected 76 | 77 | **Signature:** `shippingMethodSelected(basket : Basket, shippingMethod : ShippingMethod, event : Object, response : Object) : ApplePayHookResult` 78 | 79 | Called after handling the given ApplePayShippingMethodSelectedEvent for the given basket. 80 | 81 | ## Method Detail 82 | 83 | ## Method Details 84 | 85 | ### authorizeOrderPayment 86 | 87 | **Signature:** `authorizeOrderPayment(order : Order, event : Object) : Status` 88 | 89 | **Description:** Called to authorize the Apple Pay payment for the order. The given order will have been created by the extensionPointPaymentAuthorizedCreateOrder hook, after the basket was populated with data from the ApplePayPaymentAuthorizedEvent. Return a non-error status if you have successfully authorized the payment with your payment service provider. Your hook implementation must set the necessary payment status and transaction identifier data on the order as returned by the provider. Return an error status to indicate a problem, including unsuccessful authorization. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. See the Apple Pay JS API Reference for more information. 90 | 91 | **Parameters:** 92 | 93 | - `order`: the order paid using Apple Pay 94 | - `event`: ApplePayPaymentAuthorizedEvent object 95 | 96 | **Returns:** 97 | 98 | a non-null status ends the hook execution 99 | 100 | --- 101 | 102 | ### cancel 103 | 104 | **Signature:** `cancel(basket : Basket) : ApplePayHookResult` 105 | 106 | **Description:** Called after the Apple Pay payment sheet was canceled. There is no Apple Pay JS event object for this case. The given basket is the one that was passed to other hooks earlier in the Apple Pay checkout process. It is not guaranteed that this hook will be executed for all Apple Pay payment sheets canceled by shoppers or otherwise ended without a successful order. Calls to this hook are provided on a best-effort basis. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if possible. It is not guaranteed that the response with the hook result will be handled in the shopper browser in all cases. 107 | 108 | **Parameters:** 109 | 110 | - `basket`: the basket that was being checked out using Apple Pay 111 | 112 | **Returns:** 113 | 114 | a non-null result ends the hook execution 115 | 116 | --- 117 | 118 | ### createOrder 119 | 120 | **Signature:** `createOrder(basket : Basket, event : Object) : Order` 121 | 122 | **Description:** Called after handling the given ApplePayPaymentAuthorizedEvent for the given basket. Customer information, billing address, and/or shipping address for the default shipment will have already been updated to reflect the available contact information provided by Apple Pay based on the Apple Pay configuration for your site. Any preexisting payment instruments on the basket will have been removed, and a single DW_APPLE_PAY payment instrument added for the total amount. The purpose of this hook is to populate the created order with any necessary information from the basket or the Apple Pay event. Do not use this hook for address verification, or any other validation. Instead use the extensionPointPaymentAuthorizedAuthorizeOrderPayment hook which allows you to return an ApplePayHookResult with error status information. The default implementation of this hook simply calls OrderMgr.createOrder and returns the created order. Throw an error to indicate a problem creating the order. 123 | 124 | **Parameters:** 125 | 126 | - `basket`: the basket being checked out using Apple Pay 127 | - `event`: ApplePayPaymentAuthorizedEvent object 128 | 129 | **Returns:** 130 | 131 | a non-null order ends the hook execution 132 | 133 | --- 134 | 135 | ### failOrder 136 | 137 | **Signature:** `failOrder(order : Order, status : Status) : ApplePayHookResult` 138 | 139 | **Description:** Called after payment authorization is unsuccessful and the given Apple Pay order must be failed. The purpose of this hook is to fail the order, or return a redirect URL that results in the order being failed when the shopper browser is navigated to it. The given status object is the result of calling the extensionPointPaymentAuthorizedAuthorizeOrderPayment hook. The default implementation of this hook simply calls OrderMgr.failOrder, and returns a result with the given status and no redirect URL. Return a result with an error status to indicate a problem. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if the Apple Pay payment sheet is canceled. 140 | 141 | **Parameters:** 142 | 143 | - `order`: the order created for a failed Apple Pay checkout 144 | - `status`: status code returned by the extensionPointPaymentAuthorizedAuthorizeOrderPayment hook 145 | 146 | **Returns:** 147 | 148 | ApplePayHookResult containing a status code to be provided to Apple Pay. A non-null result ends the hook execution 149 | 150 | --- 151 | 152 | ### getRequest 153 | 154 | **Signature:** `getRequest(basket : Basket, request : Object) : ApplePayHookResult` 155 | 156 | **Description:** Called to get the Apple Pay JS PaymentRequest for the given basket. You can set properties in the given request object to extend or override default properties set automatically based on the Apple Pay configuration for your site. Return a result with an error status to indicate a problem. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if the Apple Pay payment sheet is canceled. See the Apple Pay JS API Reference for more information. 157 | 158 | **Parameters:** 159 | 160 | - `basket`: the basket for the Apple Pay request 161 | - `request`: the Apple Pay payment request object 162 | 163 | **Returns:** 164 | 165 | a non-null result ends the hook execution 166 | 167 | --- 168 | 169 | ### paymentMethodSelected 170 | 171 | **Signature:** `paymentMethodSelected(basket : Basket, event : Object, response : Object) : ApplePayHookResult` 172 | 173 | **Description:** Called after handling the given ApplePayPaymentMethodSelectedEvent for the given basket. This Apple Pay event does not contain payment card or device information. The given response object will contain properties whose values are to be passed as parameters to the ApplePaySession.completePaymentMethodSelection event callback: total - Updated total line item object lineItems - Array of updated line item objects Return a result with an error status to indicate a problem. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if the Apple Pay payment sheet is canceled. See the Apple Pay JS API Reference for more information. 174 | 175 | **Parameters:** 176 | 177 | - `basket`: the basket being checked out using Apple Pay 178 | - `event`: ApplePayPaymentMethodSelectedEvent object 179 | - `response`: JS object containing Apple Pay event callback parameters 180 | 181 | **Returns:** 182 | 183 | a non-null result ends the hook execution 184 | 185 | --- 186 | 187 | ### placeOrder 188 | 189 | **Signature:** `placeOrder(order : Order) : ApplePayHookResult` 190 | 191 | **Description:** Called after payment has been authorized and the given Apple Pay order is ready to be placed. The purpose of this hook is to place the order, or return a redirect URL that results in the order being placed when the shopper browser is navigated to it. The default implementation of this hook returns a redirect to COPlaceOrder-Submit with URL parameters order_id set to Order.getOrderNo() and order_token set to Order.getOrderToken() which corresponds to SiteGenesis-based implementations. Your hook implementation should return a result with a different redirect URL as necessary to place the order and show an order confirmation. Alternatively, your hook implementation itself can place the order and return a result with a redirect URL to an order confirmation page that does not place the order. This is inconsistent with SiteGenesis-based implementations so is not the default. Return an error status to indicate a problem. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if the Apple Pay payment sheet is canceled. 192 | 193 | **Parameters:** 194 | 195 | - `order`: the order paid using Apple Pay 196 | 197 | **Returns:** 198 | 199 | a non-null result ends the hook execution 200 | 201 | --- 202 | 203 | ### prepareBasket 204 | 205 | **Signature:** `prepareBasket(basket : Basket, parameters : Object) : ApplePayHookResult` 206 | 207 | **Description:** Called to prepare the given basket for an Apple Pay checkout. This hook will be executed after the user clicks the Apple Pay button. The default implementation of this hook calculates the basket. A custom hook implementation that returns a non-null result must calculate the basket. The given parameters object will contain properties whose values are passed from the <isapplepay></isapplepay> tag: sku - SKU of product to checkout exclusively Return a result with an error status to indicate a problem. For this hook there is no opportunity to provide user feedback, so if any error status is returned, the Apple Pay payment sheet will be aborted. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL after the Apple Pay payment sheet is aborted. 208 | 209 | **Parameters:** 210 | 211 | - `basket`: the basket for the Apple Pay request 212 | - `parameters`: parameters from the <isapplepay></isapplepay> tag 213 | 214 | **Returns:** 215 | 216 | a non-null result ends the hook execution 217 | 218 | --- 219 | 220 | ### shippingContactSelected 221 | 222 | **Signature:** `shippingContactSelected(basket : Basket, event : Object, response : Object) : ApplePayHookResult` 223 | 224 | **Description:** Called after handling the given ApplePayShippingContactSelectedEvent for the given basket. Basket customer information and/or shipping address for the default shipment will have already been updated to reflect the available shipping contact information provided by Apple Pay based on the Apple Pay configuration for your site. The basket will have already been calculated before this hook is called. The given response object will contain properties whose values are to be passed as parameters to the ApplePaySession.completeShippingContactSelection event callback: shippingMethods - Array of applicable shipping method JS objects total - Updated total line item object lineItems - Array of updated line item objects Return a result with an error status to indicate a problem. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if the Apple Pay payment sheet is canceled. See the Apple Pay JS API Reference for more information. 225 | 226 | **Parameters:** 227 | 228 | - `basket`: the basket being checked out using Apple Pay 229 | - `event`: ApplePayShippingContactSelectedEvent object 230 | - `response`: JS object containing Apple Pay event callback parameters 231 | 232 | **Returns:** 233 | 234 | a non-null result ends the hook execution 235 | 236 | --- 237 | 238 | ### shippingMethodSelected 239 | 240 | **Signature:** `shippingMethodSelected(basket : Basket, shippingMethod : ShippingMethod, event : Object, response : Object) : ApplePayHookResult` 241 | 242 | **Description:** Called after handling the given ApplePayShippingMethodSelectedEvent for the given basket. The given shipping method will have already been set on the basket. The basket will have already been calculated before this hook is called. The given response object will contain properties whose values are to be passed as parameters to the ApplePaySession.completeShippingMethodSelection event callback: total - Updated total line item object lineItems - Array of updated line item objects Return a result with an error status to indicate a problem. See ApplePayHookResult for how to indicate error statuses with detail information to be provided to Apple Pay. If the returned result includes a redirect URL, the shopper browser will be navigated to that URL if the Apple Pay payment sheet is canceled. See the Apple Pay JS API Reference for more information. 243 | 244 | **Parameters:** 245 | 246 | - `basket`: the basket being checked out using Apple Pay 247 | - `shippingMethod`: the shipping method that was selected 248 | - `event`: ApplePayShippingMethodSelectedEvent object 249 | - `response`: JS object containing Apple Pay event callback parameters 250 | 251 | **Returns:** 252 | 253 | a non-null result ends the hook execution 254 | 255 | --- ``` -------------------------------------------------------------------------------- /tests/class-content-parser.test.ts: -------------------------------------------------------------------------------- ```typescript 1 | import { ClassContentParser } from '../src/clients/docs/class-content-parser.js'; 2 | import { Logger } from '../src/utils/logger.js'; 3 | 4 | describe('ClassContentParser', () => { 5 | let mockLogger: jest.Mocked<Logger>; 6 | let parser: ClassContentParser; 7 | 8 | beforeEach(() => { 9 | mockLogger = { 10 | debug: jest.fn(), 11 | log: jest.fn(), 12 | error: jest.fn(), 13 | timing: jest.fn(), 14 | methodEntry: jest.fn(), 15 | methodExit: jest.fn(), 16 | } as any; 17 | 18 | jest.spyOn(Logger, 'getChildLogger').mockReturnValue(mockLogger); 19 | parser = new ClassContentParser(); 20 | }); 21 | 22 | afterEach(() => { 23 | jest.clearAllMocks(); 24 | }); 25 | 26 | describe('parseClassContent', () => { 27 | it('should parse basic class information correctly', () => { 28 | const content = ` 29 | # Class Product 30 | 31 | ## Package: dw.catalog 32 | 33 | ## Description 34 | Represents a product in the catalog system. 35 | This is a multi-line description. 36 | 37 | ## Constructor Summary 38 | Product(id: String) 39 | Creates a new product instance. 40 | `.trim(); 41 | 42 | const result = parser.parseClassContent(content); 43 | 44 | expect(result).toEqual({ 45 | className: 'Product', 46 | packageName: 'dw.catalog', 47 | description: 'Represents a product in the catalog system. This is a multi-line description.', 48 | constants: [], 49 | properties: [], 50 | methods: [], 51 | inheritance: undefined, 52 | constructorInfo: 'Product(id: String) Creates a new product instance.', 53 | }); 54 | }); 55 | 56 | it('should parse inheritance hierarchy correctly', () => { 57 | const content = ` 58 | # Class Product 59 | 60 | ## Package: dw.catalog 61 | 62 | ## Inheritance Hierarchy 63 | - dw.object.PersistentObject 64 | - dw.catalog.CatalogObject 65 | - dw.catalog.Product 66 | `.trim(); 67 | 68 | const result = parser.parseClassContent(content); 69 | 70 | expect(result.inheritance).toEqual([ 71 | 'dw.object.PersistentObject', 72 | 'dw.catalog.CatalogObject', 73 | 'dw.catalog.Product', 74 | ]); 75 | }); 76 | 77 | it('should parse constants correctly', () => { 78 | const content = ` 79 | # Class Product 80 | 81 | ## Package: dw.catalog 82 | 83 | ## Constants 84 | 85 | ### STATUS_ACTIVE 86 | 87 | **Type:** String = 'ACTIVE' 88 | 89 | This constant represents an active product status. 90 | 91 | ### MAX_QUANTITY 92 | 93 | **Type:** Number = 100 94 | 95 | Maximum quantity allowed for this product. 96 | 97 | ### DEPRECATED_FLAG 98 | 99 | **Type:** Boolean 100 | 101 | **Deprecated:** This flag is no longer used. Use isActive instead. 102 | 103 | This is the description for the deprecated flag. 104 | `.trim(); 105 | 106 | const result = parser.parseClassContent(content); 107 | 108 | expect(result.constants).toHaveLength(3); 109 | 110 | expect(result.constants[0]).toEqual({ 111 | name: 'STATUS_ACTIVE', 112 | type: 'String', 113 | value: "'ACTIVE'", 114 | description: 'This constant represents an active product status.', 115 | deprecated: undefined, 116 | deprecationMessage: undefined, 117 | }); 118 | 119 | expect(result.constants[1]).toEqual({ 120 | name: 'MAX_QUANTITY', 121 | type: 'Number', 122 | value: '100', 123 | description: 'Maximum quantity allowed for this product.', 124 | deprecated: undefined, 125 | deprecationMessage: undefined, 126 | }); 127 | 128 | expect(result.constants[2]).toEqual({ 129 | name: 'DEPRECATED_FLAG', 130 | type: 'Boolean', 131 | value: undefined, 132 | description: 'This is the description for the deprecated flag.', 133 | deprecated: true, 134 | deprecationMessage: 'This flag is no longer used. Use isActive instead.', 135 | }); 136 | }); 137 | 138 | it('should parse properties correctly', () => { 139 | const content = ` 140 | # Class Product 141 | 142 | ## Package: dw.catalog 143 | 144 | ## Properties 145 | 146 | ### name 147 | 148 | **Type:** String (Read Only) 149 | 150 | The name of the product. 151 | 152 | ### price 153 | 154 | **Type:** Money (Static) 155 | 156 | The price of the product. 157 | 158 | ### oldProperty 159 | 160 | **Type:** String 161 | 162 | **Deprecated:** Use newProperty instead. 163 | 164 | This property is deprecated. 165 | `.trim(); 166 | 167 | const result = parser.parseClassContent(content); 168 | 169 | expect(result.properties).toHaveLength(3); 170 | 171 | expect(result.properties[0]).toEqual({ 172 | name: 'name', 173 | type: 'String', 174 | description: 'The name of the product.', 175 | modifiers: ['Read Only'], 176 | deprecated: undefined, 177 | deprecationMessage: undefined, 178 | }); 179 | 180 | expect(result.properties[1]).toEqual({ 181 | name: 'price', 182 | type: 'Money', 183 | description: 'The price of the product.', 184 | modifiers: ['Static'], 185 | deprecated: undefined, 186 | deprecationMessage: undefined, 187 | }); 188 | 189 | expect(result.properties[2]).toEqual({ 190 | name: 'oldProperty', 191 | type: 'String', 192 | description: 'This property is deprecated.', 193 | modifiers: undefined, 194 | deprecated: true, 195 | deprecationMessage: 'Use newProperty instead.', 196 | }); 197 | }); 198 | 199 | it('should parse methods correctly', () => { 200 | const content = ` 201 | # Class Product 202 | 203 | ## Package: dw.catalog 204 | 205 | ## Method Summary 206 | 207 | ### getName 208 | 209 | **Signature:** \`getName() : String\` 210 | 211 | **Description:** Returns the product name. 212 | 213 | ### setPrice 214 | 215 | **Signature:** \`setPrice(price: Money) : void\` 216 | 217 | Sets the product price. 218 | 219 | ### oldMethod 220 | 221 | **Signature:** \`oldMethod() : String\` 222 | 223 | **Deprecated:** This method is deprecated. Use newMethod instead. 224 | 225 | This method should not be used anymore. 226 | `.trim(); 227 | 228 | const result = parser.parseClassContent(content); 229 | 230 | expect(result.methods).toHaveLength(3); 231 | 232 | expect(result.methods[0]).toEqual({ 233 | name: 'getName', 234 | signature: 'getName() : String', 235 | description: 'Returns the product name.', 236 | deprecated: undefined, 237 | deprecationMessage: undefined, 238 | }); 239 | 240 | expect(result.methods[1]).toEqual({ 241 | name: 'setPrice', 242 | signature: 'setPrice(price: Money) : void', 243 | description: 'Sets the product price.', 244 | deprecated: undefined, 245 | deprecationMessage: undefined, 246 | }); 247 | 248 | expect(result.methods[2]).toEqual({ 249 | name: 'oldMethod', 250 | signature: 'oldMethod() : String', 251 | description: 'This method should not be used anymore.', 252 | deprecated: true, 253 | deprecationMessage: 'This method is deprecated. Use newMethod instead.', 254 | }); 255 | }); 256 | 257 | it('should handle Method Details section correctly', () => { 258 | const content = ` 259 | # Class Product 260 | 261 | ## Package: dw.catalog 262 | 263 | ## Method Details 264 | 265 | ### getDetails 266 | 267 | **Signature:** \`getDetails() : ProductDetails\` 268 | 269 | **Description:** Returns detailed product information. 270 | `.trim(); 271 | 272 | const result = parser.parseClassContent(content); 273 | 274 | expect(result.methods).toHaveLength(1); 275 | expect(result.methods[0]).toEqual({ 276 | name: 'getDetails', 277 | signature: 'getDetails() : ProductDetails', 278 | description: 'Returns detailed product information.', 279 | deprecated: undefined, 280 | deprecationMessage: undefined, 281 | }); 282 | }); 283 | 284 | it('should handle methods without explicit signature', () => { 285 | const content = ` 286 | # Class Product 287 | 288 | ## Package: dw.catalog 289 | 290 | ## Method Summary 291 | 292 | ### toString 293 | 294 | Returns string representation of the product. 295 | `.trim(); 296 | 297 | const result = parser.parseClassContent(content); 298 | 299 | expect(result.methods).toHaveLength(1); 300 | expect(result.methods[0]).toEqual({ 301 | name: 'toString', 302 | signature: 'toString', 303 | description: 'Returns string representation of the product.', 304 | deprecated: undefined, 305 | deprecationMessage: undefined, 306 | }); 307 | }); 308 | 309 | it('should handle deprecation messages spanning multiple lines', () => { 310 | const content = ` 311 | # Class Product 312 | 313 | ## Package: dw.catalog 314 | 315 | ## Constants 316 | 317 | ### OLD_CONSTANT 318 | 319 | **Type:** String 320 | 321 | **Deprecated:** 322 | This constant is deprecated because it was replaced 323 | by a more efficient implementation. 324 | Use NEW_CONSTANT instead. 325 | 326 | Description after deprecation. 327 | `.trim(); 328 | 329 | const result = parser.parseClassContent(content); 330 | 331 | expect(result.constants).toHaveLength(1); 332 | expect(result.constants[0]).toEqual({ 333 | name: 'OLD_CONSTANT', 334 | type: 'String', 335 | value: undefined, 336 | description: 'This constant is deprecated because it was replaced by a more efficient implementation. Use NEW_CONSTANT instead. Description after deprecation.', 337 | deprecated: true, 338 | deprecationMessage: 'This constant is deprecated because it was replaced by a more efficient implementation. Use NEW_CONSTANT instead. Description after deprecation.', 339 | }); 340 | }); 341 | 342 | it('should handle empty sections gracefully', () => { 343 | const content = ` 344 | # Class Product 345 | 346 | ## Package: dw.catalog 347 | 348 | ## Description 349 | 350 | ## Constants 351 | 352 | ## Properties 353 | 354 | ## Method Summary 355 | `.trim(); 356 | 357 | const result = parser.parseClassContent(content); 358 | 359 | expect(result).toEqual({ 360 | className: 'Product', 361 | packageName: 'dw.catalog', 362 | description: '', 363 | constants: [], 364 | properties: [], 365 | methods: [], 366 | inheritance: undefined, 367 | constructorInfo: undefined, 368 | }); 369 | }); 370 | 371 | it('should handle complex class names correctly', () => { 372 | const content = ` 373 | # Class ContentMgr 374 | 375 | ## Package: dw.content 376 | 377 | ## Description 378 | Content manager class. 379 | `.trim(); 380 | 381 | const result = parser.parseClassContent(content); 382 | 383 | expect(result.className).toBe('ContentMgr'); 384 | expect(result.packageName).toBe('dw.content'); 385 | }); 386 | 387 | it('should handle properties with both Read Only and Static modifiers', () => { 388 | const content = ` 389 | # Class Product 390 | 391 | ## Package: dw.catalog 392 | 393 | ## Properties 394 | 395 | ### INSTANCE 396 | 397 | **Type:** Product (Read Only) (Static) 398 | 399 | The singleton instance. 400 | `.trim(); 401 | 402 | const result = parser.parseClassContent(content); 403 | 404 | expect(result.properties).toHaveLength(1); 405 | expect(result.properties[0]).toEqual({ 406 | name: 'INSTANCE', 407 | type: 'Product', 408 | description: 'The singleton instance.', 409 | modifiers: ['Read Only', 'Static'], 410 | deprecated: undefined, 411 | deprecationMessage: undefined, 412 | }); 413 | }); 414 | 415 | it('should ignore separator lines and handle complex formatting', () => { 416 | const content = ` 417 | # Class Product 418 | 419 | ## Package: dw.catalog 420 | 421 | ## Description 422 | This is a product class. 423 | 424 | --- 425 | 426 | ## Constants 427 | 428 | ### STATUS 429 | 430 | **Type:** String 431 | 432 | The status of the product. 433 | 434 | --- 435 | 436 | Some random separator that should be ignored. 437 | 438 | ## Properties 439 | 440 | ### id 441 | 442 | **Type:** String 443 | 444 | The product ID. 445 | `.trim(); 446 | 447 | const result = parser.parseClassContent(content); 448 | 449 | expect(result.description).toBe('This is a product class. ---'); 450 | expect(result.constants).toHaveLength(1); 451 | expect(result.constants[0].description).toBe('The status of the product. --- Some random separator that should be ignored.'); 452 | expect(result.properties).toHaveLength(1); 453 | expect(result.properties[0].description).toBe('The product ID.'); 454 | }); 455 | 456 | it('should handle malformed content gracefully', () => { 457 | const content = ` 458 | Some random content without proper headers 459 | 460 | ### Random Header 461 | 462 | Random content 463 | `.trim(); 464 | 465 | const result = parser.parseClassContent(content); 466 | 467 | expect(result).toEqual({ 468 | className: '', 469 | packageName: '', 470 | description: '', 471 | constants: [], 472 | properties: [], 473 | methods: [], 474 | inheritance: undefined, 475 | constructorInfo: undefined, 476 | }); 477 | }); 478 | 479 | it('should handle complex inheritance with special characters', () => { 480 | const content = ` 481 | # Class Product 482 | 483 | ## Package: dw.catalog 484 | 485 | ## Inheritance Hierarchy 486 | - dw.object.PersistentObject 487 | - dw.catalog.CatalogObject 488 | - dw.catalog.Product 489 | `.trim(); 490 | 491 | const result = parser.parseClassContent(content); 492 | 493 | expect(result.inheritance).toEqual([ 494 | 'dw.object.PersistentObject', 495 | 'dw.catalog.CatalogObject', 496 | 'dw.catalog.Product', 497 | ]); 498 | }); 499 | 500 | it('should handle constants with complex type values', () => { 501 | const content = ` 502 | # Class Product 503 | 504 | ## Package: dw.catalog 505 | 506 | ## Constants 507 | 508 | ### COMPLEX_VALUE 509 | 510 | **Type:** Object = {key: 'value', number: 42} 511 | 512 | A complex constant value. 513 | `.trim(); 514 | 515 | const result = parser.parseClassContent(content); 516 | 517 | expect(result.constants).toHaveLength(1); 518 | expect(result.constants[0]).toEqual({ 519 | name: 'COMPLEX_VALUE', 520 | type: 'Object', 521 | value: "{key: 'value', number: 42}", 522 | description: 'A complex constant value.', 523 | deprecated: undefined, 524 | deprecationMessage: undefined, 525 | }); 526 | }); 527 | 528 | it('should handle methods with descriptions that contain signature-like text', () => { 529 | const content = ` 530 | # Class Product 531 | 532 | ## Package: dw.catalog 533 | 534 | ## Method Summary 535 | 536 | ### processSignature 537 | 538 | **Signature:** \`processSignature(data: String) : void\` 539 | 540 | This method processes a signature. Note that it doesn't contain Signature: in the description. 541 | The signature parameter is important. 542 | `.trim(); 543 | 544 | const result = parser.parseClassContent(content); 545 | 546 | expect(result.methods).toHaveLength(1); 547 | expect(result.methods[0]).toEqual({ 548 | name: 'processSignature', 549 | signature: 'processSignature(data: String) : void', 550 | description: 'The signature parameter is important.', 551 | deprecated: undefined, 552 | deprecationMessage: undefined, 553 | }); 554 | }); 555 | }); 556 | 557 | describe('edge cases and error handling', () => { 558 | it('should handle empty string input', () => { 559 | const result = parser.parseClassContent(''); 560 | 561 | expect(result).toEqual({ 562 | className: '', 563 | packageName: '', 564 | description: '', 565 | constants: [], 566 | properties: [], 567 | methods: [], 568 | inheritance: undefined, 569 | constructorInfo: undefined, 570 | }); 571 | }); 572 | 573 | it('should handle input with only whitespace', () => { 574 | const result = parser.parseClassContent(' \n\n \t \n '); 575 | 576 | expect(result).toEqual({ 577 | className: '', 578 | packageName: '', 579 | description: '', 580 | constants: [], 581 | properties: [], 582 | methods: [], 583 | inheritance: undefined, 584 | constructorInfo: undefined, 585 | }); 586 | }); 587 | 588 | it('should handle single line input', () => { 589 | const result = parser.parseClassContent('# Class TestClass'); 590 | 591 | expect(result.className).toBe('TestClass'); 592 | expect(result.packageName).toBe(''); 593 | }); 594 | 595 | it('should trim whitespace from all fields correctly', () => { 596 | const content = ` 597 | # Class Product 598 | 599 | ## Package: dw.catalog 600 | 601 | ## Description 602 | This is a description with extra spaces. 603 | 604 | ## Constants 605 | 606 | ### STATUS_ACTIVE 607 | 608 | **Type:** String = 'ACTIVE' 609 | 610 | This constant has extra spaces. 611 | `; 612 | 613 | const result = parser.parseClassContent(content); 614 | 615 | expect(result.className).toBe('Product'); 616 | expect(result.packageName).toBe('dw.catalog'); 617 | expect(result.description).toBe('This is a description with extra spaces.'); 618 | expect(result.constants[0].name).toBe('STATUS_ACTIVE'); 619 | expect(result.constants[0].type).toBe('String'); 620 | expect(result.constants[0].description).toBe('This constant has extra spaces.'); 621 | }); 622 | }); 623 | 624 | describe('logger integration', () => { 625 | it('should create logger with correct name', () => { 626 | expect(Logger.getChildLogger).toHaveBeenCalledWith('ClassContentParser'); 627 | }); 628 | }); 629 | }); 630 | ``` -------------------------------------------------------------------------------- /docs/dw_system/Session.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.system 2 | 3 | # Class Session 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.system.Session 9 | 10 | ## Description 11 | 12 | Represents a session in B2C Commerce. The session has some well-defined attributes like the current authenticated customer or the click stream, but also supports storing custom values in the session. The Digital session handling works in the following way: A session is created in Digital on the first user click. This is guaranteed even if B2C Commerce caches the HTML pages. It is not guaranteed when the pages are cached by a CDN. A session is identified with a unique ID, called the session ID. When a session is created, the application server calls the pipeline OnSession-Start. It can be used to pre-initialize the session, before the actual request hits the server. Digital uses session stickiness and always routes requests within a single session to the same application server. Session data is also stored in a persistent location. In case of a fail-over situation, requests are re-routed to another application server, which then loads the session data from the persistent storage. There are two session timeouts. A soft timeout occurs 30 minutes after the last request has been made. The soft timeout logs out and clears all privacy data, but it is still possible to use the session ID to reopen the session. A hard timeout renders a session ID invalid after six hours, even if the session is still in use. The hard timeout prevents a session from being reopened. For example, if the session ID is pasted into a URL after the hard timeout, the session doesn't reopen. Certain rules apply for what and how much data can be stored in a session: All primitive types (boolean, number, string, Number, String, Boolean, Date) are supported. All B2C Commerce value types (Money, Quantity, Decimal, Calendar) are supported. Strings are limited to 2000 characters. No other types can be stored in a session. In particular, persistent objects, collections, and scripted objects cannot be stored in a session. B2C Commerce will report unsupported values with a deprecation message in the log files. An unsupported value will be stored in the session, but the results are undefined. Since version compatibility mode 19.10 unsupported types will no longer be accepted, and an exception will be thrown. There is a 10 KB size limit for the overall serialized session. 13 | 14 | ## Properties 15 | 16 | ### clickStream 17 | 18 | **Type:** ClickStream (Read Only) 19 | 20 | The current click stream if this is an HTTP session, null otherwise. 21 | 22 | ### currency 23 | 24 | **Type:** Currency 25 | 26 | Get the currency associated with the current session. The session 27 | currency is established at session construction time and is typically 28 | equal to the site default currency. In the case of a multi-currency site, 29 | the session currency may be different than the site default currency. 30 | 31 | ### custom 32 | 33 | **Type:** CustomAttributes (Read Only) 34 | 35 | The session's custom attributes. The 36 | attributes are stored for the lifetime of the session and are not 37 | cleared when the customer logs out. 38 | 39 | ### customer 40 | 41 | **Type:** Customer (Read Only) 42 | 43 | The customer associated with this storefront session. The method 44 | always returns null if called for a non-storefront session 45 | (e.g., within a job or within Business Manager). For a storefront 46 | session, the method always returns a customer. The returned customer 47 | may be anonymous if the customer could not be identified via the 48 | customer cookie. 49 | 50 | ### customerAuthenticated 51 | 52 | **Type:** boolean (Read Only) 53 | 54 | Identifies whether the customer associated with this session 55 | is authenticated. This call is equivalent to customer.isAuthenticated(). 56 | 57 | ### customerExternallyAuthenticated 58 | 59 | **Type:** boolean (Read Only) 60 | 61 | Identifies whether the customer associated with this session 62 | is externally authenticated. 63 | 64 | ### forms 65 | 66 | **Type:** Forms (Read Only) 67 | 68 | The forms object that provides access to all current forms of a customer in the session. 69 | 70 | ### lastReceivedSourceCodeInfo 71 | 72 | **Type:** SourceCodeInfo (Read Only) 73 | 74 | Returns information on the last source code handled by the session. 75 | This may or may not be the session's active source code, e.g., the 76 | last received source code was inactive and therefore was not 77 | set as the session's active source code. 78 | 79 | ### privacy 80 | 81 | **Type:** CustomAttributes (Read Only) 82 | 83 | The session's custom privacy attributes. 84 | The attributes are stored for the lifetime of the session and are 85 | automatically cleared when the customer logs out. 86 | 87 | ### sessionID 88 | 89 | **Type:** String (Read Only) 90 | 91 | The unique session id. This can safely be used as an identifier 92 | against external systems. 93 | 94 | ### sourceCodeInfo 95 | 96 | **Type:** SourceCodeInfo (Read Only) 97 | 98 | Returns information on the session's active source-code. 99 | 100 | ### trackingAllowed 101 | 102 | **Type:** boolean 103 | 104 | Returns whether the tracking allowed flag is set in the session. 105 | The value for newly created sessions defaults to the Site Preference "TrackingAllowed" unless 106 | a cookie named "dw_dnt" is found in which case the cookie value takes precedence. 107 | 108 | ### userAuthenticated 109 | 110 | **Type:** boolean (Read Only) 111 | 112 | Identifies whether the agent user associated with this session 113 | is authenticated. 114 | 115 | ### userName 116 | 117 | **Type:** String (Read Only) 118 | 119 | The current agent user name associated with this session. 120 | 121 | Note: this class allows access to sensitive security-related data. 122 | Pay special attention to PCI DSS v3 requirements 2, 4, and 12. 123 | 124 | ## Constructor Summary 125 | 126 | ## Method Summary 127 | 128 | ### generateGuestSessionSignature 129 | 130 | **Signature:** `generateGuestSessionSignature() : String` 131 | 132 | Generates a new guest session signature. 133 | 134 | ### generateRegisteredSessionSignature 135 | 136 | **Signature:** `generateRegisteredSessionSignature() : String` 137 | 138 | Generates a new registered session signature. 139 | 140 | ### getClickStream 141 | 142 | **Signature:** `getClickStream() : ClickStream` 143 | 144 | Returns the current click stream if this is an HTTP session, null otherwise. 145 | 146 | ### getCurrency 147 | 148 | **Signature:** `getCurrency() : Currency` 149 | 150 | Get the currency associated with the current session. 151 | 152 | ### getCustom 153 | 154 | **Signature:** `getCustom() : CustomAttributes` 155 | 156 | Returns the session's custom attributes. 157 | 158 | ### getCustomer 159 | 160 | **Signature:** `getCustomer() : Customer` 161 | 162 | Returns the customer associated with this storefront session. 163 | 164 | ### getForms 165 | 166 | **Signature:** `getForms() : Forms` 167 | 168 | Returns the forms object that provides access to all current forms of a customer in the session. 169 | 170 | ### getLastReceivedSourceCodeInfo 171 | 172 | **Signature:** `getLastReceivedSourceCodeInfo() : SourceCodeInfo` 173 | 174 | Returns information on the last source code handled by the session. 175 | 176 | ### getPrivacy 177 | 178 | **Signature:** `getPrivacy() : CustomAttributes` 179 | 180 | Returns the session's custom privacy attributes. 181 | 182 | ### getSessionID 183 | 184 | **Signature:** `getSessionID() : String` 185 | 186 | Returns the unique session id. 187 | 188 | ### getSourceCodeInfo 189 | 190 | **Signature:** `getSourceCodeInfo() : SourceCodeInfo` 191 | 192 | Returns information on the session's active source-code. 193 | 194 | ### getUserName 195 | 196 | **Signature:** `getUserName() : String` 197 | 198 | Returns the current agent user name associated with this session. 199 | 200 | ### isCustomerAuthenticated 201 | 202 | **Signature:** `isCustomerAuthenticated() : boolean` 203 | 204 | Identifies whether the customer associated with this session is authenticated. 205 | 206 | ### isCustomerExternallyAuthenticated 207 | 208 | **Signature:** `isCustomerExternallyAuthenticated() : boolean` 209 | 210 | Identifies whether the customer associated with this session is externally authenticated. 211 | 212 | ### isTrackingAllowed 213 | 214 | **Signature:** `isTrackingAllowed() : boolean` 215 | 216 | Returns whether the tracking allowed flag is set in the session. 217 | 218 | ### isUserAuthenticated 219 | 220 | **Signature:** `isUserAuthenticated() : boolean` 221 | 222 | Identifies whether the agent user associated with this session is authenticated. 223 | 224 | ### setCurrency 225 | 226 | **Signature:** `setCurrency(newCurrency : Currency) : void` 227 | 228 | Sets the session currency. 229 | 230 | ### setSourceCode 231 | 232 | **Signature:** `setSourceCode(sourceCode : String) : Status` 233 | 234 | Applies the specified source code to the current session and basket. 235 | 236 | ### setTrackingAllowed 237 | 238 | **Signature:** `setTrackingAllowed(trackingAllowed : boolean) : void` 239 | 240 | Sets the tracking allowed flag for the session. 241 | 242 | ## Method Detail 243 | 244 | ## Method Details 245 | 246 | ### generateGuestSessionSignature 247 | 248 | **Signature:** `generateGuestSessionSignature() : String` 249 | 250 | **Description:** Generates a new guest session signature. This is intended for guest authentication with the Shopper Login and API Access Service (SLAS). 251 | 252 | **Returns:** 253 | 254 | A new signed session token. 255 | 256 | --- 257 | 258 | ### generateRegisteredSessionSignature 259 | 260 | **Signature:** `generateRegisteredSessionSignature() : String` 261 | 262 | **Description:** Generates a new registered session signature. This is intended for use with registered session-bridge call of Shopper Login and API Access Service (SLAS). 263 | 264 | **Returns:** 265 | 266 | A new signed session token for registered dwsid. 267 | 268 | --- 269 | 270 | ### getClickStream 271 | 272 | **Signature:** `getClickStream() : ClickStream` 273 | 274 | **Description:** Returns the current click stream if this is an HTTP session, null otherwise. 275 | 276 | **Returns:** 277 | 278 | the current click stream if this is an HTTP session, null otherwise. 279 | 280 | --- 281 | 282 | ### getCurrency 283 | 284 | **Signature:** `getCurrency() : Currency` 285 | 286 | **Description:** Get the currency associated with the current session. The session currency is established at session construction time and is typically equal to the site default currency. In the case of a multi-currency site, the session currency may be different than the site default currency. 287 | 288 | **Returns:** 289 | 290 | the currency associated with this storefront session, never null. 291 | 292 | --- 293 | 294 | ### getCustom 295 | 296 | **Signature:** `getCustom() : CustomAttributes` 297 | 298 | **Description:** Returns the session's custom attributes. The attributes are stored for the lifetime of the session and are not cleared when the customer logs out. 299 | 300 | **Returns:** 301 | 302 | the session's custom attributes. 303 | 304 | --- 305 | 306 | ### getCustomer 307 | 308 | **Signature:** `getCustomer() : Customer` 309 | 310 | **Description:** Returns the customer associated with this storefront session. The method always returns null if called for a non-storefront session (e.g., within a job or within Business Manager). For a storefront session, the method always returns a customer. The returned customer may be anonymous if the customer could not be identified via the customer cookie. 311 | 312 | **Returns:** 313 | 314 | the customer associated with this storefront session. 315 | 316 | --- 317 | 318 | ### getForms 319 | 320 | **Signature:** `getForms() : Forms` 321 | 322 | **Description:** Returns the forms object that provides access to all current forms of a customer in the session. 323 | 324 | **Returns:** 325 | 326 | the forms. 327 | 328 | --- 329 | 330 | ### getLastReceivedSourceCodeInfo 331 | 332 | **Signature:** `getLastReceivedSourceCodeInfo() : SourceCodeInfo` 333 | 334 | **Description:** Returns information on the last source code handled by the session. This may or may not be the session's active source code, e.g., the last received source code was inactive and therefore was not set as the session's active source code. 335 | 336 | **Returns:** 337 | 338 | source code information for the last received source code. 339 | 340 | --- 341 | 342 | ### getPrivacy 343 | 344 | **Signature:** `getPrivacy() : CustomAttributes` 345 | 346 | **Description:** Returns the session's custom privacy attributes. The attributes are stored for the lifetime of the session and are automatically cleared when the customer logs out. 347 | 348 | **Returns:** 349 | 350 | the session's custom privacy attributes. 351 | 352 | --- 353 | 354 | ### getSessionID 355 | 356 | **Signature:** `getSessionID() : String` 357 | 358 | **Description:** Returns the unique session id. This can safely be used as an identifier against external systems. 359 | 360 | **Returns:** 361 | 362 | the unique identifier for the session. 363 | 364 | --- 365 | 366 | ### getSourceCodeInfo 367 | 368 | **Signature:** `getSourceCodeInfo() : SourceCodeInfo` 369 | 370 | **Description:** Returns information on the session's active source-code. 371 | 372 | **Returns:** 373 | 374 | the session's source-code information. 375 | 376 | --- 377 | 378 | ### getUserName 379 | 380 | **Signature:** `getUserName() : String` 381 | 382 | **Description:** Returns the current agent user name associated with this session. Note: this class allows access to sensitive security-related data. Pay special attention to PCI DSS v3 requirements 2, 4, and 12. 383 | 384 | **Returns:** 385 | 386 | the current agent user name associated with this session. 387 | 388 | --- 389 | 390 | ### isCustomerAuthenticated 391 | 392 | **Signature:** `isCustomerAuthenticated() : boolean` 393 | 394 | **Description:** Identifies whether the customer associated with this session is authenticated. This call is equivalent to customer.isAuthenticated(). 395 | 396 | **Returns:** 397 | 398 | true if the customer is authenticated, false otherwise. 399 | 400 | --- 401 | 402 | ### isCustomerExternallyAuthenticated 403 | 404 | **Signature:** `isCustomerExternallyAuthenticated() : boolean` 405 | 406 | **Description:** Identifies whether the customer associated with this session is externally authenticated. 407 | 408 | **Returns:** 409 | 410 | true if the customer is authenticated, false otherwise. 411 | 412 | --- 413 | 414 | ### isTrackingAllowed 415 | 416 | **Signature:** `isTrackingAllowed() : boolean` 417 | 418 | **Description:** Returns whether the tracking allowed flag is set in the session. The value for newly created sessions defaults to the Site Preference "TrackingAllowed" unless a cookie named "dw_dnt" is found in which case the cookie value takes precedence. 419 | 420 | **Returns:** 421 | 422 | true if the tracking allowed flag is set in the session, false otherwise. 423 | 424 | --- 425 | 426 | ### isUserAuthenticated 427 | 428 | **Signature:** `isUserAuthenticated() : boolean` 429 | 430 | **Description:** Identifies whether the agent user associated with this session is authenticated. 431 | 432 | **Returns:** 433 | 434 | true if the agent user is authenticated, false otherwise. 435 | 436 | --- 437 | 438 | ### setCurrency 439 | 440 | **Signature:** `setCurrency(newCurrency : Currency) : void` 441 | 442 | **Description:** Sets the session currency. 443 | 444 | **Parameters:** 445 | 446 | - `newCurrency`: the new currency to use. Must not be null. Method will throw an exception if a currency not allowed by the current site is passed. 447 | 448 | --- 449 | 450 | ### setSourceCode 451 | 452 | **Signature:** `setSourceCode(sourceCode : String) : Status` 453 | 454 | **Description:** Applies the specified source code to the current session and basket. This API processes the source code exactly as if it were supplied on the URL query string, with the additional benefit of returning error information. If no input parameter is passed, then the active source code in the session and basket is removed. If a basket exists, and the modification fails, then the session is not written to either. This method may open and commit a transaction, if none is currently active. 455 | 456 | **Parameters:** 457 | 458 | - `sourceCode`: the source code to set as active in the session and basket. If a null parameter is passed, then the active source code in the session is removed. 459 | 460 | **Returns:** 461 | 462 | an OK status if the source code was applied, otherwise an ERROR status. In the latter case, the possible error codes are: CODE_INVALID and CODE_INACTIVE. See documentation for SourceCodeStatusCodes for further descriptions. 463 | 464 | --- 465 | 466 | ### setTrackingAllowed 467 | 468 | **Signature:** `setTrackingAllowed(trackingAllowed : boolean) : void` 469 | 470 | **Description:** Sets the tracking allowed flag for the session. If tracking is not allowed, multiple services depending on tracking will be restricted or disabled: Predictive Intelligence recommendations, Active Data, Analytics of the customer behavior in the storefront. Additionally, collected clicks in the session click stream will be cleared. Setting this property to either value also results in setting a session-scoped cookie named "dw_dnt" (1=DoNotTrack; 0=Track) 471 | 472 | **Parameters:** 473 | 474 | - `trackingAllowed`: true if tracking is allowed, false otherwise. 475 | 476 | --- ``` -------------------------------------------------------------------------------- /tests/mcp/yaml/get-system-object-definitions.full-mode.test.mcp.yml: -------------------------------------------------------------------------------- ```yaml 1 | # ================================================================================== 2 | # SFCC MCP Server - get_system_object_definitions Tool YAML Tests 3 | # Focused testing for SFCC system object definitions retrieval functionality 4 | # Tests core functionality, select parameters, error scenarios, and edge cases 5 | # 6 | # Quick Test Commands: 7 | # aegis "tests/mcp/yaml/get-system-object-definitions.full-mode.test.mcp.yml" --config "aegis.config.with-dw.json" --verbose 8 | # aegis "tests/mcp/yaml/get-system-object-definitions.full-mode.test.mcp.yml" --config "aegis.config.with-dw.json" --debug --timing 9 | # aegis query get_system_object_definitions '{}' --config "aegis.config.with-dw.json" 10 | # aegis query get_system_object_definitions '{"start": 0, "count": 3}' --config "aegis.config.with-dw.json" 11 | # aegis query get_system_object_definitions '{"select": "(start, count, data.(object_type, display_name))", "count": 3}' --config "aegis.config.with-dw.json" 12 | # ================================================================================== 13 | 14 | description: "get_system_object_definitions tool tests - Retrieve all SFCC system object definitions" 15 | 16 | # ================================================================================== 17 | # TOOL AVAILABILITY VALIDATION 18 | # ================================================================================== 19 | tests: 20 | - it: "should include get_system_object_definitions tool in available tools" 21 | request: 22 | jsonrpc: "2.0" 23 | id: "tool-available" 24 | method: "tools/list" 25 | params: {} 26 | expect: 27 | response: 28 | jsonrpc: "2.0" 29 | id: "tool-available" 30 | result: 31 | tools: "match:arrayContains:name:get_system_object_definitions" 32 | stderr: "toBeEmpty" 33 | 34 | # ================================================================================== 35 | # CORE FUNCTIONALITY TESTS 36 | # ================================================================================== 37 | 38 | - it: "should retrieve system object definitions with default parameters" 39 | request: 40 | jsonrpc: "2.0" 41 | id: "default-params" 42 | method: "tools/call" 43 | params: 44 | name: "get_system_object_definitions" 45 | arguments: {} 46 | expect: 47 | response: 48 | jsonrpc: "2.0" 49 | id: "default-params" 50 | result: 51 | content: 52 | match:arrayElements: 53 | match:partial: 54 | type: "text" 55 | text: "match:type:string" 56 | isError: false 57 | performance: 58 | maxResponseTime: "3000ms" 59 | stderr: "toBeEmpty" 60 | 61 | - it: "should return valid JSON structure with OCAPI metadata" 62 | request: 63 | jsonrpc: "2.0" 64 | id: "json-structure" 65 | method: "tools/call" 66 | params: 67 | name: "get_system_object_definitions" 68 | arguments: 69 | count: 5 70 | expect: 71 | response: 72 | jsonrpc: "2.0" 73 | id: "json-structure" 74 | result: 75 | content: 76 | match:arrayElements: 77 | match:partial: 78 | type: "text" 79 | text: "match:regex:[\\s\\S]*\"_type\"[\\s\\S]*\"object_type_definitions\"[\\s\\S]*\"count\"[\\s\\S]*\"start\"[\\s\\S]*" 80 | isError: false 81 | 82 | - it: "should contain SFCC system object types in response" 83 | request: 84 | jsonrpc: "2.0" 85 | id: "system-objects-content" 86 | method: "tools/call" 87 | params: 88 | name: "get_system_object_definitions" 89 | arguments: 90 | count: 10 91 | expect: 92 | response: 93 | jsonrpc: "2.0" 94 | id: "system-objects-content" 95 | result: 96 | content: 97 | match:arrayElements: 98 | match:partial: 99 | type: "text" 100 | text: "match:regex:[\\s\\S]*\"object_type\"[\\s\\S]*(Product|Category|Order|Customer|Basket)[\\s\\S]*" 101 | isError: false 102 | 103 | # ================================================================================== 104 | # PAGINATION PARAMETER TESTS 105 | # ================================================================================== 106 | 107 | - it: "should handle pagination with start and count parameters" 108 | request: 109 | jsonrpc: "2.0" 110 | id: "pagination-basic" 111 | method: "tools/call" 112 | params: 113 | name: "get_system_object_definitions" 114 | arguments: 115 | start: 2 116 | count: 3 117 | expect: 118 | response: 119 | jsonrpc: "2.0" 120 | id: "pagination-basic" 121 | result: 122 | content: 123 | match:arrayElements: 124 | match:partial: 125 | type: "text" 126 | text: "match:regex:[\\s\\S]*\"count\"[\\s\\S]*:[\\s]*3[\\s\\S]*\"start\"[\\s\\S]*:[\\s]*2[\\s\\S]*" 127 | isError: false 128 | performance: 129 | maxResponseTime: "2500ms" 130 | 131 | - it: "should handle zero start parameter" 132 | request: 133 | jsonrpc: "2.0" 134 | id: "zero-start" 135 | method: "tools/call" 136 | params: 137 | name: "get_system_object_definitions" 138 | arguments: 139 | start: 0 140 | count: 3 141 | expect: 142 | response: 143 | jsonrpc: "2.0" 144 | id: "zero-start" 145 | result: 146 | content: 147 | match:arrayElements: 148 | match:partial: 149 | type: "text" 150 | text: "match:regex:[\\s\\S]*\"start\"[\\s\\S]*:[\\s]*0[\\s\\S]*" 151 | isError: false 152 | 153 | # ================================================================================== 154 | # SELECT PARAMETER TESTS - OCAPI Field Selection 155 | # ================================================================================== 156 | 157 | - it: "should handle wildcard select parameter (**)" 158 | request: 159 | jsonrpc: "2.0" 160 | id: "select-wildcard" 161 | method: "tools/call" 162 | params: 163 | name: "get_system_object_definitions" 164 | arguments: 165 | select: "(**)" 166 | count: 3 167 | expect: 168 | response: 169 | jsonrpc: "2.0" 170 | id: "select-wildcard" 171 | result: 172 | content: 173 | match:arrayElements: 174 | match:partial: 175 | type: "text" 176 | text: "match:regex:[\\s\\S]*\"_type\"[\\s\\S]*\"count\"[\\s\\S]*\"data\"[\\s\\S]*\"start\"[\\s\\S]*\"total\"[\\s\\S]*" 177 | isError: false 178 | 179 | - it: "should handle root-level field selection" 180 | request: 181 | jsonrpc: "2.0" 182 | id: "select-root-fields" 183 | method: "tools/call" 184 | params: 185 | name: "get_system_object_definitions" 186 | arguments: 187 | select: "(start, count, total)" 188 | count: 3 189 | expect: 190 | response: 191 | jsonrpc: "2.0" 192 | id: "select-root-fields" 193 | result: 194 | content: 195 | match:arrayElements: 196 | match:partial: 197 | type: "text" 198 | text: "match:regex:[\\s\\S]*\"start\"[\\s\\S]*\"count\"[\\s\\S]*\"total\"[\\s\\S]*" 199 | isError: false 200 | 201 | - it: "should exclude non-selected fields when using specific selection" 202 | request: 203 | jsonrpc: "2.0" 204 | id: "select-exclude-fields" 205 | method: "tools/call" 206 | params: 207 | name: "get_system_object_definitions" 208 | arguments: 209 | select: "(start, count)" 210 | count: 2 211 | expect: 212 | response: 213 | jsonrpc: "2.0" 214 | id: "select-exclude-fields" 215 | result: 216 | content: 217 | match:arrayElements: 218 | match:partial: 219 | type: "text" 220 | text: "match:regex:[\\s\\S]*\"start\"[\\s\\S]*\"count\"[\\s\\S]*" 221 | isError: false 222 | 223 | - it: "should handle data-level field selection" 224 | request: 225 | jsonrpc: "2.0" 226 | id: "select-data-fields" 227 | method: "tools/call" 228 | params: 229 | name: "get_system_object_definitions" 230 | arguments: 231 | select: "(start, count, data.(object_type, display_name))" 232 | count: 3 233 | expect: 234 | response: 235 | jsonrpc: "2.0" 236 | id: "select-data-fields" 237 | result: 238 | content: 239 | match:arrayElements: 240 | match:partial: 241 | type: "text" 242 | text: "match:regex:[\\s\\S]*\"start\"[\\s\\S]*\"count\"[\\s\\S]*\"data\"[\\s\\S]*\"object_type\"[\\s\\S]*\"display_name\"[\\s\\S]*" 243 | isError: false 244 | 245 | # ================================================================================== 246 | # EDGE CASES AND BOUNDARY CONDITIONS 247 | # ================================================================================== 248 | 249 | - it: "should handle minimum count parameter" 250 | request: 251 | jsonrpc: "2.0" 252 | id: "edge-min-count" 253 | method: "tools/call" 254 | params: 255 | name: "get_system_object_definitions" 256 | arguments: 257 | count: 1 258 | expect: 259 | response: 260 | jsonrpc: "2.0" 261 | id: "edge-min-count" 262 | result: 263 | content: 264 | match:arrayElements: 265 | match:partial: 266 | type: "text" 267 | text: "match:regex:[\\s\\S]*\"count\"[\\s\\S]*:[\\s]*1[\\s\\S]*" 268 | isError: false 269 | 270 | - it: "should handle large start parameter gracefully" 271 | request: 272 | jsonrpc: "2.0" 273 | id: "edge-large-start" 274 | method: "tools/call" 275 | params: 276 | name: "get_system_object_definitions" 277 | arguments: 278 | start: 1000 279 | count: 5 280 | expect: 281 | response: 282 | jsonrpc: "2.0" 283 | id: "edge-large-start" 284 | result: 285 | content: 286 | match:arrayElements: 287 | match:partial: 288 | type: "text" 289 | text: "match:type:string" 290 | isError: false 291 | 292 | - it: "should handle maximum reasonable count parameter" 293 | request: 294 | jsonrpc: "2.0" 295 | id: "edge-max-count" 296 | method: "tools/call" 297 | params: 298 | name: "get_system_object_definitions" 299 | arguments: 300 | count: 200 301 | expect: 302 | response: 303 | jsonrpc: "2.0" 304 | id: "edge-max-count" 305 | result: 306 | content: 307 | match:arrayElements: 308 | match:partial: 309 | type: "text" 310 | text: "match:type:string" 311 | isError: false 312 | performance: 313 | maxResponseTime: "5000ms" 314 | 315 | # ================================================================================== 316 | # PARAMETER VALIDATION TESTS 317 | # ================================================================================== 318 | 319 | - it: "should handle string start parameter (type coercion)" 320 | request: 321 | jsonrpc: "2.0" 322 | id: "param-string-start" 323 | method: "tools/call" 324 | params: 325 | name: "get_system_object_definitions" 326 | arguments: 327 | start: "5" 328 | count: 2 329 | expect: 330 | response: 331 | jsonrpc: "2.0" 332 | id: "param-string-start" 333 | result: 334 | content: 335 | match:arrayElements: 336 | match:partial: 337 | type: "text" 338 | text: "match:type:string" 339 | isError: false 340 | 341 | - it: "should handle string count parameter (type coercion)" 342 | request: 343 | jsonrpc: "2.0" 344 | id: "param-string-count" 345 | method: "tools/call" 346 | params: 347 | name: "get_system_object_definitions" 348 | arguments: 349 | start: 0 350 | count: "3" 351 | expect: 352 | response: 353 | jsonrpc: "2.0" 354 | id: "param-string-count" 355 | result: 356 | content: 357 | match:arrayElements: 358 | match:partial: 359 | type: "text" 360 | text: "match:type:string" 361 | isError: false 362 | 363 | - it: "should handle negative start parameter gracefully" 364 | request: 365 | jsonrpc: "2.0" 366 | id: "negative-start" 367 | method: "tools/call" 368 | params: 369 | name: "get_system_object_definitions" 370 | arguments: 371 | start: -1 372 | count: 3 373 | expect: 374 | response: 375 | jsonrpc: "2.0" 376 | id: "negative-start" 377 | result: 378 | content: 379 | match:arrayElements: 380 | match:partial: 381 | type: "text" 382 | text: "match:type:string" 383 | isError: false 384 | 385 | - it: "should handle zero count parameter" 386 | request: 387 | jsonrpc: "2.0" 388 | id: "zero-count" 389 | method: "tools/call" 390 | params: 391 | name: "get_system_object_definitions" 392 | arguments: 393 | start: 0 394 | count: 0 395 | expect: 396 | response: 397 | jsonrpc: "2.0" 398 | id: "zero-count" 399 | result: 400 | content: 401 | match:arrayElements: 402 | match:partial: 403 | type: "text" 404 | text: "match:type:string" 405 | isError: false 406 | 407 | - it: "should handle invalid select patterns gracefully" 408 | request: 409 | jsonrpc: "2.0" 410 | id: "select-invalid" 411 | method: "tools/call" 412 | params: 413 | name: "get_system_object_definitions" 414 | arguments: 415 | select: "invalid_pattern_without_parentheses" 416 | count: 2 417 | expect: 418 | response: 419 | jsonrpc: "2.0" 420 | id: "select-invalid" 421 | result: 422 | content: 423 | match:arrayElements: 424 | match:partial: 425 | type: "text" 426 | text: "match:type:string" 427 | isError: false 428 | 429 | - it: "should handle empty select parameter" 430 | request: 431 | jsonrpc: "2.0" 432 | id: "select-empty" 433 | method: "tools/call" 434 | params: 435 | name: "get_system_object_definitions" 436 | arguments: 437 | select: "" 438 | count: 2 439 | expect: 440 | response: 441 | jsonrpc: "2.0" 442 | id: "select-empty" 443 | result: 444 | content: 445 | match:arrayElements: 446 | match:partial: 447 | type: "text" 448 | text: "match:type:string" 449 | isError: false 450 | 451 | # ================================================================================== 452 | # DATA VALIDATION AND CONSISTENCY 453 | # ================================================================================== 454 | 455 | - it: "should return proper SFCC object type definition structure" 456 | request: 457 | jsonrpc: "2.0" 458 | id: "data-structure" 459 | method: "tools/call" 460 | params: 461 | name: "get_system_object_definitions" 462 | arguments: 463 | count: 3 464 | expect: 465 | response: 466 | jsonrpc: "2.0" 467 | id: "data-structure" 468 | result: 469 | content: 470 | match:arrayElements: 471 | match:partial: 472 | type: "text" 473 | text: "match:regex:[\\s\\S]*\"_type\"[\\s\\S]*\"object_type_definition\"[\\s\\S]*\"object_type\"[\\s\\S]*" 474 | isError: false 475 | 476 | - it: "should maintain consistent results across multiple calls" 477 | request: 478 | jsonrpc: "2.0" 479 | id: "consistency-check" 480 | method: "tools/call" 481 | params: 482 | name: "get_system_object_definitions" 483 | arguments: 484 | start: 0 485 | count: 3 486 | expect: 487 | response: 488 | jsonrpc: "2.0" 489 | id: "consistency-check" 490 | result: 491 | content: 492 | match:arrayElements: 493 | match:partial: 494 | type: "text" 495 | text: "match:regex:[\\s\\S]*\"count\"[\\s\\S]*:[\\s]*3[\\s\\S]*" 496 | isError: false 497 | 498 | - it: "should include API version information" 499 | request: 500 | jsonrpc: "2.0" 501 | id: "api-version" 502 | method: "tools/call" 503 | params: 504 | name: "get_system_object_definitions" 505 | arguments: 506 | count: 1 507 | expect: 508 | response: 509 | jsonrpc: "2.0" 510 | id: "api-version" 511 | result: 512 | content: 513 | match:arrayElements: 514 | match:partial: 515 | type: "text" 516 | text: "match:regex:[\\s\\S]*\"_v\"[\\s\\S]*\"\\d+\\.\\d+\"[\\s\\S]*" 517 | isError: false ``` -------------------------------------------------------------------------------- /docs/dw_util/SecureEncoder.md: -------------------------------------------------------------------------------- ```markdown 1 | ## Package: dw.util 2 | 3 | # Class SecureEncoder 4 | 5 | ## Inheritance Hierarchy 6 | 7 | - Object 8 | - dw.util.SecureEncoder 9 | 10 | ## Description 11 | 12 | SecureEncoder contains many methods for manipulating untrusted data Strings into RFC-Compliant Strings for a given context by encoding "bad" data into the proper format. 13 | 14 | ## Constructor Summary 15 | 16 | ## Method Summary 17 | 18 | ### forHtmlContent 19 | 20 | **Signature:** `static forHtmlContent(input : String) : String` 21 | 22 | Encodes a given input for use in a general HTML context. 23 | 24 | ### forHtmlInDoubleQuoteAttribute 25 | 26 | **Signature:** `static forHtmlInDoubleQuoteAttribute(input : String) : String` 27 | 28 | Encodes a given input for use in an HTML Attribute guarded by a double quote. 29 | 30 | ### forHtmlInSingleQuoteAttribute 31 | 32 | **Signature:** `static forHtmlInSingleQuoteAttribute(input : String) : String` 33 | 34 | Encodes a given input for use in an HTML Attribute guarded by a single quote. 35 | 36 | ### forHtmlUnquotedAttribute 37 | 38 | **Signature:** `static forHtmlUnquotedAttribute(input : String) : String` 39 | 40 | Encodes a given input for use in an HTML Attribute left unguarded. 41 | 42 | ### forJavaScriptInAttribute 43 | 44 | **Signature:** `static forJavaScriptInAttribute(input : String) : String` 45 | 46 | Encodes a given input for use in JavaScript inside an HTML attribute. 47 | 48 | ### forJavaScriptInBlock 49 | 50 | **Signature:** `static forJavaScriptInBlock(input : String) : String` 51 | 52 | Encodes a given input for use in JavaScript inside an HTML block. 53 | 54 | ### forJavaScriptInHTML 55 | 56 | **Signature:** `static forJavaScriptInHTML(input : String) : String` 57 | 58 | Encodes a given input for use in JavaScript inside an HTML context. 59 | 60 | ### forJavaScriptInSource 61 | 62 | **Signature:** `static forJavaScriptInSource(input : String) : String` 63 | 64 | Encodes a given input for use in JavaScript inside a JavaScript source file. 65 | 66 | ### forJSONValue 67 | 68 | **Signature:** `static forJSONValue(input : String) : String` 69 | 70 | Encodes a given input for use in a JSON Object Value to prevent escaping into a trusted context. 71 | 72 | ### forUriComponent 73 | 74 | **Signature:** `static forUriComponent(input : String) : String` 75 | 76 | Encodes a given input for use as a component of a URI. 77 | 78 | ### forUriComponentStrict 79 | 80 | **Signature:** `static forUriComponentStrict(input : String) : String` 81 | 82 | Encodes a given input for use as a component of a URI. 83 | 84 | ### forXmlCommentContent 85 | 86 | **Signature:** `static forXmlCommentContent(input : String) : String` 87 | 88 | Encodes a given input for use in an XML comments. 89 | 90 | ### forXmlContent 91 | 92 | **Signature:** `static forXmlContent(input : String) : String` 93 | 94 | Encodes a given input for use in a general XML context. 95 | 96 | ### forXmlInDoubleQuoteAttribute 97 | 98 | **Signature:** `static forXmlInDoubleQuoteAttribute(input : String) : String` 99 | 100 | Encodes a given input for use in an XML attribute guarded by a double quote. 101 | 102 | ### forXmlInSingleQuoteAttribute 103 | 104 | **Signature:** `static forXmlInSingleQuoteAttribute(input : String) : String` 105 | 106 | Encodes a given input for use in an XML attribute guarded by a single quote. 107 | 108 | ## Method Detail 109 | 110 | ## Method Details 111 | 112 | ### forHtmlContent 113 | 114 | **Signature:** `static forHtmlContent(input : String) : String` 115 | 116 | **Description:** Encodes a given input for use in a general HTML context. E.g. text content and text attributes. This method takes the UNION of allowed characters between the two context, so may be more imprecise that the more specific contexts. Generally, this method is preferred unless you specifically understand the context in which untrusted data will be output. Example Usage: <div>${SecureEncoder.forHtmlContent(unsafeData)}</div> <input value="${SecureEncoder.forHtmlContent(unsafeData)}" /> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x9F) with �, the Unicode Replacement Character Replace special HTML characters with their HTML Entity equivalents 117 | 118 | **Parameters:** 119 | 120 | - `input`: untrusted input to be encoded, if necessary 121 | 122 | **Returns:** 123 | 124 | a properly encoded string for the given input 125 | 126 | --- 127 | 128 | ### forHtmlInDoubleQuoteAttribute 129 | 130 | **Signature:** `static forHtmlInDoubleQuoteAttribute(input : String) : String` 131 | 132 | **Description:** Encodes a given input for use in an HTML Attribute guarded by a double quote. This method is preferred if you understand exactly how the output of this will be used in the HTML document. Example Usage: <div id="${SecureEncoder.forHtmlInDoubleQuoteAttribute(unsafeData)}"></div> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x9F) with �, the Unicode Replacement Character Replace special HTML characters with their HTML Entity equivalents 133 | 134 | **Parameters:** 135 | 136 | - `input`: untrusted input to be encoded, if necessary 137 | 138 | **Returns:** 139 | 140 | a properly encoded string for the given input 141 | 142 | --- 143 | 144 | ### forHtmlInSingleQuoteAttribute 145 | 146 | **Signature:** `static forHtmlInSingleQuoteAttribute(input : String) : String` 147 | 148 | **Description:** Encodes a given input for use in an HTML Attribute guarded by a single quote. This method is preferred if you understand exactly how the output of this will be used in the HTML document. Example Usage: <div id='${SecureEncoder.forHtmlInSingleQuoteAttribute(unsafeData)}'></div> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x9F) with �, the Unicode Replacement Character Replace special HTML characters with their HTML Entity equivalents 149 | 150 | **Parameters:** 151 | 152 | - `input`: untrusted input to be encoded, if necessary 153 | 154 | **Returns:** 155 | 156 | a properly encoded string for the given input 157 | 158 | --- 159 | 160 | ### forHtmlUnquotedAttribute 161 | 162 | **Signature:** `static forHtmlUnquotedAttribute(input : String) : String` 163 | 164 | **Description:** Encodes a given input for use in an HTML Attribute left unguarded. This method is preferred if you understand exactly how the output of this will be used in the HTML document. Example Usage: <div id=${SecureEncoder.forHtmlUnquotedAttribute(unsafeData)}></div> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x9F) with �, the Unicode Replacement Character Replace special HTML characters with their HTML Entity equivalents 165 | 166 | **Parameters:** 167 | 168 | - `input`: untrusted input to be encoded, if necessary 169 | 170 | **Returns:** 171 | 172 | a properly encoded string for the given input 173 | 174 | --- 175 | 176 | ### forJavaScriptInAttribute 177 | 178 | **Signature:** `static forJavaScriptInAttribute(input : String) : String` 179 | 180 | **Description:** Encodes a given input for use in JavaScript inside an HTML attribute. This method is preferred if you understand exactly how the output of the will be used in the page Example Usage: <button onclick="alert('${SecureEncoder.forJavaScriptInAttribute(unsafeData)}');"> Flow: Allow AlphaNumerics and some Special characters Slash escape certain illegal characters Replace special JavaScript characters with their Hex Encoded equivalents prepended with \\x for character codes under 128 and \\u for character codes over 128 181 | 182 | **Parameters:** 183 | 184 | - `input`: untrusted input to be encoded, if necessary 185 | 186 | **Returns:** 187 | 188 | a properly encoded string for the given input 189 | 190 | --- 191 | 192 | ### forJavaScriptInBlock 193 | 194 | **Signature:** `static forJavaScriptInBlock(input : String) : String` 195 | 196 | **Description:** Encodes a given input for use in JavaScript inside an HTML block. This method is preferred if you understand exactly how the output of the will be used in the page Example Usage: <script type="text/javascript"> var data = "${SecureEncoder.forJavaScriptInBlock(unsafeData)}"; </script> Flow: Allow AlphaNumerics and some Special characters Slash escape certain illegal characters Replace special JavaScript characters with their Hex Encoded equivalents prepended with \\x for character codes under 128 and \\u for character codes over 128 197 | 198 | **Parameters:** 199 | 200 | - `input`: untrusted input to be encoded, if necessary 201 | 202 | **Returns:** 203 | 204 | a properly encoded string for the given input 205 | 206 | --- 207 | 208 | ### forJavaScriptInHTML 209 | 210 | **Signature:** `static forJavaScriptInHTML(input : String) : String` 211 | 212 | **Description:** Encodes a given input for use in JavaScript inside an HTML context. This method takes the UNION of allowed characters among the other contexts, so may be more imprecise that the more specific contexts. Generally, this method is preferred unless you specifically understand the context in which untrusted data will be output. Example Usage: <script type="text/javascript"> var data = "${SecureEncoder.forJavaScriptInHTML(unsafeData)}"; </script> <button onclick="alert('${SecureEncoder.forJavaScriptInHTML(unsafeData)}');"> Flow: Allow AlphaNumerics and some Special characters Slash escape certain illegal characters Replace special JavaScript characters with their Hex Encoded equivalents prepended with \\x for character codes under 128 and \\u for character codes over 128 213 | 214 | **Parameters:** 215 | 216 | - `input`: untrusted input to be encoded, if necessary 217 | 218 | **Returns:** 219 | 220 | a properly encoded string for the given input 221 | 222 | --- 223 | 224 | ### forJavaScriptInSource 225 | 226 | **Signature:** `static forJavaScriptInSource(input : String) : String` 227 | 228 | **Description:** Encodes a given input for use in JavaScript inside a JavaScript source file. This method is preferred if you understand exactly how the output of the will be used in the page Example Usage: <...inside foobar.js...> var data = "${SecureEncoder.forJavaScriptInSource(unsafeData)}"; Flow: Allow AlphaNumerics and some Special characters Slash escape certain illegal characters Replace special JavaScript characters with their Hex Encoded equivalents prepended with \\x for character codes under 128 and \\u for character codes over 128 229 | 230 | **Parameters:** 231 | 232 | - `input`: untrusted input to be encoded, if necessary 233 | 234 | **Returns:** 235 | 236 | a properly encoded string for the given input 237 | 238 | --- 239 | 240 | ### forJSONValue 241 | 242 | **Signature:** `static forJSONValue(input : String) : String` 243 | 244 | **Description:** Encodes a given input for use in a JSON Object Value to prevent escaping into a trusted context. Example Usage: var json = {"trusted_data" : SecureEncoder.forJSONValue(unsafeData)}; return JSON.stringify(json); Flow: Allow AlphaNumerics Slash escape certain illegal characters Replace all other characters with their Hex Encoded equivalents prepended with \\u 245 | 246 | **Parameters:** 247 | 248 | - `input`: untrusted input to be encoded, if necessary 249 | 250 | **Returns:** 251 | 252 | a properly encoded string for the given input 253 | 254 | --- 255 | 256 | ### forUriComponent 257 | 258 | **Signature:** `static forUriComponent(input : String) : String` 259 | 260 | **Description:** Encodes a given input for use as a component of a URI. This is equivalent to javascript's encodeURIComponent and does a realistic job of encoding. Example Usage: <a href="http://host.com?value=${SecureEncoder.forUriComponent(unsafeData)}"/> Allows: A-Z, a-z, 0-9, -, _, ., ~, !, *, ', (, ) Flow: Allow AlphaNumerics and some Special characters Percent encode all other characters 261 | 262 | **Parameters:** 263 | 264 | - `input`: untrusted input to be encoded, if necessary 265 | 266 | **Returns:** 267 | 268 | a properly encoded string for the given input 269 | 270 | --- 271 | 272 | ### forUriComponentStrict 273 | 274 | **Signature:** `static forUriComponentStrict(input : String) : String` 275 | 276 | **Description:** Encodes a given input for use as a component of a URI. This is a strict encoder and fully complies with RFC3986. Example Usage: <a href="http://host.com?value=${SecureEncoder.forUriComponentStrict(unsafeData)}"/> Allows: A-Z, a-z, 0-9, -, _, ., ~ Flow: Allow AlphaNumerics and some Special characters Percent encode all other characters 277 | 278 | **Parameters:** 279 | 280 | - `input`: untrusted input to be encoded, if necessary 281 | 282 | **Returns:** 283 | 284 | a properly encoded string for the given input 285 | 286 | --- 287 | 288 | ### forXmlCommentContent 289 | 290 | **Signature:** `static forXmlCommentContent(input : String) : String` 291 | 292 | **Description:** Encodes a given input for use in an XML comments. This method is preferred if you understand the context in which untrusted data will be output. Note: It is recommended that you use a real parser, as this method can be misused, but is left here if a parser is unavailable to you Example Usage: <!-- ${SecureEncoder.forXmlCommentContent(unsafeData)} --> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x84 or between 0x86 and 0x9F or between 0xFDD0 and 0xFDDF) with an empty string Replace special XML characters with their default XML Entity equivalents 293 | 294 | **Parameters:** 295 | 296 | - `input`: untrusted input to be encoded, if necessary 297 | 298 | **Returns:** 299 | 300 | a properly encoded string for the given input 301 | 302 | --- 303 | 304 | ### forXmlContent 305 | 306 | **Signature:** `static forXmlContent(input : String) : String` 307 | 308 | **Description:** Encodes a given input for use in a general XML context. E.g. text content and text attributes. This method takes the UNION of allowed characters between the other contexts, so may be more imprecise that the more specific contexts. Generally, this method is preferred unless you specifically understand the context in which untrusted data will be output. Note: It is recommended that you use a real parser, as this method can be misused, but is left here if a parser is unavailable to you Example Usage: <foo>${SecureEncoder.forXmlContent(unsafeData)}</foo> <bar attr="${SecureEncoder.forXmlContent(unsafeData)}"></bar> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x84 or between 0x86 and 0x9F or between 0xFDD0 and 0xFDDF) with an empty string Replace special XML characters with their default XML Entity equivalents 309 | 310 | **Parameters:** 311 | 312 | - `input`: untrusted input to be encoded, if necessary 313 | 314 | **Returns:** 315 | 316 | a properly encoded string for the given input 317 | 318 | --- 319 | 320 | ### forXmlInDoubleQuoteAttribute 321 | 322 | **Signature:** `static forXmlInDoubleQuoteAttribute(input : String) : String` 323 | 324 | **Description:** Encodes a given input for use in an XML attribute guarded by a double quote. This method is preferred if you understand the context in which untrusted data will be output. Note: It is recommended that you use a real parser, as this method can be misused, but is left here if a parser is unavailable to you Example Usage: <bar attr="${SecureEncoder.forXmlInDoubleQuoteAttribute(unsafeData)}"></bar> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x84 or between 0x86 and 0x9F or between 0xFDD0 and 0xFDDF) with an empty string Replace special XML characters with their default XML Entity equivalents 325 | 326 | **Parameters:** 327 | 328 | - `input`: untrusted input to be encoded, if necessary 329 | 330 | **Returns:** 331 | 332 | a properly encoded string for the given input 333 | 334 | --- 335 | 336 | ### forXmlInSingleQuoteAttribute 337 | 338 | **Signature:** `static forXmlInSingleQuoteAttribute(input : String) : String` 339 | 340 | **Description:** Encodes a given input for use in an XML attribute guarded by a single quote. This method is preferred if you understand the context in which untrusted data will be output. Note: It is recommended that you use a real parser, as this method can be misused, but is left here if a parser is unavailable to you Example Usage: <bar attr='${SecureEncoder.forXmlInSingleQuoteAttribute(unsafeData)}'></bar> Flow: Allow AlphaNumerics and some Special characters Replace Illegal Control Characters (Below 0x1F or between 0x7F and 0x84 or between 0x86 and 0x9F or between 0xFDD0 and 0xFDDF) with an empty string Replace special XML characters with their default XML Entity equivalents 341 | 342 | **Parameters:** 343 | 344 | - `input`: untrusted input to be encoded, if necessary 345 | 346 | **Returns:** 347 | 348 | a properly encoded string for the given input 349 | 350 | --- ```