#
tokens: 47027/50000 5/825 files (page 33/43)
lines: off (toggle) GitHub
raw markdown copy
This is page 33 of 43. Use http://codebase.md/taurgis/sfcc-dev-mcp?page={x} to view the full context.

# Directory Structure

```
├── .DS_Store
├── .github
│   ├── dependabot.yml
│   ├── instructions
│   │   ├── mcp-node-tests.instructions.md
│   │   └── mcp-yml-tests.instructions.md
│   ├── ISSUE_TEMPLATE
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   ├── documentation.yml
│   │   ├── feature_request.yml
│   │   └── question.yml
│   ├── PULL_REQUEST_TEMPLATE
│   │   ├── bug_fix.md
│   │   ├── documentation.md
│   │   └── new_tool.md
│   ├── pull_request_template.md
│   └── workflows
│       ├── ci.yml
│       ├── deploy-pages.yml
│       ├── publish.yml
│       └── update-docs.yml
├── .gitignore
├── .husky
│   └── pre-commit
├── aegis.config.docs-only.json
├── aegis.config.json
├── aegis.config.with-dw.json
├── AGENTS.md
├── ai-instructions
│   ├── claude-desktop
│   │   └── claude_custom_instructions.md
│   ├── cursor
│   │   └── .cursor
│   │       └── rules
│   │           ├── debugging-workflows.mdc
│   │           ├── hooks-development.mdc
│   │           ├── isml-templates.mdc
│   │           ├── job-framework.mdc
│   │           ├── performance-optimization.mdc
│   │           ├── scapi-endpoints.mdc
│   │           ├── security-patterns.mdc
│   │           ├── sfcc-development.mdc
│   │           ├── sfra-controllers.mdc
│   │           ├── sfra-models.mdc
│   │           ├── system-objects.mdc
│   │           └── testing-patterns.mdc
│   └── github-copilot
│       └── copilot-instructions.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── docs
│   ├── best-practices
│   │   ├── cartridge_creation.md
│   │   ├── isml_templates.md
│   │   ├── job_framework.md
│   │   ├── localserviceregistry.md
│   │   ├── ocapi_hooks.md
│   │   ├── performance.md
│   │   ├── scapi_custom_endpoint.md
│   │   ├── scapi_hooks.md
│   │   ├── security.md
│   │   ├── sfra_client_side_js.md
│   │   ├── sfra_controllers.md
│   │   ├── sfra_models.md
│   │   └── sfra_scss.md
│   ├── dw_campaign
│   │   ├── ABTest.md
│   │   ├── ABTestMgr.md
│   │   ├── ABTestSegment.md
│   │   ├── AmountDiscount.md
│   │   ├── ApproachingDiscount.md
│   │   ├── BonusChoiceDiscount.md
│   │   ├── BonusDiscount.md
│   │   ├── Campaign.md
│   │   ├── CampaignMgr.md
│   │   ├── CampaignStatusCodes.md
│   │   ├── Coupon.md
│   │   ├── CouponMgr.md
│   │   ├── CouponRedemption.md
│   │   ├── CouponStatusCodes.md
│   │   ├── Discount.md
│   │   ├── DiscountPlan.md
│   │   ├── FixedPriceDiscount.md
│   │   ├── FixedPriceShippingDiscount.md
│   │   ├── FreeDiscount.md
│   │   ├── FreeShippingDiscount.md
│   │   ├── PercentageDiscount.md
│   │   ├── PercentageOptionDiscount.md
│   │   ├── PriceBookPriceDiscount.md
│   │   ├── Promotion.md
│   │   ├── PromotionMgr.md
│   │   ├── PromotionPlan.md
│   │   ├── SlotContent.md
│   │   ├── SourceCodeGroup.md
│   │   ├── SourceCodeInfo.md
│   │   ├── SourceCodeStatusCodes.md
│   │   └── TotalFixedPriceDiscount.md
│   ├── dw_catalog
│   │   ├── Catalog.md
│   │   ├── CatalogMgr.md
│   │   ├── Category.md
│   │   ├── CategoryAssignment.md
│   │   ├── CategoryLink.md
│   │   ├── PriceBook.md
│   │   ├── PriceBookMgr.md
│   │   ├── Product.md
│   │   ├── ProductActiveData.md
│   │   ├── ProductAttributeModel.md
│   │   ├── ProductAvailabilityLevels.md
│   │   ├── ProductAvailabilityModel.md
│   │   ├── ProductInventoryList.md
│   │   ├── ProductInventoryMgr.md
│   │   ├── ProductInventoryRecord.md
│   │   ├── ProductLink.md
│   │   ├── ProductMgr.md
│   │   ├── ProductOption.md
│   │   ├── ProductOptionModel.md
│   │   ├── ProductOptionValue.md
│   │   ├── ProductPriceInfo.md
│   │   ├── ProductPriceModel.md
│   │   ├── ProductPriceTable.md
│   │   ├── ProductSearchHit.md
│   │   ├── ProductSearchModel.md
│   │   ├── ProductSearchRefinementDefinition.md
│   │   ├── ProductSearchRefinements.md
│   │   ├── ProductSearchRefinementValue.md
│   │   ├── ProductVariationAttribute.md
│   │   ├── ProductVariationAttributeValue.md
│   │   ├── ProductVariationModel.md
│   │   ├── Recommendation.md
│   │   ├── SearchModel.md
│   │   ├── SearchRefinementDefinition.md
│   │   ├── SearchRefinements.md
│   │   ├── SearchRefinementValue.md
│   │   ├── SortingOption.md
│   │   ├── SortingRule.md
│   │   ├── Store.md
│   │   ├── StoreGroup.md
│   │   ├── StoreInventoryFilter.md
│   │   ├── StoreInventoryFilterValue.md
│   │   ├── StoreMgr.md
│   │   ├── Variant.md
│   │   └── VariationGroup.md
│   ├── dw_content
│   │   ├── Content.md
│   │   ├── ContentMgr.md
│   │   ├── ContentSearchModel.md
│   │   ├── ContentSearchRefinementDefinition.md
│   │   ├── ContentSearchRefinements.md
│   │   ├── ContentSearchRefinementValue.md
│   │   ├── Folder.md
│   │   ├── Library.md
│   │   ├── MarkupText.md
│   │   └── MediaFile.md
│   ├── dw_crypto
│   │   ├── CertificateRef.md
│   │   ├── CertificateUtils.md
│   │   ├── Cipher.md
│   │   ├── Encoding.md
│   │   ├── JWE.md
│   │   ├── JWEHeader.md
│   │   ├── JWS.md
│   │   ├── JWSHeader.md
│   │   ├── KeyRef.md
│   │   ├── Mac.md
│   │   ├── MessageDigest.md
│   │   ├── SecureRandom.md
│   │   ├── Signature.md
│   │   ├── WeakCipher.md
│   │   ├── WeakMac.md
│   │   ├── WeakMessageDigest.md
│   │   ├── WeakSignature.md
│   │   └── X509Certificate.md
│   ├── dw_customer
│   │   ├── AddressBook.md
│   │   ├── AgentUserMgr.md
│   │   ├── AgentUserStatusCodes.md
│   │   ├── AuthenticationStatus.md
│   │   ├── Credentials.md
│   │   ├── Customer.md
│   │   ├── CustomerActiveData.md
│   │   ├── CustomerAddress.md
│   │   ├── CustomerCDPData.md
│   │   ├── CustomerContextMgr.md
│   │   ├── CustomerGroup.md
│   │   ├── CustomerList.md
│   │   ├── CustomerMgr.md
│   │   ├── CustomerPasswordConstraints.md
│   │   ├── CustomerPaymentInstrument.md
│   │   ├── CustomerStatusCodes.md
│   │   ├── EncryptedObject.md
│   │   ├── ExternalProfile.md
│   │   ├── OrderHistory.md
│   │   ├── ProductList.md
│   │   ├── ProductListItem.md
│   │   ├── ProductListItemPurchase.md
│   │   ├── ProductListMgr.md
│   │   ├── ProductListRegistrant.md
│   │   ├── Profile.md
│   │   └── Wallet.md
│   ├── dw_extensions.applepay
│   │   ├── ApplePayHookResult.md
│   │   └── ApplePayHooks.md
│   ├── dw_extensions.facebook
│   │   ├── FacebookFeedHooks.md
│   │   └── FacebookProduct.md
│   ├── dw_extensions.paymentrequest
│   │   ├── PaymentRequestHookResult.md
│   │   └── PaymentRequestHooks.md
│   ├── dw_extensions.payments
│   │   ├── SalesforceBancontactPaymentDetails.md
│   │   ├── SalesforceCardPaymentDetails.md
│   │   ├── SalesforceEpsPaymentDetails.md
│   │   ├── SalesforceIdealPaymentDetails.md
│   │   ├── SalesforceKlarnaPaymentDetails.md
│   │   ├── SalesforcePaymentDetails.md
│   │   ├── SalesforcePaymentIntent.md
│   │   ├── SalesforcePaymentMethod.md
│   │   ├── SalesforcePaymentRequest.md
│   │   ├── SalesforcePaymentsHooks.md
│   │   ├── SalesforcePaymentsMgr.md
│   │   ├── SalesforcePaymentsSiteConfiguration.md
│   │   ├── SalesforcePayPalOrder.md
│   │   ├── SalesforcePayPalOrderAddress.md
│   │   ├── SalesforcePayPalOrderPayer.md
│   │   ├── SalesforcePayPalPaymentDetails.md
│   │   ├── SalesforceSepaDebitPaymentDetails.md
│   │   └── SalesforceVenmoPaymentDetails.md
│   ├── dw_extensions.pinterest
│   │   ├── PinterestAvailability.md
│   │   ├── PinterestFeedHooks.md
│   │   ├── PinterestOrder.md
│   │   ├── PinterestOrderHooks.md
│   │   └── PinterestProduct.md
│   ├── dw_io
│   │   ├── CSVStreamReader.md
│   │   ├── CSVStreamWriter.md
│   │   ├── File.md
│   │   ├── FileReader.md
│   │   ├── FileWriter.md
│   │   ├── InputStream.md
│   │   ├── OutputStream.md
│   │   ├── PrintWriter.md
│   │   ├── RandomAccessFileReader.md
│   │   ├── Reader.md
│   │   ├── StringWriter.md
│   │   ├── Writer.md
│   │   ├── XMLIndentingStreamWriter.md
│   │   ├── XMLStreamConstants.md
│   │   ├── XMLStreamReader.md
│   │   └── XMLStreamWriter.md
│   ├── dw_job
│   │   ├── JobExecution.md
│   │   └── JobStepExecution.md
│   ├── dw_net
│   │   ├── FTPClient.md
│   │   ├── FTPFileInfo.md
│   │   ├── HTTPClient.md
│   │   ├── HTTPRequestPart.md
│   │   ├── Mail.md
│   │   ├── SFTPClient.md
│   │   ├── SFTPFileInfo.md
│   │   ├── WebDAVClient.md
│   │   └── WebDAVFileInfo.md
│   ├── dw_object
│   │   ├── ActiveData.md
│   │   ├── CustomAttributes.md
│   │   ├── CustomObject.md
│   │   ├── CustomObjectMgr.md
│   │   ├── Extensible.md
│   │   ├── ExtensibleObject.md
│   │   ├── Note.md
│   │   ├── ObjectAttributeDefinition.md
│   │   ├── ObjectAttributeGroup.md
│   │   ├── ObjectAttributeValueDefinition.md
│   │   ├── ObjectTypeDefinition.md
│   │   ├── PersistentObject.md
│   │   ├── SimpleExtensible.md
│   │   └── SystemObjectMgr.md
│   ├── dw_order
│   │   ├── AbstractItem.md
│   │   ├── AbstractItemCtnr.md
│   │   ├── Appeasement.md
│   │   ├── AppeasementItem.md
│   │   ├── Basket.md
│   │   ├── BasketMgr.md
│   │   ├── BonusDiscountLineItem.md
│   │   ├── CouponLineItem.md
│   │   ├── CreateAgentBasketLimitExceededException.md
│   │   ├── CreateBasketFromOrderException.md
│   │   ├── CreateCouponLineItemException.md
│   │   ├── CreateOrderException.md
│   │   ├── CreateTemporaryBasketLimitExceededException.md
│   │   ├── GiftCertificate.md
│   │   ├── GiftCertificateLineItem.md
│   │   ├── GiftCertificateMgr.md
│   │   ├── GiftCertificateStatusCodes.md
│   │   ├── Invoice.md
│   │   ├── InvoiceItem.md
│   │   ├── LineItem.md
│   │   ├── LineItemCtnr.md
│   │   ├── Order.md
│   │   ├── OrderAddress.md
│   │   ├── OrderItem.md
│   │   ├── OrderMgr.md
│   │   ├── OrderPaymentInstrument.md
│   │   ├── OrderProcessStatusCodes.md
│   │   ├── PaymentCard.md
│   │   ├── PaymentInstrument.md
│   │   ├── PaymentMethod.md
│   │   ├── PaymentMgr.md
│   │   ├── PaymentProcessor.md
│   │   ├── PaymentStatusCodes.md
│   │   ├── PaymentTransaction.md
│   │   ├── PriceAdjustment.md
│   │   ├── PriceAdjustmentLimitTypes.md
│   │   ├── ProductLineItem.md
│   │   ├── ProductShippingCost.md
│   │   ├── ProductShippingLineItem.md
│   │   ├── ProductShippingModel.md
│   │   ├── Return.md
│   │   ├── ReturnCase.md
│   │   ├── ReturnCaseItem.md
│   │   ├── ReturnItem.md
│   │   ├── Shipment.md
│   │   ├── ShipmentShippingCost.md
│   │   ├── ShipmentShippingModel.md
│   │   ├── ShippingLineItem.md
│   │   ├── ShippingLocation.md
│   │   ├── ShippingMethod.md
│   │   ├── ShippingMgr.md
│   │   ├── ShippingOrder.md
│   │   ├── ShippingOrderItem.md
│   │   ├── SumItem.md
│   │   ├── TaxGroup.md
│   │   ├── TaxItem.md
│   │   ├── TaxMgr.md
│   │   ├── TrackingInfo.md
│   │   └── TrackingRef.md
│   ├── dw_order.hooks
│   │   ├── CalculateHooks.md
│   │   ├── OrderHooks.md
│   │   ├── PaymentHooks.md
│   │   ├── ReturnHooks.md
│   │   └── ShippingOrderHooks.md
│   ├── dw_rpc
│   │   ├── SOAPUtil.md
│   │   ├── Stub.md
│   │   └── WebReference.md
│   ├── dw_suggest
│   │   ├── BrandSuggestions.md
│   │   ├── CategorySuggestions.md
│   │   ├── ContentSuggestions.md
│   │   ├── CustomSuggestions.md
│   │   ├── ProductSuggestions.md
│   │   ├── SearchPhraseSuggestions.md
│   │   ├── SuggestedCategory.md
│   │   ├── SuggestedContent.md
│   │   ├── SuggestedPhrase.md
│   │   ├── SuggestedProduct.md
│   │   ├── SuggestedTerm.md
│   │   ├── SuggestedTerms.md
│   │   ├── Suggestions.md
│   │   └── SuggestModel.md
│   ├── dw_svc
│   │   ├── FTPService.md
│   │   ├── FTPServiceDefinition.md
│   │   ├── HTTPFormService.md
│   │   ├── HTTPFormServiceDefinition.md
│   │   ├── HTTPService.md
│   │   ├── HTTPServiceDefinition.md
│   │   ├── LocalServiceRegistry.md
│   │   ├── Result.md
│   │   ├── Service.md
│   │   ├── ServiceCallback.md
│   │   ├── ServiceConfig.md
│   │   ├── ServiceCredential.md
│   │   ├── ServiceDefinition.md
│   │   ├── ServiceProfile.md
│   │   ├── ServiceRegistry.md
│   │   ├── SOAPService.md
│   │   └── SOAPServiceDefinition.md
│   ├── dw_system
│   │   ├── AgentUserStatusCodes.md
│   │   ├── Cache.md
│   │   ├── CacheMgr.md
│   │   ├── HookMgr.md
│   │   ├── InternalObject.md
│   │   ├── JobProcessMonitor.md
│   │   ├── Log.md
│   │   ├── Logger.md
│   │   ├── LogNDC.md
│   │   ├── OrganizationPreferences.md
│   │   ├── Pipeline.md
│   │   ├── PipelineDictionary.md
│   │   ├── RemoteInclude.md
│   │   ├── Request.md
│   │   ├── RequestHooks.md
│   │   ├── Response.md
│   │   ├── RESTErrorResponse.md
│   │   ├── RESTResponseMgr.md
│   │   ├── RESTSuccessResponse.md
│   │   ├── SearchStatus.md
│   │   ├── Session.md
│   │   ├── Site.md
│   │   ├── SitePreferences.md
│   │   ├── Status.md
│   │   ├── StatusItem.md
│   │   ├── System.md
│   │   └── Transaction.md
│   ├── dw_util
│   │   ├── ArrayList.md
│   │   ├── Assert.md
│   │   ├── BigInteger.md
│   │   ├── Bytes.md
│   │   ├── Calendar.md
│   │   ├── Collection.md
│   │   ├── Currency.md
│   │   ├── DateUtils.md
│   │   ├── Decimal.md
│   │   ├── FilteringCollection.md
│   │   ├── Geolocation.md
│   │   ├── HashMap.md
│   │   ├── HashSet.md
│   │   ├── Iterator.md
│   │   ├── LinkedHashMap.md
│   │   ├── LinkedHashSet.md
│   │   ├── List.md
│   │   ├── Locale.md
│   │   ├── Map.md
│   │   ├── MapEntry.md
│   │   ├── MappingKey.md
│   │   ├── MappingMgr.md
│   │   ├── PropertyComparator.md
│   │   ├── SecureEncoder.md
│   │   ├── SecureFilter.md
│   │   ├── SeekableIterator.md
│   │   ├── Set.md
│   │   ├── SortedMap.md
│   │   ├── SortedSet.md
│   │   ├── StringUtils.md
│   │   ├── Template.md
│   │   └── UUIDUtils.md
│   ├── dw_value
│   │   ├── EnumValue.md
│   │   ├── MimeEncodedText.md
│   │   ├── Money.md
│   │   └── Quantity.md
│   ├── dw_web
│   │   ├── ClickStream.md
│   │   ├── ClickStreamEntry.md
│   │   ├── Cookie.md
│   │   ├── Cookies.md
│   │   ├── CSRFProtection.md
│   │   ├── Form.md
│   │   ├── FormAction.md
│   │   ├── FormElement.md
│   │   ├── FormElementValidationResult.md
│   │   ├── FormField.md
│   │   ├── FormFieldOption.md
│   │   ├── FormFieldOptions.md
│   │   ├── FormGroup.md
│   │   ├── FormList.md
│   │   ├── FormListItem.md
│   │   ├── Forms.md
│   │   ├── HttpParameter.md
│   │   ├── HttpParameterMap.md
│   │   ├── LoopIterator.md
│   │   ├── PageMetaData.md
│   │   ├── PageMetaTag.md
│   │   ├── PagingModel.md
│   │   ├── Resource.md
│   │   ├── URL.md
│   │   ├── URLAction.md
│   │   ├── URLParameter.md
│   │   ├── URLRedirect.md
│   │   ├── URLRedirectMgr.md
│   │   └── URLUtils.md
│   ├── sfra
│   │   ├── account.md
│   │   ├── address.md
│   │   ├── billing.md
│   │   ├── cart.md
│   │   ├── categories.md
│   │   ├── content.md
│   │   ├── locale.md
│   │   ├── order.md
│   │   ├── payment.md
│   │   ├── price-default.md
│   │   ├── price-range.md
│   │   ├── price-tiered.md
│   │   ├── product-bundle.md
│   │   ├── product-full.md
│   │   ├── product-line-items.md
│   │   ├── product-search.md
│   │   ├── product-tile.md
│   │   ├── querystring.md
│   │   ├── render.md
│   │   ├── request.md
│   │   ├── response.md
│   │   ├── server.md
│   │   ├── shipping.md
│   │   ├── store.md
│   │   ├── stores.md
│   │   └── totals.md
│   └── TopLevel
│       ├── APIException.md
│       ├── arguments.md
│       ├── Array.md
│       ├── ArrayBuffer.md
│       ├── BigInt.md
│       ├── Boolean.md
│       ├── ConversionError.md
│       ├── DataView.md
│       ├── Date.md
│       ├── Error.md
│       ├── ES6Iterator.md
│       ├── EvalError.md
│       ├── Fault.md
│       ├── Float32Array.md
│       ├── Float64Array.md
│       ├── Function.md
│       ├── Generator.md
│       ├── global.md
│       ├── Int16Array.md
│       ├── Int32Array.md
│       ├── Int8Array.md
│       ├── InternalError.md
│       ├── IOError.md
│       ├── Iterable.md
│       ├── Iterator.md
│       ├── JSON.md
│       ├── Map.md
│       ├── Math.md
│       ├── Module.md
│       ├── Namespace.md
│       ├── Number.md
│       ├── Object.md
│       ├── QName.md
│       ├── RangeError.md
│       ├── ReferenceError.md
│       ├── RegExp.md
│       ├── Set.md
│       ├── StopIteration.md
│       ├── String.md
│       ├── Symbol.md
│       ├── SyntaxError.md
│       ├── SystemError.md
│       ├── TypeError.md
│       ├── Uint16Array.md
│       ├── Uint32Array.md
│       ├── Uint8Array.md
│       ├── Uint8ClampedArray.md
│       ├── URIError.md
│       ├── WeakMap.md
│       ├── WeakSet.md
│       ├── XML.md
│       ├── XMLList.md
│       └── XMLStreamError.md
├── docs-site
│   ├── .gitignore
│   ├── App.tsx
│   ├── components
│   │   ├── Badge.tsx
│   │   ├── BreadcrumbSchema.tsx
│   │   ├── CodeBlock.tsx
│   │   ├── Collapsible.tsx
│   │   ├── ConfigBuilder.tsx
│   │   ├── ConfigHero.tsx
│   │   ├── ConfigModeTabs.tsx
│   │   ├── icons.tsx
│   │   ├── Layout.tsx
│   │   ├── LightCodeContainer.tsx
│   │   ├── NewcomerCTA.tsx
│   │   ├── NextStepsStrip.tsx
│   │   ├── OnThisPage.tsx
│   │   ├── Search.tsx
│   │   ├── SEO.tsx
│   │   ├── Sidebar.tsx
│   │   ├── StructuredData.tsx
│   │   ├── ToolCard.tsx
│   │   ├── ToolFilters.tsx
│   │   ├── Typography.tsx
│   │   └── VersionBadge.tsx
│   ├── constants.tsx
│   ├── index.html
│   ├── main.tsx
│   ├── metadata.json
│   ├── package-lock.json
│   ├── package.json
│   ├── pages
│   │   ├── AIInterfacesPage.tsx
│   │   ├── ConfigurationPage.tsx
│   │   ├── DevelopmentPage.tsx
│   │   ├── ExamplesPage.tsx
│   │   ├── FeaturesPage.tsx
│   │   ├── HomePage.tsx
│   │   ├── SecurityPage.tsx
│   │   ├── ToolsPage.tsx
│   │   └── TroubleshootingPage.tsx
│   ├── postcss.config.js
│   ├── public
│   │   ├── .well-known
│   │   │   └── security.txt
│   │   ├── 404.html
│   │   ├── android-chrome-192x192.png
│   │   ├── android-chrome-512x512.png
│   │   ├── apple-touch-icon.png
│   │   ├── explain-product-pricing-methods-no-mcp.png
│   │   ├── explain-product-pricing-methods.png
│   │   ├── favicon-16x16.png
│   │   ├── favicon-32x32.png
│   │   ├── favicon.ico
│   │   ├── llms.txt
│   │   ├── robots.txt
│   │   ├── site.webmanifest
│   │   └── sitemap.xml
│   ├── README.md
│   ├── scripts
│   │   ├── generate-search-index.js
│   │   ├── generate-sitemap.js
│   │   └── search-dev.js
│   ├── src
│   │   └── styles
│   │       ├── input.css
│   │       └── prism-theme.css
│   ├── tailwind.config.js
│   ├── tsconfig.json
│   ├── types.ts
│   ├── utils
│   │   ├── search.ts
│   │   └── toolsData.ts
│   └── vite.config.ts
├── eslint.config.js
├── jest.config.js
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│   └── convert-docs.js
├── SECURITY.md
├── server.json
├── src
│   ├── clients
│   │   ├── base
│   │   │   ├── http-client.ts
│   │   │   ├── oauth-token.ts
│   │   │   └── ocapi-auth-client.ts
│   │   ├── best-practices-client.ts
│   │   ├── cartridge-generation-client.ts
│   │   ├── docs
│   │   │   ├── class-content-parser.ts
│   │   │   ├── class-name-resolver.ts
│   │   │   ├── documentation-scanner.ts
│   │   │   ├── index.ts
│   │   │   └── referenced-types-extractor.ts
│   │   ├── docs-client.ts
│   │   ├── log-client.ts
│   │   ├── logs
│   │   │   ├── index.ts
│   │   │   ├── log-analyzer.ts
│   │   │   ├── log-client.ts
│   │   │   ├── log-constants.ts
│   │   │   ├── log-file-discovery.ts
│   │   │   ├── log-file-reader.ts
│   │   │   ├── log-formatter.ts
│   │   │   ├── log-processor.ts
│   │   │   ├── log-types.ts
│   │   │   └── webdav-client-manager.ts
│   │   ├── ocapi
│   │   │   ├── code-versions-client.ts
│   │   │   ├── site-preferences-client.ts
│   │   │   └── system-objects-client.ts
│   │   ├── ocapi-client.ts
│   │   └── sfra-client.ts
│   ├── config
│   │   ├── configuration-factory.ts
│   │   └── dw-json-loader.ts
│   ├── core
│   │   ├── handlers
│   │   │   ├── abstract-log-tool-handler.ts
│   │   │   ├── base-handler.ts
│   │   │   ├── best-practices-handler.ts
│   │   │   ├── cartridge-handler.ts
│   │   │   ├── client-factory.ts
│   │   │   ├── code-version-handler.ts
│   │   │   ├── docs-handler.ts
│   │   │   ├── job-log-handler.ts
│   │   │   ├── job-log-tool-config.ts
│   │   │   ├── log-handler.ts
│   │   │   ├── log-tool-config.ts
│   │   │   ├── sfra-handler.ts
│   │   │   ├── system-object-handler.ts
│   │   │   └── validation-helpers.ts
│   │   ├── server.ts
│   │   └── tool-definitions.ts
│   ├── index.ts
│   ├── main.ts
│   ├── services
│   │   ├── file-system-service.ts
│   │   ├── index.ts
│   │   └── path-service.ts
│   ├── tool-configs
│   │   ├── best-practices-tool-config.ts
│   │   ├── cartridge-tool-config.ts
│   │   ├── code-version-tool-config.ts
│   │   ├── docs-tool-config.ts
│   │   ├── job-log-tool-config.ts
│   │   ├── log-tool-config.ts
│   │   ├── sfra-tool-config.ts
│   │   └── system-object-tool-config.ts
│   ├── types
│   │   └── types.ts
│   └── utils
│       ├── cache.ts
│       ├── job-log-tool-config.ts
│       ├── job-log-utils.ts
│       ├── log-cache.ts
│       ├── log-tool-config.ts
│       ├── log-tool-constants.ts
│       ├── log-tool-utils.ts
│       ├── logger.ts
│       ├── ocapi-url-builder.ts
│       ├── path-resolver.ts
│       ├── query-builder.ts
│       ├── utils.ts
│       └── validator.ts
├── tests
│   ├── __mocks__
│   │   ├── docs-client.ts
│   │   ├── src
│   │   │   └── clients
│   │   │       └── base
│   │   │           └── http-client.js
│   │   └── webdav.js
│   ├── base-handler.test.ts
│   ├── base-http-client.test.ts
│   ├── best-practices-handler.test.ts
│   ├── cache.test.ts
│   ├── cartridge-handler.test.ts
│   ├── class-content-parser.test.ts
│   ├── class-name-resolver.test.ts
│   ├── client-factory.test.ts
│   ├── code-version-handler.test.ts
│   ├── code-versions-client.test.ts
│   ├── config.test.ts
│   ├── configuration-factory.test.ts
│   ├── docs-handler.test.ts
│   ├── documentation-scanner.test.ts
│   ├── file-system-service.test.ts
│   ├── job-log-handler.test.ts
│   ├── job-log-utils.test.ts
│   ├── log-client.test.ts
│   ├── log-handler.test.ts
│   ├── log-processor.test.ts
│   ├── logger.test.ts
│   ├── mcp
│   │   ├── AGENTS.md
│   │   ├── node
│   │   │   ├── activate-code-version-advanced.full-mode.programmatic.test.js
│   │   │   ├── code-versions.full-mode.programmatic.test.js
│   │   │   ├── generate-cartridge-structure.docs-only.programmatic.test.js
│   │   │   ├── get-available-best-practice-guides.docs-only.programmatic.test.js
│   │   │   ├── get-available-sfra-documents.programmatic.test.js
│   │   │   ├── get-best-practice-guide.docs-only.programmatic.test.js
│   │   │   ├── get-hook-reference.docs-only.programmatic.test.js
│   │   │   ├── get-job-execution-summary.full-mode.programmatic.test.js
│   │   │   ├── get-job-log-entries.full-mode.programmatic.test.js
│   │   │   ├── get-latest-debug.full-mode.programmatic.test.js
│   │   │   ├── get-latest-error.full-mode.programmatic.test.js
│   │   │   ├── get-latest-info.full-mode.programmatic.test.js
│   │   │   ├── get-latest-job-log-files.full-mode.programmatic.test.js
│   │   │   ├── get-latest-warn.full-mode.programmatic.test.js
│   │   │   ├── get-log-file-contents.full-mode.programmatic.test.js
│   │   │   ├── get-sfcc-class-documentation.docs-only.programmatic.test.js
│   │   │   ├── get-sfcc-class-info.docs-only.programmatic.test.js
│   │   │   ├── get-sfra-categories.docs-only.programmatic.test.js
│   │   │   ├── get-sfra-document.programmatic.test.js
│   │   │   ├── get-sfra-documents-by-category.docs-only.programmatic.test.js
│   │   │   ├── get-system-object-definition.full-mode.programmatic.test.js
│   │   │   ├── get-system-object-definitions.docs-only.programmatic.test.js
│   │   │   ├── get-system-object-definitions.full-mode.programmatic.test.js
│   │   │   ├── list-log-files.full-mode.programmatic.test.js
│   │   │   ├── list-sfcc-classes.docs-only.programmatic.test.js
│   │   │   ├── search-best-practices.docs-only.programmatic.test.js
│   │   │   ├── search-custom-object-attribute-definitions.full-mode.programmatic.test.js
│   │   │   ├── search-job-logs-by-name.full-mode.programmatic.test.js
│   │   │   ├── search-job-logs.full-mode.programmatic.test.js
│   │   │   ├── search-logs.full-mode.programmatic.test.js
│   │   │   ├── search-sfcc-classes.docs-only.programmatic.test.js
│   │   │   ├── search-sfcc-methods.docs-only.programmatic.test.js
│   │   │   ├── search-sfra-documentation.docs-only.programmatic.test.js
│   │   │   ├── search-site-preferences.full-mode.programmatic.test.js
│   │   │   ├── search-system-object-attribute-definitions.full-mode.programmatic.test.js
│   │   │   ├── search-system-object-attribute-groups.full-mode.programmatic.test.js
│   │   │   ├── summarize-logs.full-mode.programmatic.test.js
│   │   │   ├── tools.docs-only.programmatic.test.js
│   │   │   └── tools.full-mode.programmatic.test.js
│   │   ├── README.md
│   │   ├── test-fixtures
│   │   │   └── dw.json
│   │   └── yaml
│   │       ├── activate-code-version.docs-only.test.mcp.yml
│   │       ├── activate-code-version.full-mode.test.mcp.yml
│   │       ├── get_latest_error.test.mcp.yml
│   │       ├── get-available-best-practice-guides.docs-only.test.mcp.yml
│   │       ├── get-available-best-practice-guides.full-mode.test.mcp.yml
│   │       ├── get-available-sfra-documents.docs-only.test.mcp.yml
│   │       ├── get-available-sfra-documents.full-mode.test.mcp.yml
│   │       ├── get-best-practice-guide.docs-only.test.mcp.yml
│   │       ├── get-best-practice-guide.full-mode.test.mcp.yml
│   │       ├── get-code-versions.docs-only.test.mcp.yml
│   │       ├── get-code-versions.full-mode.test.mcp.yml
│   │       ├── get-hook-reference.docs-only.test.mcp.yml
│   │       ├── get-hook-reference.full-mode.test.mcp.yml
│   │       ├── get-job-execution-summary.full-mode.test.mcp.yml
│   │       ├── get-job-log-entries.full-mode.test.mcp.yml
│   │       ├── get-latest-debug.full-mode.test.mcp.yml
│   │       ├── get-latest-error.full-mode.test.mcp.yml
│   │       ├── get-latest-info.full-mode.test.mcp.yml
│   │       ├── get-latest-job-log-files.full-mode.test.mcp.yml
│   │       ├── get-latest-warn.full-mode.test.mcp.yml
│   │       ├── get-log-file-contents.full-mode.test.mcp.yml
│   │       ├── get-sfcc-class-documentation.docs-only.test.mcp.yml
│   │       ├── get-sfcc-class-documentation.full-mode.test.mcp.yml
│   │       ├── get-sfcc-class-info.docs-only.test.mcp.yml
│   │       ├── get-sfcc-class-info.full-mode.test.mcp.yml
│   │       ├── get-sfra-categories.docs-only.test.mcp.yml
│   │       ├── get-sfra-categories.full-mode.test.mcp.yml
│   │       ├── get-sfra-document.docs-only.test.mcp.yml
│   │       ├── get-sfra-document.full-mode.test.mcp.yml
│   │       ├── get-sfra-documents-by-category.docs-only.test.mcp.yml
│   │       ├── get-sfra-documents-by-category.full-mode.test.mcp.yml
│   │       ├── get-system-object-definition.docs-only.test.mcp.yml
│   │       ├── get-system-object-definition.full-mode.test.mcp.yml
│   │       ├── get-system-object-definitions.docs-only.test.mcp.yml
│   │       ├── get-system-object-definitions.full-mode.test.mcp.yml
│   │       ├── list-log-files.full-mode.test.mcp.yml
│   │       ├── list-sfcc-classes.docs-only.test.mcp.yml
│   │       ├── list-sfcc-classes.full-mode.test.mcp.yml
│   │       ├── search-best-practices.docs-only.test.mcp.yml
│   │       ├── search-best-practices.full-mode.test.mcp.yml
│   │       ├── search-custom-object-attribute-definitions.docs-only.test.mcp.yml
│   │       ├── search-custom-object-attribute-definitions.test.mcp.yml
│   │       ├── search-job-logs-by-name.full-mode.test.mcp.yml
│   │       ├── search-job-logs.full-mode.test.mcp.yml
│   │       ├── search-logs.full-mode.test.mcp.yml
│   │       ├── search-sfcc-classes.docs-only.test.mcp.yml
│   │       ├── search-sfcc-classes.full-mode.test.mcp.yml
│   │       ├── search-sfcc-methods.docs-only.test.mcp.yml
│   │       ├── search-sfcc-methods.full-mode.test.mcp.yml
│   │       ├── search-sfra-documentation.docs-only.test.mcp.yml
│   │       ├── search-sfra-documentation.full-mode.test.mcp.yml
│   │       ├── search-site-preferences.docs-only.test.mcp.yml
│   │       ├── search-site-preferences.full-mode.test.mcp.yml
│   │       ├── search-system-object-attribute-definitions.docs-only.test.mcp.yml
│   │       ├── search-system-object-attribute-definitions.full-mode.test.mcp.yml
│   │       ├── search-system-object-attribute-groups.docs-only.test.mcp.yml
│   │       ├── search-system-object-attribute-groups.full-mode.test.mcp.yml
│   │       ├── summarize-logs.full-mode.test.mcp.yml
│   │       ├── tools.docs-only.test.mcp.yml
│   │       └── tools.full-mode.test.mcp.yml
│   ├── oauth-token.test.ts
│   ├── ocapi-auth-client.test.ts
│   ├── ocapi-client.test.ts
│   ├── path-service.test.ts
│   ├── query-builder.test.ts
│   ├── referenced-types-extractor.test.ts
│   ├── servers
│   │   ├── sfcc-mock-server
│   │   │   ├── mock-data
│   │   │   │   └── ocapi
│   │   │   │       ├── code-versions.json
│   │   │   │       ├── custom-object-attributes-customapi.json
│   │   │   │       ├── custom-object-attributes-globalsettings.json
│   │   │   │       ├── custom-object-attributes-versionhistory.json
│   │   │   │       ├── site-preferences-ccv.json
│   │   │   │       ├── site-preferences-fastforward.json
│   │   │   │       ├── site-preferences-sfra.json
│   │   │   │       ├── site-preferences-storefront.json
│   │   │   │       ├── site-preferences-system.json
│   │   │   │       ├── system-object-attribute-groups-campaign.json
│   │   │   │       ├── system-object-attribute-groups-category.json
│   │   │   │       ├── system-object-attribute-groups-order.json
│   │   │   │       ├── system-object-attribute-groups-product.json
│   │   │   │       ├── system-object-attribute-groups-sitepreferences.json
│   │   │   │       ├── system-object-attributes-customeraddress.json
│   │   │   │       ├── system-object-attributes-product-expanded.json
│   │   │   │       ├── system-object-attributes-product.json
│   │   │   │       ├── system-object-definition-category.json
│   │   │   │       ├── system-object-definition-customer.json
│   │   │   │       ├── system-object-definition-customeraddress.json
│   │   │   │       ├── system-object-definition-order.json
│   │   │   │       ├── system-object-definition-product.json
│   │   │   │       ├── system-object-definitions-old.json
│   │   │   │       └── system-object-definitions.json
│   │   │   ├── package-lock.json
│   │   │   ├── package.json
│   │   │   ├── README.md
│   │   │   ├── scripts
│   │   │   │   └── setup-logs.js
│   │   │   ├── server.js
│   │   │   └── src
│   │   │       ├── app.js
│   │   │       ├── config
│   │   │       │   └── server-config.js
│   │   │       ├── middleware
│   │   │       │   ├── auth.js
│   │   │       │   ├── cors.js
│   │   │       │   └── logging.js
│   │   │       ├── routes
│   │   │       │   ├── ocapi
│   │   │       │   │   ├── code-versions-handler.js
│   │   │       │   │   ├── oauth-handler.js
│   │   │       │   │   ├── ocapi-error-utils.js
│   │   │       │   │   ├── ocapi-utils.js
│   │   │       │   │   ├── site-preferences-handler.js
│   │   │       │   │   └── system-objects-handler.js
│   │   │       │   ├── ocapi.js
│   │   │       │   └── webdav.js
│   │   │       └── utils
│   │   │           ├── mock-data-loader.js
│   │   │           └── webdav-xml.js
│   │   └── sfcc-mock-server-manager.ts
│   ├── sfcc-mock-server.test.ts
│   ├── site-preferences-client.test.ts
│   ├── system-objects-client.test.ts
│   ├── utils.test.ts
│   ├── validation-helpers.test.ts
│   └── validator.test.ts
├── tsconfig.json
└── tsconfig.test.json
```

