@salesforce/b2c-cli 2.3.1 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/bin/dev.js +8 -8
  2. package/bin/run.js +5 -7
  3. package/content/guidance/b2c/b2c-business-manager-extensions/SKILL.md +361 -0
  4. package/content/guidance/b2c/b2c-business-manager-extensions/references/EXTENSIONS-XML.md +458 -0
  5. package/content/guidance/b2c/b2c-controllers/SKILL.md +301 -0
  6. package/content/guidance/b2c/b2c-controllers/references/CLASSIC-PATTERNS.md +335 -0
  7. package/content/guidance/b2c/b2c-controllers/references/SFRA-PATTERNS.md +400 -0
  8. package/content/guidance/b2c/b2c-custom-api-development/SKILL.md +281 -0
  9. package/content/guidance/b2c/b2c-custom-api-development/references/CONTRACT.md +142 -0
  10. package/content/guidance/b2c/b2c-custom-api-development/references/IMPLEMENTATION.md +153 -0
  11. package/content/guidance/b2c/b2c-custom-api-development/references/TESTING.md +118 -0
  12. package/content/guidance/b2c/b2c-custom-caches/SKILL.md +279 -0
  13. package/content/guidance/b2c/b2c-custom-job-steps/SKILL.md +520 -0
  14. package/content/guidance/b2c/b2c-custom-job-steps/references/CHUNK-ORIENTED.md +377 -0
  15. package/content/guidance/b2c/b2c-custom-job-steps/references/JOBS-XML.md +212 -0
  16. package/content/guidance/b2c/b2c-custom-job-steps/references/STEPTYPES-JSON.md +373 -0
  17. package/content/guidance/b2c/b2c-custom-job-steps/references/TASK-ORIENTED.md +344 -0
  18. package/content/guidance/b2c/b2c-custom-objects/SKILL.md +327 -0
  19. package/content/guidance/b2c/b2c-custom-objects/references/OCAPI-SEARCH.md +298 -0
  20. package/content/guidance/b2c/b2c-forms/SKILL.md +242 -0
  21. package/content/guidance/b2c/b2c-forms/references/FORM-XML.md +409 -0
  22. package/content/guidance/b2c/b2c-hooks/SKILL.md +500 -0
  23. package/content/guidance/b2c/b2c-hooks/references/OCAPI-SCAPI-HOOKS.md +403 -0
  24. package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +169 -0
  25. package/content/guidance/b2c/b2c-hooks/references/SYSTEM-HOOKS.md +433 -0
  26. package/content/guidance/b2c/b2c-isml/SKILL.md +320 -0
  27. package/content/guidance/b2c/b2c-isml/references/EXPRESSIONS.md +366 -0
  28. package/content/guidance/b2c/b2c-isml/references/TAGS.md +443 -0
  29. package/content/guidance/b2c/b2c-localization/SKILL.md +344 -0
  30. package/content/guidance/b2c/b2c-localization/references/PATTERNS.md +407 -0
  31. package/content/guidance/b2c/b2c-logging/SKILL.md +352 -0
  32. package/content/guidance/b2c/b2c-logging/references/LOG-FILES.md +282 -0
  33. package/content/guidance/b2c/b2c-metadata/SKILL.md +406 -0
  34. package/content/guidance/b2c/b2c-metadata/references/SYSTEM-OBJECTS.md +320 -0
  35. package/content/guidance/b2c/b2c-metadata/references/XML-EXAMPLES.md +366 -0
  36. package/content/guidance/b2c/b2c-onboarding/SKILL.md +154 -0
  37. package/content/guidance/b2c/b2c-ordering/SKILL.md +391 -0
  38. package/content/guidance/b2c/b2c-page-designer/SKILL.md +410 -0
  39. package/content/guidance/b2c/b2c-page-designer/references/ATTRIBUTE-TYPES.md +436 -0
  40. package/content/guidance/b2c/b2c-page-designer/references/META-DEFINITIONS.md +340 -0
  41. package/content/guidance/b2c/b2c-querying-data/SKILL.md +289 -0
  42. package/content/guidance/b2c/b2c-querying-data/references/PERFORMANCE-APIS.md +74 -0
  43. package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +53 -0
  44. package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +440 -0
  45. package/content/guidance/b2c/b2c-scapi-admin/references/INTEGRATION-PATTERNS.md +518 -0
  46. package/content/guidance/b2c/b2c-scapi-admin/references/OAUTH-SCOPES.md +337 -0
  47. package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +56 -0
  48. package/content/guidance/b2c/b2c-scapi-shopper/references/CHECKOUT-FLOW.md +466 -0
  49. package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +351 -0
  50. package/content/guidance/b2c/b2c-scapi-shopper/references/COMMON-PATTERNS.md +390 -0
  51. package/content/guidance/b2c/b2c-scapi-shopper/references/SCOPES.md +290 -0
  52. package/content/guidance/b2c/b2c-slas-auth-patterns/SKILL.md +420 -0
  53. package/content/guidance/b2c/b2c-slas-auth-patterns/references/PASSKEYS.md +126 -0
  54. package/content/guidance/b2c/b2c-slas-auth-patterns/references/SESSION-BRIDGE.md +267 -0
  55. package/content/guidance/b2c/b2c-slas-auth-patterns/references/TOKEN-LIFECYCLE.md +367 -0
  56. package/content/guidance/b2c/b2c-webservices/SKILL.md +318 -0
  57. package/content/guidance/b2c/b2c-webservices/references/FTP-SERVICES.md +524 -0
  58. package/content/guidance/b2c/b2c-webservices/references/HTTP-SERVICES.md +578 -0
  59. package/content/guidance/b2c/b2c-webservices/references/SERVICES-XML.md +351 -0
  60. package/content/guidance/b2c/b2c-webservices/references/SOAP-SERVICES.md +587 -0
  61. package/content/guidance/b2c-cli/b2c-am/SKILL.md +277 -0
  62. package/content/guidance/b2c-cli/b2c-bm-users-roles/SKILL.md +210 -0
  63. package/content/guidance/b2c-cli/b2c-cap/SKILL.md +131 -0
  64. package/content/guidance/b2c-cli/b2c-cip/SKILL.md +116 -0
  65. package/content/guidance/b2c-cli/b2c-cip/references/KNOWN_TABLES.md +105 -0
  66. package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +50 -0
  67. package/content/guidance/b2c-cli/b2c-cip/references/STARTER_QUERIES.md +147 -0
  68. package/content/guidance/b2c-cli/b2c-code/SKILL.md +146 -0
  69. package/content/guidance/b2c-cli/b2c-config/SKILL.md +481 -0
  70. package/content/guidance/b2c-cli/b2c-content/SKILL.md +176 -0
  71. package/content/guidance/b2c-cli/b2c-debug/SKILL.md +138 -0
  72. package/content/guidance/b2c-cli/b2c-docs/SKILL.md +301 -0
  73. package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +137 -0
  74. package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +97 -0
  75. package/content/guidance/b2c-cli/b2c-ecdn/references/SECURITY.md +75 -0
  76. package/content/guidance/b2c-cli/b2c-import-set-migrations/SKILL.md +265 -0
  77. package/content/guidance/b2c-cli/b2c-job/SKILL.md +70 -0
  78. package/content/guidance/b2c-cli/b2c-job/references/EXPORT.md +121 -0
  79. package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +55 -0
  80. package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +148 -0
  81. package/content/guidance/b2c-cli/b2c-logs/SKILL.md +249 -0
  82. package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +315 -0
  83. package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +207 -0
  84. package/content/guidance/b2c-cli/b2c-mrt/references/BUNDLE-COMMANDS.md +203 -0
  85. package/content/guidance/b2c-cli/b2c-mrt/references/ENVIRONMENT-COMMANDS.md +218 -0
  86. package/content/guidance/b2c-cli/b2c-mrt/references/PROJECT-COMMANDS.md +154 -0
  87. package/content/guidance/b2c-cli/b2c-sandbox/SKILL.md +112 -0
  88. package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +126 -0
  89. package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +70 -0
  90. package/content/guidance/b2c-cli/b2c-scapi-schemas/references/CLI-EXAMPLES.md +108 -0
  91. package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +57 -0
  92. package/content/guidance/b2c-cli/b2c-site-import-export/references/IMPORT-OPTIONS.md +118 -0
  93. package/content/guidance/b2c-cli/b2c-site-import-export/references/METADATA-XML.md +381 -0
  94. package/content/guidance/b2c-cli/b2c-site-import-export/references/WORKFLOWS.md +182 -0
  95. package/content/guidance/b2c-cli/b2c-sites/SKILL.md +112 -0
  96. package/content/guidance/b2c-cli/b2c-slas/SKILL.md +182 -0
  97. package/content/guidance/b2c-cli/b2c-webdav/SKILL.md +186 -0
  98. package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +68 -0
  99. package/content/guidance/b2c-ops/b2c-edge-traffic-triage/SKILL.md +69 -0
  100. package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +80 -0
  101. package/content/guidance/b2c-ops/b2c-job-health/references/job-logs.md +21 -0
  102. package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +66 -0
  103. package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +87 -0
  104. package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +88 -0
  105. package/content/guidance/b2c-ops/b2c-production-triage/references/escalation.md +57 -0
  106. package/content/guidance/index.json +1969 -0
  107. package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
  108. package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
  109. package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
  110. package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
  111. package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +127 -0
  112. package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
  113. package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
  114. package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
  115. package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
  116. package/content/guidance/storefront-next/sfnext-components/SKILL.md +153 -0
  117. package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
  118. package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
  119. package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
  120. package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
  121. package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
  122. package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +163 -0
  123. package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
  124. package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
  125. package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +140 -0
  126. package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
  127. package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
  128. package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
  129. package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +39 -0
  130. package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +127 -0
  131. package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +59 -0
  132. package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +118 -0
  133. package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
  134. package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +68 -0
  135. package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
  136. package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +79 -0
  137. package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +93 -0
  138. package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +86 -0
  139. package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +152 -0
  140. package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
  141. package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
  142. package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +202 -0
  143. package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
  144. package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +111 -0
  145. package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +168 -0
  146. package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
  147. package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
  148. package/content/guidance/storefront-next/sfnext-performance/SKILL.md +102 -0
  149. package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
  150. package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
  151. package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +147 -0
  152. package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -0
  153. package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
  154. package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
  155. package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
  156. package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
  157. package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
  158. package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
  159. package/content/guidance/storefront-next/sfnext-routing/SKILL.md +123 -0
  160. package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +65 -0
  161. package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
  162. package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
  163. package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
  164. package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
  165. package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
  166. package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
  167. package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
  168. package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
  169. package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
  170. package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +114 -0
  171. package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
  172. package/content/guidance/storefront-next/sfnext-testing/SKILL.md +151 -0
  173. package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
  174. package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +97 -0
  175. package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
  176. package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
  177. package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
  178. package/dist/commands/cap/install.d.ts +1 -0
  179. package/dist/commands/cap/list.d.ts +1 -0
  180. package/dist/commands/cap/pull.d.ts +1 -0
  181. package/dist/commands/cap/tasks.d.ts +1 -0
  182. package/dist/commands/cap/uninstall.d.ts +1 -0
  183. package/dist/commands/cip/describe.d.ts +1 -0
  184. package/dist/commands/cip/query.d.ts +1 -0
  185. package/dist/commands/cip/report/bot-traffic-share.d.ts +1 -0
  186. package/dist/commands/cip/report/checkout-funnel-dropoff.d.ts +1 -0
  187. package/dist/commands/cip/report/controller-error-rate-trend.d.ts +1 -0
  188. package/dist/commands/cip/report/controller-health-scorecard.d.ts +1 -0
  189. package/dist/commands/cip/report/customer-registration-trends.d.ts +1 -0
  190. package/dist/commands/cip/report/discount-depth-breakdown.d.ts +1 -0
  191. package/dist/commands/cip/report/inventory-stockout-by-location.d.ts +1 -0
  192. package/dist/commands/cip/report/new-vs-returning-buyer-revenue.d.ts +1 -0
  193. package/dist/commands/cip/report/ocapi-client-usage.d.ts +1 -0
  194. package/dist/commands/cip/report/ocapi-requests.d.ts +1 -0
  195. package/dist/commands/cip/report/payment-method-performance.d.ts +1 -0
  196. package/dist/commands/cip/report/product-co-purchase-analysis.d.ts +1 -0
  197. package/dist/commands/cip/report/promotion-discount-analysis.d.ts +1 -0
  198. package/dist/commands/cip/report/promotion-roi-leaderboard.d.ts +1 -0
  199. package/dist/commands/cip/report/recommender-effectiveness.d.ts +1 -0
  200. package/dist/commands/cip/report/remote-include-performance.d.ts +1 -0
  201. package/dist/commands/cip/report/revenue-by-channel.d.ts +1 -0
  202. package/dist/commands/cip/report/sales-analytics.d.ts +1 -0
  203. package/dist/commands/cip/report/sales-summary.d.ts +1 -0
  204. package/dist/commands/cip/report/scapi-cache-hit-ratio.d.ts +1 -0
  205. package/dist/commands/cip/report/scapi-error-rate-by-status.d.ts +1 -0
  206. package/dist/commands/cip/report/scapi-latency-distribution.d.ts +1 -0
  207. package/dist/commands/cip/report/scapi-traffic-latency.d.ts +1 -0
  208. package/dist/commands/cip/report/search-query-performance.d.ts +1 -0
  209. package/dist/commands/cip/report/top-referrers.d.ts +1 -0
  210. package/dist/commands/cip/report/top-selling-products.d.ts +1 -0
  211. package/dist/commands/cip/report/zero-result-searches.d.ts +1 -0
  212. package/dist/commands/cip/tables.d.ts +1 -0
  213. package/dist/commands/code/activate.d.ts +1 -0
  214. package/dist/commands/code/delete.d.ts +1 -0
  215. package/dist/commands/code/deploy.d.ts +1 -0
  216. package/dist/commands/code/download.d.ts +1 -0
  217. package/dist/commands/code/watch.d.ts +1 -0
  218. package/dist/commands/commands/search.d.ts +35 -0
  219. package/dist/commands/commands/search.js +85 -0
  220. package/dist/commands/commands/search.js.map +1 -0
  221. package/dist/commands/content/export.d.ts +1 -0
  222. package/dist/commands/content/list.d.ts +1 -0
  223. package/dist/commands/content/validate.d.ts +1 -0
  224. package/dist/commands/debug/cli.d.ts +1 -0
  225. package/dist/commands/debug/index.d.ts +1 -0
  226. package/dist/commands/docs/cache.d.ts +1 -0
  227. package/dist/commands/docs/download.d.ts +1 -0
  228. package/dist/commands/docs/read.d.ts +1 -0
  229. package/dist/commands/docs/schema.d.ts +1 -0
  230. package/dist/commands/docs/search.d.ts +1 -0
  231. package/dist/commands/docs/skill.d.ts +41 -0
  232. package/dist/commands/docs/skill.js +183 -0
  233. package/dist/commands/docs/skill.js.map +1 -0
  234. package/dist/commands/ecdn/cache/purge.d.ts +1 -0
  235. package/dist/commands/ecdn/certificates/add.d.ts +1 -0
  236. package/dist/commands/ecdn/certificates/delete.d.ts +1 -0
  237. package/dist/commands/ecdn/certificates/list.d.ts +1 -0
  238. package/dist/commands/ecdn/certificates/update.d.ts +1 -0
  239. package/dist/commands/ecdn/certificates/validate.d.ts +1 -0
  240. package/dist/commands/ecdn/cipher-suites/get.d.ts +1 -0
  241. package/dist/commands/ecdn/cipher-suites/update.d.ts +1 -0
  242. package/dist/commands/ecdn/firewall/create.d.ts +1 -0
  243. package/dist/commands/ecdn/firewall/delete.d.ts +1 -0
  244. package/dist/commands/ecdn/firewall/get.d.ts +1 -0
  245. package/dist/commands/ecdn/firewall/list.d.ts +1 -0
  246. package/dist/commands/ecdn/firewall/reorder.d.ts +1 -0
  247. package/dist/commands/ecdn/firewall/update.d.ts +1 -0
  248. package/dist/commands/ecdn/logpush/jobs/create.d.ts +1 -0
  249. package/dist/commands/ecdn/logpush/jobs/delete.d.ts +1 -0
  250. package/dist/commands/ecdn/logpush/jobs/get.d.ts +1 -0
  251. package/dist/commands/ecdn/logpush/jobs/list.d.ts +1 -0
  252. package/dist/commands/ecdn/logpush/jobs/update.d.ts +1 -0
  253. package/dist/commands/ecdn/logpush/ownership.d.ts +1 -0
  254. package/dist/commands/ecdn/mrt-rules/create.d.ts +1 -0
  255. package/dist/commands/ecdn/mrt-rules/delete.d.ts +1 -0
  256. package/dist/commands/ecdn/mrt-rules/get.d.ts +1 -0
  257. package/dist/commands/ecdn/mrt-rules/rules/delete.d.ts +1 -0
  258. package/dist/commands/ecdn/mrt-rules/rules/update.d.ts +1 -0
  259. package/dist/commands/ecdn/mrt-rules/update.d.ts +1 -0
  260. package/dist/commands/ecdn/mtls/create.d.ts +1 -0
  261. package/dist/commands/ecdn/mtls/delete.d.ts +1 -0
  262. package/dist/commands/ecdn/mtls/get.d.ts +1 -0
  263. package/dist/commands/ecdn/mtls/issue.d.ts +1 -0
  264. package/dist/commands/ecdn/mtls/list.d.ts +1 -0
  265. package/dist/commands/ecdn/mtls/setup.d.ts +1 -0
  266. package/dist/commands/ecdn/origin-headers/delete.d.ts +1 -0
  267. package/dist/commands/ecdn/origin-headers/get.d.ts +1 -0
  268. package/dist/commands/ecdn/origin-headers/set.d.ts +1 -0
  269. package/dist/commands/ecdn/page-shield/notifications/create.d.ts +1 -0
  270. package/dist/commands/ecdn/page-shield/notifications/delete.d.ts +1 -0
  271. package/dist/commands/ecdn/page-shield/notifications/list.d.ts +1 -0
  272. package/dist/commands/ecdn/page-shield/policies/create.d.ts +1 -0
  273. package/dist/commands/ecdn/page-shield/policies/delete.d.ts +1 -0
  274. package/dist/commands/ecdn/page-shield/policies/get.d.ts +1 -0
  275. package/dist/commands/ecdn/page-shield/policies/list.d.ts +1 -0
  276. package/dist/commands/ecdn/page-shield/policies/update.d.ts +1 -0
  277. package/dist/commands/ecdn/page-shield/scripts/get.d.ts +1 -0
  278. package/dist/commands/ecdn/page-shield/scripts/list.d.ts +1 -0
  279. package/dist/commands/ecdn/rate-limit/create.d.ts +1 -0
  280. package/dist/commands/ecdn/rate-limit/delete.d.ts +1 -0
  281. package/dist/commands/ecdn/rate-limit/get.d.ts +1 -0
  282. package/dist/commands/ecdn/rate-limit/list.d.ts +1 -0
  283. package/dist/commands/ecdn/rate-limit/update.d.ts +1 -0
  284. package/dist/commands/ecdn/security/get.d.ts +1 -0
  285. package/dist/commands/ecdn/security/update.d.ts +1 -0
  286. package/dist/commands/ecdn/speed/get.d.ts +1 -0
  287. package/dist/commands/ecdn/speed/update.d.ts +1 -0
  288. package/dist/commands/ecdn/waf/groups/list.d.ts +1 -0
  289. package/dist/commands/ecdn/waf/groups/update.d.ts +1 -0
  290. package/dist/commands/ecdn/waf/managed-rules/list.d.ts +1 -0
  291. package/dist/commands/ecdn/waf/managed-rules/update.d.ts +1 -0
  292. package/dist/commands/ecdn/waf/migrate.d.ts +1 -0
  293. package/dist/commands/ecdn/waf/owasp/get.d.ts +1 -0
  294. package/dist/commands/ecdn/waf/owasp/update.d.ts +1 -0
  295. package/dist/commands/ecdn/waf/rules/get.d.ts +1 -0
  296. package/dist/commands/ecdn/waf/rules/list.d.ts +1 -0
  297. package/dist/commands/ecdn/waf/rules/update.d.ts +1 -0
  298. package/dist/commands/ecdn/waf/rulesets/list.d.ts +1 -0
  299. package/dist/commands/ecdn/waf/rulesets/update.d.ts +1 -0
  300. package/dist/commands/ecdn/zones/create.d.ts +1 -0
  301. package/dist/commands/ecdn/zones/list.d.ts +1 -0
  302. package/dist/commands/job/execution/delete.d.ts +1 -0
  303. package/dist/commands/job/export.d.ts +1 -0
  304. package/dist/commands/job/import-set.d.ts +1 -0
  305. package/dist/commands/job/import.d.ts +1 -0
  306. package/dist/commands/job/log.d.ts +1 -0
  307. package/dist/commands/job/run.d.ts +1 -0
  308. package/dist/commands/job/run.js +1 -1
  309. package/dist/commands/job/run.js.map +1 -1
  310. package/dist/commands/job/search.d.ts +1 -0
  311. package/dist/commands/job/wait.d.ts +1 -0
  312. package/dist/commands/logs/get.d.ts +1 -0
  313. package/dist/commands/logs/list.d.ts +1 -0
  314. package/dist/commands/logs/tail.d.ts +1 -0
  315. package/dist/commands/metrics/controller.d.ts +1 -0
  316. package/dist/commands/metrics/ecdn.d.ts +1 -0
  317. package/dist/commands/metrics/mrt.d.ts +1 -0
  318. package/dist/commands/metrics/ocapi.d.ts +1 -0
  319. package/dist/commands/metrics/overall.d.ts +1 -0
  320. package/dist/commands/metrics/sales.d.ts +1 -0
  321. package/dist/commands/metrics/scapi-hooks.d.ts +1 -0
  322. package/dist/commands/metrics/scapi.d.ts +1 -0
  323. package/dist/commands/metrics/third-party.d.ts +1 -0
  324. package/dist/commands/mrt/bundle/delete.d.ts +1 -0
  325. package/dist/commands/mrt/bundle/deploy.d.ts +1 -0
  326. package/dist/commands/mrt/bundle/download.d.ts +1 -0
  327. package/dist/commands/mrt/bundle/history.d.ts +1 -0
  328. package/dist/commands/mrt/bundle/list.d.ts +1 -0
  329. package/dist/commands/mrt/bundle/save.d.ts +1 -0
  330. package/dist/commands/mrt/bundle/upload-v2.d.ts +1 -0
  331. package/dist/commands/mrt/env/access-control/list.d.ts +1 -0
  332. package/dist/commands/mrt/env/b2c.d.ts +1 -0
  333. package/dist/commands/mrt/env/clone.d.ts +1 -0
  334. package/dist/commands/mrt/env/create.d.ts +1 -0
  335. package/dist/commands/mrt/env/delete.d.ts +1 -0
  336. package/dist/commands/mrt/env/get.d.ts +1 -0
  337. package/dist/commands/mrt/env/invalidate.d.ts +1 -0
  338. package/dist/commands/mrt/env/list.d.ts +1 -0
  339. package/dist/commands/mrt/env/redirect/clone.d.ts +1 -0
  340. package/dist/commands/mrt/env/redirect/create.d.ts +1 -0
  341. package/dist/commands/mrt/env/redirect/delete.d.ts +1 -0
  342. package/dist/commands/mrt/env/redirect/list.d.ts +1 -0
  343. package/dist/commands/mrt/env/update.d.ts +1 -0
  344. package/dist/commands/mrt/env/var/delete.d.ts +1 -0
  345. package/dist/commands/mrt/env/var/list.d.ts +1 -0
  346. package/dist/commands/mrt/env/var/push.d.ts +1 -0
  347. package/dist/commands/mrt/env/var/set.d.ts +1 -0
  348. package/dist/commands/mrt/org/b2c.d.ts +1 -0
  349. package/dist/commands/mrt/org/cert/create.d.ts +1 -0
  350. package/dist/commands/mrt/org/cert/delete.d.ts +1 -0
  351. package/dist/commands/mrt/org/cert/get.d.ts +1 -0
  352. package/dist/commands/mrt/org/cert/list.d.ts +1 -0
  353. package/dist/commands/mrt/org/cert/restart-validation.d.ts +1 -0
  354. package/dist/commands/mrt/org/list.d.ts +1 -0
  355. package/dist/commands/mrt/org/member/add.d.ts +1 -0
  356. package/dist/commands/mrt/org/member/get.d.ts +1 -0
  357. package/dist/commands/mrt/org/member/list.d.ts +1 -0
  358. package/dist/commands/mrt/org/member/remove.d.ts +1 -0
  359. package/dist/commands/mrt/org/member/update.d.ts +1 -0
  360. package/dist/commands/mrt/project/create.d.ts +1 -0
  361. package/dist/commands/mrt/project/delete.d.ts +1 -0
  362. package/dist/commands/mrt/project/get.d.ts +1 -0
  363. package/dist/commands/mrt/project/list.d.ts +1 -0
  364. package/dist/commands/mrt/project/member/add.d.ts +1 -0
  365. package/dist/commands/mrt/project/member/get.d.ts +1 -0
  366. package/dist/commands/mrt/project/member/list.d.ts +1 -0
  367. package/dist/commands/mrt/project/member/remove.d.ts +1 -0
  368. package/dist/commands/mrt/project/member/update.d.ts +1 -0
  369. package/dist/commands/mrt/project/notification/delete.d.ts +1 -0
  370. package/dist/commands/mrt/project/notification/get.d.ts +1 -0
  371. package/dist/commands/mrt/project/update.d.ts +1 -0
  372. package/dist/commands/mrt/save-credentials.d.ts +1 -0
  373. package/dist/commands/mrt/tail-logs.d.ts +1 -0
  374. package/dist/commands/mrt/user/api-key.d.ts +1 -0
  375. package/dist/commands/mrt/user/email-prefs.d.ts +1 -0
  376. package/dist/commands/mrt/user/profile.d.ts +1 -0
  377. package/dist/commands/scaffold/init.js +2 -1
  378. package/dist/commands/scaffold/init.js.map +1 -1
  379. package/dist/commands/scapi/custom/status.d.ts +1 -0
  380. package/dist/commands/scapi/schemas/get.d.ts +9 -0
  381. package/dist/commands/scapi/schemas/get.js +51 -19
  382. package/dist/commands/scapi/schemas/get.js.map +1 -1
  383. package/dist/commands/scapi/schemas/list.d.ts +6 -0
  384. package/dist/commands/scapi/schemas/list.js +28 -18
  385. package/dist/commands/scapi/schemas/list.js.map +1 -1
  386. package/dist/commands/setup/get.d.ts +36 -0
  387. package/dist/commands/setup/get.js +67 -0
  388. package/dist/commands/setup/get.js.map +1 -0
  389. package/dist/commands/setup/ide/tsserver-plugin.d.ts +1 -0
  390. package/dist/commands/setup/ide/vscode-types.d.ts +1 -0
  391. package/dist/commands/setup/index.js +4 -3
  392. package/dist/commands/setup/index.js.map +1 -1
  393. package/dist/commands/setup/inspect.d.ts +1 -0
  394. package/dist/commands/setup/inspect.js +15 -4
  395. package/dist/commands/setup/inspect.js.map +1 -1
  396. package/dist/commands/setup/instance/create.d.ts +9 -0
  397. package/dist/commands/setup/instance/create.js +22 -6
  398. package/dist/commands/setup/instance/create.js.map +1 -1
  399. package/dist/commands/setup/instance/list.d.ts +1 -0
  400. package/dist/commands/setup/instance/list.js +3 -4
  401. package/dist/commands/setup/instance/list.js.map +1 -1
  402. package/dist/commands/setup/instance/remove.d.ts +1 -0
  403. package/dist/commands/setup/instance/remove.js +5 -5
  404. package/dist/commands/setup/instance/remove.js.map +1 -1
  405. package/dist/commands/setup/instance/set-active.d.ts +6 -0
  406. package/dist/commands/setup/instance/set-active.js +20 -5
  407. package/dist/commands/setup/instance/set-active.js.map +1 -1
  408. package/dist/commands/setup/openshell.d.ts +1 -0
  409. package/dist/commands/setup/set.d.ts +37 -0
  410. package/dist/commands/setup/set.js +87 -0
  411. package/dist/commands/setup/set.js.map +1 -0
  412. package/dist/commands/setup/skills.d.ts +1 -0
  413. package/dist/commands/setup/unset.d.ts +37 -0
  414. package/dist/commands/setup/unset.js +55 -0
  415. package/dist/commands/setup/unset.js.map +1 -0
  416. package/dist/commands/slas/client/create.d.ts +1 -0
  417. package/dist/commands/slas/client/delete.d.ts +1 -0
  418. package/dist/commands/slas/client/get.d.ts +1 -0
  419. package/dist/commands/slas/client/list.d.ts +1 -0
  420. package/dist/commands/slas/client/open.d.ts +1 -0
  421. package/dist/commands/slas/client/update.d.ts +1 -0
  422. package/dist/commands/slas/token.d.ts +1 -0
  423. package/dist/commands/slas/token.js +2 -1
  424. package/dist/commands/slas/token.js.map +1 -1
  425. package/dist/commands/webdav/get.d.ts +1 -0
  426. package/dist/commands/webdav/rm.d.ts +1 -0
  427. package/dist/help.d.ts +25 -0
  428. package/dist/help.js +96 -0
  429. package/dist/help.js.map +1 -0
  430. package/dist/lib/scaffold/generate-helper.js +3 -2
  431. package/dist/lib/scaffold/generate-helper.js.map +1 -1
  432. package/dist/lib/skills.d.ts +19 -0
  433. package/dist/lib/skills.js +75 -0
  434. package/dist/lib/skills.js.map +1 -0
  435. package/dist/utils/cip/command.d.ts +1 -0
  436. package/dist/utils/ecdn/zone-command.d.ts +1 -0
  437. package/dist/utils/setup/config-field-command.d.ts +25 -0
  438. package/dist/utils/setup/config-field-command.js +41 -0
  439. package/dist/utils/setup/config-field-command.js.map +1 -0
  440. package/dist/utils/slas/client.d.ts +1 -0
  441. package/oclif.manifest.json +20802 -16968
  442. package/package.json +11 -5
