@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.
- package/bin/dev.js +8 -8
- package/bin/run.js +5 -7
- package/content/guidance/b2c/b2c-business-manager-extensions/SKILL.md +361 -0
- package/content/guidance/b2c/b2c-business-manager-extensions/references/EXTENSIONS-XML.md +458 -0
- package/content/guidance/b2c/b2c-controllers/SKILL.md +301 -0
- package/content/guidance/b2c/b2c-controllers/references/CLASSIC-PATTERNS.md +335 -0
- package/content/guidance/b2c/b2c-controllers/references/SFRA-PATTERNS.md +400 -0
- package/content/guidance/b2c/b2c-custom-api-development/SKILL.md +281 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/CONTRACT.md +142 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/IMPLEMENTATION.md +153 -0
- package/content/guidance/b2c/b2c-custom-api-development/references/TESTING.md +118 -0
- package/content/guidance/b2c/b2c-custom-caches/SKILL.md +279 -0
- package/content/guidance/b2c/b2c-custom-job-steps/SKILL.md +520 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/CHUNK-ORIENTED.md +377 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/JOBS-XML.md +212 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/STEPTYPES-JSON.md +373 -0
- package/content/guidance/b2c/b2c-custom-job-steps/references/TASK-ORIENTED.md +344 -0
- package/content/guidance/b2c/b2c-custom-objects/SKILL.md +327 -0
- package/content/guidance/b2c/b2c-custom-objects/references/OCAPI-SEARCH.md +298 -0
- package/content/guidance/b2c/b2c-forms/SKILL.md +242 -0
- package/content/guidance/b2c/b2c-forms/references/FORM-XML.md +409 -0
- package/content/guidance/b2c/b2c-hooks/SKILL.md +500 -0
- package/content/guidance/b2c/b2c-hooks/references/OCAPI-SCAPI-HOOKS.md +403 -0
- package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +169 -0
- package/content/guidance/b2c/b2c-hooks/references/SYSTEM-HOOKS.md +433 -0
- package/content/guidance/b2c/b2c-isml/SKILL.md +320 -0
- package/content/guidance/b2c/b2c-isml/references/EXPRESSIONS.md +366 -0
- package/content/guidance/b2c/b2c-isml/references/TAGS.md +443 -0
- package/content/guidance/b2c/b2c-localization/SKILL.md +344 -0
- package/content/guidance/b2c/b2c-localization/references/PATTERNS.md +407 -0
- package/content/guidance/b2c/b2c-logging/SKILL.md +352 -0
- package/content/guidance/b2c/b2c-logging/references/LOG-FILES.md +282 -0
- package/content/guidance/b2c/b2c-metadata/SKILL.md +406 -0
- package/content/guidance/b2c/b2c-metadata/references/SYSTEM-OBJECTS.md +320 -0
- package/content/guidance/b2c/b2c-metadata/references/XML-EXAMPLES.md +366 -0
- package/content/guidance/b2c/b2c-onboarding/SKILL.md +154 -0
- package/content/guidance/b2c/b2c-ordering/SKILL.md +391 -0
- package/content/guidance/b2c/b2c-page-designer/SKILL.md +410 -0
- package/content/guidance/b2c/b2c-page-designer/references/ATTRIBUTE-TYPES.md +436 -0
- package/content/guidance/b2c/b2c-page-designer/references/META-DEFINITIONS.md +340 -0
- package/content/guidance/b2c/b2c-querying-data/SKILL.md +289 -0
- package/content/guidance/b2c/b2c-querying-data/references/PERFORMANCE-APIS.md +74 -0
- package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +53 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +440 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/INTEGRATION-PATTERNS.md +518 -0
- package/content/guidance/b2c/b2c-scapi-admin/references/OAUTH-SCOPES.md +337 -0
- package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +56 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/CHECKOUT-FLOW.md +466 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +351 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/COMMON-PATTERNS.md +390 -0
- package/content/guidance/b2c/b2c-scapi-shopper/references/SCOPES.md +290 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/SKILL.md +420 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/PASSKEYS.md +126 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/SESSION-BRIDGE.md +267 -0
- package/content/guidance/b2c/b2c-slas-auth-patterns/references/TOKEN-LIFECYCLE.md +367 -0
- package/content/guidance/b2c/b2c-webservices/SKILL.md +318 -0
- package/content/guidance/b2c/b2c-webservices/references/FTP-SERVICES.md +524 -0
- package/content/guidance/b2c/b2c-webservices/references/HTTP-SERVICES.md +578 -0
- package/content/guidance/b2c/b2c-webservices/references/SERVICES-XML.md +351 -0
- package/content/guidance/b2c/b2c-webservices/references/SOAP-SERVICES.md +587 -0
- package/content/guidance/b2c-cli/b2c-am/SKILL.md +277 -0
- package/content/guidance/b2c-cli/b2c-bm-users-roles/SKILL.md +210 -0
- package/content/guidance/b2c-cli/b2c-cap/SKILL.md +131 -0
- package/content/guidance/b2c-cli/b2c-cip/SKILL.md +116 -0
- package/content/guidance/b2c-cli/b2c-cip/references/KNOWN_TABLES.md +105 -0
- package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +50 -0
- package/content/guidance/b2c-cli/b2c-cip/references/STARTER_QUERIES.md +147 -0
- package/content/guidance/b2c-cli/b2c-code/SKILL.md +146 -0
- package/content/guidance/b2c-cli/b2c-config/SKILL.md +481 -0
- package/content/guidance/b2c-cli/b2c-content/SKILL.md +176 -0
- package/content/guidance/b2c-cli/b2c-debug/SKILL.md +138 -0
- package/content/guidance/b2c-cli/b2c-docs/SKILL.md +301 -0
- package/content/guidance/b2c-cli/b2c-ecdn/SKILL.md +137 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +97 -0
- package/content/guidance/b2c-cli/b2c-ecdn/references/SECURITY.md +75 -0
- package/content/guidance/b2c-cli/b2c-import-set-migrations/SKILL.md +265 -0
- package/content/guidance/b2c-cli/b2c-job/SKILL.md +70 -0
- package/content/guidance/b2c-cli/b2c-job/references/EXPORT.md +121 -0
- package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +55 -0
- package/content/guidance/b2c-cli/b2c-job/references/RUN-AND-MONITOR.md +148 -0
- package/content/guidance/b2c-cli/b2c-logs/SKILL.md +249 -0
- package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +315 -0
- package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +207 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/BUNDLE-COMMANDS.md +203 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/ENVIRONMENT-COMMANDS.md +218 -0
- package/content/guidance/b2c-cli/b2c-mrt/references/PROJECT-COMMANDS.md +154 -0
- package/content/guidance/b2c-cli/b2c-sandbox/SKILL.md +112 -0
- package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +126 -0
- package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +70 -0
- package/content/guidance/b2c-cli/b2c-scapi-schemas/references/CLI-EXAMPLES.md +108 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +57 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/IMPORT-OPTIONS.md +118 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/METADATA-XML.md +381 -0
- package/content/guidance/b2c-cli/b2c-site-import-export/references/WORKFLOWS.md +182 -0
- package/content/guidance/b2c-cli/b2c-sites/SKILL.md +112 -0
- package/content/guidance/b2c-cli/b2c-slas/SKILL.md +182 -0
- package/content/guidance/b2c-cli/b2c-webdav/SKILL.md +186 -0
- package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +68 -0
- package/content/guidance/b2c-ops/b2c-edge-traffic-triage/SKILL.md +69 -0
- package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +80 -0
- package/content/guidance/b2c-ops/b2c-job-health/references/job-logs.md +21 -0
- package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +66 -0
- package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +87 -0
- package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +88 -0
- package/content/guidance/b2c-ops/b2c-production-triage/references/escalation.md +57 -0
- package/content/guidance/index.json +1969 -0
- package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
- package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +127 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/content/guidance/storefront-next/sfnext-components/SKILL.md +153 -0
- package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
- package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +163 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +140 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +39 -0
- package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +127 -0
- package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +59 -0
- package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +118 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +68 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +79 -0
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +93 -0
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +86 -0
- package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +152 -0
- package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
- package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
- package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +202 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +111 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +168 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/content/guidance/storefront-next/sfnext-performance/SKILL.md +102 -0
- package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +147 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
- package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/content/guidance/storefront-next/sfnext-routing/SKILL.md +123 -0
- package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +65 -0
- package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
- package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
- package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
- package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
- package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +114 -0
- package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
- package/content/guidance/storefront-next/sfnext-testing/SKILL.md +151 -0
- package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
- package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +97 -0
- package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
- package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/dist/commands/cap/install.d.ts +1 -0
- package/dist/commands/cap/list.d.ts +1 -0
- package/dist/commands/cap/pull.d.ts +1 -0
- package/dist/commands/cap/tasks.d.ts +1 -0
- package/dist/commands/cap/uninstall.d.ts +1 -0
- package/dist/commands/cip/describe.d.ts +1 -0
- package/dist/commands/cip/query.d.ts +1 -0
- package/dist/commands/cip/report/bot-traffic-share.d.ts +1 -0
- package/dist/commands/cip/report/checkout-funnel-dropoff.d.ts +1 -0
- package/dist/commands/cip/report/controller-error-rate-trend.d.ts +1 -0
- package/dist/commands/cip/report/controller-health-scorecard.d.ts +1 -0
- package/dist/commands/cip/report/customer-registration-trends.d.ts +1 -0
- package/dist/commands/cip/report/discount-depth-breakdown.d.ts +1 -0
- package/dist/commands/cip/report/inventory-stockout-by-location.d.ts +1 -0
- package/dist/commands/cip/report/new-vs-returning-buyer-revenue.d.ts +1 -0
- package/dist/commands/cip/report/ocapi-client-usage.d.ts +1 -0
- package/dist/commands/cip/report/ocapi-requests.d.ts +1 -0
- package/dist/commands/cip/report/payment-method-performance.d.ts +1 -0
- package/dist/commands/cip/report/product-co-purchase-analysis.d.ts +1 -0
- package/dist/commands/cip/report/promotion-discount-analysis.d.ts +1 -0
- package/dist/commands/cip/report/promotion-roi-leaderboard.d.ts +1 -0
- package/dist/commands/cip/report/recommender-effectiveness.d.ts +1 -0
- package/dist/commands/cip/report/remote-include-performance.d.ts +1 -0
- package/dist/commands/cip/report/revenue-by-channel.d.ts +1 -0
- package/dist/commands/cip/report/sales-analytics.d.ts +1 -0
- package/dist/commands/cip/report/sales-summary.d.ts +1 -0
- package/dist/commands/cip/report/scapi-cache-hit-ratio.d.ts +1 -0
- package/dist/commands/cip/report/scapi-error-rate-by-status.d.ts +1 -0
- package/dist/commands/cip/report/scapi-latency-distribution.d.ts +1 -0
- package/dist/commands/cip/report/scapi-traffic-latency.d.ts +1 -0
- package/dist/commands/cip/report/search-query-performance.d.ts +1 -0
- package/dist/commands/cip/report/top-referrers.d.ts +1 -0
- package/dist/commands/cip/report/top-selling-products.d.ts +1 -0
- package/dist/commands/cip/report/zero-result-searches.d.ts +1 -0
- package/dist/commands/cip/tables.d.ts +1 -0
- package/dist/commands/code/activate.d.ts +1 -0
- package/dist/commands/code/delete.d.ts +1 -0
- package/dist/commands/code/deploy.d.ts +1 -0
- package/dist/commands/code/download.d.ts +1 -0
- package/dist/commands/code/watch.d.ts +1 -0
- package/dist/commands/commands/search.d.ts +35 -0
- package/dist/commands/commands/search.js +85 -0
- package/dist/commands/commands/search.js.map +1 -0
- package/dist/commands/content/export.d.ts +1 -0
- package/dist/commands/content/list.d.ts +1 -0
- package/dist/commands/content/validate.d.ts +1 -0
- package/dist/commands/debug/cli.d.ts +1 -0
- package/dist/commands/debug/index.d.ts +1 -0
- package/dist/commands/docs/cache.d.ts +1 -0
- package/dist/commands/docs/download.d.ts +1 -0
- package/dist/commands/docs/read.d.ts +1 -0
- package/dist/commands/docs/schema.d.ts +1 -0
- package/dist/commands/docs/search.d.ts +1 -0
- package/dist/commands/docs/skill.d.ts +41 -0
- package/dist/commands/docs/skill.js +183 -0
- package/dist/commands/docs/skill.js.map +1 -0
- package/dist/commands/ecdn/cache/purge.d.ts +1 -0
- package/dist/commands/ecdn/certificates/add.d.ts +1 -0
- package/dist/commands/ecdn/certificates/delete.d.ts +1 -0
- package/dist/commands/ecdn/certificates/list.d.ts +1 -0
- package/dist/commands/ecdn/certificates/update.d.ts +1 -0
- package/dist/commands/ecdn/certificates/validate.d.ts +1 -0
- package/dist/commands/ecdn/cipher-suites/get.d.ts +1 -0
- package/dist/commands/ecdn/cipher-suites/update.d.ts +1 -0
- package/dist/commands/ecdn/firewall/create.d.ts +1 -0
- package/dist/commands/ecdn/firewall/delete.d.ts +1 -0
- package/dist/commands/ecdn/firewall/get.d.ts +1 -0
- package/dist/commands/ecdn/firewall/list.d.ts +1 -0
- package/dist/commands/ecdn/firewall/reorder.d.ts +1 -0
- package/dist/commands/ecdn/firewall/update.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/create.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/delete.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/get.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/list.d.ts +1 -0
- package/dist/commands/ecdn/logpush/jobs/update.d.ts +1 -0
- package/dist/commands/ecdn/logpush/ownership.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/create.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/delete.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/get.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/rules/delete.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/rules/update.d.ts +1 -0
- package/dist/commands/ecdn/mrt-rules/update.d.ts +1 -0
- package/dist/commands/ecdn/mtls/create.d.ts +1 -0
- package/dist/commands/ecdn/mtls/delete.d.ts +1 -0
- package/dist/commands/ecdn/mtls/get.d.ts +1 -0
- package/dist/commands/ecdn/mtls/issue.d.ts +1 -0
- package/dist/commands/ecdn/mtls/list.d.ts +1 -0
- package/dist/commands/ecdn/mtls/setup.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/delete.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/get.d.ts +1 -0
- package/dist/commands/ecdn/origin-headers/set.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/create.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/delete.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/notifications/list.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/create.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/delete.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/get.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/list.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/policies/update.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/scripts/get.d.ts +1 -0
- package/dist/commands/ecdn/page-shield/scripts/list.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/create.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/delete.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/get.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/list.d.ts +1 -0
- package/dist/commands/ecdn/rate-limit/update.d.ts +1 -0
- package/dist/commands/ecdn/security/get.d.ts +1 -0
- package/dist/commands/ecdn/security/update.d.ts +1 -0
- package/dist/commands/ecdn/speed/get.d.ts +1 -0
- package/dist/commands/ecdn/speed/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/groups/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/groups/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/managed-rules/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/managed-rules/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/migrate.d.ts +1 -0
- package/dist/commands/ecdn/waf/owasp/get.d.ts +1 -0
- package/dist/commands/ecdn/waf/owasp/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/get.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/rules/update.d.ts +1 -0
- package/dist/commands/ecdn/waf/rulesets/list.d.ts +1 -0
- package/dist/commands/ecdn/waf/rulesets/update.d.ts +1 -0
- package/dist/commands/ecdn/zones/create.d.ts +1 -0
- package/dist/commands/ecdn/zones/list.d.ts +1 -0
- package/dist/commands/job/execution/delete.d.ts +1 -0
- package/dist/commands/job/export.d.ts +1 -0
- package/dist/commands/job/import-set.d.ts +1 -0
- package/dist/commands/job/import.d.ts +1 -0
- package/dist/commands/job/log.d.ts +1 -0
- package/dist/commands/job/run.d.ts +1 -0
- package/dist/commands/job/run.js +1 -1
- package/dist/commands/job/run.js.map +1 -1
- package/dist/commands/job/search.d.ts +1 -0
- package/dist/commands/job/wait.d.ts +1 -0
- package/dist/commands/logs/get.d.ts +1 -0
- package/dist/commands/logs/list.d.ts +1 -0
- package/dist/commands/logs/tail.d.ts +1 -0
- package/dist/commands/metrics/controller.d.ts +1 -0
- package/dist/commands/metrics/ecdn.d.ts +1 -0
- package/dist/commands/metrics/mrt.d.ts +1 -0
- package/dist/commands/metrics/ocapi.d.ts +1 -0
- package/dist/commands/metrics/overall.d.ts +1 -0
- package/dist/commands/metrics/sales.d.ts +1 -0
- package/dist/commands/metrics/scapi-hooks.d.ts +1 -0
- package/dist/commands/metrics/scapi.d.ts +1 -0
- package/dist/commands/metrics/third-party.d.ts +1 -0
- package/dist/commands/mrt/bundle/delete.d.ts +1 -0
- package/dist/commands/mrt/bundle/deploy.d.ts +1 -0
- package/dist/commands/mrt/bundle/download.d.ts +1 -0
- package/dist/commands/mrt/bundle/history.d.ts +1 -0
- package/dist/commands/mrt/bundle/list.d.ts +1 -0
- package/dist/commands/mrt/bundle/save.d.ts +1 -0
- package/dist/commands/mrt/bundle/upload-v2.d.ts +1 -0
- package/dist/commands/mrt/env/access-control/list.d.ts +1 -0
- package/dist/commands/mrt/env/b2c.d.ts +1 -0
- package/dist/commands/mrt/env/clone.d.ts +1 -0
- package/dist/commands/mrt/env/create.d.ts +1 -0
- package/dist/commands/mrt/env/delete.d.ts +1 -0
- package/dist/commands/mrt/env/get.d.ts +1 -0
- package/dist/commands/mrt/env/invalidate.d.ts +1 -0
- package/dist/commands/mrt/env/list.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/clone.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/create.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/delete.d.ts +1 -0
- package/dist/commands/mrt/env/redirect/list.d.ts +1 -0
- package/dist/commands/mrt/env/update.d.ts +1 -0
- package/dist/commands/mrt/env/var/delete.d.ts +1 -0
- package/dist/commands/mrt/env/var/list.d.ts +1 -0
- package/dist/commands/mrt/env/var/push.d.ts +1 -0
- package/dist/commands/mrt/env/var/set.d.ts +1 -0
- package/dist/commands/mrt/org/b2c.d.ts +1 -0
- package/dist/commands/mrt/org/cert/create.d.ts +1 -0
- package/dist/commands/mrt/org/cert/delete.d.ts +1 -0
- package/dist/commands/mrt/org/cert/get.d.ts +1 -0
- package/dist/commands/mrt/org/cert/list.d.ts +1 -0
- package/dist/commands/mrt/org/cert/restart-validation.d.ts +1 -0
- package/dist/commands/mrt/org/list.d.ts +1 -0
- package/dist/commands/mrt/org/member/add.d.ts +1 -0
- package/dist/commands/mrt/org/member/get.d.ts +1 -0
- package/dist/commands/mrt/org/member/list.d.ts +1 -0
- package/dist/commands/mrt/org/member/remove.d.ts +1 -0
- package/dist/commands/mrt/org/member/update.d.ts +1 -0
- package/dist/commands/mrt/project/create.d.ts +1 -0
- package/dist/commands/mrt/project/delete.d.ts +1 -0
- package/dist/commands/mrt/project/get.d.ts +1 -0
- package/dist/commands/mrt/project/list.d.ts +1 -0
- package/dist/commands/mrt/project/member/add.d.ts +1 -0
- package/dist/commands/mrt/project/member/get.d.ts +1 -0
- package/dist/commands/mrt/project/member/list.d.ts +1 -0
- package/dist/commands/mrt/project/member/remove.d.ts +1 -0
- package/dist/commands/mrt/project/member/update.d.ts +1 -0
- package/dist/commands/mrt/project/notification/delete.d.ts +1 -0
- package/dist/commands/mrt/project/notification/get.d.ts +1 -0
- package/dist/commands/mrt/project/update.d.ts +1 -0
- package/dist/commands/mrt/save-credentials.d.ts +1 -0
- package/dist/commands/mrt/tail-logs.d.ts +1 -0
- package/dist/commands/mrt/user/api-key.d.ts +1 -0
- package/dist/commands/mrt/user/email-prefs.d.ts +1 -0
- package/dist/commands/mrt/user/profile.d.ts +1 -0
- package/dist/commands/scaffold/init.js +2 -1
- package/dist/commands/scaffold/init.js.map +1 -1
- package/dist/commands/scapi/custom/status.d.ts +1 -0
- package/dist/commands/scapi/schemas/get.d.ts +9 -0
- package/dist/commands/scapi/schemas/get.js +51 -19
- package/dist/commands/scapi/schemas/get.js.map +1 -1
- package/dist/commands/scapi/schemas/list.d.ts +6 -0
- package/dist/commands/scapi/schemas/list.js +28 -18
- package/dist/commands/scapi/schemas/list.js.map +1 -1
- package/dist/commands/setup/get.d.ts +36 -0
- package/dist/commands/setup/get.js +67 -0
- package/dist/commands/setup/get.js.map +1 -0
- package/dist/commands/setup/ide/tsserver-plugin.d.ts +1 -0
- package/dist/commands/setup/ide/vscode-types.d.ts +1 -0
- package/dist/commands/setup/index.js +4 -3
- package/dist/commands/setup/index.js.map +1 -1
- package/dist/commands/setup/inspect.d.ts +1 -0
- package/dist/commands/setup/inspect.js +15 -4
- package/dist/commands/setup/inspect.js.map +1 -1
- package/dist/commands/setup/instance/create.d.ts +9 -0
- package/dist/commands/setup/instance/create.js +22 -6
- package/dist/commands/setup/instance/create.js.map +1 -1
- package/dist/commands/setup/instance/list.d.ts +1 -0
- package/dist/commands/setup/instance/list.js +3 -4
- package/dist/commands/setup/instance/list.js.map +1 -1
- package/dist/commands/setup/instance/remove.d.ts +1 -0
- package/dist/commands/setup/instance/remove.js +5 -5
- package/dist/commands/setup/instance/remove.js.map +1 -1
- package/dist/commands/setup/instance/set-active.d.ts +6 -0
- package/dist/commands/setup/instance/set-active.js +20 -5
- package/dist/commands/setup/instance/set-active.js.map +1 -1
- package/dist/commands/setup/openshell.d.ts +1 -0
- package/dist/commands/setup/set.d.ts +37 -0
- package/dist/commands/setup/set.js +87 -0
- package/dist/commands/setup/set.js.map +1 -0
- package/dist/commands/setup/skills.d.ts +1 -0
- package/dist/commands/setup/unset.d.ts +37 -0
- package/dist/commands/setup/unset.js +55 -0
- package/dist/commands/setup/unset.js.map +1 -0
- package/dist/commands/slas/client/create.d.ts +1 -0
- package/dist/commands/slas/client/delete.d.ts +1 -0
- package/dist/commands/slas/client/get.d.ts +1 -0
- package/dist/commands/slas/client/list.d.ts +1 -0
- package/dist/commands/slas/client/open.d.ts +1 -0
- package/dist/commands/slas/client/update.d.ts +1 -0
- package/dist/commands/slas/token.d.ts +1 -0
- package/dist/commands/slas/token.js +2 -1
- package/dist/commands/slas/token.js.map +1 -1
- package/dist/commands/webdav/get.d.ts +1 -0
- package/dist/commands/webdav/rm.d.ts +1 -0
- package/dist/help.d.ts +25 -0
- package/dist/help.js +96 -0
- package/dist/help.js.map +1 -0
- package/dist/lib/scaffold/generate-helper.js +3 -2
- package/dist/lib/scaffold/generate-helper.js.map +1 -1
- package/dist/lib/skills.d.ts +19 -0
- package/dist/lib/skills.js +75 -0
- package/dist/lib/skills.js.map +1 -0
- package/dist/utils/cip/command.d.ts +1 -0
- package/dist/utils/ecdn/zone-command.d.ts +1 -0
- package/dist/utils/setup/config-field-command.d.ts +25 -0
- package/dist/utils/setup/config-field-command.js +41 -0
- package/dist/utils/setup/config-field-command.js.map +1 -0
- package/dist/utils/slas/client.d.ts +1 -0
- package/oclif.manifest.json +20802 -16968
- package/package.json +11 -5
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: b2c-controllers
|
|
3
|
+
description: Create storefront controllers using SFRA or classic patterns with server.get/post, middleware chains, and res.render/json. Use this skill whenever the user needs to build a page route, handle form submissions, create AJAX endpoints, extend or override existing controllers, or add middleware to a request pipeline. Also use when debugging route registration or response rendering -- even if they just say 'new page endpoint' or 'handle a POST request'.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Controllers Skill
|
|
7
|
+
|
|
8
|
+
This skill guides you through creating storefront controllers for Salesforce B2C Commerce. Controllers handle HTTP requests and render responses for the storefront.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Controllers are JavaScript modules that handle storefront requests. A controller URL has this structure:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
https://{domain}/on/demandware.store/Sites-{SiteName}-Site/{locale}/{ControllerName}-{FunctionName}
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Example:** `https://example.com/on/demandware.store/Sites-RefArch-Site/en_US/Home-Show`
|
|
19
|
+
|
|
20
|
+
## Two Controller Patterns
|
|
21
|
+
|
|
22
|
+
B2C Commerce supports two controller patterns:
|
|
23
|
+
|
|
24
|
+
| Pattern | When to Use | Module Style |
|
|
25
|
+
|---------|-------------|--------------|
|
|
26
|
+
| **SFRA** | Storefront Reference Architecture sites | `server` module with middleware |
|
|
27
|
+
| **Classic** | Non-SFRA sites, simple APIs | Direct exports with `.public = true` |
|
|
28
|
+
|
|
29
|
+
**SFRA is recommended** for most storefront development. Classic controllers are useful for simple endpoints or non-SFRA projects.
|
|
30
|
+
|
|
31
|
+
## File Location
|
|
32
|
+
|
|
33
|
+
Controllers reside in the cartridge's `controllers` directory:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
/my-cartridge
|
|
37
|
+
/cartridge
|
|
38
|
+
/controllers
|
|
39
|
+
Home.js # URL: Home-{function}
|
|
40
|
+
Product.js # URL: Product-{function}
|
|
41
|
+
Cart.js # URL: Cart-{function}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**Naming:** Controller filename becomes the URL prefix. `Home.js` handles `Home-*` requests.
|
|
45
|
+
|
|
46
|
+
## SFRA Controllers (Recommended)
|
|
47
|
+
|
|
48
|
+
SFRA controllers use the `server` module for routing and middleware:
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
'use strict';
|
|
52
|
+
|
|
53
|
+
var server = require('server');
|
|
54
|
+
|
|
55
|
+
// Handle GET request
|
|
56
|
+
server.get('Show', function (req, res, next) {
|
|
57
|
+
res.render('home/homepage');
|
|
58
|
+
next();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Handle POST request
|
|
62
|
+
server.post('Subscribe', function (req, res, next) {
|
|
63
|
+
var email = req.form.email;
|
|
64
|
+
// Process subscription...
|
|
65
|
+
res.json({ success: true });
|
|
66
|
+
next();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
module.exports = server.exports();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Request Object (req)
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
req.querystring // Query parameters: ?q=shoes -> req.querystring.q
|
|
76
|
+
req.form // Form POST data: req.form.email
|
|
77
|
+
req.httpMethod // HTTP method: 'GET', 'POST', etc.
|
|
78
|
+
req.httpHeaders // Request headers
|
|
79
|
+
req.currentCustomer // Current customer object
|
|
80
|
+
req.locale // Current locale
|
|
81
|
+
req.session // Session object
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Response Object (res)
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
res.render('template', model) // Render ISML template with data
|
|
88
|
+
res.json(object) // Return JSON response
|
|
89
|
+
res.redirect(url) // Redirect to URL
|
|
90
|
+
res.setViewData(data) // Add data to view model
|
|
91
|
+
res.getViewData() // Get current view model
|
|
92
|
+
res.setStatusCode(code) // Set HTTP status code
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Middleware
|
|
96
|
+
|
|
97
|
+
Apply middleware to routes for cross-cutting concerns:
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
var server = require('server');
|
|
101
|
+
var cache = require('*/cartridge/scripts/middleware/cache');
|
|
102
|
+
var consentTracking = require('*/cartridge/scripts/middleware/consentTracking');
|
|
103
|
+
var csrfProtection = require('*/cartridge/scripts/middleware/csrf');
|
|
104
|
+
|
|
105
|
+
// Apply caching
|
|
106
|
+
server.get('Show', cache.applyDefaultCache, function (req, res, next) {
|
|
107
|
+
res.render('home/homepage');
|
|
108
|
+
next();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Require HTTPS
|
|
112
|
+
server.post('Login', server.middleware.https, function (req, res, next) {
|
|
113
|
+
// Handle login...
|
|
114
|
+
next();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// CSRF protection for forms
|
|
118
|
+
server.post('Submit', csrfProtection.validateAjaxRequest, function (req, res, next) {
|
|
119
|
+
// Handle form submission...
|
|
120
|
+
next();
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Common Middleware
|
|
125
|
+
|
|
126
|
+
| Middleware | Purpose |
|
|
127
|
+
|------------|---------|
|
|
128
|
+
| `server.middleware.https` | Require HTTPS connection |
|
|
129
|
+
| `cache.applyDefaultCache` | Apply default page caching |
|
|
130
|
+
| `csrfProtection.validateAjaxRequest` | Validate CSRF token |
|
|
131
|
+
| `consentTracking.consent` | Check tracking consent |
|
|
132
|
+
| `userLoggedIn.validateLoggedIn` | Require authenticated user |
|
|
133
|
+
|
|
134
|
+
### Route Events
|
|
135
|
+
|
|
136
|
+
Execute code at specific points in the request lifecycle:
|
|
137
|
+
|
|
138
|
+
```javascript
|
|
139
|
+
server.post('Submit', function (req, res, next) {
|
|
140
|
+
var form = req.form;
|
|
141
|
+
res.setViewData({ email: form.email });
|
|
142
|
+
next();
|
|
143
|
+
}, function (req, res, next) {
|
|
144
|
+
// Additional middleware
|
|
145
|
+
next();
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Execute after all middleware, before render
|
|
149
|
+
this.on('route:BeforeComplete', function (req, res) {
|
|
150
|
+
var viewData = res.getViewData();
|
|
151
|
+
// Modify view data if needed
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Extending Controllers
|
|
156
|
+
|
|
157
|
+
Extend existing controllers to add or modify functionality:
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
'use strict';
|
|
161
|
+
|
|
162
|
+
var server = require('server');
|
|
163
|
+
var page = module.superModule; // Get parent controller
|
|
164
|
+
|
|
165
|
+
server.extend(page);
|
|
166
|
+
|
|
167
|
+
// Add new route
|
|
168
|
+
server.get('NewRoute', function (req, res, next) {
|
|
169
|
+
res.render('newtemplate');
|
|
170
|
+
next();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Override existing route
|
|
174
|
+
server.replace('Show', function (req, res, next) {
|
|
175
|
+
// Custom implementation
|
|
176
|
+
res.render('custom/homepage');
|
|
177
|
+
next();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Prepend to existing route
|
|
181
|
+
server.prepend('Show', function (req, res, next) {
|
|
182
|
+
// Runs before original handler
|
|
183
|
+
next();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Append to existing route
|
|
187
|
+
server.append('Show', function (req, res, next) {
|
|
188
|
+
// Runs after original handler
|
|
189
|
+
var viewData = res.getViewData();
|
|
190
|
+
viewData.customData = 'value';
|
|
191
|
+
res.setViewData(viewData);
|
|
192
|
+
next();
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
module.exports = server.exports();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Classic Controllers (Non-SFRA)
|
|
199
|
+
|
|
200
|
+
For non-SFRA sites or simple endpoints, use direct exports:
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
'use strict';
|
|
204
|
+
|
|
205
|
+
var ISML = require('dw/template/ISML');
|
|
206
|
+
|
|
207
|
+
exports.Show = function () {
|
|
208
|
+
var params = request.httpParameterMap;
|
|
209
|
+
var productId = params.pid.stringValue;
|
|
210
|
+
|
|
211
|
+
ISML.renderTemplate('product/detail', {
|
|
212
|
+
productId: productId
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
exports.Show.public = true; // Required: marks function as accessible
|
|
216
|
+
|
|
217
|
+
exports.GetData = function () {
|
|
218
|
+
var result = { status: 'ok', data: [] };
|
|
219
|
+
|
|
220
|
+
response.setContentType('application/json');
|
|
221
|
+
response.writer.print(JSON.stringify(result));
|
|
222
|
+
};
|
|
223
|
+
exports.GetData.public = true;
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
**Key difference:** Classic controllers use `exports.FunctionName.public = true` instead of the `server` module.
|
|
227
|
+
|
|
228
|
+
## Module Imports
|
|
229
|
+
|
|
230
|
+
Import B2C Commerce APIs using `require()`:
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
// B2C Commerce APIs
|
|
234
|
+
var ProductMgr = require('dw/catalog/ProductMgr');
|
|
235
|
+
var Transaction = require('dw/system/Transaction');
|
|
236
|
+
var Logger = require('dw/system/Logger');
|
|
237
|
+
var URLUtils = require('dw/web/URLUtils');
|
|
238
|
+
var Resource = require('dw/web/Resource');
|
|
239
|
+
|
|
240
|
+
// Cartridge modules (use */ for cartridge path resolution)
|
|
241
|
+
var collections = require('*/cartridge/scripts/util/collections');
|
|
242
|
+
var productHelper = require('*/cartridge/scripts/helpers/productHelpers');
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**Best Practice:** Only require modules when needed, not all at the top of the file.
|
|
246
|
+
|
|
247
|
+
## Error Handling
|
|
248
|
+
|
|
249
|
+
Wrap operations in try-catch blocks:
|
|
250
|
+
|
|
251
|
+
```javascript
|
|
252
|
+
server.get('Show', function (req, res, next) {
|
|
253
|
+
try {
|
|
254
|
+
var product = ProductMgr.getProduct(req.querystring.pid);
|
|
255
|
+
if (!product) {
|
|
256
|
+
res.setStatusCode(404);
|
|
257
|
+
res.render('error/notfound');
|
|
258
|
+
return next();
|
|
259
|
+
}
|
|
260
|
+
res.render('product/detail', { product: product });
|
|
261
|
+
} catch (e) {
|
|
262
|
+
Logger.error('Product error: ' + e.message);
|
|
263
|
+
res.setStatusCode(500);
|
|
264
|
+
res.render('error/general');
|
|
265
|
+
}
|
|
266
|
+
next();
|
|
267
|
+
});
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
## Generating URLs
|
|
271
|
+
|
|
272
|
+
Use URLUtils to generate locale-aware URLs:
|
|
273
|
+
|
|
274
|
+
```javascript
|
|
275
|
+
var URLUtils = require('dw/web/URLUtils');
|
|
276
|
+
|
|
277
|
+
// Controller URL
|
|
278
|
+
var productUrl = URLUtils.url('Product-Show', 'pid', 'ABC123');
|
|
279
|
+
// Result: /on/demandware.store/Sites-RefArch-Site/en_US/Product-Show?pid=ABC123
|
|
280
|
+
|
|
281
|
+
// HTTPS URL
|
|
282
|
+
var loginUrl = URLUtils.https('Login-Show');
|
|
283
|
+
|
|
284
|
+
// Static resource URL
|
|
285
|
+
var imageUrl = URLUtils.staticURL('/images/logo.png');
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Best Practices
|
|
289
|
+
|
|
290
|
+
1. **Always call `next()`** in SFRA middleware chain
|
|
291
|
+
2. **Use ViewModels** to prepare data for templates
|
|
292
|
+
3. **Keep controllers thin** - move business logic to scripts/helpers
|
|
293
|
+
4. **Use hooks** for functionality that works for both storefront and OCAPI
|
|
294
|
+
5. **Handle errors gracefully** - never expose stack traces
|
|
295
|
+
6. **Use `*/cartridge/...`** for portable module paths
|
|
296
|
+
|
|
297
|
+
## Detailed Reference
|
|
298
|
+
|
|
299
|
+
For comprehensive patterns and examples:
|
|
300
|
+
- [SFRA Patterns](references/SFRA-PATTERNS.md) - Full SFRA patterns with middleware
|
|
301
|
+
- [Classic Patterns](references/CLASSIC-PATTERNS.md) - Non-SFRA controller patterns
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Classic Controller Patterns
|
|
2
|
+
|
|
3
|
+
Patterns for non-SFRA controllers using direct exports with `.public = true`.
|
|
4
|
+
|
|
5
|
+
## When to Use Classic Controllers
|
|
6
|
+
|
|
7
|
+
- Non-SFRA (pipelines-based) storefronts
|
|
8
|
+
- Simple REST-like endpoints
|
|
9
|
+
- Quick prototypes
|
|
10
|
+
- Legacy integrations
|
|
11
|
+
|
|
12
|
+
## Basic Structure
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
var ISML = require('dw/template/ISML');
|
|
18
|
+
|
|
19
|
+
exports.Show = function () {
|
|
20
|
+
ISML.renderTemplate('home/homepage', {
|
|
21
|
+
pageTitle: 'Welcome'
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
exports.Show.public = true; // Required for URL access
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Key:** Every exported function must have `.public = true` to be accessible via URL.
|
|
28
|
+
|
|
29
|
+
## Request Handling
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
exports.GetProduct = function () {
|
|
33
|
+
// Query parameters
|
|
34
|
+
var params = request.httpParameterMap;
|
|
35
|
+
var productId = params.pid.stringValue;
|
|
36
|
+
var quantity = params.qty.intValue || 1;
|
|
37
|
+
|
|
38
|
+
// Check if parameter exists
|
|
39
|
+
if (params.isParameterSubmitted('pid')) {
|
|
40
|
+
// Parameter was provided
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Form data (POST)
|
|
44
|
+
var email = params.email.stringValue;
|
|
45
|
+
|
|
46
|
+
// HTTP method
|
|
47
|
+
var method = request.httpMethod; // 'GET', 'POST', etc.
|
|
48
|
+
|
|
49
|
+
// Headers
|
|
50
|
+
var contentType = request.httpHeaders.get('content-type');
|
|
51
|
+
|
|
52
|
+
ISML.renderTemplate('product/detail', {
|
|
53
|
+
productId: productId,
|
|
54
|
+
quantity: quantity
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
exports.GetProduct.public = true;
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Response Types
|
|
61
|
+
|
|
62
|
+
### HTML Response (ISML)
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
var ISML = require('dw/template/ISML');
|
|
66
|
+
|
|
67
|
+
exports.ShowPage = function () {
|
|
68
|
+
ISML.renderTemplate('path/to/template', {
|
|
69
|
+
data: 'value'
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
exports.ShowPage.public = true;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### JSON Response
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
exports.GetData = function () {
|
|
79
|
+
var result = {
|
|
80
|
+
success: true,
|
|
81
|
+
items: [],
|
|
82
|
+
count: 0
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
response.setContentType('application/json');
|
|
86
|
+
response.writer.print(JSON.stringify(result));
|
|
87
|
+
};
|
|
88
|
+
exports.GetData.public = true;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### XML Response
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
exports.GetXML = function () {
|
|
95
|
+
var xml = '<?xml version="1.0"?><data><item>value</item></data>';
|
|
96
|
+
|
|
97
|
+
response.setContentType('application/xml');
|
|
98
|
+
response.writer.print(xml);
|
|
99
|
+
};
|
|
100
|
+
exports.GetXML.public = true;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Redirect
|
|
104
|
+
|
|
105
|
+
```javascript
|
|
106
|
+
var URLUtils = require('dw/web/URLUtils');
|
|
107
|
+
|
|
108
|
+
exports.Redirect = function () {
|
|
109
|
+
response.redirect(URLUtils.url('Home-Show'));
|
|
110
|
+
};
|
|
111
|
+
exports.Redirect.public = true;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Status Codes
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
exports.NotFound = function () {
|
|
118
|
+
response.setStatus(404);
|
|
119
|
+
ISML.renderTemplate('error/notfound');
|
|
120
|
+
};
|
|
121
|
+
exports.NotFound.public = true;
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Error Handling
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
var Logger = require('dw/system/Logger');
|
|
128
|
+
|
|
129
|
+
exports.ProcessOrder = function () {
|
|
130
|
+
try {
|
|
131
|
+
var params = request.httpParameterMap;
|
|
132
|
+
var orderId = params.orderID.stringValue;
|
|
133
|
+
|
|
134
|
+
if (!orderId) {
|
|
135
|
+
response.setStatus(400);
|
|
136
|
+
response.setContentType('application/json');
|
|
137
|
+
response.writer.print(JSON.stringify({
|
|
138
|
+
error: true,
|
|
139
|
+
message: 'Order ID required'
|
|
140
|
+
}));
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Process order...
|
|
145
|
+
|
|
146
|
+
response.setContentType('application/json');
|
|
147
|
+
response.writer.print(JSON.stringify({ success: true }));
|
|
148
|
+
|
|
149
|
+
} catch (e) {
|
|
150
|
+
Logger.error('Order processing error: ' + e.message);
|
|
151
|
+
response.setStatus(500);
|
|
152
|
+
response.setContentType('application/json');
|
|
153
|
+
response.writer.print(JSON.stringify({
|
|
154
|
+
error: true,
|
|
155
|
+
message: 'Internal error'
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
exports.ProcessOrder.public = true;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Database Operations
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
var Transaction = require('dw/system/Transaction');
|
|
166
|
+
var ProductMgr = require('dw/catalog/ProductMgr');
|
|
167
|
+
|
|
168
|
+
exports.UpdateProduct = function () {
|
|
169
|
+
var params = request.httpParameterMap;
|
|
170
|
+
var pid = params.pid.stringValue;
|
|
171
|
+
var product = ProductMgr.getProduct(pid);
|
|
172
|
+
|
|
173
|
+
if (!product) {
|
|
174
|
+
response.setStatus(404);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
Transaction.wrap(function () {
|
|
179
|
+
product.custom.lastViewed = new Date();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
response.setContentType('application/json');
|
|
183
|
+
response.writer.print(JSON.stringify({ updated: true }));
|
|
184
|
+
};
|
|
185
|
+
exports.UpdateProduct.public = true;
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## HTTPS Enforcement
|
|
189
|
+
|
|
190
|
+
```javascript
|
|
191
|
+
exports.SecurePage = function () {
|
|
192
|
+
if (!request.isHttpSecure()) {
|
|
193
|
+
var URLUtils = require('dw/web/URLUtils');
|
|
194
|
+
response.redirect(URLUtils.https('Controller-SecurePage'));
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
ISML.renderTemplate('secure/page');
|
|
199
|
+
};
|
|
200
|
+
exports.SecurePage.public = true;
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
## Authentication Check
|
|
204
|
+
|
|
205
|
+
```javascript
|
|
206
|
+
var CustomerMgr = require('dw/customer/CustomerMgr');
|
|
207
|
+
|
|
208
|
+
exports.AccountPage = function () {
|
|
209
|
+
var customer = session.customer;
|
|
210
|
+
|
|
211
|
+
if (!customer.authenticated) {
|
|
212
|
+
var URLUtils = require('dw/web/URLUtils');
|
|
213
|
+
response.redirect(URLUtils.url('Login-Show'));
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
ISML.renderTemplate('account/dashboard', {
|
|
218
|
+
customer: customer
|
|
219
|
+
});
|
|
220
|
+
};
|
|
221
|
+
exports.AccountPage.public = true;
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Complete Example
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
'use strict';
|
|
228
|
+
|
|
229
|
+
var ISML = require('dw/template/ISML');
|
|
230
|
+
var Transaction = require('dw/system/Transaction');
|
|
231
|
+
var ProductMgr = require('dw/catalog/ProductMgr');
|
|
232
|
+
var BasketMgr = require('dw/order/BasketMgr');
|
|
233
|
+
var URLUtils = require('dw/web/URLUtils');
|
|
234
|
+
var Logger = require('dw/system/Logger');
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Display product detail page
|
|
238
|
+
*/
|
|
239
|
+
exports.Show = function () {
|
|
240
|
+
var params = request.httpParameterMap;
|
|
241
|
+
var pid = params.pid.stringValue;
|
|
242
|
+
|
|
243
|
+
var product = ProductMgr.getProduct(pid);
|
|
244
|
+
|
|
245
|
+
if (!product || !product.online) {
|
|
246
|
+
response.setStatus(404);
|
|
247
|
+
ISML.renderTemplate('error/notfound');
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
ISML.renderTemplate('product/detail', {
|
|
252
|
+
product: product,
|
|
253
|
+
quantity: params.qty.intValue || 1
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
exports.Show.public = true;
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Add product to cart (AJAX)
|
|
260
|
+
*/
|
|
261
|
+
exports.AddToCart = function () {
|
|
262
|
+
var params = request.httpParameterMap;
|
|
263
|
+
var pid = params.pid.stringValue;
|
|
264
|
+
var qty = params.qty.intValue || 1;
|
|
265
|
+
|
|
266
|
+
try {
|
|
267
|
+
var product = ProductMgr.getProduct(pid);
|
|
268
|
+
if (!product) {
|
|
269
|
+
sendJSON({ success: false, error: 'Product not found' }, 404);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
var basket = BasketMgr.getCurrentOrNewBasket();
|
|
274
|
+
|
|
275
|
+
Transaction.wrap(function () {
|
|
276
|
+
var pli = basket.createProductLineItem(pid, basket.defaultShipment);
|
|
277
|
+
pli.setQuantityValue(qty);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
sendJSON({
|
|
281
|
+
success: true,
|
|
282
|
+
cartCount: basket.productQuantityTotal
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
} catch (e) {
|
|
286
|
+
Logger.error('Add to cart error: ' + e.message);
|
|
287
|
+
sendJSON({ success: false, error: 'Unable to add to cart' }, 500);
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
exports.AddToCart.public = true;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Get product availability (AJAX)
|
|
294
|
+
*/
|
|
295
|
+
exports.GetAvailability = function () {
|
|
296
|
+
var params = request.httpParameterMap;
|
|
297
|
+
var pid = params.pid.stringValue;
|
|
298
|
+
|
|
299
|
+
var product = ProductMgr.getProduct(pid);
|
|
300
|
+
if (!product) {
|
|
301
|
+
sendJSON({ available: false }, 404);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
var availability = product.availabilityModel;
|
|
306
|
+
sendJSON({
|
|
307
|
+
available: availability.inStock,
|
|
308
|
+
quantity: availability.inventoryRecord ? availability.inventoryRecord.ATS.value : 0
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
exports.GetAvailability.public = true;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Helper: Send JSON response
|
|
315
|
+
*/
|
|
316
|
+
function sendJSON(data, status) {
|
|
317
|
+
if (status) {
|
|
318
|
+
response.setStatus(status);
|
|
319
|
+
}
|
|
320
|
+
response.setContentType('application/json');
|
|
321
|
+
response.writer.print(JSON.stringify(data));
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Comparison: Classic vs SFRA
|
|
326
|
+
|
|
327
|
+
| Aspect | Classic | SFRA |
|
|
328
|
+
|--------|---------|------|
|
|
329
|
+
| Public access | `exports.fn.public = true` | Automatic via `server` |
|
|
330
|
+
| Request data | `request.httpParameterMap` | `req.querystring`, `req.form` |
|
|
331
|
+
| Render HTML | `ISML.renderTemplate()` | `res.render()` |
|
|
332
|
+
| Return JSON | `response.writer.print()` | `res.json()` |
|
|
333
|
+
| Middleware | Manual checks | Built-in middleware chain |
|
|
334
|
+
| Controller extension | Not supported | `module.superModule` |
|
|
335
|
+
| Route events | Not available | `this.on('route:BeforeComplete')` |
|