# Files

--------------------------------------------------------------------------------
/docs/best-practices/sfra_client_side_js.md:
--------------------------------------------------------------------------------

```markdown
---
title: Mastering Client-Side JavaScript in SFRA
description: Comprehensive best practices for extending, structuring, validating, and optimizing client-side JavaScript in Salesforce B2C Commerce SFRA storefronts.
status: stable
---

# Mastering Client-Side JavaScript in Salesforce B2C Commerce (SFRA)

This guide distills architectural fundamentals and production-grade patterns for building, extending, and optimizing client-side functionality in SFRA storefronts. It complements base documentation by focusing on how things *really* work in practice: build-time aliasing, asset injection, extension patterns, AJAX + CSRF flows, robust validation, DOM efficiency, accessibility, and maintainable modular code.

## Table of Contents
1. [Architecture Overview](#architecture-overview)
2. [Cartridges & Directory Structure](#cartridges--directory-structure)
3. [Build Process & Cross-Cartridge Inheritance](#build-process--cross-cartridge-inheritance)
4. [Asset Loading via `assets.js`](#asset-loading-via-assetsjs)
5. [Client-Side Extension Pattern](#client-side-extension-pattern)
     - [Misconception: `module.superModule`](#misconception-modulesupermodule)
     - [Extension Steps](#extension-steps)
     - [Full PDP Example](#full-pdp-extension-example)
6. [`require()` Path Syntax Reference](#require-path-syntax-reference)
7. [AJAX Architecture & CSRF](#ajax-architecture--csrf)
8. [Newsletter End-to-End Example](#newsletter-end-to-end-example)
9. [Form Framework & Validation Flow](#form-framework--validation-flow)
10. [jQuery / DOM Best Practices](#jquery--dom-best-practices)
11. [Performance Optimization](#performance-optimization)
12. [Accessibility (A11y)](#accessibility-a11y)
13. [Code Quality & Maintainability](#code-quality--maintainability)
14. [Quick Checklist](#quick-checklist)
15. [Event & Module Design Patterns](#event--module-design-patterns)
16. [Security & Data Protection](#security--data-protection)
17. [Advanced AJAX & Error Handling](#advanced-ajax--error-handling)
18. [Testing Strategy for Client Modules](#testing-strategy-for-client-modules)
19. [Instrumentation & Telemetry](#instrumentation--telemetry)
20. [Internationalization (i18n)](#internationalization-i18n)

---

## Architecture Overview
SFRA separates:
- **Server runtime resolution** (cartridge path in Business Manager) – affects controllers, scripts, ISML.
- **Client build resolution** (compile-time `paths` aliases) – affects only assets under `cartridge/client/default/`.

Client-side behavior is determined **at build time**, not by the live cartridge path. This decoupling is powerful and a frequent source of confusion.

## Cartridges & Directory Structure
Structure your custom cartridge like:
```
app_custom_mybrand/
    cartridge/
        client/
            default/
                js/           # Feature modules (product, account, checkout, etc.)
                scss/         # Sass source
                images/       # Static imagery (if needed)