@@ -0,0 +1,267 @@
1
+ # Session Bridge Reference
2
+
3
+ > Illustrative of the flow; confirm platform-agnostic API contract with `b2c docs read commerce-api/slas-session-bridge-auth`. PWA Kit examples use framework-specific convenience wrappers.
4
+
5
+ Detailed implementation patterns for session bridging between PWA Kit and SFRA.
6
+
7
+ ## Token Types
8
+
9
+ | Token | Description | Duration |
10
+ |-------|-------------|----------|
11
+ | `dwsgst` | Guest session token | 30 minutes |
12
+ | `dwsrst` | Registered session token | 30 minutes |
13
+ | `dwsid` | SFRA session cookie | Session-based |
14
+
15
+ ## PWA Kit to SFRA
16
+
17
+ ### Step 1: Generate Bridge Tokens
18
+
19
+ ```javascript
20
+ // commerce-sdk-isomorphic or direct API call
21
+ async function generateBridgeTokens(shopperToken) {
22
+ const response = await shopperLogin.getSessionBridgeAccessToken({
23
+ headers: {
24
+ Authorization: `Bearer ${shopperToken.access_token}`
25
+ },
26
+ body: {
27
+ channel_id: siteId,
28
+ login_id: shopperToken.customer_id
29
+ }
30
+ });
31
+
32
+ return {
33
+ dwsgst: response.dwsgst,
34
+ dwsrst: response.dwsrst // Only present if logged in
35
+ };
36
+ }
37
+ ```
38
+
39
+ ### Step 2: Redirect with Tokens
40
+
41
+ Option A: URL Parameters (simple)
42
+
43
+ ```javascript
44
+ function redirectToSFRA(bridgeTokens, targetPath) {
45
+ const url = new URL(sfraBaseUrl + targetPath);
46
+ url.searchParams.set('dwsgst', bridgeTokens.dwsgst);
47
+ if (bridgeTokens.dwsrst) {
48
+ url.searchParams.set('dwsrst', bridgeTokens.dwsrst);
49
+ }
50
+ window.location.href = url.toString();
51
+ }
52
+ ```
53
+
54
+ Option B: POST Form (more secure)
55
+
56
+ ```javascript
57
+ function redirectViaPOST(bridgeTokens, targetPath) {
58
+ const form = document.createElement('form');
59
+ form.method = 'POST';
60
+ form.action = sfraBaseUrl + '/SessionBridge-Establish';
61
+
62
+ const addInput = (name, value) => {
63
+ const input = document.createElement('input');
64
+ input.type = 'hidden';
65
+ input.name = name;
66
+ input.value = value;
67
+ form.appendChild(input);
68
+ };
69
+
70
+ addInput('dwsgst', bridgeTokens.dwsgst);
71
+ if (bridgeTokens.dwsrst) {
72
+ addInput('dwsrst', bridgeTokens.dwsrst);
73
+ }
74
+ addInput('redirect', targetPath);
75
+
76
+ document.body.appendChild(form);
77
+ form.submit();
78
+ }
79
+ ```
80
+
81
+ ### Step 3: SFRA Establishes Session
82
+
83
+ ```javascript
84
+ // SFRA Controller: SessionBridge-Establish
85
+ var server = require('server');
86
+ var SLASBridge = require('*/cartridge/scripts/services/SLASBridge');
87
+
88
+ server.post('Establish', function(req, res, next) {
89
+ var dwsgst = req.form.dwsgst;
90
+ var dwsrst = req.form.dwsrst;
91
+ var redirect = req.form.redirect || '/';
92
+
93
+ try {
94
+ // Exchange bridge tokens for session
95
+ var result = SLASBridge.establishSession(dwsgst, dwsrst);
96
+
97
+ if (result.success) {
98
+ // Session established, dwsid cookie is set by platform
99
+ res.redirect(redirect);
100
+ } else {
101
+ res.redirect('/login?error=bridge_failed');
102
+ }
103
+ } catch (e) {
104
+ res.redirect('/login?error=bridge_error');
105
+ }
106
+
107
+ next();
108
+ });
109
+ ```
110
+
111
+ ## SFRA to PWA Kit
112
+
113
+ ### Step 1: Generate Bridge Tokens in SFRA
114
+
115
+ ```javascript
116
+ // SFRA Helper
117
+ var LocalServiceRegistry = require('dw/svc/LocalServiceRegistry');
118
+ var Site = require('dw/system/Site');
119
+
120
+ function getBridgeTokensForPWA() {
121
+ var customer = session.customer;
122
+ var svc = LocalServiceRegistry.createService('slas.sessionbridge', {
123
+ createRequest: function(svc, args) {
124
+ svc.setRequestMethod('POST');
125
+ svc.addHeader('Content-Type', 'application/x-www-form-urlencoded');
126
+
127
+ var params = 'channel_id=' + Site.current.ID;
128
+ if (customer.authenticated) {
129
+ params += '&login_id=' + customer.profile.credentials.login;
130
+ }
131
+ return params;
132
+ },
133
+ parseResponse: function(svc, response) {
134
+ return JSON.parse(response.text);
135
+ }
136
+ });
137
+
138
+ var result = svc.call();
139
+ return result.ok ? result.object : null;
140
+ }
141
+ ```
142
+
143
+ ### Step 2: Redirect to PWA Kit
144
+
145
+ ```javascript
146
+ // SFRA Controller: SessionBridge-ToPWA
147
+ server.get('ToPWA', function(req, res, next) {
148
+ var SLASBridge = require('*/cartridge/scripts/services/SLASBridge');
149
+ var targetPath = req.querystring.path || '/';
150
+
151
+ var bridgeTokens = SLASBridge.getBridgeTokensForPWA();
152
+
153
+ if (bridgeTokens) {
154
+ var pwaUrl = 'https://pwa.yoursite.com/session-bridge/callback';
155
+ pwaUrl += '?dwsgst=' + encodeURIComponent(bridgeTokens.dwsgst);
156
+ if (bridgeTokens.dwsrst) {
157
+ pwaUrl += '&dwsrst=' + encodeURIComponent(bridgeTokens.dwsrst);
158
+ }
159
+ pwaUrl += '&redirect=' + encodeURIComponent(targetPath);
160
+
161
+ res.redirect(pwaUrl);
162
+ } else {
163
+ res.redirect('https://pwa.yoursite.com' + targetPath);
164
+ }
165
+
166
+ next();
167
+ });
168
+ ```
169
+
170
+ ### Step 3: PWA Kit Handles Callback
171
+
172
+ ```javascript
173
+ // PWA Kit: pages/session-bridge/callback.jsx
174
+ import { useEffect } from 'react';
175
+ import { useSearchParams, useNavigate } from 'react-router-dom';
176
+ import { useAuth } from '@salesforce/commerce-sdk-react';
177
+
178
+ export default function SessionBridgeCallback() {
179
+ const [searchParams] = useSearchParams();
180
+ const navigate = useNavigate();
181
+ const auth = useAuth();
182
+
183
+ useEffect(() => {
184
+ async function establishSession() {
185
+ const dwsgst = searchParams.get('dwsgst');
186
+ const dwsrst = searchParams.get('dwsrst');
187
+ const redirect = searchParams.get('redirect') || '/';
188
+
189
+ try {
190
+ // Exchange bridge tokens
191
+ await auth.loginSessionBridge({ dwsgst, dwsrst });
192
+ navigate(redirect);
193
+ } catch (error) {
194
+ console.error('Bridge failed:', error);
195
+ navigate('/login?error=bridge_failed');
196
+ }
197
+ }
198
+
199
+ establishSession();
200
+ }, [searchParams]);
201
+
202
+ return <div>Establishing session...</div>;
203
+ }
204
+ ```
205
+
206
+ ## Hybrid Navigation Component
207
+
208
+ ```jsx
209
+ // PWA Kit: components/hybrid-link.jsx
210
+ import { useAuth } from '@salesforce/commerce-sdk-react';
211
+
212
+ export function HybridLink({ href, children, ...props }) {
213
+ const auth = useAuth();
214
+
215
+ const handleClick = async (e) => {
216
+ // Check if href is SFRA
217
+ if (href.includes('sfra.yoursite.com')) {
218
+ e.preventDefault();
219
+
220
+ // Get bridge tokens
221
+ const tokens = await auth.getSessionBridgeTokens();
222
+
223
+ // Build SFRA URL with tokens
224
+ const url = new URL(href);
225
+ url.searchParams.set('dwsgst', tokens.dwsgst);
226
+ if (tokens.dwsrst) {
227
+ url.searchParams.set('dwsrst', tokens.dwsrst);
228
+ }
229
+
230
+ window.location.href = url.toString();
231
+ }
232
+ // Otherwise, let normal navigation happen
233
+ };
234
+
235
+ return (
236
+ <a href={href} onClick={handleClick} {...props}>
237
+ {children}
238
+ </a>
239
+ );
240
+ }
241
+ ```
242
+
243
+ ## Error Handling
244
+
245
+ | Error | Cause | Solution |
246
+ |-------|-------|----------|
247
+ | `invalid_token` | Bridge token expired | Re-generate tokens |
248
+ | `session_mismatch` | Different customer | Clear and restart |
249
+ | `channel_mismatch` | Wrong site ID | Verify channel_id |
250
+ | `bridge_disabled` | Feature not enabled | Enable in SLAS config |
251
+
252
+ ## Security Considerations
253
+
254
+ 1. **Token Expiry**: Bridge tokens expire quickly (30 min) - generate fresh tokens before redirect
255
+ 2. **HTTPS Only**: Always use HTTPS for token exchange
256
+ 3. **Referrer Validation**: Validate source domain on callback endpoints
257
+ 4. **Rate Limiting**: Implement rate limiting on bridge endpoints
258
+ 5. **Token Usage**: Each bridge token should only be used once
259
+
260
+ ## Testing
261
+
262
+ ```bash
263
+ # Verify bridge token generation
264
+ curl -X POST "https://{shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/{orgId}/oauth2/session-bridge/token" \
265
+ -H "Authorization: Bearer {access_token}" \
266
+ -d "channel_id={siteId}&login_id={customerId}"
267
+ ```
@@ -0,0 +1,367 @@
1
+ # Token Lifecycle Reference
2
+
3
+ Understanding token expiry, refresh patterns, and lifecycle management for SLAS.
4
+
5
+ ## Token Types and Expiry
6
+
7
+ | Token Type | Default Expiry | Configurable | Use Case |
8
+ |------------|----------------|--------------|----------|
9
+ | Access Token | 30 minutes | Yes (SLAS Admin) | API requests |
10
+ | Refresh Token (Public) | 90 days | Yes | Token renewal |
11
+ | Refresh Token (Private) | 90 days | Yes | Token renewal |
12
+ | Session Bridge Token | 30 minutes | No | Cross-platform auth |
13
+ | Passwordless Token | 10 minutes | No | OTP verification |
14
+
15
+ ## Access Token Lifecycle
16
+
17
+ ```
18
+ [Issue] → [Active] → [Expired]
19
+ ↓ ↓
20
+ Use Refresh
21
+ ```
22
+
23
+ ### Best Practices for Access Tokens
24
+
25
+ ```javascript
26
+ class TokenManager {
27
+ constructor(config) {
28
+ this.accessToken = null;
29
+ this.refreshToken = null;
30
+ this.expiresAt = null;
31
+ this.refreshThreshold = 5 * 60 * 1000; // 5 minutes
32
+ }
33
+
34
+ isExpired() {
35
+ return Date.now() >= this.expiresAt;
36
+ }
37
+
38
+ shouldRefresh() {
39
+ // Refresh when within threshold of expiry
40
+ return Date.now() >= (this.expiresAt - this.refreshThreshold);
41
+ }
42
+
43
+ async getValidToken() {
44
+ if (this.shouldRefresh()) {
45
+ await this.refresh();
46
+ }
47
+ return this.accessToken;
48
+ }
49
+
50
+ async refresh() {
51
+ const tokens = await this.slasRefresh(this.refreshToken);
52
+ this.setTokens(tokens);
53
+ }
54
+
55
+ setTokens(tokens) {
56
+ this.accessToken = tokens.access_token;
57
+ this.refreshToken = tokens.refresh_token;
58
+ this.expiresAt = Date.now() + (tokens.expires_in * 1000);
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Refresh Token Patterns
64
+
65
+ ### Public Client (Single-Use)
66
+
67
+ For browser-based apps without a backend:
68
+
69
+ ```javascript
70
+ // Refresh tokens are single-use - must store new token
71
+ async function refreshPublicClient(refreshToken) {
72
+ const response = await fetch(tokenEndpoint, {
73
+ method: 'POST',
74
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
75
+ body: new URLSearchParams({
76
+ grant_type: 'refresh_token',
77
+ refresh_token: refreshToken,
78
+ client_id: clientId,
79
+ channel_id: siteId
80
+ })
81
+ });
82
+
83
+ const tokens = await response.json();
84
+
85
+ // IMPORTANT: Old refresh token is now invalid
86
+ // Must use the new refresh_token for next refresh
87
+ return {
88
+ accessToken: tokens.access_token,
89
+ refreshToken: tokens.refresh_token, // NEW token
90
+ expiresIn: tokens.expires_in
91
+ };
92
+ }
93
+ ```
94
+
95
+ ### Private Client (Reusable)
96
+
97
+ For server-side applications:
98
+
99
+ ```javascript
100
+ // Refresh tokens are reusable with client secret
101
+ async function refreshPrivateClient(refreshToken) {
102
+ const response = await fetch(tokenEndpoint, {
103
+ method: 'POST',
104
+ headers: {
105
+ 'Content-Type': 'application/x-www-form-urlencoded',
106
+ 'Authorization': `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`
107
+ },
108
+ body: new URLSearchParams({
109
+ grant_type: 'refresh_token',
110
+ refresh_token: refreshToken,
111
+ channel_id: siteId
112
+ })
113
+ });
114
+
115
+ const tokens = await response.json();
116
+
117
+ // Can reuse same refresh token (though new one may be provided)
118
+ return {
119
+ accessToken: tokens.access_token,
120
+ refreshToken: tokens.refresh_token || refreshToken,
121
+ expiresIn: tokens.expires_in
122
+ };
123
+ }
124
+ ```
125
+
126
+ ## Token Rotation Strategy
127
+
128
+ ### Public Clients - Handle Race Conditions
129
+
130
+ ```javascript
131
+ class PublicTokenManager {
132
+ constructor() {
133
+ this.refreshPromise = null;
134
+ this.tokenVersion = 0;
135
+ }
136
+
137
+ async refresh() {
138
+ // Prevent multiple concurrent refreshes
139
+ if (this.refreshPromise) {
140
+ return this.refreshPromise;
141
+ }
142
+
143
+ const currentVersion = this.tokenVersion;
144
+
145
+ this.refreshPromise = this._doRefresh()
146
+ .finally(() => {
147
+ this.refreshPromise = null;
148
+ });
149
+
150
+ return this.refreshPromise;
151
+ }
152
+
153
+ async _doRefresh() {
154
+ const tokens = await refreshPublicClient(this.refreshToken);
155
+
156
+ // Check for race condition
157
+ if (this.tokenVersion !== currentVersion) {
158
+ // Another refresh happened, tokens might be stale
159
+ throw new Error('Token version mismatch');
160
+ }
161
+
162
+ this.tokenVersion++;
163
+ this.setTokens(tokens);
164
+ return tokens;
165
+ }
166
+ }
167
+ ```
168
+
169
+ ### Storage Strategies
170
+
171
+ ```javascript
172
+ // Browser - httpOnly cookie preferred (requires BFF)
173
+ // Fallback to localStorage with encryption
174
+
175
+ class TokenStorage {
176
+ // Option 1: httpOnly cookies via BFF
177
+ async storeViaBackend(tokens) {
178
+ await fetch('/api/auth/store-tokens', {
179
+ method: 'POST',
180
+ credentials: 'include',
181
+ body: JSON.stringify(tokens)
182
+ });
183
+ }
184
+
185
+ // Option 2: localStorage (less secure)
186
+ storeLocally(tokens) {
187
+ // Consider encrypting before storage
188
+ localStorage.setItem('auth_tokens', JSON.stringify({
189
+ accessToken: tokens.access_token,
190
+ refreshToken: tokens.refresh_token,
191
+ expiresAt: Date.now() + (tokens.expires_in * 1000)
192
+ }));
193
+ }
194
+
195
+ // Option 3: Memory only (cleared on refresh)
196
+ storeInMemory(tokens) {
197
+ this._tokens = tokens;
198
+ }
199
+ }
200
+ ```
201
+
202
+ ## Session Timeout Handling
203
+
204
+ ### Proactive Refresh
205
+
206
+ ```javascript
207
+ class SessionManager {
208
+ constructor() {
209
+ this.refreshTimer = null;
210
+ }
211
+
212
+ scheduleRefresh(expiresIn) {
213
+ // Clear existing timer
214
+ if (this.refreshTimer) {
215
+ clearTimeout(this.refreshTimer);
216
+ }
217
+
218
+ // Schedule refresh 5 minutes before expiry
219
+ const refreshIn = (expiresIn - 300) * 1000;
220
+
221
+ this.refreshTimer = setTimeout(() => {
222
+ this.refresh().catch(this.handleRefreshError);
223
+ }, refreshIn);
224
+ }
225
+
226
+ handleRefreshError(error) {
227
+ // Check if refresh token is also expired
228
+ if (error.message.includes('invalid_grant')) {
229
+ // Full re-authentication required
230
+ this.logout();
231
+ this.redirectToLogin();
232
+ }
233
+ }
234
+ }
235
+ ```
236
+
237
+ ### Activity-Based Extension
238
+
239
+ ```javascript
240
+ class ActivityTracker {
241
+ constructor(tokenManager) {
242
+ this.tokenManager = tokenManager;
243
+ this.lastActivity = Date.now();
244
+ this.activityTimeout = 15 * 60 * 1000; // 15 minutes
245
+
246
+ this.setupListeners();
247
+ }
248
+
249
+ setupListeners() {
250
+ ['click', 'keydown', 'scroll', 'mousemove'].forEach(event => {
251
+ window.addEventListener(event, () => this.recordActivity(), { passive: true });
252
+ });
253
+ }
254
+
255
+ recordActivity() {
256
+ const now = Date.now();
257
+ if (now - this.lastActivity > 60000) { // Throttle to 1 minute
258
+ this.lastActivity = now;
259
+ this.checkTokenRefresh();
260
+ }
261
+ }
262
+
263
+ checkTokenRefresh() {
264
+ if (this.tokenManager.shouldRefresh()) {
265
+ this.tokenManager.refresh();
266
+ }
267
+ }
268
+
269
+ isInactive() {
270
+ return Date.now() - this.lastActivity > this.activityTimeout;
271
+ }
272
+ }
273
+ ```
274
+
275
+ ## Guest to Registered Transition
276
+
277
+ When a guest user logs in, merge sessions:
278
+
279
+ ```javascript
280
+ async function loginWithSessionMerge(credentials, guestAccessToken) {
281
+ const response = await fetch(tokenEndpoint, {
282
+ method: 'POST',
283
+ headers: {
284
+ 'Content-Type': 'application/x-www-form-urlencoded',
285
+ // Include guest token for basket/session merge
286
+ 'Authorization': `Bearer ${guestAccessToken}`
287
+ },
288
+ body: new URLSearchParams({
289
+ grant_type: 'password',
290
+ username: credentials.username,
291
+ password: credentials.password,
292
+ client_id: clientId,
293
+ channel_id: siteId
294
+ })
295
+ });
296
+
297
+ // Returns registered user tokens
298
+ // Guest basket is automatically merged
299
+ return response.json();
300
+ }
301
+ ```
302
+
303
+ ## Logout and Token Revocation
304
+
305
+ ```javascript
306
+ async function logout(accessToken, refreshToken) {
307
+ // Revoke refresh token
308
+ await fetch(
309
+ `https://${shortCode}.api.commercecloud.salesforce.com/shopper/auth/v1/organizations/${orgId}/oauth2/revoke`,
310
+ {
311
+ method: 'POST',
312
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
313
+ body: new URLSearchParams({
314
+ token: refreshToken,
315
+ token_type_hint: 'refresh_token',
316
+ client_id: clientId,
317
+ channel_id: siteId
318
+ })
319
+ }
320
+ );
321
+
322
+ // Clear local storage
323
+ localStorage.removeItem('auth_tokens');
324
+
325
+ // Clear cookies if using BFF
326
+ await fetch('/api/auth/logout', {
327
+ method: 'POST',
328
+ credentials: 'include'
329
+ });
330
+ }
331
+ ```
332
+
333
+ ## Error Handling Reference
334
+
335
+ | Error | Meaning | Action |
336
+ |-------|---------|--------|
337
+ | `invalid_grant` | Refresh token expired/revoked | Re-authenticate |
338
+ | `invalid_token` | Access token invalid | Try refresh |
339
+ | `expired_token` | Access token expired | Refresh token |
340
+ | `invalid_client` | Client credentials wrong | Check configuration |
341
+ | `unauthorized_client` | Client not allowed | Check SLAS client settings |
342
+
343
+ ## Debugging Token Issues
344
+
345
+ ```javascript
346
+ // Decode JWT without validation (for debugging only)
347
+ function decodeToken(token) {
348
+ const parts = token.split('.');
349
+ if (parts.length !== 3) return null;
350
+
351
+ const payload = JSON.parse(atob(parts[1]));
352
+ return {
353
+ subject: payload.sub,
354
+ issuer: payload.iss,
355
+ audience: payload.aud,
356
+ expiresAt: new Date(payload.exp * 1000),
357
+ issuedAt: new Date(payload.iat * 1000),
358
+ scopes: payload.scope?.split(' ') || []
359
+ };
360
+ }
361
+
362
+ // Check if token is expired
363
+ function isTokenExpired(token) {
364
+ const decoded = decodeToken(token);
365
+ return decoded && Date.now() >= decoded.expiresAt.getTime();
366
+ }
367
+ ```