@salesforce/templates 66.13.5 → 66.13.7

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 (281) hide show
  1. package/lib/templates/project/angularextapp/CHANGELOG.md +258 -0
  2. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/angular.json +1 -1
  3. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
  4. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
  5. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package-lock.json +680 -408
  6. package/lib/templates/project/angularextapp/_p_/_m_/_w_/_a_/package.json +2 -2
  7. package/lib/templates/project/angularextapp/package.json +1 -1
  8. package/lib/templates/project/angularextapp/scripts/org-setup-config-schema.mjs +17 -0
  9. package/lib/templates/project/angularextapp/scripts/org-setup-utils.mjs +33 -3
  10. package/lib/templates/project/angularextapp/scripts/org-setup.mjs +535 -3
  11. package/lib/templates/project/angularintapp/CHANGELOG.md +266 -0
  12. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/angular.json +1 -1
  13. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint-plugin-angular-graphql.js +148 -0
  14. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/eslint.config.js +9 -1
  15. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package-lock.json +690 -418
  16. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/package.json +2 -2
  17. package/lib/templates/project/angularintapp/_p_/_m_/_w_/_a_/src/app/features/agentforce/agentforce-embed.service.ts +6 -1
  18. package/lib/templates/project/angularintapp/package.json +1 -1
  19. package/lib/templates/project/angularintapp/scripts/org-setup-config-schema.mjs +17 -0
  20. package/lib/templates/project/angularintapp/scripts/org-setup-utils.mjs +33 -3
  21. package/lib/templates/project/angularintapp/scripts/org-setup.mjs +535 -3
  22. package/lib/templates/project/reactexternalapp/CHANGELOG.md +1409 -0
  23. package/lib/templates/project/reactexternalapp/PRD.md +38 -0
  24. package/lib/templates/project/reactexternalapp/README.md +14 -10
  25. package/lib/templates/project/reactexternalapp/_p_/_m_/_ps_/reactexternalapp_Guest_User_Api_Access.permissionset-meta.xml +25 -0
  26. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package-lock.json +953 -714
  27. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/package.json +9 -7
  28. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/scripts/get-graphql-schema.mjs +8 -5
  29. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/LanguageSwitcher.tsx +116 -0
  30. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/__examples__/language-switcher-example.tsx +36 -0
  31. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/__examples__/vite-config-site-example.ts +44 -0
  32. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/buildLanguageUrl.ts +158 -0
  33. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/index.ts +28 -0
  34. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_ls_/languages.ts +46 -0
  35. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/components/SocialLogin.tsx +141 -0
  36. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/authentication/pages/Login.tsx +2 -0
  37. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/README.md +246 -0
  38. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/apiUtils.ts +56 -0
  39. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/orgApiVersionService.ts +37 -0
  40. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/searchableContentTypesService.ts +116 -0
  41. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/channelResolver.ts +40 -0
  42. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/cmsQueryFragment.ts +97 -0
  43. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeSessionCache.ts +134 -0
  44. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeUtils.ts +38 -0
  45. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/hooks/useSearchableContentTypes.ts +128 -0
  46. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/index.ts +54 -0
  47. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/parseResponse.ts +65 -0
  48. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/searchChannel.ts +15 -0
  49. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/types.ts +66 -0
  50. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/registry.ts +38 -0
  51. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/index.ts +19 -0
  52. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/parseResponse.ts +56 -0
  53. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/queryFragment.ts +141 -0
  54. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/types.ts +101 -0
  55. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
  56. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +136 -0
  57. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.tsx +98 -0
  58. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +294 -0
  59. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +203 -0
  60. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +88 -0
  61. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +187 -0
  62. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
  63. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +107 -0
  64. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
  65. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
  66. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
  67. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
  68. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
  69. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  70. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
  71. package/lib/templates/project/{reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters → reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs}/FilterFieldWrapper.tsx +11 -6
  72. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
  73. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
  74. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
  75. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
  76. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/CmsResultRow.tsx +101 -0
  77. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
  78. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/resolveResultRenderer.ts +49 -0
  79. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +88 -0
  80. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/constants.ts +8 -0
  81. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
  82. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
  83. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +966 -0
  84. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +115 -0
  85. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  86. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +100 -0
  87. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +376 -0
  88. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  89. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  90. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
  91. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  92. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphqlClient.ts +24 -8
  93. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/appLayout.tsx +7 -0
  94. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/CustomerWebClientChat.tsx +74 -0
  95. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
  96. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  97. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
  98. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
  99. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/index.ts +8 -0
  100. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +53 -18
  101. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +3 -27
  102. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/TestChatPage.tsx +26 -0
  103. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +21 -8
  104. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/types/chat.ts +36 -0
  105. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/types/globals.d.ts +23 -0
  106. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
  107. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
  108. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  109. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls +133 -0
  110. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig.cls-meta.xml +5 -0
  111. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls +101 -0
  112. package/lib/templates/project/reactexternalapp/_p_/_m_/classes/UIBundleSocialLoginConfig_Test.cls-meta.xml +5 -0
  113. package/lib/templates/project/reactexternalapp/_p_/_m_/package.xml +4 -0
  114. package/lib/templates/project/reactexternalapp/package.json +8 -2
  115. package/lib/templates/project/reactexternalapp/scripts/org-setup-config-schema.mjs +120 -0
  116. package/lib/templates/project/reactexternalapp/scripts/org-setup-dev.mjs +87 -0
  117. package/lib/templates/project/reactexternalapp/scripts/org-setup-utils.mjs +569 -0
  118. package/lib/templates/project/reactexternalapp/scripts/org-setup-xml.mjs +182 -0
  119. package/lib/templates/project/reactexternalapp/scripts/org-setup.config.json +6 -2
  120. package/lib/templates/project/reactexternalapp/scripts/org-setup.mjs +1509 -328
  121. package/lib/templates/project/reactexternalapp/scripts/validate-org-setup-config.mjs +38 -0
  122. package/lib/templates/project/reactinternalapp/CHANGELOG.md +1223 -0
  123. package/lib/templates/project/reactinternalapp/PRD.md +35 -0
  124. package/lib/templates/project/reactinternalapp/README.md +14 -10
  125. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package-lock.json +813 -538
  126. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/package.json +10 -9
  127. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/README.md +246 -0
  128. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/apiUtils.ts +56 -0
  129. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/orgApiVersionService.ts +37 -0
  130. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/api/searchableContentTypesService.ts +116 -0
  131. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/channelResolver.ts +40 -0
  132. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/cmsQueryFragment.ts +97 -0
  133. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeSessionCache.ts +134 -0
  134. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/contentTypeUtils.ts +38 -0
  135. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/hooks/useSearchableContentTypes.ts +128 -0
  136. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/index.ts +54 -0
  137. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/parseResponse.ts +65 -0
  138. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/searchChannel.ts +15 -0
  139. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/cms/types.ts +66 -0
  140. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/registry.ts +38 -0
  141. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/index.ts +19 -0
  142. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/parseResponse.ts +56 -0
  143. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/sobject/queryFragment.ts +141 -0
  144. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/adapters/types.ts +101 -0
  145. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/distinctValuesService.ts +84 -0
  146. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/api/searchService.ts +136 -0
  147. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/GlobalSearchBox.tsx +98 -0
  148. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/MergedSearchResults.tsx +294 -0
  149. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/Search.tsx +203 -0
  150. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SearchResults.tsx +88 -0
  151. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/SourceSection.tsx +187 -0
  152. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/PaginationControls.tsx +185 -0
  153. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/ScopeSelector.tsx +107 -0
  154. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SearchBar.tsx +55 -0
  155. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/controls/SortControl.tsx +62 -0
  156. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/ActiveFilters.tsx +61 -0
  157. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/DefaultFilterPanel.tsx +125 -0
  158. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_/components → search/components/filters}/FilterContext.tsx +7 -20
  159. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/BooleanFilter.tsx +50 -0
  160. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/DateRangeFilter.tsx +160 -0
  161. package/lib/templates/project/{reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters → reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs}/FilterFieldWrapper.tsx +11 -6
  162. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/MultiSelectFilter.tsx +89 -0
  163. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/NumericRangeFilter.tsx +108 -0
  164. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/SelectFilter.tsx +46 -0
  165. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/filters/inputs/TextFilter.tsx +52 -0
  166. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/CmsResultRow.tsx +101 -0
  167. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/DefaultResultRow.tsx +109 -0
  168. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/components/results/resolveResultRenderer.ts +49 -0
  169. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/config.json +88 -0
  170. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/constants.ts +8 -0
  171. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/{_os_ → search}/hooks/useAsyncData.ts +3 -10
  172. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useDistinctValues.ts +59 -0
  173. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/hooks/useSearch.ts +966 -0
  174. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/index.ts +115 -0
  175. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/loadConfig.ts +14 -0
  176. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/queryBuilder.ts +100 -0
  177. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/types.ts +376 -0
  178. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/debounce.ts +17 -0
  179. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/fieldUtils.ts +14 -0
  180. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/filterUtils.ts +285 -0
  181. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/search/utils/sortUtils.ts +34 -0
  182. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/AgentforceConversationClient.tsx +16 -132
  183. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/components → components}/ObjectBreadcrumb.tsx +7 -2
  184. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/button.tsx +1 -1
  185. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/datePicker.tsx +2 -2
  186. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/components/ui/table.tsx +9 -2
  187. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountObjectDetailPage.tsx +49 -16
  188. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/Home.tsx +3 -27
  189. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/routes.tsx +12 -5
  190. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/{_f_/_os_/utils/fieldUtils.ts → utils/accountFields.ts} +9 -0
  191. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.json +2 -2
  192. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/tsconfig.tsbuildinfo +1 -0
  193. package/lib/templates/project/reactinternalapp/package.json +4 -2
  194. package/lib/templates/project/reactinternalapp/scripts/org-setup-config-schema.mjs +24 -0
  195. package/lib/templates/project/reactinternalapp/scripts/org-setup-dev.mjs +87 -0
  196. package/lib/templates/project/reactinternalapp/scripts/org-setup-utils.mjs +569 -0
  197. package/lib/templates/project/reactinternalapp/scripts/org-setup-xml.mjs +182 -0
  198. package/lib/templates/project/reactinternalapp/scripts/org-setup.mjs +1162 -214
  199. package/lib/templates/uiBundles/angularbasic/angular.json +1 -1
  200. package/lib/templates/uiBundles/angularbasic/eslint-plugin-angular-graphql.js +148 -0
  201. package/lib/templates/uiBundles/angularbasic/eslint.config.js +9 -1
  202. package/lib/templates/uiBundles/angularbasic/package-lock.json +680 -408
  203. package/lib/templates/uiBundles/angularbasic/package.json +2 -2
  204. package/lib/templates/uiBundles/reactbasic/package-lock.json +738 -440
  205. package/lib/utils/template-placeholders.js +14 -0
  206. package/lib/utils/template-placeholders.js.map +1 -1
  207. package/lib/utils/uiBundleTemplateUtils.d.ts +5 -1
  208. package/lib/utils/uiBundleTemplateUtils.js +7 -1
  209. package/lib/utils/uiBundleTemplateUtils.js.map +1 -1
  210. package/package.json +7 -7
  211. package/lib/templates/project/reactexternalapp/AGENT.md +0 -252
  212. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
  213. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
  214. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
  215. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
  216. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
  217. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
  218. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
  219. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
  220. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
  221. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
  222. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
  223. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
  224. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
  225. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
  226. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
  227. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
  228. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
  229. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
  230. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
  231. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
  232. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
  233. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
  234. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
  235. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
  236. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
  237. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
  238. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
  239. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
  240. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
  241. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
  242. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
  243. package/lib/templates/project/reactexternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +0 -297
  244. package/lib/templates/project/reactexternalapp/scripts/prepare-import-unique-fields.js +0 -122
  245. package/lib/templates/project/reactinternalapp/AGENT.md +0 -252
  246. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/accountSearchService.ts +0 -46
  247. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountIndustries.graphql +0 -19
  248. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/distinctAccountTypes.graphql +0 -19
  249. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/getAccountDetail.graphql +0 -121
  250. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/api/query/searchAccounts.graphql +0 -51
  251. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountObjectDetailPage.tsx +0 -355
  252. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/AccountSearch.tsx +0 -304
  253. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/_ex_/pages/Home.tsx +0 -34
  254. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/api/objectSearchService.ts +0 -82
  255. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/ActiveFilters.tsx +0 -89
  256. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/PaginationControls.tsx +0 -109
  257. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SearchBar.tsx +0 -41
  258. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/SortControl.tsx +0 -143
  259. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/BooleanFilter.tsx +0 -78
  260. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateFilter.tsx +0 -128
  261. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/DateRangeFilter.tsx +0 -70
  262. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/MultiSelectFilter.tsx +0 -97
  263. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/NumericRangeFilter.tsx +0 -167
  264. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SearchFilter.tsx +0 -52
  265. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/SelectFilter.tsx +0 -97
  266. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/components/filters/TextFilter.tsx +0 -93
  267. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useDebouncedCallback.ts +0 -34
  268. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/hooks/useObjectSearchParams.ts +0 -254
  269. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/debounce.ts +0 -25
  270. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/filterUtils.ts +0 -404
  271. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/_f_/_os_/utils/sortUtils.ts +0 -38
  272. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/accountSearchService.ts +0 -46
  273. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountIndustries.graphql +0 -19
  274. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/distinctAccountTypes.graphql +0 -19
  275. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/account/query/searchAccounts.graphql +0 -51
  276. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/api/graphql-operations-types.ts +0 -11260
  277. package/lib/templates/project/reactinternalapp/_p_/_m_/_w_/_a_/src/pages/AccountSearch.tsx +0 -297
  278. package/lib/templates/project/reactinternalapp/scripts/prepare-import-unique-fields.js +0 -122
  279. /package/lib/templates/project/angularextapp/_p_/_m_/{permissionsets → _ps_}/angularextapp_Guest_User_Api_Access.permissionset-meta.xml +0 -0
  280. /package/lib/templates/project/angularintapp/_p_/_m_/{permissionsets → _ps_}/angularintapp_Access.permissionset-meta.xml +0 -0
  281. /package/lib/templates/project/reactinternalapp/_p_/_m_/{permissionsets → _ps_}/reactinternalapp_Access.permissionset-meta.xml +0 -0
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Public API for the search feature.
3
+ *
4
+ * Most apps only need:
5
+ * ```tsx
6
+ * import { Search, config } from ".../features/search";
7
+ * <Search config={config} />
8
+ * ```
9
+ *
10
+ * For more control, drop down to primitives:
11
+ * - {@link useSearch} hook + {@link SearchBar} + {@link SearchResults}
12
+ * - {@link DefaultResultRow} / {@link DefaultFilterPanel} for opt-in defaults
13
+ * - filter components (TextFilter, SelectFilter, ...) for custom sidebars
14
+ */
15
+
16
+ // Drop-in wrapper (most common entry point)
17
+ export { Search } from "./components/Search";
18
+
19
+ // Primitives
20
+ export { useSearch } from "./hooks/useSearch";
21
+ export { useAsyncData } from "./hooks/useAsyncData";
22
+ export { useDistinctValues } from "./hooks/useDistinctValues";
23
+
24
+ export { SearchBar } from "./components/controls/SearchBar";
25
+ export { SearchResults } from "./components/SearchResults";
26
+ export { MergedSearchResults } from "./components/MergedSearchResults";
27
+ export type { MergedSearchResultsProps } from "./components/MergedSearchResults";
28
+ export { SourceSection } from "./components/SourceSection";
29
+ export { SortControl } from "./components/controls/SortControl";
30
+ export { PaginationControls } from "./components/controls/PaginationControls";
31
+ export { ScopeSelector } from "./components/controls/ScopeSelector";
32
+ export { ActiveFilters } from "./components/filters/ActiveFilters";
33
+ export { DefaultResultRow } from "./components/results/DefaultResultRow";
34
+ export { GlobalSearchBox } from "./components/GlobalSearchBox";
35
+ export type { GlobalSearchBoxProps } from "./components/GlobalSearchBox";
36
+ export { CmsResultRow } from "./components/results/CmsResultRow";
37
+ export { resolveResultRenderer } from "./components/results/resolveResultRenderer";
38
+ export type { ResultRenderer } from "./components/results/resolveResultRenderer";
39
+ export { DefaultFilterPanel } from "./components/filters/DefaultFilterPanel";
40
+ export {
41
+ FilterProvider,
42
+ FilterResetButton,
43
+ useFilterField,
44
+ useFilterPanel,
45
+ } from "./components/filters/FilterContext";
46
+
47
+ export { TextFilter } from "./components/filters/inputs/TextFilter";
48
+ export { SelectFilter } from "./components/filters/inputs/SelectFilter";
49
+ export { MultiSelectFilter } from "./components/filters/inputs/MultiSelectFilter";
50
+ export { NumericRangeFilter } from "./components/filters/inputs/NumericRangeFilter";
51
+ export { BooleanFilter } from "./components/filters/inputs/BooleanFilter";
52
+ export { DateRangeFilter } from "./components/filters/inputs/DateRangeFilter";
53
+ export { FilterFieldWrapper } from "./components/filters/inputs/FilterFieldWrapper";
54
+
55
+ export { fieldValue } from "./utils/fieldUtils";
56
+ export {
57
+ buildFilter,
58
+ buildGlobalQueryClause,
59
+ readSourceParams,
60
+ writeSourceParams,
61
+ GLOBAL_QUERY_KEY,
62
+ } from "./utils/filterUtils";
63
+ export type {
64
+ ActiveFilterValue,
65
+ DateFilterMode,
66
+ FilterFieldConfig,
67
+ FilterFieldType,
68
+ } from "./utils/filterUtils";
69
+ export { buildOrderBy } from "./utils/sortUtils";
70
+ export type { SortFieldConfig, SortState } from "./utils/sortUtils";
71
+
72
+ export { buildSearchQuery } from "./queryBuilder";
73
+ export type { SourceRequest, SearchQueryPayload } from "./queryBuilder";
74
+
75
+ export { runSearch } from "./api/searchService";
76
+ export { fetchDistinctValues } from "./api/distinctValuesService";
77
+ export type { PicklistOption } from "./api/distinctValuesService";
78
+
79
+ export { config } from "./loadConfig";
80
+ export { MIN_QUERY_LENGTH } from "./constants";
81
+
82
+ // CMS adapter surface — the registered adapter, its config type, and the
83
+ // runtime content-type discovery hook. Apps adding a CMS source import
84
+ // `CmsSourceConfig` for typing; advanced integrations can reuse the adapter
85
+ // contracts and the discovery hook directly.
86
+ export { cmsAdapter } from "./adapters/cms";
87
+ export { useSearchableContentTypes } from "./adapters/cms/hooks/useSearchableContentTypes";
88
+ export type { UseSearchableContentTypesResult } from "./adapters/cms/hooks/useSearchableContentTypes";
89
+ export { formatContentTypeLabel, isValidCmsFqn } from "./adapters/cms/contentTypeUtils";
90
+ export type {
91
+ SourceAdapter,
92
+ SourceRequest as AdapterSourceRequest,
93
+ QueryFragmentContribution,
94
+ } from "./adapters/types";
95
+ export type { CmsSourceConfig, CmsSearchItem, CmsSearchResponse } from "./adapters/cms/types";
96
+ export { getAdapter } from "./adapters/registry";
97
+ export type { RunSearchOutcome } from "./api/searchService";
98
+
99
+ export { ALL_SCOPE, CMS_SCOPE_SEPARATOR, parseScope } from "./types";
100
+ export type {
101
+ DisplayField,
102
+ SObjectSourceConfig,
103
+ SourceConfig,
104
+ SearchConfig,
105
+ SearchPaginationConfig,
106
+ SourceController,
107
+ SourceResult,
108
+ SourcePageInfo,
109
+ SearchHandle,
110
+ SearchScope,
111
+ ParsedScope,
112
+ RenderResultFn,
113
+ GlobalPagination,
114
+ MergedResultItem,
115
+ } from "./types";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Typed re-export of the static config.json that ships with the feature.
3
+ *
4
+ * Application code:
5
+ * import { config } from ".../features/search/loadConfig";
6
+ * const handle = useSearch(config);
7
+ *
8
+ * To customize, edit `config.json` directly (no code changes required).
9
+ */
10
+
11
+ import rawConfig from "./config.json";
12
+ import type { SearchConfig } from "./types";
13
+
14
+ export const config: SearchConfig = rawConfig as SearchConfig;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Builds a single combined GraphQL document for search across every source.
3
+ *
4
+ * The builder is kind-agnostic: for each source request it asks the registered
5
+ * adapter (`getAdapter(kind).buildRequest`) for a `QueryFragmentContribution`
6
+ * and assembles them:
7
+ * - `placement: "uiapi.query"` fragments (e.g. SObject sources) go inside the
8
+ * shared `uiapi { query { … } }` block.
9
+ * - `placement: "root"` fragments (e.g. the CMS `managed_content` block) go in
10
+ * as siblings of `uiapi` at the document root.
11
+ * - every contribution's `variableDeclarations` are concatenated into the
12
+ * `query Search(...)` header and every contribution's `variables` merged
13
+ * into one flat map.
14
+ *
15
+ * A contribution may declare zero extra variables (the CMS bootstrap call omits
16
+ * `$cmsContentTypeFQNs` entirely), so the merge tolerates declaration lists of
17
+ * differing lengths and never emits a declared-but-unused variable.
18
+ *
19
+ * When only SObject sources participate, the emitted document is identical to
20
+ * the pre-adapter builder — the `uiapi` block is unchanged and no root siblings
21
+ * are added.
22
+ */
23
+
24
+ import { getAdapter } from "./adapters/registry";
25
+ import type { SourceRequest } from "./adapters/types";
26
+
27
+ // `SourceRequest` is now defined canonically in `adapters/types.ts`; re-export
28
+ // it here for backward compatibility (the barrel and existing consumers import
29
+ // `SourceRequest` from `./queryBuilder`).
30
+ export type { SourceRequest } from "./adapters/types";
31
+
32
+ export interface SearchQueryPayload {
33
+ document: string;
34
+ variables: Record<string, unknown>;
35
+ }
36
+
37
+ /**
38
+ * Builds the combined query document and a flat variables map by dispatching
39
+ * each source through its adapter and partitioning fragments by placement.
40
+ */
41
+ export function buildSearchQuery(requests: SourceRequest[]): SearchQueryPayload {
42
+ if (requests.length === 0) {
43
+ throw new Error("buildSearchQuery requires at least one source request");
44
+ }
45
+
46
+ const variableDeclarations: string[] = [];
47
+ const uiapiFragments: string[] = [];
48
+ const rootFragments: string[] = [];
49
+ const variables: Record<string, unknown> = {};
50
+
51
+ for (const request of requests) {
52
+ const contribution = getAdapter(request.source.kind).buildRequest(request);
53
+
54
+ // Concatenate declarations (may be empty for a given source) and merge
55
+ // values — an omitted declaration means the variable is never declared,
56
+ // so it is likewise never supplied.
57
+ variableDeclarations.push(...contribution.variableDeclarations);
58
+ Object.assign(variables, contribution.variables);
59
+
60
+ if (contribution.placement === "root") {
61
+ rootFragments.push(contribution.fragment);
62
+ } else {
63
+ uiapiFragments.push(contribution.fragment);
64
+ }
65
+ }
66
+
67
+ const parts: string[] = [`query Search(${variableDeclarations.join(", ")}) {`];
68
+
69
+ // The `uiapi { query { … } }` block holds every `uiapi.query`-placed fragment.
70
+ // Emit it only when at least one such fragment exists — a CMS-only request
71
+ // (all SObject sources dropped) must not produce an empty, invalid selection
72
+ // set. When SObject sources are present its shape is identical to the
73
+ // pre-adapter builder.
74
+ if (uiapiFragments.length > 0) {
75
+ parts.push(` uiapi {`);
76
+ parts.push(` query {`);
77
+ parts.push(uiapiFragments.map((s) => indent(s, " ")).join("\n"));
78
+ parts.push(` }`);
79
+ parts.push(` }`);
80
+ }
81
+
82
+ // Root-placement fragments (e.g. CMS `managed_content`) are siblings of uiapi.
83
+ for (const fragment of rootFragments) {
84
+ parts.push(indent(fragment, " "));
85
+ }
86
+
87
+ parts.push(`}`);
88
+
89
+ // Trailing newline preserved from the original builder.
90
+ const document = parts.join("\n") + "\n";
91
+
92
+ return { document, variables };
93
+ }
94
+
95
+ function indent(s: string, prefix: string): string {
96
+ return s
97
+ .split("\n")
98
+ .map((line) => prefix + line)
99
+ .join("\n");
100
+ }
@@ -0,0 +1,376 @@
1
+ /**
2
+ * Configuration types for unified (multi-source) search.
3
+ *
4
+ * The application developer declares a SearchConfig with one entry per
5
+ * searchable backend. Today every source is an SObject queried via the uiapi
6
+ * GraphQL bridge; future adapters (CMS, REST, etc.) can plug in by introducing
7
+ * a new `kind` and a matching runtime adapter without changing any consumer.
8
+ *
9
+ * The library handles query construction, filter/sort/pagination state, URL
10
+ * sync, and result fan-out. The application owns rendering and routing.
11
+ */
12
+
13
+ import type { FilterFieldConfig, ActiveFilterValue } from "./utils/filterUtils";
14
+ import type { SortFieldConfig, SortState } from "./utils/sortUtils";
15
+ import type { CmsSourceConfig } from "./adapters/cms/types";
16
+ import type { DiscoveredContentType } from "./adapters/cms/contentTypeUtils";
17
+
18
+ // Re-export the CMS source config so consumers can import it from the public
19
+ // type surface without reaching into `adapters/cms`.
20
+ export type { CmsSourceConfig };
21
+
22
+ /**
23
+ * A single field to include in the GraphQL selection set of an SObject source.
24
+ *
25
+ * - `"Name"` (string shorthand): emits `Name @optional { value displayValue }`.
26
+ * - `{ name, subfields }`: emits a nested selection (relationship traversal).
27
+ * - `{ name, raw: true }`: emits the bare field name (e.g. for Id-like fields
28
+ * that are not wrapped in `{ value displayValue }`).
29
+ *
30
+ * The configured `idField` (default: "Id") is added automatically; do not list
31
+ * it explicitly.
32
+ */
33
+ export type DisplayField =
34
+ | string
35
+ | { name: string; raw: true }
36
+ | { name: string; subfields: DisplayField[] };
37
+
38
+ /** Configuration for one SObject source in a search experience. */
39
+ export interface SObjectSourceConfig {
40
+ /** Discriminator — selects the runtime adapter. */
41
+ kind: "sobject";
42
+ /**
43
+ * Stable identifier. Used as the GraphQL alias, the URL namespace, and the
44
+ * result-map key. Must match `/^[A-Za-z_][A-Za-z0-9_]*$/`.
45
+ */
46
+ key: string;
47
+ /** GraphQL object name (e.g. "Account", "Contact"). */
48
+ objectName: string;
49
+ /**
50
+ * Plural display label — used in section headers, the scope dropdown, and
51
+ * empty-state messages (e.g. "Accounts", "Maintenance Requests").
52
+ */
53
+ label: string;
54
+ /**
55
+ * Singular display label for a single record of this type (e.g. "Account",
56
+ * "Maintenance Request"). Used for the per-card source badge in the merged
57
+ * grid. Falls back to `label` when omitted.
58
+ */
59
+ labelSingular?: string;
60
+ /** Field name that uniquely identifies a record. Defaults to "Id". */
61
+ idField?: string;
62
+ /**
63
+ * URL pattern used by the default renderer to build a result link.
64
+ *
65
+ * Tokens of the form `:fieldName` are replaced with the corresponding
66
+ * field's value at render time (e.g. `:id` resolves to the record's
67
+ * `idField` value, `:Name` resolves to the Name field's `value`).
68
+ *
69
+ * Example: `"/accounts/:id"` produces `<Link to="/accounts/001xx0000003DGb">`.
70
+ *
71
+ * Optional — when omitted, the default renderer emits non-clickable rows.
72
+ */
73
+ routePattern?: string;
74
+ /**
75
+ * Fields the global `q` term should match against.
76
+ * Built into an `or` of `like %q%`. Supports dot-notation for relationship
77
+ * fields (e.g. "Owner.Name").
78
+ */
79
+ searchableFields: string[];
80
+ /**
81
+ * Fields to include in the GraphQL selection set. The id field is added
82
+ * automatically; do not list it.
83
+ */
84
+ displayFields: DisplayField[];
85
+ /**
86
+ * Optional structured filters for this source.
87
+ *
88
+ * Named `filterBy` (rather than "the filters shown in the panel") because a
89
+ * future entry may constrain the query without rendering a control — e.g. a
90
+ * default `Status != Completed` that hides completed items from results while
91
+ * never appearing in the UI. Today every entry renders an input via
92
+ * `DefaultFilterPanel`.
93
+ */
94
+ filterBy?: FilterFieldConfig[];
95
+ /** Optional sort options surfaced in the per-source sort dropdown. */
96
+ sortBy?: SortFieldConfig[];
97
+ /** Initial sort applied when no URL sort is present. */
98
+ defaultSort?: SortState;
99
+ /**
100
+ * GraphQL type name for the `where` variable.
101
+ * Defaults to `${objectName}_Filter` — override only for non-conventional schemas.
102
+ */
103
+ whereTypeName?: string;
104
+ /** GraphQL type name for the `orderBy` variable. Defaults to `${objectName}_OrderBy`. */
105
+ orderByTypeName?: string;
106
+ }
107
+
108
+ /**
109
+ * Discriminated union of every source kind a search experience can query.
110
+ *
111
+ * The `kind` field selects the runtime adapter (see `adapters/registry.ts`) and
112
+ * narrows the config to the fields that kind understands. New backends extend
113
+ * this union with a new `kind` + a matching adapter — no consumer changes.
114
+ *
115
+ * `CmsSourceConfig` is authored in `adapters/cms/types.ts` and unioned here so
116
+ * `SourceConfig` remains the single kind-agnostic config type.
117
+ */
118
+ export type SourceConfig = SObjectSourceConfig | CmsSourceConfig;
119
+
120
+ /**
121
+ * One global pagination config for the whole search experience. It is the
122
+ * single source of truth — there is no per-source pagination. The same
123
+ * `pageSize` / `pageSizeOptions` apply across every object type and in every
124
+ * scope, including single-object pages (`restrictTo` / `lockedScope`) and when
125
+ * the scope dropdown narrows to one source.
126
+ */
127
+ export interface SearchPaginationConfig {
128
+ /**
129
+ * How results are paginated:
130
+ * - `"per-source"` (default): each source advances its own cursor; a page
131
+ * can hold up to `sources × pageSize` items. This is what the drop-in
132
+ * `<Search>` (one section per source) expects.
133
+ * - `"merged"`: treat the cumulative result set as one list and window it
134
+ * into fixed pages of `pageSize`. Each page shows exactly `pageSize` items
135
+ * across all sources — use for a single combined grid.
136
+ */
137
+ mode?: "per-source" | "merged";
138
+ /**
139
+ * In `"merged"` mode, how nodes from different sources are ordered:
140
+ * - `"sequential"` (default): source 1 in full, then source 2, …
141
+ * - `"interleaved"`: round-robin — every source gets equal priority.
142
+ * - `"proportional"`: each source spread by its result count, so larger
143
+ * sources appear more often. Ignored in `"per-source"` mode.
144
+ */
145
+ mergeOrder?: "sequential" | "interleaved" | "proportional";
146
+ /** Items per page (across all sources in `"merged"` mode; per source otherwise). */
147
+ pageSize: number;
148
+ /** Page sizes offered in the "results per page" control. */
149
+ pageSizeOptions: number[];
150
+ }
151
+
152
+ /** Top-level config passed to {@link useSearch}. */
153
+ export interface SearchConfig {
154
+ sources: SourceConfig[];
155
+ /**
156
+ * Global pagination config — the single source of truth for page size, page
157
+ * options, mode, and merge order. See {@link SearchPaginationConfig}. When
158
+ * omitted, pagination defaults to per-source mode, page size 10, options
159
+ * `[10, 25, 50]`.
160
+ */
161
+ pagination?: SearchPaginationConfig;
162
+ }
163
+
164
+ // ---------------------------------------------------------------------------
165
+ // Runtime types
166
+ // ---------------------------------------------------------------------------
167
+
168
+ export interface SourcePageInfo {
169
+ hasNextPage: boolean;
170
+ hasPreviousPage: boolean;
171
+ endCursor: string | null;
172
+ startCursor: string | null;
173
+ }
174
+
175
+ /**
176
+ * Per-source result. Nodes are typed as `unknown` at the library boundary —
177
+ * the application narrows them in its `renderResult` callback (typically by
178
+ * casting to a codegen-generated node type).
179
+ */
180
+ export interface SourceResult {
181
+ nodes: unknown[];
182
+ pageInfo: SourcePageInfo | null;
183
+ totalCount: number | null;
184
+ }
185
+
186
+ export interface SourceController {
187
+ /**
188
+ * The source's config. Widened to the `SourceConfig` union so a controller
189
+ * can front any kind (SObject, CMS, …); consumers narrow on `config.kind`
190
+ * before reading kind-specific fields (`objectName`, `filterBy`, `sortBy`, …).
191
+ */
192
+ config: SourceConfig;
193
+ result: SourceResult | null;
194
+ loading: boolean;
195
+ error: string | null;
196
+ filters: {
197
+ active: ActiveFilterValue[];
198
+ set: (field: string, value: ActiveFilterValue | undefined) => void;
199
+ remove: (field: string) => void;
200
+ };
201
+ sort: {
202
+ current: SortState | null;
203
+ set: (sort: SortState | null) => void;
204
+ };
205
+ pagination: {
206
+ pageSize: number;
207
+ /** Allowed page sizes — from the global pagination config. */
208
+ pageSizeOptions: readonly number[];
209
+ pageIndex: number;
210
+ hasNextPage: boolean;
211
+ hasPreviousPage: boolean;
212
+ setPageSize: (size: number) => void;
213
+ goToNextPage: () => void;
214
+ goToPreviousPage: () => void;
215
+ };
216
+ }
217
+
218
+ /**
219
+ * The currently-selected search scope. Grammar:
220
+ *
221
+ * ```
222
+ * scope = "all" | <sobjectKey> | <cmsKey> | "<cmsKey>:<contentTypeFqn>"
223
+ * ```
224
+ *
225
+ * - `"all"`: every source in the config is queried and rendered.
226
+ * - `<sobjectKey>` / `<cmsKey>`: only that source is queried and rendered; the
227
+ * combined query still runs (a CMS source in scope sends its discovered
228
+ * content types if any are known, else omits them on the bootstrap call).
229
+ * - `"<cmsKey>:<contentTypeFqn>"`: a **CMS-only** search narrowed to one content
230
+ * type — SObject sources are dropped from the request and the CMS fragment
231
+ * sends `contentTypes = [<fqn>]`. `<fqn>` must pass `isValidCmsFqn`. These
232
+ * entries are appended to the scope dropdown after content-type discovery.
233
+ *
234
+ * The `":"` separator disambiguates the two halves; source keys match
235
+ * `/^[A-Za-z_][A-Za-z0-9_]*$/` (no colon), and FQNs match `CMS_FQN_PATTERN`.
236
+ */
237
+ export type SearchScope = "all" | string;
238
+
239
+ export const ALL_SCOPE = "all" as const;
240
+
241
+ /** Separator between a CMS source key and a content-type FQN in a scope value. */
242
+ export const CMS_SCOPE_SEPARATOR = ":" as const;
243
+
244
+ /**
245
+ * A parsed {@link SearchScope}. `base` is the plain scope (`"all"` or a source
246
+ * key); `cmsFqn` is the selected CMS content-type FQN when the scope carries the
247
+ * `"<cmsKey>:<fqn>"` form, else `undefined`.
248
+ */
249
+ export interface ParsedScope {
250
+ base: SearchScope;
251
+ cmsFqn?: string;
252
+ }
253
+
254
+ /**
255
+ * Splits a {@link SearchScope} into `{ base, cmsFqn }`. Only the first `":"`
256
+ * separates the CMS source key from the content-type FQN; source keys contain
257
+ * no colon and FQNs (`sfdc_cms__…`) contain no colon either, so a single split
258
+ * is unambiguous. A scope with no separator has `cmsFqn === undefined`.
259
+ */
260
+ export function parseScope(scope: SearchScope): ParsedScope {
261
+ const sep = scope.indexOf(CMS_SCOPE_SEPARATOR);
262
+ if (sep === -1) return { base: scope };
263
+ return { base: scope.slice(0, sep), cmsFqn: scope.slice(sep + 1) };
264
+ }
265
+
266
+ /**
267
+ * One result node tagged with the source it came from. Produced by
268
+ * {@link SearchHandle.mergedResults} so a single combined grid can render
269
+ * cross-source results and still pick the right card per node.
270
+ */
271
+ export interface MergedResultItem {
272
+ /** The `key` of the source this node came from. */
273
+ sourceKey: string;
274
+ /** The raw result node (cast to your typed node in the renderer). */
275
+ node: unknown;
276
+ }
277
+
278
+ /**
279
+ * Aggregate pagination across every in-scope source, exposed by
280
+ * {@link SearchHandle.globalPagination}. Its exact behaviour depends on the
281
+ * `pagination` mode passed to {@link useSearch}:
282
+ *
283
+ * - **`"merged"`** (recommended for a single combined grid): the cumulative
284
+ * result set is treated as one list and windowed into fixed pages of
285
+ * `pageSize`. Page `P` always shows **exactly** `pageSize` items (the last
286
+ * page may show fewer), `pageCount` is `ceil(totalCount / pageSize)`, and
287
+ * `goToPage` can jump to any page. Under the hood each in-scope source fetches
288
+ * `(P + 1) * pageSize` rows from its front, the results are concatenated in
289
+ * config order, and the page-`P` slice is taken — so the math is exact, not an
290
+ * estimate.
291
+ * - **`"per-source"`** (default): each source paginates with its own cursor and
292
+ * a "global page" is the furthest-advanced in-scope source's page. `Next`
293
+ * advances only the sources still on the current global page that have more
294
+ * data; a source that runs out is left behind. `goToPage` is best-effort
295
+ * (adjacent pages only) because cursors can't seek to an arbitrary offset.
296
+ */
297
+ export interface GlobalPagination {
298
+ /** Current global page, 0-based. */
299
+ pageIndex: number;
300
+ /**
301
+ * Total number of global pages. In `"merged"` mode this is exactly
302
+ * `ceil(totalCount / pageSize)`. In `"per-source"` mode it is the `max` over
303
+ * in-scope sources of `ceil(totalCount / pageSize)` and may be an estimate if
304
+ * a source omits `totalCount`. `0` when there are no results, otherwise `>= 1`.
305
+ */
306
+ pageCount: number;
307
+ /** Shared page size. */
308
+ pageSize: number;
309
+ /** Allowed page sizes (from the first in-scope source). */
310
+ pageSizeOptions: readonly number[];
311
+ /** True when there is a page after the current one. */
312
+ hasNextPage: boolean;
313
+ /** True when the current global page is past the first. */
314
+ hasPreviousPage: boolean;
315
+ /** Cumulative result count summed across in-scope sources. */
316
+ totalCount: number;
317
+ /** Advance to the next global page. */
318
+ goToNextPage: () => void;
319
+ /** Step back to the previous global page. */
320
+ goToPreviousPage: () => void;
321
+ /**
322
+ * Jump to a specific 0-based page. Exact in `"merged"` mode; in
323
+ * `"per-source"` mode only adjacent pages are honoured (others are a no-op).
324
+ */
325
+ goToPage: (pageIndex: number) => void;
326
+ /** Set the page size (resets to the first page). */
327
+ setPageSize: (size: number) => void;
328
+ }
329
+
330
+ export interface SearchHandle {
331
+ q: string;
332
+ setQ: (q: string) => void;
333
+ scope: SearchScope;
334
+ setScope: (scope: SearchScope) => void;
335
+ /**
336
+ * True when the caller passed `lockedScope` to `useSearch`. Consumers
337
+ * should hide the scope dropdown and read-only display the locked source.
338
+ */
339
+ scopeLocked: boolean;
340
+ sources: Record<string, SourceController>;
341
+ /**
342
+ * Source controllers that participate in the current scope, in config
343
+ * declaration order. In `"all"` scope this is every source; otherwise just
344
+ * the selected one. Convenience for callers building aggregate UI.
345
+ */
346
+ inScopeSources: SourceController[];
347
+ /**
348
+ * In-scope nodes flattened into one list (config order, source by source),
349
+ * each tagged with its `sourceKey` — for rendering a single combined grid
350
+ * instead of one section per source. In `"merged"` pagination mode this is
351
+ * exactly the current page's window (at most `globalPagination.pageSize`
352
+ * items); in `"per-source"` mode it is every in-scope source's current page
353
+ * concatenated.
354
+ */
355
+ mergedResults: MergedResultItem[];
356
+ /**
357
+ * Aggregate pagination across all in-scope sources — drive one shared
358
+ * pager over the cumulative result set. See {@link GlobalPagination}.
359
+ */
360
+ globalPagination: GlobalPagination;
361
+ loading: boolean;
362
+ error: string | null;
363
+ /**
364
+ * CMS content types discovered at runtime from the CMS channel — each with
365
+ * its FQN and server-provided display `label` (empty until the first CMS
366
+ * result yields a channel id and discovery completes). The scope dropdown
367
+ * appends a `"<cmsKey>:<fqn>"` entry per type so a user can narrow a CMS
368
+ * search to a single content type. Empty for SObject-only configs or before
369
+ * discovery.
370
+ */
371
+ discoveredContentTypes: DiscoveredContentType[];
372
+ resetAll: () => void;
373
+ }
374
+
375
+ /** Type alias for a render callback per source key. */
376
+ export type RenderResultFn = (sourceKey: string, node: unknown) => React.ReactNode;
@@ -0,0 +1,17 @@
1
+ /** Default debounce delay for keystroke-driven inputs. */
2
+ export const FILTER_DEBOUNCE_MS = 300;
3
+
4
+ /**
5
+ * Creates a debounced version of `fn`. Each call resets the internal timer;
6
+ * `fn` runs only after the timer expires without being reset.
7
+ */
8
+ export function debounce<T extends (...args: any[]) => void>(
9
+ fn: T,
10
+ ms: number,
11
+ ): (...args: Parameters<T>) => void {
12
+ let timer: ReturnType<typeof setTimeout> | undefined;
13
+ return (...args: Parameters<T>) => {
14
+ clearTimeout(timer);
15
+ timer = setTimeout(() => fn(...args), ms);
16
+ };
17
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Helpers for reading values out of uiapi GraphQL response nodes.
3
+ *
4
+ * Nodes typically come back wrapped as `{ value, displayValue }`. `fieldValue`
5
+ * picks the user-facing string (preferring displayValue) or returns null.
6
+ */
7
+
8
+ export function fieldValue(
9
+ field: { displayValue?: string | null; value?: unknown } | null | undefined,
10
+ ): string | null {
11
+ if (field?.displayValue != null) return field.displayValue;
12
+ if (field?.value != null) return String(field.value);
13
+ return null;
14
+ }