```
Guidelines:
- Never modify `app_storefront_base` directly.
- Mirror base file locations when extending (`js/product/detail.js`).
- Group by domain (`product/`, `checkout/`, `account/`) not by technical layer.
- Keep each module focused (cohesive public API via `module.exports`).

## Build Process & Cross-Cartridge Inheritance
Run build scripts (commonly via `sgmf-scripts`):
- `npm run compile:js`
- `npm run compile:scss`

Features:
- Transpiles, bundles, minifies.
- Resolves aliased `require('base/...')` imports through `paths` mapping.
- Produces deployable assets uploaded via UX Studio / CI pipeline.

Key distinction: **Changing the Business Manager cartridge path does not retroactively affect already compiled client bundles.** Recompile after structural changes.

## Asset Loading via `assets.js`
Asset registration flow:
1. In an ISML template: `assets.addJs('/js/product/detail.js')` or `assets.addCss('/css/product.css')`.
2. The singleton (`*/cartridge/scripts/assets.js`) accumulates assets **per request**.
3. Decorator templates (`common/layout/page.isml`) render loops in `htmlHead.isml` (CSS) and `scripts.isml` (JS).

Remote include caveat:
> Assets added inside a *remote include* live only in that secondary request and will **not** appear in the parent page. Register required assets in the main controller/template context.

## Client-Side Extension Pattern
Client-side extension is **composition via build-time aliases**, not runtime inheritance.

### Misconception: `module.superModule`
`module.superModule` exists only on the **server** (Rhino engine) for controllers / scripts. It does **not** exist in browser bundles. Using it client-side will throw (undefined reference).

### Extension Steps
#### 1. Configure `paths` alias in custom cartridge `package.json`
```jsonc
// my_custom_cartridge/package.json
{
    "name": "app_custom_mybrand",
    "scripts": {
        "compile:js": "sgmf-scripts --compile js",
        "compile:scss": "sgmf-scripts --compile css"
    },
    "paths": {
        "base": "../storefront-reference-architecture/cartridges/app_storefront_base/"
    }
}
```
#### 2. Require base module
```javascript
'use strict';
var base = require('base/product/detail');
```
#### 3. Decorate / override
Modify `base` object (add or replace functions). If you need original logic, copy/refactor it—there is no automatic super call.
#### 4. Re-export
```javascript
module.exports = base;
```

### Full PDP Extension Example
**Base (`app_storefront_base/.../product/detail.js`)**
```javascript
'use strict';
function updateAddToCartButton(update) {
    $('button.add-to-cart').attr('disabled', !update.readyToOrder || !update.available);
}
module.exports = { updateAddToCartButton: updateAddToCartButton };
```
**Custom (`app_custom_mybrand/.../product/detail.js`)**
```javascript
'use strict';
var base = require('base/product/detail');

function handleNotifyMe() {
    console.log('Notify Me button clicked!');
}

function updateNotifyMeButton(update) {
    if (!update.available && update.readyToOrder) {
        $('.notify-me').show();
    } else {
        $('.notify-me').hide();
    }
}

base.updateAddToCartButton = function (update) {
    $('button.add-to-cart').attr('disabled', !update.readyToOrder || !update.available);
    updateNotifyMeButton(update);
};

base.initializeNotifyMeEvent = function () {
    $('body').on('click', '.notify-me', handleNotifyMe);
};

module.exports = base;
```

## `require()` Path Syntax Reference
| Syntax       | Context                       | Purpose / Behavior                                                                 | Example |
|--------------|-------------------------------|--------------------------------------------------------------------------------------|---------|
| `./` / `../` | Client & Server               | Relative to current file.                                                          | `require('./utils')` |
| `~/`         | Server only (runtime)         | Current cartridge root in runtime path. Not for client build.                      | `require('~/cartridge/scripts/assets.js')` |
| `*/`         | Server only (runtime)         | Searches entire cartridge path (left→right).                                       | `require('*/cartridge/scripts/middleware/consentTracking')` |
| `[alias]/`   | Client only (build-time)      | Resolves via `package.json` `paths` mapping across cartridges.                     | `require('base/product/detail')` |

## AJAX Architecture & CSRF
Core components:
1. **Controller route** (`server.post('Route', ...)`) returns JSON via `res.json()`.
2. **Client module** uses `$.ajax()` (or `fetch`) with serialized form data.
3. **URL generation** via `URLUtils.url('Controller-Route')` passed through `data-*` attributes (avoid hardcoding).
4. **CSRF token** injected as hidden inputs; included automatically when using `form.serialize()`.
5. **Error handling**: differentiate transport errors vs. business validation (`success: false`).

Concurrency & Abort:
- Maintain reference to last in-flight xhr for a feature (e.g. typeahead) and abort before issuing a new one to avoid race conditions that render stale results.
- Use increasing request tokens (simple incrementing counter) to ignore late arrivals when abort is not possible (some libraries swallow abort errors).

Idempotency & Double-Click Safety:
- Disable triggering buttons until response or use a short-lived in-memory lock keyed by action (`add-to-wishlist:PID`).
- For destructive operations (remove, update) prefer server idempotent endpoints; client can re-send safely after timeout.

### Controller Example (`Newsletter.js`)
```javascript
'use strict';
var server = require('server');
var Resource = require('dw/web/Resource');

server.post('Subscribe', function (req, res, next) {
    var email = req.form.email;
    var success = !!email;
    var message = success
        ? Resource.msg('subscribe.success.message', 'newsletter', null)
        : Resource.msg('subscribe.error.invalidemail', 'newsletter', null);

    res.json({ success: success, message: message, submittedEmail: email });
    return next();
});

module.exports = server.exports();
```

## Newsletter End-to-End Example
### ISML (`newsletter.isml`)
```isml
<div class="newsletter-signup">
    <h2>${Resource.msg('heading.newsletter', 'newsletter', null)}</h2>
    <form id="newsletter-form"
                action="${URLUtils.url('Newsletter-Subscribe')}"
                method="POST"
                data-action-url="${URLUtils.url('Newsletter-Subscribe')}">
        <div class="form-group">
            <label for="newsletter-email">${Resource.msg('label.input.email', 'forms', null)}</label>
            <input type="email" id="newsletter-email" name="email" required>
            <div class="invalid-feedback"></div>
        </div>
        <input type="hidden" name="${pdict.csrf.tokenName}" value="${pdict.csrf.tokenValue}" />
        <button type="submit" class="btn btn-primary">${Resource.msg('button.subscribe', 'newsletter', null)}</button>
    </form>
    <div class="newsletter-message" role="alert"></div>
    <button type="button" class="notify-me" style="display:none">Notify Me</button>
</div>
```
### Client Module (`newsletter.js`)
```javascript
'use strict';
module.exports = function () {
    $('#newsletter-form').on('submit', function (e) {
        e.preventDefault();
        var $form = $(this);
        var url = $form.data('action-url');
        var $msg = $('.newsletter-message');
        var $email = $('#newsletter-email');
        $form.spinner().start();
        $.ajax({
            url: url,
            type: 'post',
            dataType: 'json',
            data: $form.serialize(),
            success: function (data) {
                $form.spinner().stop();
                $msg.removeClass('alert-danger').addClass('alert-success').text(data.message).show();
                $email.val('');
            },
            error: function (err) {
                $form.spinner().stop();
                var text = (err.responseJSON && err.responseJSON.message) || 'An unexpected error occurred.';
                $msg.removeClass('alert-success').addClass('alert-danger').text(text).show();
            }
        });
    });
};
```

## Form Framework & Validation Flow
**Server XML definitions** (under `forms/default/`) are the *single source of truth* for field rules.

Example snippet:
```xml
<form formid="newsletter">
    <field formid="email" type="string" mandatory="true" max-length="120" regexp="^[^@]+@[^@]+\.[^@]+$"
                 parse-error="error.parse.email" missing-error="error.missing.email" />
</form>
```
Client & server synergy:
1. Controller: `server.forms.getForm('newsletter')` loads + binds definition.
2. Template: injects metadata (often via `data-*`).
3. Browser: native HTML5 validation (type / required / maxlength).
4. `clientSideValidation.js`: intercepts invalid events, adds `is-invalid` styling.
5. `form-validation.js`: enforces XML-derived rules client-side.
6. AJAX submit → server re-validates.
7. Failure: JSON payload enumerates field errors; client maps & displays.

### Validation Flow Summary
```text
Load → User Input → HTML5 check → (If fail) prevent submit + style
→ If pass: AJAX submit → Server re-validate → Success OR Error JSON
→ On error: map messages → show per-field + global feedback
```

## jQuery / DOM Best Practices
### 1. Selector Caching
```javascript
// Inefficient
$('.product-price').text('$99.99');
$('.product-price').addClass('price-updated');

// Optimized
var $price = $('.product-price');
$price.text('$99.99');
$price.addClass('price-updated');
```
### 2. Event Delegation
```javascript
// Fragile (lost after DOM replacement)
$('.add-to-cart').on('click', handler);

// Robust
$('.product-grid-container').on('click', '.add-to-cart', handler);
```
### 3. Batch DOM Writes
```javascript
function renderProductList(products) {
    var html = products.map(p => `<li>${p.name}</li>`).join('');
    $('#product-list').html(html);
}
```
### 4. Avoid Layout Thrashing
Minimize interleaving reads (`.width()`) and writes (`.addClass()`). Group writes together.

## Performance Optimization
| Technique | Benefit | Notes |
|-----------|---------|-------|
| Debounce typing | Reduces AJAX bursts | Use 250–400ms window for search suggest |
| Single bundle (`main.js`) | Fewer requests | Let build handle splitting if needed |
| Late script injection | Faster first render | Scripts at end of `<body>` via decorator |
| Cache selectors | Lower DOM traversal cost | Prefix jQuery vars with `$` |
| Build HTML in memory | Min fewer reflows | Use string or detached fragment |

Example debounce (vanilla):
```javascript
function debounce(fn, wait) {
    var t; return function () {
        clearTimeout(t);
        var args = arguments, ctx = this;
        t = setTimeout(function () { fn.apply(ctx, args); }, wait);
    };
}
$('#search-input').on('input', debounce(fetchSuggestions, 300));
```

## Accessibility (A11y)
Core practices:
- Use semantic elements (`<button>`, `<nav>`, headings hierarchy).
- Add `aria-live="polite"` to regions updated via AJAX.
- Manage focus on modal open/close.
- Maintain keyboard operability (Tab order, Enter/Escape, Arrow keys for composites).
- Reflect state with ARIA (`aria-expanded`, `aria-hidden`).

Example toggle pattern:
```javascript
$('.filter-toggle').on('click', function () {
    var $panel = $('#filter-panel');
    var expanded = $(this).attr('aria-expanded') === 'true';
    $(this).attr('aria-expanded', !expanded);
    $panel.toggleClass('is-open', !expanded);
    if (!expanded) { $panel.find('input,button,a').first().focus(); }
});
```

## Code Quality & Maintainability
| Principle | Why It Matters | Practice |
|-----------|----------------|----------|
| Modularity | Easier testing & reuse | Split large PDP logic into domain modules |
| No inline JS | Separation of concerns | Use external modules + `assets.js` registration |
| Scoped exports | Avoid globals | Rely on CommonJS closure & `module.exports` |
| Consistent naming | Predictability | Domain-first folders (`product/`, `checkout/`) |
| Progressive enhancement | Resilience | Base HTML works w/out JS; JS augments |

## Quick Checklist
✅ Use `paths` alias for base extension, never edit `app_storefront_base` directly.
✅ Register assets in main request context, not remote includes.
✅ Compose client overrides—no `module.superModule`.
✅ Generate controller URLs server-side; pass via `data-*`.
✅ Always include CSRF token on POST (form or manual payload).
✅ Cache selectors & delegate events for dynamic regions.
✅ Batch DOM updates; avoid per-iteration `.append()` in loops.
✅ Debounce high-frequency input handlers.
✅ Enforce validation both client (UX) & server (authority).
✅ Provide keyboard & screen reader accessible interactions.
✅ Keep modules small, explicit exports, no inline script blocks.
✅ Namespace events (e.g. `.on('click.wishlistRemove', ...)`) & provide destroy() hooks.
✅ Escape dynamic data inserted into DOM; never trust server echo or user input.
✅ Centralize toast / modal / spinner helpers; avoid duplicate markup strings.
✅ Abort or ignore stale AJAX responses to prevent UI rewind.
✅ Include accessibility states (`aria-pressed`, `aria-live`, focus management) for dynamic UI.
✅ Provide test seams (export pure helpers separately from DOM glue).
✅ Use resource bundles for user-visible text; avoid hard-coded English in logic modules.
✅ Measure: instrument key actions (add/remove, search) with custom events.

## Plugin Cartridge Audit & Advanced Patterns (Wishlist Example)

This section analyzes real patterns from a widely used wishlist plugin cartridge (client-side layer) and extracts **concrete do / don't guidance** for AI agents generating new plugin cartridges. Treat this as a diagnostic checklist when reviewing or creating feature code.

### Observed Anti‑Patterns & Risks
| Category | Issue (Excerpt / Pattern) | Why It Matters | Recommended Fix |
|----------|---------------------------|----------------|-----------------|
| Message UI | Repeated ad‑hoc containers: `$('body').append('<div class="add-to-wishlist-messages"></div>')` then string concatenated alerts | Duplicated logic, memory churn, inconsistent roles, XSS risk via unescaped vars | Centralize via `toastService.show(type, message, {live:true})` injecting into a single managed region with ARIA attributes & auto‑dismiss |
| String HTML Construction | Concatenating user/content data into HTML (e.g. building search results list with `hit.firstName + ' ' + hit.lastName`) | Potential HTML injection if data not sanitized; readability suffers | Use small template helper that **escapes** (`escapeHtml`) and builds DOM with jQuery or template literals + encode |
| Oversized Module | `wishlist/wishlist.js` ~600 lines exporting a giant object | Hard to test, cognitive overload, hidden coupling | Split by concern: `modal.js`, `publicStatus.js`, `pagination.js`, `searchResults.js`, `toast.js`, `itemsCrud.js` then compose in page orchestrator |
| Global Delegation Scope | Universal `$('body').on('click', '.selector', ...)` for almost everything | Higher event dispatch cost; collision risk; harder to constrain removal | Delegate from closest stable container (`.wishlist-container`) unless events truly cross page |
| Lack of Namespaced Events | Triggers like `'afterRemoveFromCart'`, `'product:afterAddToCart'` used but custom bindings lack namespaces | Difficult selective unbinding, risk of collisions across cartridges | Use `$('...').on('click.wishlistRemove', ...)` and trigger namespaced custom events (`wishlist:remove:after`) |
| Spinners | Frequent `$.spinner().start()` without scoping to local container / ensuring stop in all branches | Flicker, race conditions if multiple concurrent requests | Use scoped spinner: `$container.spinner().start()`; wrap in `try/finally` or `always` callback |
| Modal Assembly | Manual string concatenation for full modal markup each time | Risk of drift vs. base styles, missing a11y attributes (`aria-modal`, labelledby) | Provide reusable `createModalShell(id, options)` helper; ensure focus trap, labelled elements |
| Clipboard | Direct `navigator.clipboard.writeText` without fallback | Fails silently on insecure origins / permissions | Add feature detect & fallback to temporary input select/copy |
| DOM Queries | Repeated uncached selectors inside loops (`$('.wishlistItemCards')`) | Performance waste for large lists | Cache at module scope or inside handler before loops |
| Icon Toggle | Direct class swap `.removeClass('fa-heart-o').addClass('fa-heart')` without state semantics | No accessibility state conveyed | Add `aria-pressed` or `aria-label` update; use utility `toggleWishlistState($el, isActive)` |
| Error Handling | Some AJAX error branches pass entire `err` object to display function expecting `{success,msg}` | Leads to `undefined` outputs; user confusion | Normalize responses: common `extractMessage(xhr)` utility |
| CSRF Token | POST requests rely on cookie; no explicit token injection | Fragile if custom middleware expects token param | Retrieve token from hidden input or `/CSRF-Generate` endpoint and include in payload (unless endpoint exempt) |
| Re-fetch Full Page | Pagination replaces entire list container then resets scroll manually | Jank, focus not managed | Use incremental append w/ sentinel or intersection observer; restore focus to consistent element |

### Improved Architectural Slice
Break the monolith – each concern returns an initializer consumed by the page entry script:
```
// wishlist/index.js (page orchestrator)
'use strict';
var initModal = require('./modal');
var initPublicStatus = require('./publicStatus');
var initItems = require('./items');
var initSearch = require('./search');
var toast = require('./toast');

