{
  "features": {
    "cms-toolkit": {
      "name": "CMS Toolkit",
      "package": "@salesforce/ui-bundle-template-feature-cms-toolkit",
      "shortDescription": "Framework-agnostic APIs for reading Salesforce CMS delivery content (by public URL or contentKey, single or bulk) and decoding RichText.",
      "longDescription": "Pure TypeScript library — no React/Angular/Vue — for reading Salesforce CMS delivery content. Provides unauthenticated public-URL reads (public CDN), authenticated by-contentKey reads (single and bulk) via the Connect API, CMS image-field URL resolution, RichText HTML-entity decoding, catalog-driven channel resolution, and source→target contentKey remapping (so one build runs against any org without re-baking keys). Consumers call the exported functions directly from their own framework pages; framework-specific renderers live in the consuming app, not here. The public surface is additive-only: new capability arrives as new optional options, new named exports, or new error subclasses — never as a changed signature.",
      "keywords": [
        "cms",
        "content",
        "delivery",
        "richtext",
        "connect api",
        "contentKey",
        "channel",
        "image",
        "framework-agnostic"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/platform-sdk": "^11.51.0",
        "@salesforce/ui-bundle": "^11.51.0"
      },
      "copy": [
        {
          "from": "src/force-app/main/default/uiBundles/feature-cms-toolkit/src/features/cmsToolkit",
          "to": "<uiBundleDir>/src/features/cmsToolkit",
          "description": "CMS delivery API (public + authenticated Connect transports), catalog loader, image URL and RichText decode utilities, and shared types"
        },
        {
          "from": "src/force-app/main/default/uiBundles/feature-cms-toolkit/src/index.ts",
          "to": "<uiBundleDir>/src/__example__index.ts",
          "description": "Barrel of public exports — re-export the functions and types you need from your own app entry point",
          "integrationTarget": "src/index.ts"
        }
      ],
      "features": [
        "getCmsContentByUrl — read a public CMS delivery URL (unauthenticated CDN)",
        "getCmsContentByKey — read one item by contentKey via the authenticated Connect API (throws on miss)",
        "getCmsContentByKeys — bulk read many contentKeys in one call (best-effort; per-key error/result)",
        "resolveCmsImageUrl — resolve a CMS image field to a loadable URL (external or root-relative, origin-prefixed); synchronous and localizes root-relative media via the language chain",
        "resolveCmsLanguage — async: resolve the active delivery language (explicit → SFDC_ENV.language → platform-sdk i18n) and warm the cache",
        "getResolvedCmsLanguage — sync: read the active language (explicit → SFDC_ENV.language → warmed i18n); backs the synchronous resolveCmsImageUrl",
        "localiseMediaUrl — sync: read the active language (via getResolvedCmsLanguage) and append it to a directly-passed media URL (render-time sibling of resolveCmsImageUrl)",
        "localiseCmsUrl — async: resolve the active language (performing the i18n fetch if needed) and append it to a directly-passed content/media URL",
        "appendLanguageParam — sync/pure: set or override the language query param on a URL (removes duplicates; otherwise byte-for-byte)",
        "resolveEffectiveContentKey — remap a baked-in source contentKey to the deployed org's target key via the catalog",
        "getCmsDefaultChannelId — read the catalog's default channelId (fail-open; undefined when absent)",
        "decodeRichHtmlEntities — decode entity-encoded RichText to literal characters before sanitize + injection",
        "getCmsInstanceOrigin — read the instance origin used to prefix root-relative media URLs",
        "Catalog loader — fail-open, fetch-once channelId and contentKey-map resolution from content-metadata.json",
        "Typed error subclasses (CmsDeliveryError, CmsDeliveryNotFoundError, ConnectApiError, CmsNotFoundError) stable for instanceof checks"
      ],
      "components": [
        "getCmsContentByUrl / getCmsContentByKey / getCmsContentByKeys - CMS delivery read functions",
        "resolveCmsImageUrl - CMS image field → loadable URL resolver (synchronous)",
        "resolveCmsLanguage / getResolvedCmsLanguage - active delivery language resolvers (async warm / sync read)",
        "localiseMediaUrl / localiseCmsUrl / appendLanguageParam - URL language-param localizers (sync / async / sync-pure)",
        "resolveEffectiveContentKey - catalog source→target contentKey remapper",
        "getCmsDefaultChannelId - catalog default channelId accessor (fail-open)",
        "decodeRichHtmlEntities - RichText HTML-entity decoder (single pass, no DOM)",
        "getCmsInstanceOrigin - instance origin accessor for media prefixing",
        "CmsReadOptions (incl. language) / CmsImageOptions / ResolveLocaleOptions / CmsBulkResult / CmsContentBody / CmsImageField / CmsContentCatalog - shared types",
        "CmsDeliveryError / CmsDeliveryNotFoundError / ConnectApiError / CmsNotFoundError - typed errors"
      ]
    },
    "authentication": {
      "name": "Authentication",
      "package": "@salesforce/ui-bundle-template-feature-react-authentication",
      "shortDescription": "Complete user authentication system with login, registration, and password management",
      "longDescription": "Complete user authentication system with login, registration, and password reset flows. Includes protected route guards, session management, and authentication context providers. Handles user state across the application with secure token storage and automatic session refresh. Features include: AuthContext for managing auth state, PrivateRoute component for protecting authenticated-only pages, authentication pages (Login, Register, Profile, Forgot Password, Reset Password, Change Password), and backend Apex classes for authentication handling.",
      "keywords": [
        "login",
        "register",
        "password reset",
        "protected routes",
        "auth",
        "session",
        "user management"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/platform-sdk": "^4.0.0",
        "@salesforce/ui-bundle": "^4.0.0",
        "@tanstack/react-form": "^1.28.3",
        "zod": "^4.3.6"
      },
      "copy": [
        {
          "from": "force-app/main/default/classes",
          "to": "<sfdxRoot>/classes",
          "description": "Apex authentication handler classes"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-authentication/src/features/authentication",
          "to": "<uiBundleDir>/src/features/authentication",
          "description": "Authentication components, context, and pages"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-authentication/src/routes.tsx",
          "to": "<uiBundleDir>/src/features/authentication/__example__authentication-routes.tsx",
          "description": "Example showing how to add authentication routes",
          "integrationTarget": "src/routes.tsx"
        }
      ],
      "features": [
        "Checks authentication status via Salesforce Chatter API (/chatter/users/me)",
        "Protects routes with automatic redirect to login",
        "Supports return URL (retUrl) query parameter for post-login navigation",
        "Session timeout with configurable duration",
        "Password strength validation",
        "Forgot password and reset password flows",
        "User profile display",
        "Change password functionality"
      ],
      "components": [
        "AuthContext - React context for managing authentication state",
        "AuthMenu - Composable authentication menu with login/logout dropdown",
        "PrivateRoute - Route protection for authenticated-only pages",
        "AuthenticationRoute - Route layout that redirects authenticated users",
        "Login - Login page component",
        "Register - Registration page component",
        "Profile - User profile page",
        "ForgotPassword - Password recovery flow",
        "ResetPassword - Password reset page",
        "ChangePassword - Password change page"
      ]
    },
    "language-switcher": {
      "name": "Language Switcher",
      "package": "@salesforce/ui-bundle-template-feature-react-language-switcher",
      "shortDescription": "B2X language switcher that rewrites the URL language segment and reloads the page",
      "longDescription": "A drop-in <LanguageSwitcher /> control for public B2X (Experience) apps. It renders a labeled <select> of the site's supported languages; selecting one rewrites the current URL so the chosen language becomes the first path segment after basePath, then reloads the page at that new URL. A full reload lets the platform serve the correctly localized content — the feature owns only URL rewriting, not translation loading or i18n state. The current language is read from globalThis.SFDC_ENV.language, falling back to a default when absent or unrecognized. The list of available languages is hardcoded (in languages.ts) and manually kept in sync with the site's digitalExperiences/site/<siteName>/sfdc_cms__languageSettings/content.json, since there is no runtime API to read language settings on a published site. For LOCAL DEVELOPMENT, the feature integrates with the site entry of @salesforce/vite-plugin-ui-bundle: switch your vite.config.ts to import @salesforce/vite-plugin-ui-bundle/site and pass the supported LANGUAGES, and the dev server will inject SFDC_ENV.language and a language-prefixed basePath per request (mirroring production) so switching works locally without a server restart. This feature is intended for B2X apps only; B2E (internal) apps derive language from the logged-in user's profile and have no language URL segment.",
      "keywords": [
        "language",
        "language switcher",
        "locale",
        "localization",
        "i18n",
        "b2x",
        "url"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "react": "^19.2.1",
        "react-router": "^7.15.1"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/features/language-switcher",
          "to": "<uiBundleDir>/src/features/language-switcher",
          "description": "Language switcher library: <LanguageSwitcher /> component, hardcoded language list, and the pure buildLanguageUrl URL-rewriting utility"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/types/globals.d.ts",
          "to": "<uiBundleDir>/src/types/language-switcher-globals.d.ts",
          "description": "Ambient augmentation adding the optional SFDC_ENV.language field the switcher reads"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/features/language-switcher/__examples__/language-switcher-example.tsx",
          "to": "<uiBundleDir>/src/features/language-switcher/__examples__/language-switcher-example.tsx",
          "description": "Example showing how to mount <LanguageSwitcher /> in an app header/layout",
          "integrationTarget": "src/appLayout.tsx"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-language-switcher/src/features/language-switcher/__examples__/vite-config-site-example.ts",
          "to": "<uiBundleDir>/src/features/language-switcher/__examples__/vite-config-site-example.ts",
          "description": "Example showing how to switch vite.config.ts to the @salesforce/vite-plugin-ui-bundle/site entry so language switching works in local dev (inject SFDC_ENV.language + language-prefixed basePath)",
          "integrationTarget": "vite.config.ts"
        }
      ],
      "features": [
        "Rewrites the URL so the chosen language is the first path segment after basePath, then reloads",
        "Replaces an existing known language segment instead of stacking a new one",
        "Serves the default language un-prefixed: switching to it removes the language segment",
        "Preserves the rest of the path, the query string, and the hash when rewriting",
        "Reads the current language from SFDC_ENV.language with a safe default fallback",
        "Hardcoded language list kept in sync with the site's sfdc_cms__languageSettings content.json",
        "No-ops when the selected language already matches the current one",
        "Local dev: integrates with @salesforce/vite-plugin-ui-bundle/site to inject SFDC_ENV.language + a language-prefixed basePath per request, so switching works locally without a server restart"
      ],
      "components": [
        "LanguageSwitcher - Drop-in labeled <select> that switches language via URL rewrite + reload",
        "buildLanguageUrl - Pure helper that inserts/replaces/removes the leading language path segment",
        "getCurrentLanguage - Resolves the active language from SFDC_ENV with default fallback",
        "LANGUAGES - Typed list of supported languages ({ code, label })",
        "DEFAULT_LANGUAGE - Default language code used when SFDC_ENV.language is missing/unknown"
      ]
    },
    "mfa": {
      "name": "MFA",
      "package": "@salesforce/ui-bundle-template-feature-react-mfa",
      "shortDescription": "Enable Multi-Factor Authentication for Experience Cloud React sites",
      "longDescription": "Deploys permission sets to enable MFA enforcement for community users. Includes MFA_Required_For_Community (ForceTwoFactor) and API_Enabled_For_Community (ApiEnabled). The platform MFA challenge UI handles the actual verification flow automatically — no custom React component is needed. Supports TOTP, Salesforce Authenticator, WebAuthn, SMS, and Email OTP verification methods.",
      "keywords": [
        "mfa",
        "multi-factor",
        "authentication",
        "security",
        "2fa",
        "totp",
        "permission set",
        "ForceTwoFactor"
      ],
      "featureDependencies": [],
      "packageDependencies": {},
      "packageDevDependencies": {},
      "copy": [
        {
          "from": "src/force-app/main/default/permissionsets",
          "to": "<sfdxSource>/permissionsets",
          "description": "MFA and API Enabled permission sets for community users"
        }
      ],
      "features": [
        "Permission set: MFA_Required_For_Community (enforces MFA at login via ForceTwoFactor)",
        "Permission set: API_Enabled_For_Community (enables REST API access for React sites)",
        "Works with platform OOTB MFA challenge UI (no custom React page needed)",
        "Supports TOTP, SMS, Email, Salesforce Authenticator, and WebAuthn verification methods"
      ],
      "components": []
    },
    "search": {
      "name": "Search (Beta)",
      "package": "@salesforce/ui-bundle-template-feature-react-search",
      "shortDescription": "[Beta] Configuration-driven multi-source (multi-object) search with one query box, per-source filters/sort, and global or per-source pagination over GraphQL",
      "longDescription": "[Beta — API may change in a future release] Configuration-driven unified search across multiple Salesforce objects from a single query box. The application declares a SearchConfig with one entry per searchable SObject source; the library handles query construction, per-source filter/sort/pagination state, URL sync, and a single batched multi-aliased GraphQL request that fans out across every source. Supports two pagination models: per-source cursor pagination (each source advances its own Relay cursor) and merged/global pagination (the cumulative result set is windowed into fixed pages of pageSize). Provides a drop-in <Search> component plus lower-level primitives (useSearch hook, SearchBar, SearchResults, ScopeSelector, sort and pagination controls) and a configuration-driven filter panel (text, select, multi-select, numeric range, date range, boolean). Results can render one section per source or as a single combined grid via mergedResults, and a scope selector narrows the search to a single object or 'all'.",
      "keywords": [
        "search",
        "multi-object",
        "unified search",
        "global search",
        "filter",
        "sort",
        "pagination",
        "GraphQL",
        "scope",
        "multi-source",
        "beta"
      ],
      "featureDependencies": [],
      "packageDependencies": {
        "@salesforce/platform-sdk": "^11.2.0",
        "lucide-react": "^0.562.0",
        "react-router": "^7.10.1"
      },
      "copy": [
        {
          "from": "force-app/main/default/uiBundles/feature-react-search/src/features/search",
          "to": "<uiBundleDir>/src/features/search",
          "description": "Multi-source search library: useSearch hook, drop-in <Search> component, scope selector, filter panel, sort and pagination controls, query builder, GraphQL search service, and the example config.json"
        },
        {
          "from": "force-app/main/default/uiBundles/feature-react-search/src/pages/Home.tsx",
          "to": "<uiBundleDir>/src/features/search/__examples__/search-page-example.tsx",
          "description": "Example page rendering the drop-in <Search config={config} /> — shows how to mount the search experience on a route",
          "integrationTarget": "src/routes.tsx"
        }
      ],
      "features": [
        "Configuration-driven multi-object search from a single query box",
        "One batched multi-aliased GraphQL request fans out across all in-scope sources",
        "Two pagination models: per-source cursor pagination and merged/global fixed-size pagination",
        "Merge ordering for the combined result list: sequential, interleaved, or proportional",
        "Scope selector to narrow the search to a single object or search across all",
        "Per-source structured filters: text, select, multi-select, numeric range, date range, boolean",
        "Per-source sort controls with configurable sort fields and default sort",
        "URL-synced query, scope, filters, sort, and pagination for bookmarkable/shareable searches",
        "Drop-in <Search> component (one section per source) plus low-level primitives for custom layouts",
        "mergedResults for rendering a single combined cross-source grid",
        "Extensible adapter boundary — SObject sources today, room for CMS/REST adapters"
      ],
      "components": [
        "Search - Drop-in multi-source search experience (search bar, scope, sections, pagination)",
        "useSearch - Hook orchestrating query, scope, per-source filter/sort/pagination, URL sync, and fetch",
        "SearchBar - Global query input driving every source",
        "ScopeSelector - Dropdown to narrow search scope to one source or 'all'",
        "SearchResults - Renders in-scope source results",
        "SourceSection - One result section for a single source",
        "SortControl - Per-source sort field and direction dropdown",
        "PaginationControls - Pagination with page navigation and configurable page size",
        "DefaultFilterPanel - Sidebar panel rendering filter controls from config",
        "DefaultResultRow - Default renderer for a single result node",
        "ActiveFilters - Chip display of active filters with removal",
        "FilterContext - FilterProvider and hooks (useFilterField, useFilterPanel) for custom filter UIs",
        "TextFilter - Debounced text input filter",
        "SelectFilter - Single-select picklist filter",
        "MultiSelectFilter - Multi-select picklist filter",
        "NumericRangeFilter - Min/max numeric range filter",
        "DateRangeFilter - Date range filter with start/end pickers",
        "BooleanFilter - Boolean toggle filter",
        "useDistinctValues - Hook for fetching distinct picklist values",
        "useAsyncData - Hook for async data fetching with loading/error states",
        "queryBuilder - Builds the multi-aliased GraphQL document and variables",
        "searchService - Runs the batched GraphQL search and parses per-source results",
        "filterUtils / sortUtils / fieldUtils - URL serialization, GraphQL filter/order building, field extraction"
      ]
    }
  }
}