module.exports = function () {
    toast.init();
    initModal();
    initPublicStatus();
    initItems();
    initSearch();
};
```

### Central Toast / Message Service Example
```
// wishlist/toast.js
'use strict';
var REGION_SELECTOR = '#global-toast-region';

function ensureRegion() {
    if (!$(REGION_SELECTOR).length) {
        $('body').append('<div id="global-toast-region" class="toast-region" aria-live="polite" aria-atomic="true"></div>');
    }
}

function escapeHtml(str) {
    return String(str)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;');
}

function show(type, message, opts) {
    ensureRegion();
    var safe = escapeHtml(message);
    var $r = $(REGION_SELECTOR);
    var $toast = $('<div class="alert alert-' + (type || 'info') + '" role="alert"></div>').html(safe);
    $r.append($toast);
    setTimeout(function () { $toast.fadeOut(150, function () { $(this).remove(); }); }, (opts && opts.duration) || 3000);
}

module.exports = { init: ensureRegion, show: show };
```

Usage replacing multiple scattered blocks:
```
var toast = require('./toast');
toast.show(data.success ? 'success' : 'danger', data.msg);
```

### Namespaced Event & Scoped Delegation
```
// Instead of $('body').on('click', '.remove-from-wishlist', handler)
$('.wishlist-container').on('click.wishlistRemove', '.remove-from-wishlist', handler);
```
Add cleanup when unloading dynamic section:
```
function destroy() { $('.wishlist-container').off('.wishlistRemove'); }
```

### AJAX Utility Wrapper
```
// utils/ajax.js
module.exports = function request(opts) {
    var d = $.Deferred();
    $.ajax(opts).done(d.resolve).fail(function (xhr) {
        var msg = (xhr.responseJSON && (xhr.responseJSON.msg || xhr.responseJSON.message)) || 'Unexpected error';
        d.reject({ success: false, msg: msg });
    });
    return d.promise();
};
```

### Safer Dynamic List Rendering
```
function renderHits(hits) {
    var html = hits.map(function (h) {
        var name = escapeHtml(h.firstName + ' ' + h.lastName);
        var urlText = escapeHtml(h.urlText);
        return '<div class="row wl-hit">' +
            '<div class="text-left col-6">' + name + '</div>' +
            '<div class="text-right col-6">' +
            '<a href="' + h.url + '" title="' + escapeHtml(h.urlTitle) + '" data-id="' + h.id + '">' + urlText + '</a>' +
            '</div></div>';
    }).join('');
    $('.wl-hits').html(html);
}
```

### Accessibility Enhancements
| Pattern | Upgrade |
|---------|---------|
| Heart toggle icon changes class only | Add `aria-pressed` state + label update |
| Toasts missing live region | Use single `aria-live="polite"` container | 
| Modal close sets focus implicitly | Explicitly return focus to invoking control (store a reference before open) |
| Copy link success only visual | Also append visually-hidden status text for screen readers |

### Performance & Maintainability Payoffs
| Refactor | Benefit |
|----------|---------|
| Split mega file into 6 modules | Lower merge conflict risk; targeted test surfaces |
| Central toast service | One place to adjust styling, timing, a11y |
| Namespaced events | Predictable teardown preventing memory leaks |
| Escaping utility | Mitigates XSS across all dynamic insertions |
| AJAX wrapper | Consistent error contract for UI handlers |

### Rapid Review Heuristics for Generated Code
Before finalizing a new client feature, ask:
1. Does any module exceed ~200 LOC? If yes, split.
2. Are all dynamic string insertions encoded? (Search for `+` around user data.)
3. Do events have namespaces for teardown? (Regex search: `\.on\('[^']+\.`)
4. Are repeated UX patterns (toast, modal, spinner) abstracted?
5. Are POSTs including CSRF token (if required) & handling both transport + business errors distinctly?
6. Is there at least one accessibility enhancement beyond defaults (live region, focus management, ARIA state)?

Integrate these improvements when generating or refactoring plugin cartridges to keep the ecosystem consistent, secure, and maintainable.

## Event & Module Design Patterns
Design modules with a predictable lifecycle so AI-generated code composes cleanly.

Pattern:
```
// product/favorites.js
'use strict';
var selectors = { container: '.favorites-container' };
function bindEvents($root) {
        $root.on('click.favoritesAdd', '.favorite-add', onAdd);
}
function unbindEvents($root) { $root.off('.favoritesAdd'); }
function onAdd(e) { /* feature logic */ }
module.exports = {
        init: function () { bindEvents($(selectors.container)); },
        destroy: function () { unbindEvents($(selectors.container)); }
};
```

Guidelines:
- Namespace every delegated event (`.featureNameAction`).
- Export `init()` + optional `destroy()`; page orchestrator calls these.
- Keep pure logic (parsing, transforms) in separate files for unit tests.
- Avoid circular requires: one orchestrator imports leaf modules; leaves only export functions.

## Security & Data Protection
Client code must not introduce XSS or data leakage.

Threat Vectors & Mitigations:
| Vector | Example | Mitigation |
|--------|---------|-----------|
| DOM XSS via concatenation | `'<div>'+ userName +'</div>'` | `escapeHtml(userName)` or build text nodes (`$('<div>').text(userName)`) |
| Injection via attributes | `'<a title="'+ title +'">'` | Escape quotes + `<` or use jQuery attr: `$('<a>').attr('title', title)` |
| Untrusted server message | Displaying raw `data.msg` | Whitelist keys or sanitize before insertion |
| Sensitive data in HTML | Embedding tokens in `data-*` | Store CSRF only in hidden input / meta; keep access tokens server-side |
| Over-broad event listeners | Listening on `body` for key events | Scope selectors to limit accidental data capture |

Escaping Utility:
```
function escapeHtml(str) {
    return String(str).replace(/[&<>"]g, s => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[s]));
}
```

Never trust: query params, form input values, server-returned text fields that originated from users (wish list names, product reviews). Always escape at insertion.

## Advanced AJAX & Error Handling
Standardize request lifecycle.
```
function requestJSON(opts) {
    var d = $.Deferred();
    var xhr = $.ajax(opts);
    xhr.done(function (data) { d.resolve(normalize(data)); })
         .fail(function (xhr) { d.reject(normalizeError(xhr)); });
    d.abort = function(){ if (xhr && xhr.readyState !== 4) { xhr.abort(); } };
    return d;
}
```
`normalize()` ensures a consistent shape: `{success:Boolean, payload:Object, msg:String}`.

Retry Decision Matrix:
| Failure | Retry? | Strategy |
|---------|--------|----------|
| Network timeout | Yes (1-2x) | Exponential backoff (300ms, 900ms) |
| 5xx server error | Optional | Single retry; log event for monitoring |
| 4xx validation | No | Surface messages; focus first invalid field |
| 403 CSRF | Yes (once) | Refresh token then replay |

User Feedback Levels:
- Inline field error
- Toast / alert region
- Silent (background prefetch) – only log to telemetry

## Testing Strategy for Client Modules
Testing ensures generated code stays reliable during SFRA upgrades.

Layers:
1. Pure utilities: Jest unit tests (no DOM) – e.g. escaping, debounce.
2. DOM behavior: jsdom + jQuery – simulate click, assert ARIA changes.
3. Contract tests for overrides: ensure extended module still exports required API surface (e.g. base + new functions).
4. Accessibility smoke: simple test that dynamically added toast region has `role="alert"` and is keyboard reachable.

Fixture Strategy:
- Keep minimal HTML snippets under `tests/fixtures/client/` loaded per suite.
- Avoid depending on full SFRA markup to reduce brittleness.

## Instrumentation & Telemetry
Emit analytics-friendly custom events; helps correlate client actions with server logs:
```
function emit(name, detail) {
    window.dispatchEvent(new CustomEvent('sfra:' + name, { detail: detail }));
}
emit('wishlist:add', { pid: pid, ts: Date.now() });
```
Collect events via a small listener pushing into `dataLayer` if present.

Key Metrics:
- Time to first interactive action (menu open, first search request).
- AJAX error rate per endpoint.
- Average debounce delay real vs configured (for tuning).

## Internationalization (i18n)
Rules:
- Never concatenate partial Resource strings (avoid building sentences piecewise).
- Pass dynamic values through `Resource.msgf` server-side where possible; if client must construct, keep placeholders (`{name}`) and a simple replace.
- Avoid embedding language-dependent punctuation in code (e.g. `':'` after labels); include it in localized string.
- For aria labels, re-use same bundle keys or provide parallel ones (e.g. `wishlist.add.success.aria`).

Example Placeholder Replacement:
```
var template = $('#welcome-banner').data('welcome-template'); // "Welcome back, {firstName}!"
$('#welcome-banner .text').text(template.replace('{firstName}', firstName));
```

Lint Heuristic: flag hard-coded English by searching for regex `"[A-Za-z]{3,}\s` outside tests.

## Appendix A: Base Cartridge Client-Side Modules Index

The following index was generated from the SFRA base cartridge (`app_storefront_base/cartridge/client/default/js`). It lists **override / extension candidates** you can decorate in custom cartridges using the `paths` alias (e.g. `require('base/product/detail')`). Total discovered JavaScript modules: **56**.

### Full File Listing (Relative Paths)
```
addressBook.js
addressBook/addressBook.js
campaignBanner.js
carousel.js
cart.js
cart/cart.js
checkout.js
checkout/address.js
checkout/billing.js
checkout/checkout.js
checkout/customer.js
checkout/formErrors.js
checkout/shipping.js
checkout/summary.js
checkoutRegistration.js
components/cleave.js
components/clientSideValidation.js
components/collapsibleItem.js
components/consentTracking.js
components/cookie.js
components/countrySelector.js
components/errorNotification.js
components/focus.js
components/footer.js
components/formValidation.js
components/keyboardAccessibility.js
components/menu.js
components/miniCart.js
components/scrollAnimate.js
components/search.js
components/spinner.js
components/toolTip.js
contactUs.js
contactUs/contactUs.js
einsteinCarousel.js
login.js
login/login.js
main.js
mobileGridLookBook.js
orderHistory.js
orderHistory/orderHistory.js
paymentInstruments.js
paymentInstruments/paymentInstruments.js
product/base.js
product/detail.js
product/quickView.js
productDetail.js
productTile.js
profile.js
profile/profile.js
search.js
search/search.js
storeLocator.js
storeLocator/storeLocator.js
thirdParty/bootstrap.js
util.js
```

### Extension Guidance
| Type | Recommended Strategy | Example |
|------|----------------------|---------|
| UI component (`components/*`) | Add feature then re-export base object | `var base = require('base/components/menu'); base.open = customOpen; module.exports = base;` |
| Page orchestrator (e.g. `product/detail.js`) | Override specific functions; add init hooks | Override `updateAddToCartButton` & append new DOM behaviors |
| Form logic (`checkout/*.js`) | Split complex logic into helper modules first (in base or custom) | Extract validation helper to call from override |
| Accessibility (`components/keyboardAccessibility.js`) | Patch by progressive enhancement; keep semantics intact | Add new key handlers before export |
| Bootstrap / vendor (`thirdParty/bootstrap.js`) | Avoid direct override; extend via event hooks | Wrap after requiring for plugin init |

### When NOT to Override
- If a base module only needs minor event binding, prefer **decorating after require** instead of rewriting the file path.
- Avoid duplicating large functions just to change a selector—refactor into a helper inside custom cartridge and call original logic you copied responsibly.
- Do not modify vendored third-party code directly—wrap or extend.

### Quick Start Template for an Override
```javascript
'use strict';
var base = require('base/components/menu');

// Preserve reference if you need original
var originalToggle = base.toggle;

base.toggle = function () {
    originalToggle.apply(this, arguments);
    // Custom enhancement
    window.dispatchEvent(new CustomEvent('menu:toggled'));
};

module.exports = base;
```

---
Need deeper server-side extension patterns? See the `sfra_controllers` and `sfra_models` guides for parallel server strategies.


```

--------------------------------------------------------------------------------
/docs/dw_io/XMLStreamReader.md:
--------------------------------------------------------------------------------

```markdown
## Package: dw.io

# Class XMLStreamReader

## Inheritance Hierarchy

- Object
  - dw.io.XMLStreamReader

## Description

The XMLStreamReader allows forward, read-only access to XML. It is designed to be the lowest level and most efficient way to read XML data. The XMLStreamReader is designed to iterate over XML using next() and hasNext(). The data can be accessed using methods such as getEventType(), getNamespaceURI(), getLocalName() and getText(); The next() method causes the reader to read the next parse event. The next() method returns an integer which identifies the type of event just read. The event type can be determined using getEventType(). Parsing events are defined as the XML Declaration, a DTD, start tag, character data, white space, end tag, comment, or processing instruction. An attribute or namespace event may be encountered at the root level of a document as the result of a query operation. The following table describes which methods are valid in what state. If a method is called in an invalid state the method will throw a java.lang.IllegalStateException. Valid methods for each state Event Type Valid Methods All States getProperty(), hasNext(), require(), close(), getNamespaceURI(), isStartElement(), isEndElement(), isCharacters(), isWhiteSpace(), getNamespaceContext(), getEventType(),getLocation(), hasText(), hasName() START_ELEMENT next(), getName(), getLocalName(), hasName(), getPrefix(), getAttributeXXX(), isAttributeSpecified(), getNamespaceXXX(), getElementText(), nextTag(), getXMLObject() ATTRIBUTE next(), nextTag() getAttributeXXX(), isAttributeSpecified(), NAMESPACE next(), nextTag() getNamespaceXXX() END_ELEMENT next(), getName(), getLocalName(), hasName(), getPrefix(), getNamespaceXXX(), nextTag() CHARACTERS next(), getTextXXX(), nextTag() CDATA next(), getTextXXX(), nextTag() COMMENT next(), getTextXXX(), nextTag() SPACE next(), getTextXXX(), nextTag() START_DOCUMENT next(), getEncoding(), getVersion(), isStandalone(), standaloneSet(), getCharacterEncodingScheme(), nextTag() END_DOCUMENT close() PROCESSING_INSTRUCTION next(), getPITarget(), getPIData(), nextTag() ENTITY_REFERENCE next(), getLocalName(), getText(), nextTag() DTD next(), getText(), nextTag() The following is a code sample to read an XML file containing multiple "myobject" sub-elements. Only one myObject instance is kept in memory at any given time to keep memory consumption low: var fileReader : FileReader = new FileReader(file, "UTF-8"); var xmlStreamReader : XMLStreamReader = new XMLStreamReader(fileReader); while (xmlStreamReader.hasNext()) { if (xmlStreamReader.next() == XMLStreamConstants.START_ELEMENT) { var localElementName : String = xmlStreamReader.getLocalName(); if (localElementName == "myobject") { // read single "myobject" as XML var myObject : XML = xmlStreamReader.getXMLObject(); // process myObject } } } xmlStreamReader.close(); fileReader.close();

## Properties

### attributeCount

**Type:** Number (Read Only)

The count of attributes on this START_ELEMENT,
 this method is only valid on a START_ELEMENT or ATTRIBUTE.  This
 count excludes namespace definitions.  Attribute indices are
 zero-based.

### characterEncodingScheme

**Type:** String (Read Only)

The character encoding declared on the XML declaration
 Returns null if none was declared.

### characters

**Type:** boolean (Read Only)

Identifies if the cursor points to a character data event.

### columnNumber

**Type:** Number (Read Only)

The column number where the current event ends or -1 if none is
 available.

### elementText

**Type:** String (Read Only)

Reads the content of a text-only element, an exception is thrown if this is not a text-only element. This method
 always returns coalesced content. 
 Precondition: the current event is START_ELEMENT. 
 Postcondition: the current event is the corresponding END_ELEMENT. 
 The method does the following (implementations are free to be optimized but must do equivalent processing):

  if ( getEventType() != XMLStreamConstants.START_ELEMENT )
 {
     throw new XMLStreamException( "parser must be on START_ELEMENT to read next text", getLocation() );
 }
 int eventType = next();
 StringBuffer content = new StringBuffer();
 while ( eventType != XMLStreamConstants.END_ELEMENT )
 {
     if ( eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA
         || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE )
     {
         buf.append( getText() );
     }
     else if ( eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT )
     {
         // skipping
     }
     else if ( eventType == XMLStreamConstants.END_DOCUMENT )
     {
         throw new XMLStreamException( "unexpected end of document when reading element text content", this );
     }
     else if ( eventType == XMLStreamConstants.START_ELEMENT )
     {
         throw new XMLStreamException( "element text content may not contain START_ELEMENT", getLocation() );
     }
     else
     {
         throw new XMLStreamException( "Unexpected event type " + eventType, getLocation() );
     }
     eventType = next();
 }
 return buf.toString();

### encoding

**Type:** String (Read Only)

Return input encoding if known or null if unknown.

### endElement

**Type:** boolean (Read Only)

Identifies if the cursor points to an end tag.

### eventType

**Type:** Number (Read Only)

An integer code that indicates the type
 of the event the cursor is pointing to.

### lineNumber

**Type:** Number (Read Only)

The line number where the current event ends or -1 if none is
 available.

### localName

**Type:** String (Read Only)

The (local) name of the current event.
 For START_ELEMENT or END_ELEMENT returns the (local) name of the current element.
 For ENTITY_REFERENCE it returns entity name.
 The current event must be START_ELEMENT or END_ELEMENT,
 or ENTITY_REFERENCE.

### namespaceCount

**Type:** Number (Read Only)

The count of namespaces declared on this START_ELEMENT or END_ELEMENT,
 this method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE. On
 an END_ELEMENT the count is of the namespaces that are about to go
 out of scope.  This is the equivalent of the information reported
 by SAX callback for an end element event.

### namespaceURI

**Type:** String (Read Only)

If the current event is a START_ELEMENT or END_ELEMENT  this method
 returns the URI of the prefix or the default namespace.
 Returns null if the event does not have a prefix.

### PIData

**Type:** String (Read Only)

Get the data section of a processing instruction.

### PITarget

**Type:** String (Read Only)

Get the target of a processing instruction.

### prefix

**Type:** String (Read Only)

The prefix of the current event or null if the event does not have a prefix

### standalone

**Type:** boolean (Read Only)

Get the standalone declaration from the xml declaration.

### startElement

**Type:** boolean (Read Only)

Identifies if the cursor points to a start tag.

### text

**Type:** String (Read Only)

The current value of the parse event as a string,
 this returns the string value of a CHARACTERS event,
 returns the value of a COMMENT, the replacement value
 for an ENTITY_REFERENCE, the string value of a CDATA section,
 the string value for a SPACE event,
 or the String value of the internal subset of the DTD.
 If an ENTITY_REFERENCE has been resolved, any character data
 will be reported as CHARACTERS events.

### textLength

**Type:** Number (Read Only)

The length of the sequence of characters for this
 Text event within the text character array.

### textStart

**Type:** Number (Read Only)

The offset into the text character array where the first
 character (of this text event) is stored.

### version

**Type:** String (Read Only)

Get the xml version declared on the xml declaration.
 Returns null if none was declared.

### whiteSpace

**Type:** boolean (Read Only)

Identifies if the cursor points to a character data event
 that consists of all whitespace.

### XMLObject

**Type:** Object (Read Only)

Reads a sub-tree of the XML document and parses it as XML object.
 
 The stream must be positioned on a START_ELEMENT. Do not call the method
 when the stream is positioned at document's root element. This would
 cause the whole document to be parsed into a single XML what may lead to
 an out-of-memory condition. Instead use #next() to navigate to
 sub-elements and invoke getXMLObject() there. Do not keep references to
 more than the currently processed XML to keep memory consumption low. The
 method reads the stream up to the matching END_ELEMENT. When the method
 returns the current event is the END_ELEMENT event.

## Constructor Summary

XMLStreamReader(reader : Reader) Constructs the stream readon on behalf of the reader.

## Method Summary

### close

**Signature:** `close() : void`

Frees any resources associated with this Reader.

### getAttributeCount

**Signature:** `getAttributeCount() : Number`

Returns the count of attributes on this START_ELEMENT, this method is only valid on a START_ELEMENT or ATTRIBUTE.

### getAttributeLocalName

**Signature:** `getAttributeLocalName(index : Number) : String`

Returns the localName of the attribute at the provided index.

### getAttributeNamespace

**Signature:** `getAttributeNamespace(index : Number) : String`

Returns the namespace of the attribute at the provided index.

### getAttributePrefix

**Signature:** `getAttributePrefix(index : Number) : String`

Returns the prefix of this attribute at the provided index.

### getAttributeType

**Signature:** `getAttributeType(index : Number) : String`

Returns the XML type of the attribute at the provided index.

### getAttributeValue

**Signature:** `getAttributeValue(namespaceURI : String, localName : String) : String`

Returns the normalized attribute value of the attribute with the namespace and localName If the namespaceURI is null the namespace is not checked for equality

### getAttributeValue

**Signature:** `getAttributeValue(index : Number) : String`

Returns the value of the attribute at the index.

### getCharacterEncodingScheme

**Signature:** `getCharacterEncodingScheme() : String`

Returns the character encoding declared on the XML declaration Returns null if none was declared.

### getColumnNumber

**Signature:** `getColumnNumber() : Number`

Returns the column number where the current event ends or -1 if none is available.

### getElementText

**Signature:** `getElementText() : String`

Reads the content of a text-only element, an exception is thrown if this is not a text-only element.

### getEncoding

**Signature:** `getEncoding() : String`

Return input encoding if known or null if unknown.

### getEventType

**Signature:** `getEventType() : Number`

Returns an integer code that indicates the type of the event the cursor is pointing to.

### getLineNumber

**Signature:** `getLineNumber() : Number`

Returns the line number where the current event ends or -1 if none is available.

### getLocalName

**Signature:** `getLocalName() : String`

Returns the (local) name of the current event.

### getNamespaceCount

**Signature:** `getNamespaceCount() : Number`

Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT, this method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE.

### getNamespacePrefix

**Signature:** `getNamespacePrefix(index : Number) : String`

Returns the prefix for the namespace declared at the index.

### getNamespaceURI

**Signature:** `getNamespaceURI(prefix : String) : String`

Return the uri for the given prefix.

### getNamespaceURI

**Signature:** `getNamespaceURI(index : Number) : String`

Returns the uri for the namespace declared at the index.

### getNamespaceURI

**Signature:** `getNamespaceURI() : String`

If the current event is a START_ELEMENT or END_ELEMENT this method returns the URI of the prefix or the default namespace.

### getPIData

**Signature:** `getPIData() : String`

Get the data section of a processing instruction.

### getPITarget

**Signature:** `getPITarget() : String`

Get the target of a processing instruction.

### getPrefix

**Signature:** `getPrefix() : String`

Returns the prefix of the current event or null if the event does not have a prefix

### getText

**Signature:** `getText() : String`

Returns the current value of the parse event as a string, this returns the string value of a CHARACTERS event, returns the value of a COMMENT, the replacement value for an ENTITY_REFERENCE, the string value of a CDATA section, the string value for a SPACE event, or the String value of the internal subset of the DTD.

### getTextLength

**Signature:** `getTextLength() : Number`

Returns the length of the sequence of characters for this Text event within the text character array.

### getTextStart

**Signature:** `getTextStart() : Number`

Returns the offset into the text character array where the first character (of this text event) is stored.

### getVersion

**Signature:** `getVersion() : String`

Get the xml version declared on the xml declaration.

### getXMLObject

**Signature:** `getXMLObject() : Object`

Reads a sub-tree of the XML document and parses it as XML object.

### hasName

**Signature:** `hasName() : boolean`

Identifies if the current event has a name (is a START_ELEMENT or END_ELEMENT)

### hasNext

**Signature:** `hasNext() : boolean`

Returns true if there are more parsing events and false if there are no more events.

### hasText

**Signature:** `hasText() : boolean`

Indicates if the current event has text.

### isAttributeSpecified

**Signature:** `isAttributeSpecified(index : Number) : boolean`

Identifies if this attribute was created by default.

### isCharacters

**Signature:** `isCharacters() : boolean`

Identifies if the cursor points to a character data event.

### isEndElement

**Signature:** `isEndElement() : boolean`

Identifies if the cursor points to an end tag.

### isStandalone

**Signature:** `isStandalone() : boolean`

Get the standalone declaration from the xml declaration.

### isStartElement

**Signature:** `isStartElement() : boolean`

Identifies if the cursor points to a start tag.

### isWhiteSpace

**Signature:** `isWhiteSpace() : boolean`

Identifies if the cursor points to a character data event that consists of all whitespace.

### next

**Signature:** `next() : Number`

Get next parsing event - a processor may return all contiguous character data in a single chunk, or it may split it into several chunks.

### nextTag

**Signature:** `nextTag() : Number`

Skips any white space (isWhiteSpace() returns true), COMMENT, or PROCESSING_INSTRUCTION, until a START_ELEMENT or END_ELEMENT is reached.

### readElementText

**Signature:** `readElementText() : String`

Reads the content of a text-only element, an exception is thrown if this is not a text-only element.

### readXMLObject

**Signature:** `readXMLObject() : Object`

Reads a sub-tree of the XML document and parses it as XML object.

### require

**Signature:** `require(type : Number, namespaceURI : String, localName : String) : void`

Test if the current event is of the given type and if the namespace and name match the current namespace and name of the current event.

### standaloneSet

**Signature:** `standaloneSet() : boolean`

Identifies if standalone was set in the document.

## Constructor Detail

## Method Detail

## Method Details

### close

**Signature:** `close() : void`

**Description:** Frees any resources associated with this Reader. This method does not close the underlying reader.

---

### getAttributeCount

**Signature:** `getAttributeCount() : Number`

**Description:** Returns the count of attributes on this START_ELEMENT, this method is only valid on a START_ELEMENT or ATTRIBUTE. This count excludes namespace definitions. Attribute indices are zero-based.

**Returns:**

returns the number of attributes.

---

### getAttributeLocalName

**Signature:** `getAttributeLocalName(index : Number) : String`

**Description:** Returns the localName of the attribute at the provided index.

**Parameters:**

- `index`: the position of the attribute.

**Returns:**

the local name of the attribute.

---

### getAttributeNamespace

**Signature:** `getAttributeNamespace(index : Number) : String`

**Description:** Returns the namespace of the attribute at the provided index.

**Parameters:**

- `index`: the position of the attribute

**Returns:**

the namespace URI (can be null)

---

### getAttributePrefix

**Signature:** `getAttributePrefix(index : Number) : String`

**Description:** Returns the prefix of this attribute at the provided index.

**Parameters:**

- `index`: the position of the attribute.

**Returns:**

the prefix of the attribute.

---

### getAttributeType

**Signature:** `getAttributeType(index : Number) : String`

**Description:** Returns the XML type of the attribute at the provided index.

**Parameters:**

- `index`: the position of the attribute.

**Returns:**

the XML type of the attribute.

---

### getAttributeValue

**Signature:** `getAttributeValue(namespaceURI : String, localName : String) : String`

**Description:** Returns the normalized attribute value of the attribute with the namespace and localName If the namespaceURI is null the namespace is not checked for equality

**Parameters:**

- `namespaceURI`: the namespace of the attribute
- `localName`: the local name of the attribute, cannot be null

**Returns:**

returns the value of the attribute or null if not found.

---

### getAttributeValue

**Signature:** `getAttributeValue(index : Number) : String`

**Description:** Returns the value of the attribute at the index.

**Parameters:**

- `index`: the position of the attribute.

**Returns:**

the attribute value.

---

### getCharacterEncodingScheme

**Signature:** `getCharacterEncodingScheme() : String`

**Description:** Returns the character encoding declared on the XML declaration Returns null if none was declared.

**Returns:**

the encoding declared in the document or null.

---

### getColumnNumber

**Signature:** `getColumnNumber() : Number`

**Description:** Returns the column number where the current event ends or -1 if none is available.

**Returns:**

the column number or -1.

---

### getElementText

**Signature:** `getElementText() : String`

**Description:** Reads the content of a text-only element, an exception is thrown if this is not a text-only element. This method always returns coalesced content. Precondition: the current event is START_ELEMENT. Postcondition: the current event is the corresponding END_ELEMENT. The method does the following (implementations are free to be optimized but must do equivalent processing): if ( getEventType() != XMLStreamConstants.START_ELEMENT ) { throw new XMLStreamException( "parser must be on START_ELEMENT to read next text", getLocation() ); } int eventType = next(); StringBuffer content = new StringBuffer(); while ( eventType != XMLStreamConstants.END_ELEMENT ) { if ( eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE ) { buf.append( getText() ); } else if ( eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT ) { // skipping } else if ( eventType == XMLStreamConstants.END_DOCUMENT ) { throw new XMLStreamException( "unexpected end of document when reading element text content", this ); } else if ( eventType == XMLStreamConstants.START_ELEMENT ) { throw new XMLStreamException( "element text content may not contain START_ELEMENT", getLocation() ); } else { throw new XMLStreamException( "Unexpected event type " + eventType, getLocation() ); } eventType = next(); } return buf.toString();

**Deprecated:**

Use readElementText()

---

### getEncoding

**Signature:** `getEncoding() : String`

**Description:** Return input encoding if known or null if unknown.

**Returns:**

the encoding of this instance or null

---

### getEventType

**Signature:** `getEventType() : Number`

**Description:** Returns an integer code that indicates the type of the event the cursor is pointing to.

**Returns:**

an integer code that indicates the type of the event the cursor is pointing to.

---

### getLineNumber

**Signature:** `getLineNumber() : Number`

**Description:** Returns the line number where the current event ends or -1 if none is available.

**Returns:**

the line number or -1.

---

### getLocalName

**Signature:** `getLocalName() : String`

**Description:** Returns the (local) name of the current event. For START_ELEMENT or END_ELEMENT returns the (local) name of the current element. For ENTITY_REFERENCE it returns entity name. The current event must be START_ELEMENT or END_ELEMENT, or ENTITY_REFERENCE.

**Returns:**

the local name.

---

### getNamespaceCount

**Signature:** `getNamespaceCount() : Number`

**Description:** Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT, this method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE. On an END_ELEMENT the count is of the namespaces that are about to go out of scope. This is the equivalent of the information reported by SAX callback for an end element event.

**Returns:**

returns the number of namespace declarations on this specific element.

---

### getNamespacePrefix

**Signature:** `getNamespacePrefix(index : Number) : String`

**Description:** Returns the prefix for the namespace declared at the index. Returns null if this is the default namespace declaration.

**Parameters:**

- `index`: the position of the namespace declaration.

**Returns:**

returns the namespace prefix.

---

### getNamespaceURI

**Signature:** `getNamespaceURI(prefix : String) : String`

**Description:** Return the uri for the given prefix. The uri returned depends on the current state of the processor. NOTE:The 'xml' prefix is bound as defined in Namespaces in XML specification to "http://www.w3.org/XML/1998/namespace". NOTE: The 'xmlns' prefix must be resolved to following namespace http://www.w3.org/2000/xmlns/

**Parameters:**

- `prefix`: The prefix to lookup, may not be null

**Returns:**

the uri bound to the given prefix or null if it is not bound

---

### getNamespaceURI

**Signature:** `getNamespaceURI(index : Number) : String`

**Description:** Returns the uri for the namespace declared at the index.

**Parameters:**

- `index`: the position of the namespace declaration.

**Returns:**

returns the namespace uri.

---

### getNamespaceURI

**Signature:** `getNamespaceURI() : String`

**Description:** If the current event is a START_ELEMENT or END_ELEMENT this method returns the URI of the prefix or the default namespace. Returns null if the event does not have a prefix.

**Returns:**

the URI bound to this elements prefix, the default namespace, or null.

---

### getPIData

**Signature:** `getPIData() : String`

**Description:** Get the data section of a processing instruction.

**Returns:**

the data or null.

---

### getPITarget

**Signature:** `getPITarget() : String`

**Description:** Get the target of a processing instruction.

**Returns:**

the target or null.

---

### getPrefix

**Signature:** `getPrefix() : String`

**Description:** Returns the prefix of the current event or null if the event does not have a prefix

**Returns:**

the prefix or null.

---

### getText

**Signature:** `getText() : String`

**Description:** Returns the current value of the parse event as a string, this returns the string value of a CHARACTERS event, returns the value of a COMMENT, the replacement value for an ENTITY_REFERENCE, the string value of a CDATA section, the string value for a SPACE event, or the String value of the internal subset of the DTD. If an ENTITY_REFERENCE has been resolved, any character data will be reported as CHARACTERS events.

**Returns:**

the current text or null.

---

### getTextLength

**Signature:** `getTextLength() : Number`

**Description:** Returns the length of the sequence of characters for this Text event within the text character array.

**Returns:**

the length of the sequence of characters for this Text event within the text character array.

---

### getTextStart

**Signature:** `getTextStart() : Number`

**Description:** Returns the offset into the text character array where the first character (of this text event) is stored.

**Returns:**

the offset into the text character array where the first character (of this text event) is stored.

---

### getVersion

**Signature:** `getVersion() : String`

**Description:** Get the xml version declared on the xml declaration. Returns null if none was declared.

**Returns:**

the XML version or null.

---

### getXMLObject

**Signature:** `getXMLObject() : Object`

**Description:** Reads a sub-tree of the XML document and parses it as XML object. The stream must be positioned on a START_ELEMENT. Do not call the method when the stream is positioned at document's root element. This would cause the whole document to be parsed into a single XML what may lead to an out-of-memory condition. Instead use #next() to navigate to sub-elements and invoke getXMLObject() there. Do not keep references to more than the currently processed XML to keep memory consumption low. The method reads the stream up to the matching END_ELEMENT. When the method returns the current event is the END_ELEMENT event.

**Deprecated:**

Use readXMLObject()

---

### hasName

**Signature:** `hasName() : boolean`

**Description:** Identifies if the current event has a name (is a START_ELEMENT or END_ELEMENT)

**Returns:**

true if the current event has a name, false otherwise.

---

### hasNext

**Signature:** `hasNext() : boolean`

**Description:** Returns true if there are more parsing events and false if there are no more events. This method will return false if the current state of the XMLStreamReader is END_DOCUMENT

**Returns:**

true if there are more events, false otherwise

---

### hasText

**Signature:** `hasText() : boolean`

**Description:** Indicates if the current event has text. The following events have text: CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE.

**Returns:**

true if the current event has text, false otherwise.

---

### isAttributeSpecified

**Signature:** `isAttributeSpecified(index : Number) : boolean`

**Description:** Identifies if this attribute was created by default.

**Parameters:**

- `index`: the position of the attribute.

**Returns:**

true if this is a default attribute, false otherwise.

---

### isCharacters

**Signature:** `isCharacters() : boolean`

**Description:** Identifies if the cursor points to a character data event.

**Returns:**

true if the cursor points to character data, false otherwise.

---

### isEndElement

**Signature:** `isEndElement() : boolean`

**Description:** Identifies if the cursor points to an end tag.

**Returns:**

true if the cursor points to an end tag, false otherwise.

---

### isStandalone

**Signature:** `isStandalone() : boolean`

**Description:** Get the standalone declaration from the xml declaration.

**Returns:**

true if this is standalone, or false otherwise.

---

### isStartElement

**Signature:** `isStartElement() : boolean`

**Description:** Identifies if the cursor points to a start tag.

**Returns:**

true if the cursor points to a start tag, false otherwise.

---

### isWhiteSpace

**Signature:** `isWhiteSpace() : boolean`

**Description:** Identifies if the cursor points to a character data event that consists of all whitespace.

**Returns:**

true if the cursor points to all whitespace, false otherwise.

---

### next

**Signature:** `next() : Number`

**Description:** Get next parsing event - a processor may return all contiguous character data in a single chunk, or it may split it into several chunks. If the property javax.xml.stream.isCoalescing is set to true element content must be coalesced and only one CHARACTERS event must be returned for contiguous element content or CDATA Sections. By default entity references must be expanded and reported transparently to the application. An exception will be thrown if an entity reference cannot be expanded. If element content is empty (i.e. content is "") then no CHARACTERS event will be reported. Given the following XML: <foo><!--description-->content text<![CDATA[<greeting>Hello</greeting>]]>other content</foo> The behavior of calling next() when being on foo will be: 1- the comment (COMMENT) 2- then the characters section (CHARACTERS) 3- then the CDATA section (another CHARACTERS) 4- then the next characters section (another CHARACTERS) 5- then the END_ELEMENT NOTE: empty element (such as <tag/>) will be reported with two separate events: START_ELEMENT, END_ELEMENT - This preserves parsing equivalency of empty element to <tag></tag>. This method will throw an IllegalStateException if it is called after hasNext() returns false.

**Returns:**

the integer code corresponding to the current parse event

---

### nextTag

**Signature:** `nextTag() : Number`

**Description:** Skips any white space (isWhiteSpace() returns true), COMMENT, or PROCESSING_INSTRUCTION, until a START_ELEMENT or END_ELEMENT is reached. If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT are encountered, an exception is thrown. This method should be used when processing element-only content separated by white space. Precondition: none Postcondition: the current event is START_ELEMENT or END_ELEMENT and cursor may have moved over any whitespace event. Essentially it does the following (implementations are free to optimized but must do equivalent processing): int eventType = next(); while ( (eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace() ) || (eventType == XMLStreamConstants.CDATA && isWhiteSpace()) || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT ) { eventType = next(); } if ( eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT ) { throw new String XMLStreamException( "expected start or end tag", getLocation() ); } return eventType;

**Returns:**

the event type of the element read (START_ELEMENT or END_ELEMENT)

---

### readElementText

**Signature:** `readElementText() : String`

**Description:** Reads the content of a text-only element, an exception is thrown if this is not a text-only element. This method always returns coalesced content. Precondition: the current event is START_ELEMENT. Postcondition: the current event is the corresponding END_ELEMENT. The method does the following (implementations are free to be optimized but must do equivalent processing): if ( getEventType() != XMLStreamConstants.START_ELEMENT ) { throw new XMLStreamException( "parser must be on START_ELEMENT to read next text", getLocation() ); } int eventType = next(); StringBuffer content = new StringBuffer(); while ( eventType != XMLStreamConstants.END_ELEMENT ) { if ( eventType == XMLStreamConstants.CHARACTERS || eventType == XMLStreamConstants.CDATA || eventType == XMLStreamConstants.SPACE || eventType == XMLStreamConstants.ENTITY_REFERENCE ) { buf.append( getText() ); } else if ( eventType == XMLStreamConstants.PROCESSING_INSTRUCTION || eventType == XMLStreamConstants.COMMENT ) { // skipping } else if ( eventType == XMLStreamConstants.END_DOCUMENT ) { throw new XMLStreamException( "unexpected end of document when reading element text content", this ); } else if ( eventType == XMLStreamConstants.START_ELEMENT ) { throw new XMLStreamException( "element text content may not contain START_ELEMENT", getLocation() ); } else { throw new XMLStreamException( "Unexpected event type " + eventType, getLocation() ); } eventType = next(); } return buf.toString();

---

### readXMLObject

**Signature:** `readXMLObject() : Object`

**Description:** Reads a sub-tree of the XML document and parses it as XML object. The stream must be positioned on a START_ELEMENT. Do not call the method when the stream is positioned at document's root element. This would cause the whole document to be parsed into a single XML what may lead to an out-of-memory condition. Instead use #next() to navigate to sub-elements and invoke getXMLObject() there. Do not keep references to more than the currently processed XML to keep memory consumption low. The method reads the stream up to the matching END_ELEMENT. When the method returns the current event is the END_ELEMENT event.

---

### require

**Signature:** `require(type : Number, namespaceURI : String, localName : String) : void`

**Description:** Test if the current event is of the given type and if the namespace and name match the current namespace and name of the current event. If the namespaceURI is null it is not checked for equality, if the localName is null it is not checked for equality.

**Parameters:**

- `type`: the event type
- `namespaceURI`: the uri of the event, may be null
- `localName`: the localName of the event, may be null

---

### standaloneSet

**Signature:** `standaloneSet() : boolean`

**Description:** Identifies if standalone was set in the document.

**Returns:**

true if standalone was set in the document, false otherwise.

---
```

--------------------------------------------------------------------------------
/docs/dw_order/Shipment.md:
--------------------------------------------------------------------------------

```markdown
## Package: dw.order

# Class Shipment

## Inheritance Hierarchy

- Object
  - dw.object.PersistentObject
  - dw.object.ExtensibleObject
    - dw.order.Shipment

## Description

Represents an order shipment.

## Constants

### SHIPMENT_NOTSHIPPED

**Type:** Number = 0

Shipment shipping status representing 'Not shipped'.

### SHIPMENT_SHIPPED

**Type:** Number = 2

Shipment shipping status representing 'Shipped'.

### SHIPPING_STATUS_NOTSHIPPED

**Type:** Number = 0

Shipment shipping status representing 'Not shipped'.

### SHIPPING_STATUS_SHIPPED

**Type:** Number = 2

Shipment shipping status representing 'Shipped'.

## Properties

### adjustedMerchandizeTotalGrossPrice

**Type:** Money (Read Only)

The adjusted total gross price, including tax, in the purchase currency. The adjusted total gross price
 represents the sum of product prices and adjustments including tax, excluding services.

### adjustedMerchandizeTotalNetPrice

**Type:** Money (Read Only)

The adjusted net price, excluding tax, in the purchase currency. The adjusted net price represents the
 the sum of product prices and adjustments, excluding services and tax.

### adjustedMerchandizeTotalPrice

**Type:** Money (Read Only)

The product total price after all product discounts. If the line item container is based on net pricing
 the adjusted product total net price is returned. If the line item container is based on gross pricing the
 adjusted product total gross price is returned.

### adjustedMerchandizeTotalTax

**Type:** Money (Read Only)

The total adjusted product tax in the purchase currency. The total adjusted product tax represents the
 tax on products and adjustments, excluding services.

### adjustedShippingTotalGrossPrice

**Type:** Money (Read Only)

The adjusted sum of all shipping line items of the shipment, including shipping adjustuments and tax

### adjustedShippingTotalNetPrice

**Type:** Money (Read Only)

The sum of all shipping line items of the shipment, including shipping adjustments, excluding tax.

### adjustedShippingTotalPrice

**Type:** Money (Read Only)

The adjusted shipping total price. If the line item container is based on net pricing the adjusted
 shipping total net price is returned. If the line item container is based on gross pricing the adjusted shipping
 total gross price is returned.

### adjustedShippingTotalTax

**Type:** Money (Read Only)

The tax of all shipping line items of the shipment , including shipping adjustments.

### allLineItems

**Type:** Collection (Read Only)

All line items related to the shipment.
 
 The returned collection may include line items of the following types:
 
 ProductLineItem
 ShippingLineItem
 GiftCertificateLineItem
 PriceAdjustment
 
 Their common type is LineItem.
 
 Each ProductLineItem in the collection may itself contain bundled or option product line items,
 as well as a product-level shipping line item.

### default

**Type:** boolean (Read Only)

Return true if this shipment is the default shipment (shipment ID "me").

### gift

**Type:** boolean

Returns true if this line item represents a gift, false otherwise.

### giftCertificateLineItems

**Type:** Collection (Read Only)

All gift certificate line items of the shipment.

### giftMessage

**Type:** String

The value set for gift message or null if no value set.

### ID

**Type:** String (Read Only)

The ID of this shipment ("me" for the default shipment).

### merchandizeTotalGrossPrice

**Type:** Money (Read Only)

The gross product subtotal in the purchase currency. The gross product subtotal represents the sum of
 product prices including tax, excluding services and adjustments.

### merchandizeTotalNetPrice

**Type:** Money (Read Only)

The net product subtotal, excluding tax, in the purchase currency. The net product subtotal represents
 the sum of product prices, excluding services, adjustments, and tax.

### merchandizeTotalPrice

**Type:** Money (Read Only)

The product total price. If the line item container is based on net pricing the product total net
 price is returned. If the line item container is based on gross pricing the product total gross price is
 returned.

### merchandizeTotalPriceAdjustments

**Type:** Collection (Read Only)

A collection of price adjustments that have been applied to the totals, such as a promotion on the
 purchase value (i.e. $10 Off or 10% Off).

### merchandizeTotalTax

**Type:** Money (Read Only)

The total product tax in the purchase currency. The total product tax represents the tax on products,
 excluding services and adjustments.

### productLineItems

**Type:** Collection (Read Only)

A collection of all product line items related to this shipment.

### proratedMerchandizeTotalPrice

**Type:** Money (Read Only)

The total product price of the shipment, including product-level adjustments and prorating all
 Buy-X-Get-Y and order-level adjustments, according to the scheme described in
 PriceAdjustment.getProratedPrices(). For net pricing the net price is returned. For gross
 pricing, the gross price is returned.

### shipmentNo

**Type:** String (Read Only)

The shipment number for this shipment.
 
 When an order is placed (OrderMgr.placeOrder(Order)) shipment number will be filled using a
 sequence. Before order was placed null will be returned.

### shippingAddress

**Type:** OrderAddress (Read Only)

The shipping address or null if none is set.

### shippingLineItems

**Type:** Collection (Read Only)

A collection of all shipping line items of the shipment, excluding any product-level shipping costs that
 are associated with ProductLineItems of the shipment.

### shippingMethod

**Type:** ShippingMethod

The shipping method or null if none is set.

### shippingMethodID

**Type:** String (Read Only)

The shipping method ID or null if none is set.

### shippingPriceAdjustments

**Type:** Collection (Read Only)

A collection of price adjustments that have been applied to the shipping costs of the shipment, for
 example by the promotions engine.
 Note that this method returns all shipping price adjustments in this shipment, regardless of which shipping line
 item they belong to. Use ShippingLineItem.getShippingPriceAdjustments() to retrieve the shipping
 price adjustments associated with a specific shipping line item.

### shippingStatus

**Type:** EnumValue

The shipping status. Possible values are SHIPMENT_NOTSHIPPED or SHIPMENT_SHIPPED.

### shippingTotalGrossPrice

**Type:** Money (Read Only)

The sum of all shipping line items of the shipment, including tax, excluding shipping adjustments.

### shippingTotalNetPrice

**Type:** Money (Read Only)

The sum of all shipping line items of the shipment, excluding tax and adjustments.

### shippingTotalPrice

**Type:** Money (Read Only)

The shipping total price. If the line item container is based on net pricing the shipping total net price
 is returned. If the line item container is based on gross pricing the shipping total gross price is returned.

### shippingTotalTax

**Type:** Money (Read Only)

The tax of all shipping line items of the shipment before shipping adjustments have been applied.

### standardShippingLineItem

**Type:** ShippingLineItem (Read Only)

Convenience method. Same as getShippingLineItem(ShippingLineItem.STANDARD_SHIPPING_ID)

### totalGrossPrice

**Type:** Money (Read Only)

The total gross price of the shipment in the purchase currency. The total gross price is the sum of
 product prices, service prices, adjustments, and tax.

### totalNetPrice

**Type:** Money (Read Only)

The total net price of the shipment in the purchase currency. The total net price is the sum of product
 prices, service prices, and adjustments, excluding tax.

### totalTax

**Type:** Money (Read Only)

The total tax for the shipment in the purchase currency.

### trackingNumber

**Type:** String

The tracking number of this shipment.

## Constructor Summary

## Method Summary

### createShippingAddress

**Signature:** `createShippingAddress() : OrderAddress`

A shipment has initially no shipping address.

### createShippingLineItem

**Signature:** `createShippingLineItem(id : String) : ShippingLineItem`

Creates a new shipping line item for this shipment.

### createShippingPriceAdjustment

**Signature:** `createShippingPriceAdjustment(promotionID : String) : PriceAdjustment`

Creates a shipping price adjustment to be applied to the shipment.

### getAdjustedMerchandizeTotalGrossPrice

**Signature:** `getAdjustedMerchandizeTotalGrossPrice() : Money`

Returns the adjusted total gross price, including tax, in the purchase currency.

### getAdjustedMerchandizeTotalNetPrice

**Signature:** `getAdjustedMerchandizeTotalNetPrice() : Money`

Returns the adjusted net price, excluding tax, in the purchase currency.

### getAdjustedMerchandizeTotalPrice

**Signature:** `getAdjustedMerchandizeTotalPrice() : Money`

Returns the product total price after all product discounts.

### getAdjustedMerchandizeTotalPrice

**Signature:** `getAdjustedMerchandizeTotalPrice(applyOrderLevelAdjustments : boolean) : Money`

Returns the total product price including product-level adjustments and, optionally, prorated order-level adjustments.

### getAdjustedMerchandizeTotalTax

**Signature:** `getAdjustedMerchandizeTotalTax() : Money`

Returns the total adjusted product tax in the purchase currency.

### getAdjustedShippingTotalGrossPrice

**Signature:** `getAdjustedShippingTotalGrossPrice() : Money`

Returns the adjusted sum of all shipping line items of the shipment, including shipping adjustuments and tax

### getAdjustedShippingTotalNetPrice

**Signature:** `getAdjustedShippingTotalNetPrice() : Money`

Returns the sum of all shipping line items of the shipment, including shipping adjustments, excluding tax.

### getAdjustedShippingTotalPrice

**Signature:** `getAdjustedShippingTotalPrice() : Money`

Returns the adjusted shipping total price.

### getAdjustedShippingTotalTax

**Signature:** `getAdjustedShippingTotalTax() : Money`

Returns the tax of all shipping line items of the shipment , including shipping adjustments.

### getAllLineItems

**Signature:** `getAllLineItems() : Collection`

Returns all line items related to the shipment.

### getGiftCertificateLineItems

**Signature:** `getGiftCertificateLineItems() : Collection`

Returns all gift certificate line items of the shipment.

### getGiftMessage

**Signature:** `getGiftMessage() : String`

Returns the value set for gift message or null if no value set.

### getID

**Signature:** `getID() : String`

Returns the ID of this shipment ("me" for the default shipment).

### getMerchandizeTotalGrossPrice

**Signature:** `getMerchandizeTotalGrossPrice() : Money`

Returns the gross product subtotal in the purchase currency.

### getMerchandizeTotalNetPrice

**Signature:** `getMerchandizeTotalNetPrice() : Money`

Returns the net product subtotal, excluding tax, in the purchase currency.

### getMerchandizeTotalPrice

**Signature:** `getMerchandizeTotalPrice() : Money`

Returns the product total price.

### getMerchandizeTotalPriceAdjustments

**Signature:** `getMerchandizeTotalPriceAdjustments() : Collection`

Returns a collection of price adjustments that have been applied to the totals, such as a promotion on the purchase value (i.e.

### getMerchandizeTotalTax

**Signature:** `getMerchandizeTotalTax() : Money`

Returns the total product tax in the purchase currency.

### getProductLineItems

**Signature:** `getProductLineItems() : Collection`

Returns a collection of all product line items related to this shipment.

### getProratedMerchandizeTotalPrice

**Signature:** `getProratedMerchandizeTotalPrice() : Money`

Returns the total product price of the shipment, including product-level adjustments and prorating all Buy-X-Get-Y and order-level adjustments, according to the scheme described in PriceAdjustment.getProratedPrices().

### getShipmentNo

**Signature:** `getShipmentNo() : String`

Returns the shipment number for this shipment.

### getShippingAddress

**Signature:** `getShippingAddress() : OrderAddress`

Returns the shipping address or null if none is set.

### getShippingLineItem

**Signature:** `getShippingLineItem(id : String) : ShippingLineItem`

Returns the shipping line item identified by the specified ID, or null if not found.

### getShippingLineItems

**Signature:** `getShippingLineItems() : Collection`

Returns a collection of all shipping line items of the shipment, excluding any product-level shipping costs that are associated with ProductLineItems of the shipment.

### getShippingMethod

**Signature:** `getShippingMethod() : ShippingMethod`

Returns the shipping method or null if none is set.

### getShippingMethodID

**Signature:** `getShippingMethodID() : String`

Returns the shipping method ID or null if none is set.

### getShippingPriceAdjustmentByPromotionID

**Signature:** `getShippingPriceAdjustmentByPromotionID(promotionID : String) : PriceAdjustment`

Returns the shipping price adjustment associated with the specified promotion ID.

### getShippingPriceAdjustments

**Signature:** `getShippingPriceAdjustments() : Collection`

Returns a collection of price adjustments that have been applied to the shipping costs of the shipment, for example by the promotions engine. Note that this method returns all shipping price adjustments in this shipment, regardless of which shipping line item they belong to.

### getShippingStatus

**Signature:** `getShippingStatus() : EnumValue`

Returns the shipping status.

### getShippingTotalGrossPrice

**Signature:** `getShippingTotalGrossPrice() : Money`

Returns the sum of all shipping line items of the shipment, including tax, excluding shipping adjustments.

### getShippingTotalNetPrice

**Signature:** `getShippingTotalNetPrice() : Money`

Returns the sum of all shipping line items of the shipment, excluding tax and adjustments.

### getShippingTotalPrice

**Signature:** `getShippingTotalPrice() : Money`

Returns the shipping total price.

### getShippingTotalTax

**Signature:** `getShippingTotalTax() : Money`

Returns the tax of all shipping line items of the shipment before shipping adjustments have been applied.

### getStandardShippingLineItem

**Signature:** `getStandardShippingLineItem() : ShippingLineItem`

Convenience method.

### getTotalGrossPrice

**Signature:** `getTotalGrossPrice() : Money`

Returns the total gross price of the shipment in the purchase currency.

### getTotalNetPrice

**Signature:** `getTotalNetPrice() : Money`

Returns the total net price of the shipment in the purchase currency.

### getTotalTax

**Signature:** `getTotalTax() : Money`

Returns the total tax for the shipment in the purchase currency.

### getTrackingNumber

**Signature:** `getTrackingNumber() : String`

Returns the tracking number of this shipment.

### isDefault

**Signature:** `isDefault() : boolean`

Return true if this shipment is the default shipment (shipment ID "me").

### isGift

**Signature:** `isGift() : boolean`

Returns true if this line item represents a gift, false otherwise.

### removeShippingLineItem

**Signature:** `removeShippingLineItem(shippingLineItem : ShippingLineItem) : void`

Removes the specified shipping line item and any of its dependent shipping price adjustments.

### removeShippingPriceAdjustment

**Signature:** `removeShippingPriceAdjustment(priceAdjustment : PriceAdjustment) : void`

Removes the specified shipping price adjustment from the shipment.

### setGift

**Signature:** `setGift(isGift : boolean) : void`

Controls if this line item is a gift or not.

### setGiftMessage

**Signature:** `setGiftMessage(message : String) : void`

Sets the value to set for the gift message.

### setShippingMethod

**Signature:** `setShippingMethod(method : ShippingMethod) : void`

Set the specified shipping method for the specified shipment.

### setShippingStatus

**Signature:** `setShippingStatus(status : Number) : void`

Sets the shipping status of the shipment.

### setTrackingNumber

**Signature:** `setTrackingNumber(aValue : String) : void`

Sets the tracking number of this shipment.

## Method Detail

## Method Details

### createShippingAddress

**Signature:** `createShippingAddress() : OrderAddress`

**Description:** A shipment has initially no shipping address. This method creates a shipping address for the shipment and replaces an existing shipping address.

**Returns:**

The new shipping address of the shipment

---

### createShippingLineItem

**Signature:** `createShippingLineItem(id : String) : ShippingLineItem`

**Description:** Creates a new shipping line item for this shipment. If the specified ID is already assigned to any of the existing shipping line items of the shipment, the method throws an exception.

**Parameters:**

- `id`: The id to use to locate the new shipping line item.

**Returns:**

The new shipping line item.

---

### createShippingPriceAdjustment

**Signature:** `createShippingPriceAdjustment(promotionID : String) : PriceAdjustment`

**Description:** Creates a shipping price adjustment to be applied to the shipment. The price adjustment implicitly belongs to the standard shipping line item if this line item exists, otherwise it belongs to the shipment itself. The promotion ID is mandatory and must not be the ID of any actual promotion defined in Salesforce B2C Commerce. If there already exists a shipping price adjustment line item referring to the specified promotion ID, an exception is thrown.

**Deprecated:**

Deprecated in favor of ShippingLineItem.createShippingPriceAdjustment(String), which explicitly relates the price adjustment to a shipping line item.

**Parameters:**

- `promotionID`: Promotion ID

**Returns:**

The new price adjustment line item.

---

### getAdjustedMerchandizeTotalGrossPrice

**Signature:** `getAdjustedMerchandizeTotalGrossPrice() : Money`

**Description:** Returns the adjusted total gross price, including tax, in the purchase currency. The adjusted total gross price represents the sum of product prices and adjustments including tax, excluding services.

**Returns:**

the adjusted total gross price, including tax, in the purchase currency.

---

### getAdjustedMerchandizeTotalNetPrice

**Signature:** `getAdjustedMerchandizeTotalNetPrice() : Money`

**Description:** Returns the adjusted net price, excluding tax, in the purchase currency. The adjusted net price represents the the sum of product prices and adjustments, excluding services and tax.

**Returns:**

the adjusted net price, excluding tax, in the purchase currency.

---

### getAdjustedMerchandizeTotalPrice

**Signature:** `getAdjustedMerchandizeTotalPrice() : Money`

**Description:** Returns the product total price after all product discounts. If the line item container is based on net pricing the adjusted product total net price is returned. If the line item container is based on gross pricing the adjusted product total gross price is returned.

**Returns:**

either the adjusted product total net or gross price.

---

### getAdjustedMerchandizeTotalPrice

**Signature:** `getAdjustedMerchandizeTotalPrice(applyOrderLevelAdjustments : boolean) : Money`

**Description:** Returns the total product price including product-level adjustments and, optionally, prorated order-level adjustments. For net pricing the net price is returned. For gross pricing, the gross price is returned.

**Parameters:**

- `applyOrderLevelAdjustments`: If true, prorated order-level adjustments will be applied to total price

**Returns:**

Adjusted net or gross product total price

**See Also:**

getAdjustedMerchandizeTotalPrice()

---

### getAdjustedMerchandizeTotalTax

**Signature:** `getAdjustedMerchandizeTotalTax() : Money`

**Description:** Returns the total adjusted product tax in the purchase currency. The total adjusted product tax represents the tax on products and adjustments, excluding services.

**Returns:**

the total tax in purchase currency.

---

### getAdjustedShippingTotalGrossPrice

**Signature:** `getAdjustedShippingTotalGrossPrice() : Money`

**Description:** Returns the adjusted sum of all shipping line items of the shipment, including shipping adjustuments and tax

**Returns:**

the adjusted sum of all shipping line items of the shipment, including shipping adjustuments and tax

---

### getAdjustedShippingTotalNetPrice

**Signature:** `getAdjustedShippingTotalNetPrice() : Money`

**Description:** Returns the sum of all shipping line items of the shipment, including shipping adjustments, excluding tax.

**Returns:**

the sum of all shipping line items of the shipment, including shipping adjustments, excluding tax.

---

### getAdjustedShippingTotalPrice

**Signature:** `getAdjustedShippingTotalPrice() : Money`

**Description:** Returns the adjusted shipping total price. If the line item container is based on net pricing the adjusted shipping total net price is returned. If the line item container is based on gross pricing the adjusted shipping total gross price is returned.

**Returns:**

either the adjusted shipping total net or gross price

---

### getAdjustedShippingTotalTax

**Signature:** `getAdjustedShippingTotalTax() : Money`

**Description:** Returns the tax of all shipping line items of the shipment , including shipping adjustments.

**Returns:**

the tax of all shipping line items of the shipment , including shipping adjustments.

---

### getAllLineItems

**Signature:** `getAllLineItems() : Collection`

**Description:** Returns all line items related to the shipment. The returned collection may include line items of the following types: ProductLineItem ShippingLineItem GiftCertificateLineItem PriceAdjustment Their common type is LineItem. Each ProductLineItem in the collection may itself contain bundled or option product line items, as well as a product-level shipping line item.

**Returns:**

all line items related to ths shipment.

---

### getGiftCertificateLineItems

**Signature:** `getGiftCertificateLineItems() : Collection`

**Description:** Returns all gift certificate line items of the shipment.

**Returns:**

A collection of all GiftCertificateLineItems of the shipment.

---

### getGiftMessage

**Signature:** `getGiftMessage() : String`

**Description:** Returns the value set for gift message or null if no value set.

**Returns:**

the value set for gift message or null if no value set.

---

### getID

**Signature:** `getID() : String`

**Description:** Returns the ID of this shipment ("me" for the default shipment).

**Returns:**

the ID of this shipment

---

### getMerchandizeTotalGrossPrice

**Signature:** `getMerchandizeTotalGrossPrice() : Money`

**Description:** Returns the gross product subtotal in the purchase currency. The gross product subtotal represents the sum of product prices including tax, excluding services and adjustments.

**Returns:**

the total gross price, including tax, in the purchase currency.

---

### getMerchandizeTotalNetPrice

**Signature:** `getMerchandizeTotalNetPrice() : Money`

**Description:** Returns the net product subtotal, excluding tax, in the purchase currency. The net product subtotal represents the sum of product prices, excluding services, adjustments, and tax.

**Returns:**

the net price, excluding tax, in the purchase currency.

---

### getMerchandizeTotalPrice

**Signature:** `getMerchandizeTotalPrice() : Money`

**Description:** Returns the product total price. If the line item container is based on net pricing the product total net price is returned. If the line item container is based on gross pricing the product total gross price is returned.

**Returns:**

either the product total net or gross price

---

### getMerchandizeTotalPriceAdjustments

**Signature:** `getMerchandizeTotalPriceAdjustments() : Collection`

**Description:** Returns a collection of price adjustments that have been applied to the totals, such as a promotion on the purchase value (i.e. $10 Off or 10% Off).

**Deprecated:**

Shipments cannot have product price adjustments, therefore this method will always return an empty collection

**Returns:**

a collection of price adjustments that have been applied to the totals, such as a promotion on the purchase value (i.e. $10 Off or 10% Off).

---

### getMerchandizeTotalTax

**Signature:** `getMerchandizeTotalTax() : Money`

**Description:** Returns the total product tax in the purchase currency. The total product tax represents the tax on products, excluding services and adjustments.

**Returns:**

the total tax in purchase currency.

---

### getProductLineItems

**Signature:** `getProductLineItems() : Collection`

**Description:** Returns a collection of all product line items related to this shipment.

**Returns:**

a collection of all product line items related to this shipment.

---

### getProratedMerchandizeTotalPrice

**Signature:** `getProratedMerchandizeTotalPrice() : Money`

**Description:** Returns the total product price of the shipment, including product-level adjustments and prorating all Buy-X-Get-Y and order-level adjustments, according to the scheme described in PriceAdjustment.getProratedPrices(). For net pricing the net price is returned. For gross pricing, the gross price is returned.

**Returns:**

Adjusted and prorated net or gross product total price

---

### getShipmentNo

**Signature:** `getShipmentNo() : String`

**Description:** Returns the shipment number for this shipment. When an order is placed (OrderMgr.placeOrder(Order)) shipment number will be filled using a sequence. Before order was placed null will be returned.

**Returns:**

the shipment number for this shipment.

---

### getShippingAddress

**Signature:** `getShippingAddress() : OrderAddress`

**Description:** Returns the shipping address or null if none is set.

**Returns:**

the shipping address or null if none is set.

---

### getShippingLineItem

**Signature:** `getShippingLineItem(id : String) : ShippingLineItem`

**Description:** Returns the shipping line item identified by the specified ID, or null if not found. To get the standard shipping line item for this shipment, use the identifier ShippingLineItem.STANDARD_SHIPPING_ID.

**Parameters:**

- `id`: the identifier to use to locate the shipping line item.

**Returns:**

the shipping line item identified by the specified ID, or null if not found.

---

### getShippingLineItems

**Signature:** `getShippingLineItems() : Collection`

**Description:** Returns a collection of all shipping line items of the shipment, excluding any product-level shipping costs that are associated with ProductLineItems of the shipment.

**Returns:**

a collection of all shipping line items of the shipment, excluding any product-level shipping costs.

---

### getShippingMethod

**Signature:** `getShippingMethod() : ShippingMethod`

**Description:** Returns the shipping method or null if none is set.

**Returns:**

the shipping method or null if none is set.

---

### getShippingMethodID

**Signature:** `getShippingMethodID() : String`

**Description:** Returns the shipping method ID or null if none is set.

**Returns:**

the shipping method ID or null if none is set.

---

### getShippingPriceAdjustmentByPromotionID

**Signature:** `getShippingPriceAdjustmentByPromotionID(promotionID : String) : PriceAdjustment`

**Description:** Returns the shipping price adjustment associated with the specified promotion ID.

**Deprecated:**

This item is deprecated.

**Parameters:**

- `promotionID`: the promotion ID

**Returns:**

The price adjustment associated with the given promotion ID

---

### getShippingPriceAdjustments

**Signature:** `getShippingPriceAdjustments() : Collection`

**Description:** Returns a collection of price adjustments that have been applied to the shipping costs of the shipment, for example by the promotions engine. Note that this method returns all shipping price adjustments in this shipment, regardless of which shipping line item they belong to. Use ShippingLineItem.getShippingPriceAdjustments() to retrieve the shipping price adjustments associated with a specific shipping line item.

**Returns:**

a collection of price adjustments that have been applied to the shipping costs of the shipment.

---

### getShippingStatus

**Signature:** `getShippingStatus() : EnumValue`

**Description:** Returns the shipping status. Possible values are SHIPMENT_NOTSHIPPED or SHIPMENT_SHIPPED.

**Returns:**

the shipping status. Possible values are SHIPMENT_NOTSHIPPED or SHIPMENT_SHIPPED.

---

### getShippingTotalGrossPrice

**Signature:** `getShippingTotalGrossPrice() : Money`

**Description:** Returns the sum of all shipping line items of the shipment, including tax, excluding shipping adjustments.

**Returns:**

the sum of all shipping line items of the shipment, including tax, excluding shipping adjustments.

---

### getShippingTotalNetPrice

**Signature:** `getShippingTotalNetPrice() : Money`

**Description:** Returns the sum of all shipping line items of the shipment, excluding tax and adjustments.

**Returns:**

the sum of all shipping line items of the shipment, excluding tax and adjustments.

---

### getShippingTotalPrice

**Signature:** `getShippingTotalPrice() : Money`

**Description:** Returns the shipping total price. If the line item container is based on net pricing the shipping total net price is returned. If the line item container is based on gross pricing the shipping total gross price is returned.

**Returns:**

either the shipping total net or gross price

---

### getShippingTotalTax

**Signature:** `getShippingTotalTax() : Money`

**Description:** Returns the tax of all shipping line items of the shipment before shipping adjustments have been applied.

**Returns:**

the tax of all shipping line items of the shipment before shipping adjustments have been applied.

---

### getStandardShippingLineItem

**Signature:** `getStandardShippingLineItem() : ShippingLineItem`

**Description:** Convenience method. Same as getShippingLineItem(ShippingLineItem.STANDARD_SHIPPING_ID)

**Returns:**

The standard shipping line item, or null if it does not exist.

---

### getTotalGrossPrice

**Signature:** `getTotalGrossPrice() : Money`

**Description:** Returns the total gross price of the shipment in the purchase currency. The total gross price is the sum of product prices, service prices, adjustments, and tax.

**Returns:**

the grand total price gross of tax for the shipment, in purchase currency.

---

### getTotalNetPrice

**Signature:** `getTotalNetPrice() : Money`

**Description:** Returns the total net price of the shipment in the purchase currency. The total net price is the sum of product prices, service prices, and adjustments, excluding tax.

**Returns:**

the grand total price for the shipment net of tax, in purchase currency.

---

### getTotalTax

**Signature:** `getTotalTax() : Money`

**Description:** Returns the total tax for the shipment in the purchase currency.

**Returns:**

the total tax for the shipment, in purchase currency.

---

### getTrackingNumber

**Signature:** `getTrackingNumber() : String`

**Description:** Returns the tracking number of this shipment.

**Returns:**

the tracking number of this shipment.

---

### isDefault

**Signature:** `isDefault() : boolean`

**Description:** Return true if this shipment is the default shipment (shipment ID "me").

**Returns:**

true if this shipment is the default shipment

---

### isGift

**Signature:** `isGift() : boolean`

**Description:** Returns true if this line item represents a gift, false otherwise.

**Returns:**

true if this line item represents a gift, false otherwise.

---

### removeShippingLineItem

**Signature:** `removeShippingLineItem(shippingLineItem : ShippingLineItem) : void`

**Description:** Removes the specified shipping line item and any of its dependent shipping price adjustments.

**Parameters:**

- `shippingLineItem`: The shipping line item to be removed.

---

### removeShippingPriceAdjustment

**Signature:** `removeShippingPriceAdjustment(priceAdjustment : PriceAdjustment) : void`

**Description:** Removes the specified shipping price adjustment from the shipment.

**Deprecated:**

Deprecated in favor of ShippingLineItem.removeShippingPriceAdjustment(PriceAdjustment) since shipping price adjustments belong to a specific shipping line item.

**Parameters:**

- `priceAdjustment`: The price adjustment line item to remove

---

### setGift

**Signature:** `setGift(isGift : boolean) : void`

**Description:** Controls if this line item is a gift or not.

**Parameters:**

- `isGift`: set to true if you want this line item to represent a gift.

---

### setGiftMessage

**Signature:** `setGiftMessage(message : String) : void`

**Description:** Sets the value to set for the gift message.

**Parameters:**

- `message`: the value to set for the gift message.

---

### setShippingMethod

**Signature:** `setShippingMethod(method : ShippingMethod) : void`

**Description:** Set the specified shipping method for the specified shipment.

**Parameters:**

- `method`: the shipping method to use.

---

### setShippingStatus

**Signature:** `setShippingStatus(status : Number) : void`

**Description:** Sets the shipping status of the shipment. Possible values are SHIPPING_STATUS_NOTSHIPPED or SHIPPING_STATUS_SHIPPED.

**Parameters:**

- `status`: Shipment shipping status

---

### setTrackingNumber

**Signature:** `setTrackingNumber(aValue : String) : void`

**Description:** Sets the tracking number of this shipment.

**Parameters:**

- `aValue`: the tracking number of this shipment.

---
```

--------------------------------------------------------------------------------
/tests/mcp/yaml/get-sfcc-class-info.full-mode.test.mcp.yml:
--------------------------------------------------------------------------------

```yaml
# ==================================================================================
# SFCC MCP Server - get_sfcc_class_info Tool YAML Tests
# Comprehensive testing for SFCC class information retrieval functionality
# Tests both successful responses and error handling scenarios
# 
# Quick Test Commands:
# aegis "tests/mcp/yaml/sfcc-class-info.full-mode.test.mcp.yml" --config "aegis.config.with-dw.json" --verbose
# aegis "tests/mcp/yaml/sfcc-class-info.full-mode.test.mcp.yml" --config "aegis.config.with-dw.json" --debug --timing
# aegis query get_sfcc_class_info '{"className": "dw.catalog.Product"}' --config "aegis.config.with-dw.json"
# aegis query get_sfcc_class_info '{"className": "dw.catalog.Product", "expand": true}' --config "aegis.config.with-dw.json"
# ==================================================================================
description: "SFCC MCP Server get_sfcc_class_info tool - comprehensive validation"

# ==================================================================================
# BASIC TOOL STRUCTURE VALIDATION
# ==================================================================================
tests:
  - it: "should list get_sfcc_class_info tool in available tools"
    request:
      jsonrpc: "2.0"
      id: "tool-available"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-available"
        result:
          match:extractField: "tools.*.name"
          value: "match:arrayContains:get_sfcc_class_info"
      stderr: "toBeEmpty"

  - it: "should have get_sfcc_class_info in tools list with proper structure"
    request:
      jsonrpc: "2.0"
      id: "tool-metadata"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-metadata"
        result:
          tools: "match:arrayContains:name:get_sfcc_class_info"
      stderr: "toBeEmpty"

  - it: "should have tool with meaningful description"
    request:
      jsonrpc: "2.0"
      id: "tool-description-quality"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-description-quality"
        result:
          tools: "match:arrayContains:name:get_sfcc_class_info"
      stderr: "toBeEmpty"

  - it: "should have proper inputSchema structure for get_sfcc_class_info"
    request:
      jsonrpc: "2.0"
      id: "tool-schema-structure"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-schema-structure"
        result:
          tools:
            match:arrayElements:
              match:partial:
                name: "match:type:string"
                inputSchema:
                  type: "object"
                  properties: "match:type:object"

      stderr: "toBeEmpty"

# ==================================================================================
# SUCCESSFUL EXECUTION TESTS - BASIC CLASSES
# ==================================================================================

  - it: "should execute with basic dw.catalog.Catalog class"
    request:
      jsonrpc: "2.0"
      id: "exec-catalog-basic"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-catalog-basic"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should return JSON structure for dw.catalog.Product"
    request:
      jsonrpc: "2.0"
      id: "exec-product-json"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-product-json"
        result:
          content:
            - type: "text"
              text: "match:regex:\\{[\\s\\S]*\\}"  # Valid JSON structure
          isError: false
      stderr: "toBeEmpty"

  - it: "should include required class information in JSON response"
    request:
      jsonrpc: "2.0"
      id: "exec-catalog-fields"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-catalog-fields"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include packageName in response"
    request:
      jsonrpc: "2.0"
      id: "exec-packagename"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-packagename"
        result:
          content:
            - type: "text"
              text: "match:contains:packageName"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include description in response"
    request:
      jsonrpc: "2.0"
      id: "exec-description"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-description"
        result:
          content:
            - type: "text"
              text: "match:contains:description"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include methods in response"
    request:
      jsonrpc: "2.0"
      id: "exec-methods"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-methods"
        result:
          content:
            - type: "text"
              text: "match:contains:methods"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include properties in response"
    request:
      jsonrpc: "2.0"
      id: "exec-properties"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-properties"
        result:
          content:
            - type: "text"
              text: "match:contains:properties"
          isError: false
      stderr: "toBeEmpty"

  - it: "should have inheritance chain information"
    request:
      jsonrpc: "2.0"
      id: "exec-inheritance"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-inheritance"
        result:
          content:
            - type: "text"
              text: "match:contains:inheritance"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# CLASS NAME VARIATIONS TESTING
# ==================================================================================

  - it: "should work with fully qualified class names"
    request:
      jsonrpc: "2.0"
      id: "exec-fqn"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.ProductVariationModel"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-fqn"
        result:
          content:
            - type: "text"
              text: "match:contains:ProductVariationModel"
          isError: false
      stderr: "toBeEmpty"

  - it: "should work with short class names"
    request:
      jsonrpc: "2.0"
      id: "exec-short-name"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-short-name"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should work with TopLevel classes"
    request:
      jsonrpc: "2.0"
      id: "exec-toplevel"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "Number"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-toplevel"
        result:
          content:
            - type: "text"
              text: "match:contains:Number"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# EXPAND PARAMETER TESTING
# ==================================================================================

  - it: "should work with expand parameter set to false"
    request:
      jsonrpc: "2.0"
      id: "exec-expand-false"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          expand: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-expand-false"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should work with expand parameter set to true"
    request:
      jsonrpc: "2.0"
      id: "exec-expand-true"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-expand-true"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# SPECIFIC CLASS INFORMATION VALIDATION
# ==================================================================================

  - it: "should return proper package name for dw.catalog classes"
    request:
      jsonrpc: "2.0"
      id: "validate-package-catalog"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-package-catalog"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should return methods array for classes with methods"
    request:
      jsonrpc: "2.0"
      id: "validate-methods-array"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-methods-array"
        result:
          content:
            - type: "text"
              text: "match:regex:\"methods\"\\s*:\\s*\\["
          isError: false
      stderr: "toBeEmpty"

  - it: "should return properties array for classes with properties"
    request:
      jsonrpc: "2.0"
      id: "validate-properties-array"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-properties-array"
        result:
          content:
            - type: "text"
              text: "match:regex:\"properties\"\\s*:\\s*\\["
          isError: false
      stderr: "toBeEmpty"

  - it: "should include method signatures"
    request:
      jsonrpc: "2.0"
      id: "validate-method-signatures"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-method-signatures"
        result:
          content:
            - type: "text"
              text: "match:contains:signature"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# FILTERING AND SEARCH FUNCTIONALITY TESTS
# Tests all boolean filtering parameters and search functionality
# ==================================================================================

  - it: "should get class info with default parameters (all sections included)"
    request:
      jsonrpc: "2.0"
      id: "filter-default"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-default"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.catalog.Product"
          isError: false
      stderr: "toBeEmpty"

  - it: "should get class info with expand enabled"
    request:
      jsonrpc: "2.0"
      id: "filter-expand"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-expand"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.catalog.Catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out description when includeDescription is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-description"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeDescription: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-description"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out constants when includeConstants is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-constants"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeConstants: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-constants"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out properties when includeProperties is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-properties"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeProperties: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-properties"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out methods when includeMethods is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-methods"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeMethods: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-methods"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out inheritance when includeInheritance is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-inheritance"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeInheritance: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-inheritance"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should apply multiple filters together (minimal response)"
    request:
      jsonrpc: "2.0"
      id: "filter-minimal"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeDescription: false
          includeConstants: false
          includeProperties: false
          includeMethods: false
          includeInheritance: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-minimal"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should search within class info using search parameter"
    request:
      jsonrpc: "2.0"
      id: "search-basic"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          search: "get"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-basic"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should combine filtering with search functionality"
    request:
      jsonrpc: "2.0"
      id: "search-filtered"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeMethods: true
          includeProperties: false
          includeConstants: false
          search: "getName"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-filtered"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle class name without dw prefix"
    request:
      jsonrpc: "2.0"
      id: "filter-short-name"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-short-name"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle System class with all filters enabled"
    request:
      jsonrpc: "2.0"
      id: "filter-system-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.system.System"
          expand: true
          includeDescription: true
          includeConstants: true
          includeProperties: true
          includeMethods: true
          includeInheritance: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-system-class"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.system.System"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle Customer class with case-insensitive search"
    request:
      jsonrpc: "2.0"
      id: "search-case-insensitive"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.customer.Customer"
          search: "EMAIL"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-case-insensitive"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle search with no matches gracefully"
    request:
      jsonrpc: "2.0"
      id: "search-no-matches"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          search: "zzznomatchesexpected"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-no-matches"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# ERROR HANDLING TESTS
# ==================================================================================

  - it: "should handle invalid class names gracefully"
    request:
      jsonrpc: "2.0"
      id: "error-invalid-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "NonExistentClass"
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-invalid-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

  - it: "should handle empty class name"
    request:
      jsonrpc: "2.0"
      id: "error-empty-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: ""
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-empty-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

  - it: "should handle missing className parameter with error response"
    request:
      jsonrpc: "2.0"
      id: "error-missing-param"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-missing-param"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: true
      stderr: "toBeEmpty"

  - it: "should handle malformed class names"
    request:
      jsonrpc: "2.0"
      id: "error-malformed-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "..invalid..class..name.."
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-malformed-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

# ==================================================================================
# RESPONSE FORMAT VALIDATION
# ==================================================================================

  - it: "should return consistent MCP content structure"
    request:
      jsonrpc: "2.0"
      id: "format-content-structure"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "format-content-structure"
        result:
          content:
            match:arrayElements:
              match:partial:
                type: "text"
                text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should return single content item for successful calls"
    request:
      jsonrpc: "2.0"
      id: "format-single-content"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "format-single-content"
        result:
          content: "match:arrayLength:1"
          isError: false
      stderr: "toBeEmpty"

  - it: "should not set isError flag for successful responses"
    request:
      jsonrpc: "2.0"
      id: "format-no-error-flag"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "format-no-error-flag"
        result:
          content: "match:type:array"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# EDGE CASES AND COMPLEX SCENARIOS
# ==================================================================================

  - it: "should handle classes with many methods (like Product)"
    request:
      jsonrpc: "2.0"
      id: "edge-many-methods"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-many-methods"
        result:
          content:
            - type: "text"
              text: "match:regex:\"methods\"[\\s\\S]*getID[\\s\\S]*getName"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle classes with variation models"
    request:
      jsonrpc: "2.0"
      id: "edge-variation-model"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.ProductVariationModel"
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-variation-model"
        result:
          content:
            - type: "text"
              text: "match:contains:ProductVariationModel"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle inventory-related classes"
    request:
      jsonrpc: "2.0"
      id: "edge-inventory-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.ProductInventoryList"
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-inventory-class"
        result:
          content:
            - type: "text"
              text: "match:contains:ProductInventoryList"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# PERFORMANCE AND CONSISTENCY VALIDATION
# ==================================================================================

  - it: "should respond consistently for repeated calls"
    request:
      jsonrpc: "2.0"
      id: "perf-consistent-1"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-consistent-1"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should respond consistently for repeated calls (second time)"
    request:
      jsonrpc: "2.0"
      id: "perf-consistent-2"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-consistent-2"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle case sensitivity properly"
    request:
      jsonrpc: "2.0"
      id: "edge-case-sensitivity"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.product"  # lowercase 'product'
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-case-sensitivity"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

# ==================================================================================
# PERFORMANCE TIMING TESTS
# ==================================================================================

  - it: "should return basic class info within acceptable time"
    request:
      jsonrpc: "2.0"
      id: "perf-basic-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-basic-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      performance:
        maxResponseTime: "150ms"  # Documentation lookup should be very fast
      stderr: "toBeEmpty"

  - it: "should return complex class info with expand within timeout"
    request:
      jsonrpc: "2.0"
      id: "perf-expand-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-expand-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Product"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Even expanded info should be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle large class documentation efficiently"
    request:
      jsonrpc: "2.0"
      id: "perf-large-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.system.Site"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-large-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Site"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Large classes should still be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle simple customer classes quickly"
    request:
      jsonrpc: "2.0"
      id: "perf-customer-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.customer.Customer"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-customer-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Customer"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Standard class lookup should be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle order classes within timeout"
    request:
      jsonrpc: "2.0"
      id: "perf-order-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.order.Order"
          expand: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-order-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Order"
          isError: false
      performance:
        maxResponseTime: "150ms"  # Basic order class lookup should be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle non-existent class error within timeout"
    request:
      jsonrpc: "2.0"
      id: "perf-error-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.nonexistent.FakeClass"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-error-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      performance:
        maxResponseTime: "150ms"  # Error handling should be very fast
      stderr: "toBeEmpty"

  - it: "should handle empty class name error quickly"
    request:
      jsonrpc: "2.0"
      id: "perf-empty-error-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: ""
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-empty-error-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      performance:
        maxResponseTime: "150ms"  # Validation errors should be extremely fast
      stderr: "toBeEmpty"

  - it: "should handle malformed class name error efficiently"
    request:
      jsonrpc: "2.0"
      id: "perf-malformed-error-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "..invalid..class..name.."
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-malformed-error-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      performance:
        maxResponseTime: "150ms"  # Invalid input should fail extremely fast
      stderr: "toBeEmpty"

  - it: "should handle cached responses quickly"
    request:
      jsonrpc: "2.0"
      id: "perf-cached-response"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"  # Same as first test - should be cached
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-cached-response"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      performance:
        maxResponseTime: "150ms"  # Cached responses should be extremely fast
      stderr: "toBeEmpty"

```

--------------------------------------------------------------------------------
/tests/mcp/yaml/get-sfcc-class-info.docs-only.test.mcp.yml:
--------------------------------------------------------------------------------

```yaml
# ==================================================================================
# SFCC MCP Server - get_sfcc_class_info Tool YAML Tests
# Comprehensive testing for SFCC class information retrieval functionality
# Tests both successful responses and error handling scenarios
# 
# Quick Test Commands:
# aegis "tests/mcp/yaml/sfcc-class-info.docs-only.test.mcp.yml" --config "aegis.config.docs-only.json" --verbose
# aegis "tests/mcp/yaml/sfcc-class-info.docs-only.test.mcp.yml" --config "aegis.config.docs-only.json" --debug --timing
# aegis query get_sfcc_class_info '{"className": "dw.catalog.Product"}' --config "aegis.config.docs-only.json"
# aegis query get_sfcc_class_info '{"className": "dw.catalog.Product", "expand": true}' --config "aegis.config.docs-only.json"
# ==================================================================================
description: "SFCC MCP Server get_sfcc_class_info tool - comprehensive validation"

# ==================================================================================
# BASIC TOOL STRUCTURE VALIDATION
# ==================================================================================
tests:
  - it: "should list get_sfcc_class_info tool in available tools"
    request:
      jsonrpc: "2.0"
      id: "tool-available"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-available"
        result:
          match:extractField: "tools.*.name"
          value: "match:arrayContains:get_sfcc_class_info"
      stderr: "toBeEmpty"

  - it: "should have get_sfcc_class_info in tools list with proper structure"
    request:
      jsonrpc: "2.0"
      id: "tool-metadata"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-metadata"
        result:
          tools: "match:arrayContains:name:get_sfcc_class_info"
      stderr: "toBeEmpty"

  - it: "should have tool with meaningful description"
    request:
      jsonrpc: "2.0"
      id: "tool-description-quality"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-description-quality"
        result:
          tools: "match:arrayContains:name:get_sfcc_class_info"
      stderr: "toBeEmpty"

  - it: "should have proper inputSchema structure for get_sfcc_class_info"
    request:
      jsonrpc: "2.0"
      id: "tool-schema-structure"
      method: "tools/list"
      params: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "tool-schema-structure"
        result:
          tools:
            match:arrayElements:
              match:partial:
                name: "match:type:string"
                inputSchema:
                  type: "object"
                  properties: "match:type:object"

      stderr: "toBeEmpty"

# ==================================================================================
# SUCCESSFUL EXECUTION TESTS - BASIC CLASSES
# ==================================================================================

  - it: "should execute with basic dw.catalog.Catalog class"
    request:
      jsonrpc: "2.0"
      id: "exec-catalog-basic"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-catalog-basic"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should return JSON structure for dw.catalog.Product"
    request:
      jsonrpc: "2.0"
      id: "exec-product-json"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-product-json"
        result:
          content:
            - type: "text"
              text: "match:regex:\\{[\\s\\S]*\\}"  # Valid JSON structure
          isError: false
      stderr: "toBeEmpty"

  - it: "should include required class information in JSON response"
    request:
      jsonrpc: "2.0"
      id: "exec-catalog-fields"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-catalog-fields"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include packageName in response"
    request:
      jsonrpc: "2.0"
      id: "exec-packagename"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-packagename"
        result:
          content:
            - type: "text"
              text: "match:contains:packageName"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include description in response"
    request:
      jsonrpc: "2.0"
      id: "exec-description"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-description"
        result:
          content:
            - type: "text"
              text: "match:contains:description"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include methods in response"
    request:
      jsonrpc: "2.0"
      id: "exec-methods"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-methods"
        result:
          content:
            - type: "text"
              text: "match:contains:methods"
          isError: false
      stderr: "toBeEmpty"

  - it: "should include properties in response"
    request:
      jsonrpc: "2.0"
      id: "exec-properties"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-properties"
        result:
          content:
            - type: "text"
              text: "match:contains:properties"
          isError: false
      stderr: "toBeEmpty"

  - it: "should have inheritance chain information"
    request:
      jsonrpc: "2.0"
      id: "exec-inheritance"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-inheritance"
        result:
          content:
            - type: "text"
              text: "match:contains:inheritance"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# CLASS NAME VARIATIONS TESTING
# ==================================================================================

  - it: "should work with fully qualified class names"
    request:
      jsonrpc: "2.0"
      id: "exec-fqn"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.ProductVariationModel"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-fqn"
        result:
          content:
            - type: "text"
              text: "match:contains:ProductVariationModel"
          isError: false
      stderr: "toBeEmpty"

  - it: "should work with short class names"
    request:
      jsonrpc: "2.0"
      id: "exec-short-name"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-short-name"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should work with TopLevel classes"
    request:
      jsonrpc: "2.0"
      id: "exec-toplevel"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "Number"
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-toplevel"
        result:
          content:
            - type: "text"
              text: "match:contains:Number"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# EXPAND PARAMETER TESTING
# ==================================================================================

  - it: "should work with expand parameter set to false"
    request:
      jsonrpc: "2.0"
      id: "exec-expand-false"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          expand: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-expand-false"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

  - it: "should work with expand parameter set to true"
    request:
      jsonrpc: "2.0"
      id: "exec-expand-true"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "exec-expand-true"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# SPECIFIC CLASS INFORMATION VALIDATION
# ==================================================================================

  - it: "should return proper package name for dw.catalog classes"
    request:
      jsonrpc: "2.0"
      id: "validate-package-catalog"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-package-catalog"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should return methods array for classes with methods"
    request:
      jsonrpc: "2.0"
      id: "validate-methods-array"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-methods-array"
        result:
          content:
            - type: "text"
              text: "match:regex:\"methods\"\\s*:\\s*\\["
          isError: false
      stderr: "toBeEmpty"

  - it: "should return properties array for classes with properties"
    request:
      jsonrpc: "2.0"
      id: "validate-properties-array"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-properties-array"
        result:
          content:
            - type: "text"
              text: "match:regex:\"properties\"\\s*:\\s*\\["
          isError: false
      stderr: "toBeEmpty"

  - it: "should include method signatures"
    request:
      jsonrpc: "2.0"
      id: "validate-method-signatures"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "validate-method-signatures"
        result:
          content:
            - type: "text"
              text: "match:contains:signature"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# FILTERING AND SEARCH FUNCTIONALITY TESTS
# Tests all boolean filtering parameters and search functionality
# ==================================================================================

  - it: "should get class info with default parameters (all sections included)"
    request:
      jsonrpc: "2.0"
      id: "filter-default"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-default"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.catalog.Product"
          isError: false
      stderr: "toBeEmpty"

  - it: "should get class info with expand enabled"
    request:
      jsonrpc: "2.0"
      id: "filter-expand"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-expand"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.catalog.Catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out description when includeDescription is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-description"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeDescription: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-description"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out constants when includeConstants is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-constants"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeConstants: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-constants"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out properties when includeProperties is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-properties"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeProperties: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-properties"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out methods when includeMethods is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-methods"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeMethods: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-methods"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should filter out inheritance when includeInheritance is false"
    request:
      jsonrpc: "2.0"
      id: "filter-no-inheritance"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeInheritance: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-no-inheritance"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should apply multiple filters together (minimal response)"
    request:
      jsonrpc: "2.0"
      id: "filter-minimal"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeDescription: false
          includeConstants: false
          includeProperties: false
          includeMethods: false
          includeInheritance: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-minimal"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should search within class info using search parameter"
    request:
      jsonrpc: "2.0"
      id: "search-basic"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          search: "get"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-basic"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should combine filtering with search functionality"
    request:
      jsonrpc: "2.0"
      id: "search-filtered"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          includeMethods: true
          includeProperties: false
          includeConstants: false
          search: "getName"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-filtered"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle class name without dw prefix"
    request:
      jsonrpc: "2.0"
      id: "filter-short-name"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-short-name"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle System class with all filters enabled"
    request:
      jsonrpc: "2.0"
      id: "filter-system-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.system.System"
          expand: true
          includeDescription: true
          includeConstants: true
          includeProperties: true
          includeMethods: true
          includeInheritance: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "filter-system-class"
        result:
          content:
            - type: "text"
              text: "match:contains:dw.system.System"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle Customer class with case-insensitive search"
    request:
      jsonrpc: "2.0"
      id: "search-case-insensitive"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.customer.Customer"
          search: "EMAIL"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-case-insensitive"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle search with no matches gracefully"
    request:
      jsonrpc: "2.0"
      id: "search-no-matches"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          search: "zzznomatchesexpected"
    expect:
      response:
        jsonrpc: "2.0"
        id: "search-no-matches"
        result:
          content:
            - type: "text"
              text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# ERROR HANDLING TESTS
# ==================================================================================

  - it: "should handle invalid class names gracefully"
    request:
      jsonrpc: "2.0"
      id: "error-invalid-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "NonExistentClass"
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-invalid-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

  - it: "should handle empty class name"
    request:
      jsonrpc: "2.0"
      id: "error-empty-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: ""
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-empty-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

  - it: "should handle missing className parameter with error response"
    request:
      jsonrpc: "2.0"
      id: "error-missing-param"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments: {}
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-missing-param"
        result:
          content:
            - type: "text"
              text: "match:contains:className"
          isError: true
      stderr: "toBeEmpty"

  - it: "should handle malformed class names"
    request:
      jsonrpc: "2.0"
      id: "error-malformed-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "..invalid..class..name.."
    expect:
      response:
        jsonrpc: "2.0"
        id: "error-malformed-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

# ==================================================================================
# RESPONSE FORMAT VALIDATION
# ==================================================================================

  - it: "should return consistent MCP content structure"
    request:
      jsonrpc: "2.0"
      id: "format-content-structure"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "format-content-structure"
        result:
          content:
            match:arrayElements:
              match:partial:
                type: "text"
                text: "match:type:string"
          isError: false
      stderr: "toBeEmpty"

  - it: "should return single content item for successful calls"
    request:
      jsonrpc: "2.0"
      id: "format-single-content"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "format-single-content"
        result:
          content: "match:arrayLength:1"
          isError: false
      stderr: "toBeEmpty"

  - it: "should not set isError flag for successful responses"
    request:
      jsonrpc: "2.0"
      id: "format-no-error-flag"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "format-no-error-flag"
        result:
          content: "match:type:array"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# EDGE CASES AND COMPLEX SCENARIOS
# ==================================================================================

  - it: "should handle classes with many methods (like Product)"
    request:
      jsonrpc: "2.0"
      id: "edge-many-methods"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-many-methods"
        result:
          content:
            - type: "text"
              text: "match:regex:\"methods\"[\\s\\S]*getID[\\s\\S]*getName"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle classes with variation models"
    request:
      jsonrpc: "2.0"
      id: "edge-variation-model"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.ProductVariationModel"
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-variation-model"
        result:
          content:
            - type: "text"
              text: "match:contains:ProductVariationModel"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle inventory-related classes"
    request:
      jsonrpc: "2.0"
      id: "edge-inventory-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.ProductInventoryList"
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-inventory-class"
        result:
          content:
            - type: "text"
              text: "match:contains:ProductInventoryList"
          isError: false
      stderr: "toBeEmpty"

# ==================================================================================
# PERFORMANCE AND CONSISTENCY VALIDATION
# ==================================================================================

  - it: "should respond consistently for repeated calls"
    request:
      jsonrpc: "2.0"
      id: "perf-consistent-1"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-consistent-1"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should respond consistently for repeated calls (second time)"
    request:
      jsonrpc: "2.0"
      id: "perf-consistent-2"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-consistent-2"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      stderr: "toBeEmpty"

  - it: "should handle case sensitivity properly"
    request:
      jsonrpc: "2.0"
      id: "edge-case-sensitivity"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.product"  # lowercase 'product'
    expect:
      response:
        jsonrpc: "2.0"
        id: "edge-case-sensitivity"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      stderr: "toBeEmpty"

# ==================================================================================
# PERFORMANCE TIMING TESTS
# ==================================================================================

  - it: "should return basic class info within acceptable time"
    request:
      jsonrpc: "2.0"
      id: "perf-basic-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-basic-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      performance:
        maxResponseTime: "150ms"  # Documentation lookup should be very fast
      stderr: "toBeEmpty"

  - it: "should return complex class info with expand within timeout"
    request:
      jsonrpc: "2.0"
      id: "perf-expand-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Product"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-expand-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Product"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Even expanded info should be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle large class documentation efficiently"
    request:
      jsonrpc: "2.0"
      id: "perf-large-class"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.system.Site"
          expand: true
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-large-class"
        result:
          content:
            - type: "text"
              text: "match:contains:Site"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Large classes should still be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle simple customer classes quickly"
    request:
      jsonrpc: "2.0"
      id: "perf-customer-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.customer.Customer"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-customer-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Customer"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Standard class lookup should be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle order classes within timeout"
    request:
      jsonrpc: "2.0"
      id: "perf-order-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.order.Order"
          expand: false
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-order-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Order"
          isError: false
      performance:
        maxResponseTime: "100ms"  # Basic order class lookup should be under 100ms
      stderr: "toBeEmpty"

  - it: "should handle non-existent class error within timeout"
    request:
      jsonrpc: "2.0"
      id: "perf-error-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.nonexistent.FakeClass"
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-error-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      performance:
        maxResponseTime: "50ms"  # Error handling should be very fast
      stderr: "toBeEmpty"

  - it: "should handle empty class name error quickly"
    request:
      jsonrpc: "2.0"
      id: "perf-empty-error-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: ""
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-empty-error-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      performance:
        maxResponseTime: "50ms"  # Validation errors should be extremely fast
      stderr: "toBeEmpty"

  - it: "should handle malformed class name error efficiently"
    request:
      jsonrpc: "2.0"
      id: "perf-malformed-error-timing"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "..invalid..class..name.."
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-malformed-error-timing"
        result:
          content:
            - type: "text"
              text: "match:contains:Error"
          isError: true
      performance:
        maxResponseTime: "50ms"  # Invalid input should fail extremely fast
      stderr: "toBeEmpty"

  - it: "should handle cached responses quickly"
    request:
      jsonrpc: "2.0"
      id: "perf-cached-response"
      method: "tools/call"
      params:
        name: "get_sfcc_class_info"
        arguments:
          className: "dw.catalog.Catalog"  # Same as first test - should be cached
    expect:
      response:
        jsonrpc: "2.0"
        id: "perf-cached-response"
        result:
          content:
            - type: "text"
              text: "match:contains:Catalog"
          isError: false
      performance:
        maxResponseTime: "50ms"  # Cached responses should be extremely fast
      stderr: "toBeEmpty"

```
Page 33/43FirstPrevNextLast