@cohesivesystems/presentation-core 0.1.0-alpha.1

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 (447) hide show
  1. package/LICENSE +55 -0
  2. package/dist/api-scope-request.d.ts +43 -0
  3. package/dist/api-scope-request.d.ts.map +1 -0
  4. package/dist/api-scope-request.js +96 -0
  5. package/dist/api-scope-request.js.map +1 -0
  6. package/dist/collection-chrome-icons.d.ts +18 -0
  7. package/dist/collection-chrome-icons.d.ts.map +1 -0
  8. package/dist/collection-chrome-icons.js +57 -0
  9. package/dist/collection-chrome-icons.js.map +1 -0
  10. package/dist/collection-chrome-runtime.d.ts +25 -0
  11. package/dist/collection-chrome-runtime.d.ts.map +1 -0
  12. package/dist/collection-chrome-runtime.js +72 -0
  13. package/dist/collection-chrome-runtime.js.map +1 -0
  14. package/dist/collection-chrome-slot-renderer-registry.d.ts +110 -0
  15. package/dist/collection-chrome-slot-renderer-registry.d.ts.map +1 -0
  16. package/dist/collection-chrome-slot-renderer-registry.js +136 -0
  17. package/dist/collection-chrome-slot-renderer-registry.js.map +1 -0
  18. package/dist/collection-selection-state.d.ts +18 -0
  19. package/dist/collection-selection-state.d.ts.map +1 -0
  20. package/dist/collection-selection-state.js +2 -0
  21. package/dist/collection-selection-state.js.map +1 -0
  22. package/dist/data-source-projection.d.ts +475 -0
  23. package/dist/data-source-projection.d.ts.map +1 -0
  24. package/dist/data-source-projection.js +880 -0
  25. package/dist/data-source-projection.js.map +1 -0
  26. package/dist/data-source-query-lowering.d.ts +35 -0
  27. package/dist/data-source-query-lowering.d.ts.map +1 -0
  28. package/dist/data-source-query-lowering.js +104 -0
  29. package/dist/data-source-query-lowering.js.map +1 -0
  30. package/dist/date-time-filter-model.d.ts +20 -0
  31. package/dist/date-time-filter-model.d.ts.map +1 -0
  32. package/dist/date-time-filter-model.js +115 -0
  33. package/dist/date-time-filter-model.js.map +1 -0
  34. package/dist/document-badge-icons.d.ts +4 -0
  35. package/dist/document-badge-icons.d.ts.map +1 -0
  36. package/dist/document-badge-icons.js +4 -0
  37. package/dist/document-badge-icons.js.map +1 -0
  38. package/dist/document-module.d.ts +268 -0
  39. package/dist/document-module.d.ts.map +1 -0
  40. package/dist/document-module.js +347 -0
  41. package/dist/document-module.js.map +1 -0
  42. package/dist/document-summary-model.d.ts +2 -0
  43. package/dist/document-summary-model.d.ts.map +1 -0
  44. package/dist/document-summary-model.js +2 -0
  45. package/dist/document-summary-model.js.map +1 -0
  46. package/dist/document-workspace-chrome-projection.d.ts +18 -0
  47. package/dist/document-workspace-chrome-projection.d.ts.map +1 -0
  48. package/dist/document-workspace-chrome-projection.js +35 -0
  49. package/dist/document-workspace-chrome-projection.js.map +1 -0
  50. package/dist/document-workspace-surface-slots.d.ts +75 -0
  51. package/dist/document-workspace-surface-slots.d.ts.map +1 -0
  52. package/dist/document-workspace-surface-slots.js +268 -0
  53. package/dist/document-workspace-surface-slots.js.map +1 -0
  54. package/dist/endpoint-executor.d.ts +62 -0
  55. package/dist/endpoint-executor.d.ts.map +1 -0
  56. package/dist/endpoint-executor.js +35 -0
  57. package/dist/endpoint-executor.js.map +1 -0
  58. package/dist/field-display-resolution.d.ts +5 -0
  59. package/dist/field-display-resolution.d.ts.map +1 -0
  60. package/dist/field-display-resolution.js +50 -0
  61. package/dist/field-display-resolution.js.map +1 -0
  62. package/dist/index.d.ts +90 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +89 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/module.d.ts +48 -0
  67. package/dist/module.d.ts.map +1 -0
  68. package/dist/module.js +108 -0
  69. package/dist/module.js.map +1 -0
  70. package/dist/navigation-shell-frame-renderer-registry.d.ts +12 -0
  71. package/dist/navigation-shell-frame-renderer-registry.d.ts.map +1 -0
  72. package/dist/navigation-shell-frame-renderer-registry.js +29 -0
  73. package/dist/navigation-shell-frame-renderer-registry.js.map +1 -0
  74. package/dist/navigation-shell-layout-runtime.d.ts +29 -0
  75. package/dist/navigation-shell-layout-runtime.d.ts.map +1 -0
  76. package/dist/navigation-shell-layout-runtime.js +50 -0
  77. package/dist/navigation-shell-layout-runtime.js.map +1 -0
  78. package/dist/navigation-shell-region-component-registry.d.ts +96 -0
  79. package/dist/navigation-shell-region-component-registry.d.ts.map +1 -0
  80. package/dist/navigation-shell-region-component-registry.js +108 -0
  81. package/dist/navigation-shell-region-component-registry.js.map +1 -0
  82. package/dist/navigation-shell-runtime.d.ts +48 -0
  83. package/dist/navigation-shell-runtime.d.ts.map +1 -0
  84. package/dist/navigation-shell-runtime.js +457 -0
  85. package/dist/navigation-shell-runtime.js.map +1 -0
  86. package/dist/navigation-shell-slot-renderer-registry.d.ts +15 -0
  87. package/dist/navigation-shell-slot-renderer-registry.d.ts.map +1 -0
  88. package/dist/navigation-shell-slot-renderer-registry.js +48 -0
  89. package/dist/navigation-shell-slot-renderer-registry.js.map +1 -0
  90. package/dist/navigation.d.ts +84 -0
  91. package/dist/navigation.d.ts.map +1 -0
  92. package/dist/navigation.js +167 -0
  93. package/dist/navigation.js.map +1 -0
  94. package/dist/object-path.d.ts +23 -0
  95. package/dist/object-path.d.ts.map +1 -0
  96. package/dist/object-path.js +63 -0
  97. package/dist/object-path.js.map +1 -0
  98. package/dist/page-host-renderer-registry.d.ts +119 -0
  99. package/dist/page-host-renderer-registry.d.ts.map +1 -0
  100. package/dist/page-host-renderer-registry.js +305 -0
  101. package/dist/page-host-renderer-registry.js.map +1 -0
  102. package/dist/presentation-action-endpoint-request-projection.d.ts +23 -0
  103. package/dist/presentation-action-endpoint-request-projection.d.ts.map +1 -0
  104. package/dist/presentation-action-endpoint-request-projection.js +117 -0
  105. package/dist/presentation-action-endpoint-request-projection.js.map +1 -0
  106. package/dist/presentation-action-endpoint.d.ts +24 -0
  107. package/dist/presentation-action-endpoint.d.ts.map +1 -0
  108. package/dist/presentation-action-endpoint.js +56 -0
  109. package/dist/presentation-action-endpoint.js.map +1 -0
  110. package/dist/presentation-action-icons.d.ts +4 -0
  111. package/dist/presentation-action-icons.d.ts.map +1 -0
  112. package/dist/presentation-action-icons.js +4 -0
  113. package/dist/presentation-action-icons.js.map +1 -0
  114. package/dist/presentation-action-result-state.d.ts +48 -0
  115. package/dist/presentation-action-result-state.d.ts.map +1 -0
  116. package/dist/presentation-action-result-state.js +109 -0
  117. package/dist/presentation-action-result-state.js.map +1 -0
  118. package/dist/presentation-action-runtime-binding.d.ts +48 -0
  119. package/dist/presentation-action-runtime-binding.d.ts.map +1 -0
  120. package/dist/presentation-action-runtime-binding.js +52 -0
  121. package/dist/presentation-action-runtime-binding.js.map +1 -0
  122. package/dist/presentation-action-runtime-diagnostics.d.ts +18 -0
  123. package/dist/presentation-action-runtime-diagnostics.d.ts.map +1 -0
  124. package/dist/presentation-action-runtime-diagnostics.js +69 -0
  125. package/dist/presentation-action-runtime-diagnostics.js.map +1 -0
  126. package/dist/presentation-action-runtime-labels.d.ts +15 -0
  127. package/dist/presentation-action-runtime-labels.d.ts.map +1 -0
  128. package/dist/presentation-action-runtime-labels.js +28 -0
  129. package/dist/presentation-action-runtime-labels.js.map +1 -0
  130. package/dist/presentation-action-runtime-projection.d.ts +17 -0
  131. package/dist/presentation-action-runtime-projection.d.ts.map +1 -0
  132. package/dist/presentation-action-runtime-projection.js +31 -0
  133. package/dist/presentation-action-runtime-projection.js.map +1 -0
  134. package/dist/presentation-badge-resolution.d.ts +8 -0
  135. package/dist/presentation-badge-resolution.d.ts.map +1 -0
  136. package/dist/presentation-badge-resolution.js +73 -0
  137. package/dist/presentation-badge-resolution.js.map +1 -0
  138. package/dist/presentation-collection-pagination.d.ts +32 -0
  139. package/dist/presentation-collection-pagination.d.ts.map +1 -0
  140. package/dist/presentation-collection-pagination.js +275 -0
  141. package/dist/presentation-collection-pagination.js.map +1 -0
  142. package/dist/presentation-content-diagnostics.d.ts +17 -0
  143. package/dist/presentation-content-diagnostics.d.ts.map +1 -0
  144. package/dist/presentation-content-diagnostics.js +61 -0
  145. package/dist/presentation-content-diagnostics.js.map +1 -0
  146. package/dist/presentation-content-resolution.d.ts +9 -0
  147. package/dist/presentation-content-resolution.d.ts.map +1 -0
  148. package/dist/presentation-content-resolution.js +19 -0
  149. package/dist/presentation-content-resolution.js.map +1 -0
  150. package/dist/presentation-data-source-binding-model.d.ts +81 -0
  151. package/dist/presentation-data-source-binding-model.d.ts.map +1 -0
  152. package/dist/presentation-data-source-binding-model.js +56 -0
  153. package/dist/presentation-data-source-binding-model.js.map +1 -0
  154. package/dist/presentation-data-source-runtime.d.ts +62 -0
  155. package/dist/presentation-data-source-runtime.d.ts.map +1 -0
  156. package/dist/presentation-data-source-runtime.js +80 -0
  157. package/dist/presentation-data-source-runtime.js.map +1 -0
  158. package/dist/presentation-design-intent-diagnostics.d.ts +25 -0
  159. package/dist/presentation-design-intent-diagnostics.d.ts.map +1 -0
  160. package/dist/presentation-design-intent-diagnostics.js +55 -0
  161. package/dist/presentation-design-intent-diagnostics.js.map +1 -0
  162. package/dist/presentation-icon-diagnostics.d.ts +45 -0
  163. package/dist/presentation-icon-diagnostics.d.ts.map +1 -0
  164. package/dist/presentation-icon-diagnostics.js +235 -0
  165. package/dist/presentation-icon-diagnostics.js.map +1 -0
  166. package/dist/presentation-icon-registry.d.ts +36 -0
  167. package/dist/presentation-icon-registry.d.ts.map +1 -0
  168. package/dist/presentation-icon-registry.js +81 -0
  169. package/dist/presentation-icon-registry.js.map +1 -0
  170. package/dist/presentation-navigation-action-runtime-bindings.d.ts +13 -0
  171. package/dist/presentation-navigation-action-runtime-bindings.d.ts.map +1 -0
  172. package/dist/presentation-navigation-action-runtime-bindings.js +29 -0
  173. package/dist/presentation-navigation-action-runtime-bindings.js.map +1 -0
  174. package/dist/presentation-pagination.d.ts +98 -0
  175. package/dist/presentation-pagination.d.ts.map +1 -0
  176. package/dist/presentation-pagination.js +427 -0
  177. package/dist/presentation-pagination.js.map +1 -0
  178. package/dist/presentation-projection-coverage.d.ts +38 -0
  179. package/dist/presentation-projection-coverage.d.ts.map +1 -0
  180. package/dist/presentation-projection-coverage.js +2429 -0
  181. package/dist/presentation-projection-coverage.js.map +1 -0
  182. package/dist/presentation-projection-diagnostics.d.ts +33 -0
  183. package/dist/presentation-projection-diagnostics.d.ts.map +1 -0
  184. package/dist/presentation-projection-diagnostics.js +17 -0
  185. package/dist/presentation-projection-diagnostics.js.map +1 -0
  186. package/dist/presentation-projection-trace.d.ts +97 -0
  187. package/dist/presentation-projection-trace.d.ts.map +1 -0
  188. package/dist/presentation-projection-trace.js +110 -0
  189. package/dist/presentation-projection-trace.js.map +1 -0
  190. package/dist/presentation-query-form-state.d.ts +15 -0
  191. package/dist/presentation-query-form-state.d.ts.map +1 -0
  192. package/dist/presentation-query-form-state.js +20 -0
  193. package/dist/presentation-query-form-state.js.map +1 -0
  194. package/dist/presentation-renderer-registry.d.ts +86 -0
  195. package/dist/presentation-renderer-registry.d.ts.map +1 -0
  196. package/dist/presentation-renderer-registry.js +108 -0
  197. package/dist/presentation-renderer-registry.js.map +1 -0
  198. package/dist/presentation-semantics.d.ts +288 -0
  199. package/dist/presentation-semantics.d.ts.map +1 -0
  200. package/dist/presentation-semantics.js +560 -0
  201. package/dist/presentation-semantics.js.map +1 -0
  202. package/dist/presentation-standards.d.ts +8 -0
  203. package/dist/presentation-standards.d.ts.map +1 -0
  204. package/dist/presentation-standards.js +9 -0
  205. package/dist/presentation-standards.js.map +1 -0
  206. package/dist/presentation-test-selectors.d.ts +146 -0
  207. package/dist/presentation-test-selectors.d.ts.map +1 -0
  208. package/dist/presentation-test-selectors.js +113 -0
  209. package/dist/presentation-test-selectors.js.map +1 -0
  210. package/dist/presentation-value-formatting.d.ts +12 -0
  211. package/dist/presentation-value-formatting.d.ts.map +1 -0
  212. package/dist/presentation-value-formatting.js +33 -0
  213. package/dist/presentation-value-formatting.js.map +1 -0
  214. package/dist/presentation-value-resolution.d.ts +7 -0
  215. package/dist/presentation-value-resolution.d.ts.map +1 -0
  216. package/dist/presentation-value-resolution.js +69 -0
  217. package/dist/presentation-value-resolution.js.map +1 -0
  218. package/dist/presentation-view-tree.d.ts +6 -0
  219. package/dist/presentation-view-tree.d.ts.map +1 -0
  220. package/dist/presentation-view-tree.js +15 -0
  221. package/dist/presentation-view-tree.js.map +1 -0
  222. package/dist/process-task-model.d.ts +80 -0
  223. package/dist/process-task-model.d.ts.map +1 -0
  224. package/dist/process-task-model.js +52 -0
  225. package/dist/process-task-model.js.map +1 -0
  226. package/dist/process-task-projection.d.ts +46 -0
  227. package/dist/process-task-projection.d.ts.map +1 -0
  228. package/dist/process-task-projection.js +233 -0
  229. package/dist/process-task-projection.js.map +1 -0
  230. package/dist/projected-action-status-projection.d.ts +18 -0
  231. package/dist/projected-action-status-projection.d.ts.map +1 -0
  232. package/dist/projected-action-status-projection.js +19 -0
  233. package/dist/projected-action-status-projection.js.map +1 -0
  234. package/dist/projected-activity-state-model.d.ts +22 -0
  235. package/dist/projected-activity-state-model.d.ts.map +1 -0
  236. package/dist/projected-activity-state-model.js +87 -0
  237. package/dist/projected-activity-state-model.js.map +1 -0
  238. package/dist/projected-collection-action-runtime-bindings.d.ts +12 -0
  239. package/dist/projected-collection-action-runtime-bindings.d.ts.map +1 -0
  240. package/dist/projected-collection-action-runtime-bindings.js +37 -0
  241. package/dist/projected-collection-action-runtime-bindings.js.map +1 -0
  242. package/dist/projected-collection-action-runtime-diagnostics.d.ts +23 -0
  243. package/dist/projected-collection-action-runtime-diagnostics.d.ts.map +1 -0
  244. package/dist/projected-collection-action-runtime-diagnostics.js +168 -0
  245. package/dist/projected-collection-action-runtime-diagnostics.js.map +1 -0
  246. package/dist/projected-collection-runtime.d.ts +475 -0
  247. package/dist/projected-collection-runtime.d.ts.map +1 -0
  248. package/dist/projected-collection-runtime.js +832 -0
  249. package/dist/projected-collection-runtime.js.map +1 -0
  250. package/dist/projected-document-action-diagnostics.d.ts +16 -0
  251. package/dist/projected-document-action-diagnostics.d.ts.map +1 -0
  252. package/dist/projected-document-action-diagnostics.js +113 -0
  253. package/dist/projected-document-action-diagnostics.js.map +1 -0
  254. package/dist/projected-document-action-enablements.d.ts +25 -0
  255. package/dist/projected-document-action-enablements.d.ts.map +1 -0
  256. package/dist/projected-document-action-enablements.js +38 -0
  257. package/dist/projected-document-action-enablements.js.map +1 -0
  258. package/dist/projected-document-action-projection.d.ts +45 -0
  259. package/dist/projected-document-action-projection.d.ts.map +1 -0
  260. package/dist/projected-document-action-projection.js +201 -0
  261. package/dist/projected-document-action-projection.js.map +1 -0
  262. package/dist/projected-document-action-runtime-profile-diagnostics.d.ts +16 -0
  263. package/dist/projected-document-action-runtime-profile-diagnostics.d.ts.map +1 -0
  264. package/dist/projected-document-action-runtime-profile-diagnostics.js +168 -0
  265. package/dist/projected-document-action-runtime-profile-diagnostics.js.map +1 -0
  266. package/dist/projected-document-action-runtime-profile.d.ts +64 -0
  267. package/dist/projected-document-action-runtime-profile.d.ts.map +1 -0
  268. package/dist/projected-document-action-runtime-profile.js +33 -0
  269. package/dist/projected-document-action-runtime-profile.js.map +1 -0
  270. package/dist/projected-document-action-status-notice-diagnostics.d.ts +10 -0
  271. package/dist/projected-document-action-status-notice-diagnostics.d.ts.map +1 -0
  272. package/dist/projected-document-action-status-notice-diagnostics.js +64 -0
  273. package/dist/projected-document-action-status-notice-diagnostics.js.map +1 -0
  274. package/dist/projected-document-badge-formatting.d.ts +2 -0
  275. package/dist/projected-document-badge-formatting.d.ts.map +1 -0
  276. package/dist/projected-document-badge-formatting.js +7 -0
  277. package/dist/projected-document-badge-formatting.js.map +1 -0
  278. package/dist/projected-document-editor-model.d.ts +4 -0
  279. package/dist/projected-document-editor-model.d.ts.map +1 -0
  280. package/dist/projected-document-editor-model.js +2 -0
  281. package/dist/projected-document-editor-model.js.map +1 -0
  282. package/dist/projected-document-field-navigation.d.ts +72 -0
  283. package/dist/projected-document-field-navigation.d.ts.map +1 -0
  284. package/dist/projected-document-field-navigation.js +143 -0
  285. package/dist/projected-document-field-navigation.js.map +1 -0
  286. package/dist/projected-document-field-semantics.d.ts +5 -0
  287. package/dist/projected-document-field-semantics.d.ts.map +1 -0
  288. package/dist/projected-document-field-semantics.js +16 -0
  289. package/dist/projected-document-field-semantics.js.map +1 -0
  290. package/dist/projected-document-workspace-data-source-bindings.d.ts +69 -0
  291. package/dist/projected-document-workspace-data-source-bindings.d.ts.map +1 -0
  292. package/dist/projected-document-workspace-data-source-bindings.js +81 -0
  293. package/dist/projected-document-workspace-data-source-bindings.js.map +1 -0
  294. package/dist/projected-document-workspace-notice-diagnostics.d.ts +12 -0
  295. package/dist/projected-document-workspace-notice-diagnostics.d.ts.map +1 -0
  296. package/dist/projected-document-workspace-notice-diagnostics.js +13 -0
  297. package/dist/projected-document-workspace-notice-diagnostics.js.map +1 -0
  298. package/dist/projected-input-form-runtime.d.ts +62 -0
  299. package/dist/projected-input-form-runtime.d.ts.map +1 -0
  300. package/dist/projected-input-form-runtime.js +2 -0
  301. package/dist/projected-input-form-runtime.js.map +1 -0
  302. package/dist/projected-process-task-notice-diagnostics.d.ts +13 -0
  303. package/dist/projected-process-task-notice-diagnostics.d.ts.map +1 -0
  304. package/dist/projected-process-task-notice-diagnostics.js +170 -0
  305. package/dist/projected-process-task-notice-diagnostics.js.map +1 -0
  306. package/dist/projected-query-form-runtime.d.ts +46 -0
  307. package/dist/projected-query-form-runtime.d.ts.map +1 -0
  308. package/dist/projected-query-form-runtime.js +2 -0
  309. package/dist/projected-query-form-runtime.js.map +1 -0
  310. package/dist/prompt-document-preview-projection.d.ts +46 -0
  311. package/dist/prompt-document-preview-projection.d.ts.map +1 -0
  312. package/dist/prompt-document-preview-projection.js +173 -0
  313. package/dist/prompt-document-preview-projection.js.map +1 -0
  314. package/dist/prompt-icons.d.ts +4 -0
  315. package/dist/prompt-icons.d.ts.map +1 -0
  316. package/dist/prompt-icons.js +4 -0
  317. package/dist/prompt-icons.js.map +1 -0
  318. package/dist/prompt-status-message-resolution.d.ts +18 -0
  319. package/dist/prompt-status-message-resolution.d.ts.map +1 -0
  320. package/dist/prompt-status-message-resolution.js +83 -0
  321. package/dist/prompt-status-message-resolution.js.map +1 -0
  322. package/dist/query-form-lowering.d.ts +16 -0
  323. package/dist/query-form-lowering.d.ts.map +1 -0
  324. package/dist/query-form-lowering.js +38 -0
  325. package/dist/query-form-lowering.js.map +1 -0
  326. package/dist/query-form-url-state.d.ts +44 -0
  327. package/dist/query-form-url-state.d.ts.map +1 -0
  328. package/dist/query-form-url-state.js +197 -0
  329. package/dist/query-form-url-state.js.map +1 -0
  330. package/dist/query-offset-page.d.ts +13 -0
  331. package/dist/query-offset-page.d.ts.map +1 -0
  332. package/dist/query-offset-page.js +24 -0
  333. package/dist/query-offset-page.js.map +1 -0
  334. package/dist/relation-query-input-form-target.d.ts +10 -0
  335. package/dist/relation-query-input-form-target.d.ts.map +1 -0
  336. package/dist/relation-query-input-form-target.js +30 -0
  337. package/dist/relation-query-input-form-target.js.map +1 -0
  338. package/dist/scope-selection.d.ts +94 -0
  339. package/dist/scope-selection.d.ts.map +1 -0
  340. package/dist/scope-selection.js +95 -0
  341. package/dist/scope-selection.js.map +1 -0
  342. package/dist/target-bindings.d.ts +39 -0
  343. package/dist/target-bindings.d.ts.map +1 -0
  344. package/dist/target-bindings.js +40 -0
  345. package/dist/target-bindings.js.map +1 -0
  346. package/dist/view-chrome-content-diagnostics.d.ts +8 -0
  347. package/dist/view-chrome-content-diagnostics.d.ts.map +1 -0
  348. package/dist/view-chrome-content-diagnostics.js +84 -0
  349. package/dist/view-chrome-content-diagnostics.js.map +1 -0
  350. package/dist/view-chrome-icons.d.ts +12 -0
  351. package/dist/view-chrome-icons.d.ts.map +1 -0
  352. package/dist/view-chrome-icons.js +50 -0
  353. package/dist/view-chrome-icons.js.map +1 -0
  354. package/dist/view-chrome-slot-renderer-registry.d.ts +19 -0
  355. package/dist/view-chrome-slot-renderer-registry.d.ts.map +1 -0
  356. package/dist/view-chrome-slot-renderer-registry.js +62 -0
  357. package/dist/view-chrome-slot-renderer-registry.js.map +1 -0
  358. package/package.json +53 -0
  359. package/src/api-scope-request.ts +186 -0
  360. package/src/collection-chrome-icons.ts +89 -0
  361. package/src/collection-chrome-runtime.ts +151 -0
  362. package/src/collection-chrome-slot-renderer-registry.ts +227 -0
  363. package/src/collection-selection-state.ts +32 -0
  364. package/src/data-source-projection.ts +2149 -0
  365. package/src/data-source-query-lowering.ts +217 -0
  366. package/src/date-time-filter-model.ts +156 -0
  367. package/src/document-badge-icons.ts +3 -0
  368. package/src/document-module.ts +741 -0
  369. package/src/document-summary-model.ts +1 -0
  370. package/src/document-workspace-chrome-projection.ts +62 -0
  371. package/src/document-workspace-surface-slots.ts +458 -0
  372. package/src/endpoint-executor.ts +122 -0
  373. package/src/field-display-resolution.ts +99 -0
  374. package/src/index.ts +104 -0
  375. package/src/module.ts +281 -0
  376. package/src/navigation-shell-frame-renderer-registry.ts +65 -0
  377. package/src/navigation-shell-layout-runtime.ts +124 -0
  378. package/src/navigation-shell-region-component-registry.ts +242 -0
  379. package/src/navigation-shell-runtime.ts +579 -0
  380. package/src/navigation-shell-slot-renderer-registry.ts +94 -0
  381. package/src/navigation.ts +364 -0
  382. package/src/object-path.ts +99 -0
  383. package/src/page-host-renderer-registry.ts +615 -0
  384. package/src/presentation-action-endpoint-request-projection.ts +223 -0
  385. package/src/presentation-action-endpoint.ts +130 -0
  386. package/src/presentation-action-icons.ts +3 -0
  387. package/src/presentation-action-result-state.ts +189 -0
  388. package/src/presentation-action-runtime-binding.ts +177 -0
  389. package/src/presentation-action-runtime-diagnostics.ts +120 -0
  390. package/src/presentation-action-runtime-labels.ts +57 -0
  391. package/src/presentation-action-runtime-projection.ts +67 -0
  392. package/src/presentation-badge-resolution.ts +138 -0
  393. package/src/presentation-collection-pagination.ts +436 -0
  394. package/src/presentation-content-diagnostics.ts +121 -0
  395. package/src/presentation-content-resolution.ts +46 -0
  396. package/src/presentation-data-source-binding-model.ts +140 -0
  397. package/src/presentation-data-source-runtime.ts +190 -0
  398. package/src/presentation-design-intent-diagnostics.ts +104 -0
  399. package/src/presentation-icon-diagnostics.ts +368 -0
  400. package/src/presentation-icon-registry.ts +181 -0
  401. package/src/presentation-navigation-action-runtime-bindings.ts +54 -0
  402. package/src/presentation-pagination.ts +694 -0
  403. package/src/presentation-projection-coverage.ts +3257 -0
  404. package/src/presentation-projection-diagnostics.ts +71 -0
  405. package/src/presentation-projection-trace.ts +293 -0
  406. package/src/presentation-query-form-state.ts +54 -0
  407. package/src/presentation-renderer-registry.ts +269 -0
  408. package/src/presentation-semantics.ts +1028 -0
  409. package/src/presentation-standards.ts +14 -0
  410. package/src/presentation-test-selectors.ts +312 -0
  411. package/src/presentation-value-formatting.ts +65 -0
  412. package/src/presentation-value-resolution.ts +100 -0
  413. package/src/presentation-view-tree.ts +33 -0
  414. package/src/process-task-model.ts +158 -0
  415. package/src/process-task-projection.ts +398 -0
  416. package/src/projected-action-status-projection.ts +43 -0
  417. package/src/projected-activity-state-model.ts +123 -0
  418. package/src/projected-collection-action-runtime-bindings.ts +76 -0
  419. package/src/projected-collection-action-runtime-diagnostics.ts +289 -0
  420. package/src/projected-collection-runtime.ts +1772 -0
  421. package/src/projected-document-action-diagnostics.ts +196 -0
  422. package/src/projected-document-action-enablements.ts +99 -0
  423. package/src/projected-document-action-projection.ts +464 -0
  424. package/src/projected-document-action-runtime-profile-diagnostics.ts +250 -0
  425. package/src/projected-document-action-runtime-profile.ts +133 -0
  426. package/src/projected-document-action-status-notice-diagnostics.ts +116 -0
  427. package/src/projected-document-badge-formatting.ts +7 -0
  428. package/src/projected-document-editor-model.ts +7 -0
  429. package/src/projected-document-field-navigation.ts +300 -0
  430. package/src/projected-document-field-semantics.ts +27 -0
  431. package/src/projected-document-workspace-data-source-bindings.ts +182 -0
  432. package/src/projected-document-workspace-notice-diagnostics.ts +41 -0
  433. package/src/projected-input-form-runtime.ts +86 -0
  434. package/src/projected-process-task-notice-diagnostics.ts +283 -0
  435. package/src/projected-query-form-runtime.ts +62 -0
  436. package/src/prompt-document-preview-projection.ts +345 -0
  437. package/src/prompt-icons.ts +3 -0
  438. package/src/prompt-status-message-resolution.ts +158 -0
  439. package/src/query-form-lowering.ts +77 -0
  440. package/src/query-form-url-state.ts +346 -0
  441. package/src/query-offset-page.ts +50 -0
  442. package/src/relation-query-input-form-target.ts +61 -0
  443. package/src/scope-selection.ts +201 -0
  444. package/src/target-bindings.ts +123 -0
  445. package/src/view-chrome-content-diagnostics.ts +139 -0
  446. package/src/view-chrome-icons.ts +81 -0
  447. package/src/view-chrome-slot-renderer-registry.ts +128 -0
@@ -0,0 +1,2149 @@
1
+ import {
2
+ findPresentationDataSource,
3
+ type PresentationBindingDefinition,
4
+ type DataSourceDefinition,
5
+ type PresentationModuleDefinition,
6
+ } from './module'
7
+ import {
8
+ isTanStackQueryBinding,
9
+ presentationDataSourceBindings,
10
+ presentationDataSourceAuthorization,
11
+ type PresentationLocalValueDataSourceBinding,
12
+ type PresentationLocalValueDataSourceBindingInput,
13
+ type PresentationDataSourceAuthorizationRequirement,
14
+ type PresentationDataSourceBinding,
15
+ type PresentationTanStackQueryDataSourceBindingInput,
16
+ type PresentationTanStackQueryDataSourceBinding,
17
+ } from './presentation-data-source-binding-model'
18
+ import {
19
+ createDataSourceEndpointQueryRequest,
20
+ createDataSourcePaginationRequest,
21
+ findDataSourceQueryEndpointBinding,
22
+ type DataSourceQueryLoweringTransform,
23
+ } from './data-source-query-lowering'
24
+ import {
25
+ aggregateOperators,
26
+ cachePolicyKinds,
27
+ dataSourceAggregateMaterializationKinds,
28
+ dataSourceAggregatePredicateKinds,
29
+ dataSourceKindLabels,
30
+ dataSourceKinds,
31
+ presentationBindingKinds,
32
+ type AggregateOperator,
33
+ type DataSourceAggregatePredicate,
34
+ type DataSourceAggregateQuery,
35
+ type DataSourceKind,
36
+ type ParameterDefinition,
37
+ } from '@cohesivesystems/presentation-contracts'
38
+ import {
39
+ readPresentationQueryFormAppliedValue,
40
+ type PresentationQueryFormStateMap,
41
+ } from './presentation-query-form-state'
42
+ import {
43
+ readObjectPath,
44
+ writeObjectPath,
45
+ } from './object-path'
46
+ import type {
47
+ PresentationActionResultStateValues,
48
+ } from './presentation-action-result-state'
49
+
50
+ /**
51
+ * Runtime inputs available while projecting semantic data-source definitions
52
+ * into concrete frontend bindings.
53
+ */
54
+ export interface PresentationDataSourceProjectionContext {
55
+ /** Current query-form states keyed by query form or data-source state id. */
56
+ readonly queryFormStates?: PresentationQueryFormStateMap
57
+
58
+ /** Route parameters supplied by the active presentation/navigation host. */
59
+ readonly routeParameters?: Readonly<Record<string, string | undefined>>
60
+
61
+ /** Additional cache-key fragments supplied by the app or route host. */
62
+ readonly queryKeyParts?: readonly unknown[]
63
+
64
+ /** Workspace id used to scope local state or cache identity, when available. */
65
+ readonly workspaceId?: string | null
66
+ }
67
+
68
+ /**
69
+ * Context passed to a registry factory while interpreting one semantic
70
+ * data-source definition.
71
+ */
72
+ export interface PresentationDataSourceBindingFactoryContext {
73
+ /** Backend target binding attached to the data source, when one is declared. */
74
+ readonly binding: PresentationBindingDefinition | null
75
+
76
+ /** Projection context shared by all data sources in the current host. */
77
+ readonly context: PresentationDataSourceProjectionContext
78
+
79
+ /** Data-source definition being projected. */
80
+ readonly dataSource: DataSourceDefinition
81
+
82
+ /** Presentation module that owns the data source and related query metadata. */
83
+ readonly module: PresentationModuleDefinition | null
84
+ }
85
+
86
+ /**
87
+ * Factory that projects one data source into a frontend binding.
88
+ *
89
+ * Returning `null` or `undefined` lets later registry fallbacks attempt the
90
+ * projection.
91
+ */
92
+ export type PresentationDataSourceBindingFactory = (
93
+ context: PresentationDataSourceBindingFactoryContext,
94
+ ) => PresentationDataSourceBinding | null | undefined
95
+
96
+ /**
97
+ * Factory that produces TanStack Query binding input before target-level
98
+ * authorization is applied.
99
+ */
100
+ export type PresentationTanStackQueryDataSourceBindingFactory = (
101
+ context: PresentationDataSourceBindingFactoryContext,
102
+ ) => PresentationTargetInterpretedTanStackQueryDataSourceBindingInput | null | undefined
103
+
104
+ /**
105
+ * Executes a backend endpoint id with the already-projected route/query
106
+ * request payload.
107
+ *
108
+ * @typeParam TResult - Result shape returned by the endpoint executor.
109
+ */
110
+ export type PresentationDataSourceEndpointExecutor = <TResult = unknown>(
111
+ endpointId: string,
112
+ request: PresentationDataSourceEndpointExecutionRequest,
113
+ ) => Promise<TResult>
114
+
115
+ /**
116
+ * Request envelope passed to endpoint executors from projected data-source
117
+ * bindings.
118
+ *
119
+ * @typeParam TQuery - Query payload shape produced by query lowering.
120
+ */
121
+ export interface PresentationDataSourceEndpointExecutionRequest<TQuery = unknown> {
122
+ /** Lowered query payload for endpoint-query data sources. */
123
+ readonly query?: TQuery | null
124
+
125
+ /** Route parameters for endpoint-fetch data sources. */
126
+ readonly routeParameters?: Readonly<Record<string, string | null | undefined>>
127
+ }
128
+
129
+ /**
130
+ * Options read from backend target bindings that steer frontend endpoint and
131
+ * authorization interpretation.
132
+ */
133
+ export interface PresentationDataSourceTargetBindingOptions {
134
+ /** Authorization policy id resolved by the target interpretation. */
135
+ readonly authorizationPolicyId?: string | null
136
+
137
+ /** Endpoint executor target id resolved by the API endpoint interpretation. */
138
+ readonly executionTargetId?: string | null
139
+ }
140
+
141
+ /**
142
+ * Runtime behavior defaults read from data-source annotations and applied to
143
+ * query bindings.
144
+ */
145
+ export interface PresentationDataSourceBindingRuntimeOptions {
146
+ /** Message shown when a successful query returns no presentable items. */
147
+ readonly emptyMessage?: string
148
+
149
+ /** Data used before a query resolves or when a source cannot be materialized. */
150
+ readonly fallbackData?: unknown
151
+
152
+ /** Loading label shown while the binding is pending. */
153
+ readonly pendingLabel?: string
154
+
155
+ /** TanStack Query refetch interval in milliseconds, or `false` to disable it. */
156
+ readonly refetchInterval?: number | false
157
+
158
+ /** TanStack Query retry setting. */
159
+ readonly retry?: boolean | number
160
+
161
+ /** TanStack Query stale time in milliseconds. */
162
+ readonly staleTime?: number
163
+ }
164
+
165
+ /**
166
+ * Local-value binding input whose authorization can be supplied by the active
167
+ * target interpretation instead of every feature-owned binding factory.
168
+ */
169
+ export type PresentationTargetInterpretedLocalValueDataSourceBindingInput = Omit<
170
+ PresentationLocalValueDataSourceBindingInput,
171
+ 'authorization'
172
+ > & {
173
+ readonly authorization?: PresentationDataSourceAuthorizationRequirement
174
+ }
175
+
176
+ // TODO: extract
177
+ /**
178
+ * TanStack Query binding input whose authorization can be supplied by the
179
+ * target interpretation. Feature registries still own request/query shaping.
180
+ */
181
+ export type PresentationTargetInterpretedTanStackQueryDataSourceBindingInput = Omit<
182
+ PresentationTanStackQueryDataSourceBindingInput,
183
+ 'authorization'
184
+ > & {
185
+ readonly authorization?: PresentationDataSourceAuthorizationRequirement
186
+ }
187
+
188
+ /** Resolves a data-source authorization requirement for a target binding. */
189
+ export type PresentationDataSourceAuthorizationFactory = (
190
+ context: PresentationDataSourceBindingFactoryContext,
191
+ ) => PresentationDataSourceAuthorizationRequirement
192
+
193
+ /** Endpoint executors keyed by backend-declared execution target id. */
194
+ export type PresentationDataSourceEndpointExecutorMap = Readonly<Record<
195
+ string,
196
+ PresentationDataSourceEndpointExecutor
197
+ >>
198
+
199
+ /** Authorization factories keyed by backend-declared authorization policy id. */
200
+ export type PresentationDataSourceAuthorizationPolicyMap = Readonly<Record<
201
+ string,
202
+ PresentationDataSourceAuthorizationFactory
203
+ >>
204
+
205
+ /** Target-specific interpretation shared by all data sources of one binding kind. */
206
+ export interface PresentationDataSourceBindingTargetInterpretation {
207
+ /** Default authorization policy for this target binding kind. */
208
+ readonly authorization?: PresentationDataSourceAuthorizationFactory
209
+ }
210
+
211
+ /**
212
+ * Target interpretation for API endpoint data sources. This owns endpoint
213
+ * execution and cross-cutting query defaults; semantic registries can still
214
+ * provide per-source query payloads, labels, and cache keys.
215
+ */
216
+ export interface PresentationDataSourceApiEndpointTargetInterpretation
217
+ extends PresentationDataSourceBindingTargetInterpretation {
218
+ /** Creates a query key for endpoint-backed data sources. */
219
+ readonly createQueryKey?: (context: PresentationDataSourceApiEndpointFactoryContext) => readonly unknown[]
220
+
221
+ /** Default executor for API endpoint data sources. */
222
+ readonly executeEndpoint?: PresentationDataSourceEndpointExecutor
223
+
224
+ /** Executors keyed by target binding `executionTargetId`. */
225
+ readonly executeEndpointByTargetId?: PresentationDataSourceEndpointExecutorMap
226
+
227
+ /** Enables or disables endpoint-backed query execution. */
228
+ readonly isEnabled?: (context: PresentationDataSourceApiEndpointFactoryContext) => boolean
229
+
230
+ /** Default pending label for endpoint-backed query bindings. */
231
+ readonly pendingLabel?:
232
+ | string
233
+ | ((context: PresentationDataSourceApiEndpointFactoryContext) => string)
234
+
235
+ /** Default retry behavior for endpoint-backed query bindings. */
236
+ readonly retry?: boolean
237
+ }
238
+
239
+ /** Target interpretation for backend-declared query lowering transform ids. */
240
+ export interface PresentationDataSourceQueryLoweringTargetInterpretation {
241
+ /** Query-lowering transforms keyed by backend-declared transform id. */
242
+ readonly transformsById?: Readonly<Record<string, DataSourceQueryLoweringTransform>>
243
+ }
244
+
245
+ /**
246
+ * Frontend interpretation of backend data-source target bindings for one
247
+ * concrete presentation target.
248
+ */
249
+ export interface PresentationDataSourceTargetInterpretation {
250
+ /** Interpretation for API endpoint data-source bindings. */
251
+ readonly apiEndpoint?: PresentationDataSourceApiEndpointTargetInterpretation
252
+
253
+ /** Named authorization policies available to target bindings. */
254
+ readonly authorizationPoliciesById?: PresentationDataSourceAuthorizationPolicyMap
255
+
256
+ /** Fallback authorization policy for bindings without a narrower policy. */
257
+ readonly defaultAuthorization?: PresentationDataSourceAuthorizationFactory
258
+
259
+ /** Interpretation for frontend-owned local state data-source bindings. */
260
+ readonly localState?: PresentationDataSourceBindingTargetInterpretation
261
+
262
+ /** Interpretation for backend-declared query-lowering transforms. */
263
+ readonly queryLowering?: PresentationDataSourceQueryLoweringTargetInterpretation
264
+ }
265
+
266
+ /** Options used when invoking a projected endpoint through the target. */
267
+ export interface ExecutePresentationDataSourceTargetEndpointOptions {
268
+ /** Binding whose target options select endpoint executor and authorization policy. */
269
+ readonly binding?: PresentationBindingDefinition | null
270
+ }
271
+
272
+ /**
273
+ * Registry of data-source binding factories used to project semantic data
274
+ * sources onto frontend runtime bindings.
275
+ */
276
+ export interface PresentationDataSourceBindingProjectionRegistry {
277
+ /** Generic factory for API endpoint bindings. */
278
+ readonly apiEndpoint?: PresentationDataSourceBindingFactory
279
+
280
+ /** Exact factories keyed by data-source id. */
281
+ readonly byDataSourceId?: Readonly<Record<string, PresentationDataSourceBindingFactory>>
282
+
283
+ /** Exact factories keyed by endpoint id. */
284
+ readonly byEndpointId?: Readonly<Record<string, PresentationDataSourceBindingFactory>>
285
+
286
+ /** Default authorization policy used by unbound or projected bindings. */
287
+ readonly defaultAuthorization?: (
288
+ context: PresentationDataSourceBindingFactoryContext,
289
+ ) => PresentationDataSourceAuthorizationRequirement
290
+
291
+ /** Last-resort factory when no exact or generic API factory matches. */
292
+ readonly fallback?: PresentationDataSourceBindingFactory
293
+ }
294
+
295
+ /**
296
+ * Options for adapting target-interpreted TanStack Query binding factories into
297
+ * a full data-source projection registry.
298
+ */
299
+ export interface TanStackQueryDataSourceBindingProjectionRegistryOptions {
300
+ /** Generic endpoint factory returning TanStack Query binding input. */
301
+ readonly apiEndpoint?: PresentationTanStackQueryDataSourceBindingFactory
302
+
303
+ /** Exact factories keyed by data-source id. */
304
+ readonly byDataSourceId?: Readonly<Record<string, PresentationDataSourceBindingFactory>>
305
+
306
+ /** Exact endpoint factories keyed by endpoint id. */
307
+ readonly byEndpointId?: Readonly<Record<string, PresentationTanStackQueryDataSourceBindingFactory>>
308
+
309
+ /** Authorization policy applied when a factory does not provide one. */
310
+ readonly defaultAuthorization?: (
311
+ context: PresentationDataSourceBindingFactoryContext,
312
+ ) => PresentationDataSourceAuthorizationRequirement
313
+
314
+ /** Active target interpretation that supplies authorization and execution defaults. */
315
+ readonly targetInterpretation?: PresentationDataSourceTargetInterpretation
316
+ }
317
+
318
+ /**
319
+ * Options for the generic API endpoint TanStack Query projector.
320
+ */
321
+ export interface ApiEndpointTanStackQueryDataSourceBindingProjectionRegistryOptions {
322
+ /** Optional target-specific cache key builder. */
323
+ readonly createQueryKey?: (
324
+ context: PresentationDataSourceApiEndpointFactoryContext,
325
+ ) => readonly unknown[]
326
+
327
+ /** Optional endpoint executor overriding the active target interpretation. */
328
+ readonly executeEndpoint?: PresentationDataSourceEndpointExecutor
329
+
330
+ /** Optional query enablement guard. */
331
+ readonly isEnabled?: (context: PresentationDataSourceApiEndpointFactoryContext) => boolean
332
+
333
+ /** Pending label or label factory for generated query bindings. */
334
+ readonly pendingLabel?: string | ((context: PresentationDataSourceApiEndpointFactoryContext) => string)
335
+
336
+ /** Retry behavior for generated query bindings. */
337
+ readonly retry?: boolean
338
+
339
+ /** Default authorization policy applied to generated query bindings. */
340
+ readonly defaultAuthorization?: (
341
+ context: PresentationDataSourceBindingFactoryContext,
342
+ ) => PresentationDataSourceAuthorizationRequirement
343
+
344
+ /** Active target interpretation that supplies defaults not provided here. */
345
+ readonly targetInterpretation?: PresentationDataSourceTargetInterpretation
346
+ }
347
+
348
+ /**
349
+ * Factory context for API endpoint data-source bindings after endpoint id and
350
+ * route parameters have been resolved.
351
+ */
352
+ export interface PresentationDataSourceApiEndpointFactoryContext
353
+ extends PresentationDataSourceBindingFactoryContext {
354
+ /** Resolved API endpoint id. */
355
+ readonly endpointId: string
356
+
357
+ /** Route parameters projected for this data source. */
358
+ readonly routeParameters: Readonly<Record<string, string | null | undefined>>
359
+ }
360
+
361
+ /** Options for projecting a list of semantic data-source ids. */
362
+ export interface ProjectPresentationDataSourceBindingsOptions {
363
+ /** Shared runtime projection context. */
364
+ readonly context?: PresentationDataSourceProjectionContext
365
+
366
+ /** Fallback data-source definitions when the module does not contain an id. */
367
+ readonly dataSourceDefinitions?: readonly DataSourceDefinition[]
368
+
369
+ /** Data-source ids to project, de-duplicated before projection. */
370
+ readonly dataSourceIds: readonly string[]
371
+
372
+ /** Presentation module that owns data-source definitions and target bindings. */
373
+ readonly module: PresentationModuleDefinition | null
374
+
375
+ /** Projection registry used to resolve concrete frontend bindings. */
376
+ readonly registry: PresentationDataSourceBindingProjectionRegistry
377
+ }
378
+
379
+ /**
380
+ * Options for creating endpoint-query binding input from backend query
381
+ * lowering.
382
+ *
383
+ * @typeParam TRequest - Lowered endpoint query request shape.
384
+ */
385
+ export interface CreateDataSourceEndpointQueryBindingInputOptions<
386
+ TRequest extends object,
387
+ > {
388
+ /** Factory context for the data source being projected. */
389
+ readonly context: PresentationDataSourceBindingFactoryContext
390
+
391
+ /** Base request values merged into the lowered query request. */
392
+ readonly defaultRequest?: Partial<TRequest>
393
+
394
+ /** Empty-state message for the generated query binding. */
395
+ readonly emptyMessage?: string
396
+
397
+ /** Query enablement override. */
398
+ readonly enabled?: boolean
399
+
400
+ /** Endpoint id to execute. */
401
+ readonly endpointId: string
402
+
403
+ /** Fallback data for the generated query binding. */
404
+ readonly fallbackData?: unknown
405
+
406
+ /** Pagination request merged into the lowered query request. */
407
+ readonly paginationRequest?: object | null
408
+
409
+ /** Pending label for the generated query binding. */
410
+ readonly pendingLabel?: string
411
+
412
+ /** Additional query-key fragments. */
413
+ readonly queryKeyParts?: readonly unknown[]
414
+
415
+ /** Refetch interval in milliseconds, or `false` to disable it. */
416
+ readonly refetchInterval?: number | false
417
+
418
+ /** Retry behavior for the generated query binding. */
419
+ readonly retry?: boolean | number
420
+
421
+ /** Stale time in milliseconds. */
422
+ readonly staleTime?: number
423
+
424
+ /** Target interpretation used for endpoint execution and authorization. */
425
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
426
+
427
+ /** Per-source query lowering transforms. */
428
+ readonly transforms?: Readonly<Record<string, DataSourceQueryLoweringTransform>>
429
+
430
+ /** Source value used by query lowering. */
431
+ readonly value?: unknown
432
+ }
433
+
434
+ /** Options for creating endpoint-fetch binding input from a data source. */
435
+ export interface CreateDataSourceEndpointFetchBindingInputOptions {
436
+ /** Factory context for the data source being projected. */
437
+ readonly context: PresentationDataSourceBindingFactoryContext
438
+
439
+ /** Empty-state message for the generated query binding. */
440
+ readonly emptyMessage?: string
441
+
442
+ /** Query enablement override. */
443
+ readonly enabled?: boolean
444
+
445
+ /** Endpoint id to execute, defaulting to the data-source binding endpoint. */
446
+ readonly endpointId?: string
447
+
448
+ /** Fallback data for the generated query binding. */
449
+ readonly fallbackData?: unknown
450
+
451
+ /** Pending label for the generated query binding. */
452
+ readonly pendingLabel?: string
453
+
454
+ /** Additional query-key fragments. */
455
+ readonly queryKeyParts?: readonly unknown[]
456
+
457
+ /** Refetch interval in milliseconds, or `false` to disable it. */
458
+ readonly refetchInterval?: number | false
459
+
460
+ /** Retry behavior for the generated query binding. */
461
+ readonly retry?: boolean | number
462
+
463
+ /** Route parameters to pass to the endpoint executor. */
464
+ readonly routeParameters?: Readonly<Record<string, string | null | undefined>>
465
+
466
+ /** Stale time in milliseconds. */
467
+ readonly staleTime?: number
468
+
469
+ /** Target interpretation used for endpoint execution and authorization. */
470
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
471
+ }
472
+
473
+ /** Options for projecting an aggregate-query data source. */
474
+ export interface CreateDataSourceAggregateQueryBindingOptions {
475
+ /** Factory context for the aggregate data source being projected. */
476
+ readonly context: PresentationDataSourceBindingFactoryContext
477
+
478
+ /** Additional query-key fragments. */
479
+ readonly queryKeyParts?: readonly unknown[]
480
+
481
+ /** Target interpretation used to materialize source data. */
482
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
483
+
484
+ /** Per-source query lowering transforms used to query the source data source. */
485
+ readonly transforms?: Readonly<Record<string, DataSourceQueryLoweringTransform>>
486
+
487
+ /** Source value used by query lowering. */
488
+ readonly value?: unknown
489
+ }
490
+
491
+ /** Options for creating a collection-query projection registry. */
492
+ export interface CreateCollectionQueryDataSourceBindingProjectionRegistryOptions {
493
+ /** Pagination requests keyed by data-source id. */
494
+ readonly paginationRequestsByDataSourceId?: Readonly<Record<string, object | null | undefined>>
495
+
496
+ /** Static or computed query-key fragments. */
497
+ readonly queryKeyParts?:
498
+ | readonly unknown[]
499
+ | ((context: PresentationDataSourceBindingFactoryContext) => readonly unknown[])
500
+
501
+ /** Optional local-value override for collection data sources. */
502
+ readonly resolveLocalValue?: (
503
+ context: PresentationDataSourceBindingFactoryContext,
504
+ ) => PresentationTargetInterpretedLocalValueDataSourceBindingInput | null | undefined
505
+
506
+ /** Optional per-source query-lowering transform resolver. */
507
+ readonly resolveTransforms?: (
508
+ context: PresentationDataSourceBindingFactoryContext,
509
+ ) => Readonly<Record<string, DataSourceQueryLoweringTransform>> | undefined
510
+
511
+ /** Optional source value resolver for query lowering. */
512
+ readonly resolveValue?: (
513
+ context: PresentationDataSourceBindingFactoryContext,
514
+ ) => unknown
515
+
516
+ /** Target interpretation used for generated bindings. */
517
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
518
+ }
519
+
520
+ /** Options for creating an aggregate-query projection registry. */
521
+ export interface CreateAggregateQueryDataSourceBindingProjectionRegistryOptions {
522
+ /** Static or computed query-key fragments. */
523
+ readonly queryKeyParts?:
524
+ | readonly unknown[]
525
+ | ((context: PresentationDataSourceBindingFactoryContext) => readonly unknown[])
526
+
527
+ /** Optional per-source query-lowering transform resolver. */
528
+ readonly resolveTransforms?: (
529
+ context: PresentationDataSourceBindingFactoryContext,
530
+ ) => Readonly<Record<string, DataSourceQueryLoweringTransform>> | undefined
531
+
532
+ /** Optional source value resolver for query lowering. */
533
+ readonly resolveValue?: (
534
+ context: PresentationDataSourceBindingFactoryContext,
535
+ ) => unknown
536
+
537
+ /** Target interpretation used for generated bindings. */
538
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
539
+ }
540
+
541
+ /** Options for creating endpoint-fetch projection registries. */
542
+ export interface CreateApiEndpointFetchDataSourceBindingProjectionRegistryOptions {
543
+ /** Static or computed query-key fragments. */
544
+ readonly queryKeyParts?:
545
+ | readonly unknown[]
546
+ | ((context: PresentationDataSourceBindingFactoryContext) => readonly unknown[])
547
+
548
+ /** Target interpretation used for generated bindings. */
549
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
550
+ }
551
+
552
+ /** Options for creating local-state projection registries. */
553
+ export interface CreateLocalStateDataSourceBindingProjectionRegistryOptions {
554
+ /** Resolves a local-value binding input for a local-state data source. */
555
+ readonly resolveLocalValue: (
556
+ context: PresentationDataSourceBindingFactoryContext,
557
+ ) => PresentationTargetInterpretedLocalValueDataSourceBindingInput | null | undefined
558
+
559
+ /** Target interpretation used for authorization defaults. */
560
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
561
+ }
562
+
563
+ /** Options for projecting action-result state values as data-source bindings. */
564
+ export interface CreateActionResultStateDataSourceBindingProjectionRegistryOptions {
565
+ /** Route-scoped data-source values written by action result policies. */
566
+ readonly values?: PresentationActionResultStateValues
567
+
568
+ /** Target interpretation used for authorization defaults. */
569
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
570
+ }
571
+
572
+ /** Static or factory-produced query-key fragments used by binding projectors. */
573
+ export type DataSourceQueryKeyParts =
574
+ | readonly unknown[]
575
+ | ((context: PresentationDataSourceBindingFactoryContext) => readonly unknown[])
576
+
577
+ /**
578
+ * Per-data-source interpretation hooks used by collection and aggregate query
579
+ * projectors.
580
+ */
581
+ export interface DataSourceQueryInterpretation {
582
+ /** Optional local-value override for the data source. */
583
+ readonly localValue?: (context: PresentationDataSourceBindingFactoryContext) => PresentationTargetInterpretedLocalValueDataSourceBindingInput | null | undefined
584
+
585
+ /** Normalizes a source value before query lowering. */
586
+ readonly normalizeValue?: (value: unknown, context: PresentationDataSourceBindingFactoryContext) => unknown
587
+
588
+ /** Query-key fragments for this data source. */
589
+ readonly queryKeyParts?: DataSourceQueryKeyParts
590
+
591
+ /** Reads the source value used by query lowering. */
592
+ readonly readValue?: (context: PresentationDataSourceBindingFactoryContext) => unknown
593
+
594
+ /** Per-data-source query lowering transforms or transform resolver. */
595
+ readonly transforms?:
596
+ | Readonly<Record<string, DataSourceQueryLoweringTransform>>
597
+ | ((context: PresentationDataSourceBindingFactoryContext) => Readonly<Record<string, DataSourceQueryLoweringTransform>> | undefined)
598
+ }
599
+
600
+ /** Registry of query interpretation hooks keyed by data-source id. */
601
+ export interface DataSourceQueryInterpretationRegistry {
602
+ /** Per-source interpretation hooks keyed by data-source id. */
603
+ readonly byDataSourceId?: Readonly<Record<string, DataSourceQueryInterpretation>>
604
+
605
+ /** Default query-key fragments when a source has no override. */
606
+ readonly defaultQueryKeyParts?: DataSourceQueryKeyParts
607
+
608
+ /** Shared query lowering transforms or transform resolver. */
609
+ readonly transforms?:
610
+ | Readonly<Record<string, DataSourceQueryLoweringTransform>>
611
+ | ((context: PresentationDataSourceBindingFactoryContext) => Readonly<Record<string, DataSourceQueryLoweringTransform>> | undefined)
612
+ }
613
+
614
+ /**
615
+ * Resolvers adapted from a query interpretation registry to the option shape
616
+ * consumed by collection and aggregate binding registry factories.
617
+ */
618
+ export type DataSourceQueryInterpretationResolvers = Pick<
619
+ CreateCollectionQueryDataSourceBindingProjectionRegistryOptions,
620
+ 'queryKeyParts' | 'resolveLocalValue' | 'resolveTransforms' | 'resolveValue'
621
+ > &
622
+ Pick<
623
+ CreateAggregateQueryDataSourceBindingProjectionRegistryOptions,
624
+ 'queryKeyParts' | 'resolveTransforms' | 'resolveValue'
625
+ >
626
+
627
+ /** Preserves target interpretation objects as a named projection concept. */
628
+ export function createPresentationDataSourceTargetInterpretation(
629
+ interpretation: PresentationDataSourceTargetInterpretation,
630
+ ): PresentationDataSourceTargetInterpretation {
631
+ return interpretation
632
+ }
633
+
634
+ /**
635
+ * Resolves authorization from the target interpretation based on the backend
636
+ * binding kind declared for the data source.
637
+ */
638
+ export function resolvePresentationDataSourceTargetAuthorization(
639
+ targetInterpretation: PresentationDataSourceTargetInterpretation | undefined,
640
+ context: PresentationDataSourceBindingFactoryContext,
641
+ ): PresentationDataSourceAuthorizationRequirement {
642
+ const options = readPresentationDataSourceTargetBindingOptions(context.binding)
643
+ if (options.authorizationPolicyId) {
644
+ return (
645
+ targetInterpretation?.authorizationPoliciesById?.[options.authorizationPolicyId]?.(context) ??
646
+ presentationDataSourceAuthorization.required({
647
+ blockedLabel: `No frontend authorization policy is registered for '${options.authorizationPolicyId}'.`,
648
+ isAuthorized: false,
649
+ })
650
+ )
651
+ }
652
+
653
+ if (isApiEndpointBinding(context.binding)) {
654
+ return (
655
+ targetInterpretation?.apiEndpoint?.authorization?.(context) ??
656
+ targetInterpretation?.defaultAuthorization?.(context) ??
657
+ presentationDataSourceAuthorization.none()
658
+ )
659
+ }
660
+
661
+ if (isLocalStateBinding(context.binding)) {
662
+ return (
663
+ targetInterpretation?.localState?.authorization?.(context) ??
664
+ targetInterpretation?.defaultAuthorization?.(context) ??
665
+ presentationDataSourceAuthorization.none()
666
+ )
667
+ }
668
+
669
+ return (
670
+ targetInterpretation?.defaultAuthorization?.(context) ??
671
+ presentationDataSourceAuthorization.none()
672
+ )
673
+ }
674
+
675
+ /** Creates a local-value binding with authorization supplied by the target. */
676
+ export function createTargetInterpretedLocalValueDataSourceBinding(
677
+ context: PresentationDataSourceBindingFactoryContext,
678
+ targetInterpretation: PresentationDataSourceTargetInterpretation | undefined,
679
+ binding: PresentationTargetInterpretedLocalValueDataSourceBindingInput,
680
+ ): PresentationLocalValueDataSourceBinding {
681
+ const { authorization, ...bindingWithoutAuthorization } = binding
682
+ return presentationDataSourceBindings.localValue({
683
+ ...bindingWithoutAuthorization,
684
+ authorization:
685
+ authorization ??
686
+ resolvePresentationDataSourceTargetAuthorization(targetInterpretation, context),
687
+ })
688
+ }
689
+
690
+ /** Creates a TanStack Query binding with authorization supplied by the target. */
691
+ export function createTargetInterpretedTanStackQueryDataSourceBinding(
692
+ context: PresentationDataSourceBindingFactoryContext,
693
+ targetInterpretation: PresentationDataSourceTargetInterpretation | undefined,
694
+ binding: PresentationTargetInterpretedTanStackQueryDataSourceBindingInput,
695
+ defaultAuthorization?: PresentationDataSourceAuthorizationFactory,
696
+ ): PresentationTanStackQueryDataSourceBinding {
697
+ const { authorization, ...bindingWithoutAuthorization } = binding
698
+ return presentationDataSourceBindings.tanstackQuery({
699
+ ...bindingWithoutAuthorization,
700
+ authorization:
701
+ authorization ??
702
+ defaultAuthorization?.(context) ??
703
+ resolvePresentationDataSourceTargetAuthorization(targetInterpretation, context),
704
+ })
705
+ }
706
+
707
+ /** Creates endpoint-query binding input from backend-declared query lowering. */
708
+ export function createDataSourceEndpointQueryBindingInput<
709
+ TRequest extends object = Record<string, unknown>,
710
+ TResult = unknown,
711
+ >({
712
+ context,
713
+ defaultRequest,
714
+ emptyMessage,
715
+ enabled,
716
+ endpointId,
717
+ fallbackData,
718
+ paginationRequest,
719
+ pendingLabel,
720
+ queryKeyParts = [],
721
+ refetchInterval,
722
+ retry,
723
+ staleTime,
724
+ targetInterpretation,
725
+ transforms,
726
+ value,
727
+ }: CreateDataSourceEndpointQueryBindingInputOptions<TRequest>): PresentationTargetInterpretedTanStackQueryDataSourceBindingInput {
728
+ const loweredTransforms = mergeDataSourceQueryLoweringTransforms(
729
+ targetInterpretation.queryLowering?.transformsById,
730
+ transforms,
731
+ )
732
+ const query = createDataSourceEndpointQueryRequest<TRequest>({
733
+ dataSource: context.dataSource,
734
+ defaultRequest,
735
+ endpointId,
736
+ paginationRequest,
737
+ transforms: loweredTransforms,
738
+ value,
739
+ })
740
+ const runtimeOptions = readDataSourceBindingRuntimeOptions(context.dataSource)
741
+
742
+ return {
743
+ dataSourceId: context.dataSource.Id,
744
+ emptyMessage: emptyMessage ?? runtimeOptions.emptyMessage,
745
+ enabled,
746
+ fallbackData: fallbackData === undefined ? runtimeOptions.fallbackData : fallbackData,
747
+ pendingLabel: pendingLabel ?? runtimeOptions.pendingLabel,
748
+ queryFn: () =>
749
+ executePresentationDataSourceTargetEndpoint<TResult>(
750
+ targetInterpretation,
751
+ endpointId,
752
+ { query },
753
+ { binding: context.binding },
754
+ ),
755
+ queryKey: [
756
+ 'presentation-data-source-endpoint-query',
757
+ context.dataSource.Id,
758
+ endpointId,
759
+ query,
760
+ ...queryKeyParts,
761
+ ],
762
+ refetchInterval: refetchInterval ?? runtimeOptions.refetchInterval,
763
+ retry: retry ?? runtimeOptions.retry,
764
+ staleTime: staleTime ?? runtimeOptions.staleTime,
765
+ }
766
+ }
767
+
768
+ /** Creates a fully wrapped endpoint-query binding from backend query lowering. */
769
+ export function createDataSourceEndpointQueryBinding<
770
+ TRequest extends object = Record<string, unknown>,
771
+ TResult = unknown,
772
+ >(
773
+ options: CreateDataSourceEndpointQueryBindingInputOptions<TRequest>,
774
+ ): PresentationTanStackQueryDataSourceBinding {
775
+ return createTargetInterpretedTanStackQueryDataSourceBinding(
776
+ options.context,
777
+ options.targetInterpretation,
778
+ createDataSourceEndpointQueryBindingInput<TRequest, TResult>(options),
779
+ )
780
+ }
781
+
782
+ /** Creates a default binding registry for backend-declared collection-query data sources. */
783
+ export function createCollectionQueryDataSourceBindingProjectionRegistry({
784
+ paginationRequestsByDataSourceId = {},
785
+ queryKeyParts = [],
786
+ resolveLocalValue,
787
+ resolveTransforms,
788
+ resolveValue,
789
+ targetInterpretation,
790
+ }: CreateCollectionQueryDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
791
+ return {
792
+ apiEndpoint: (context) => {
793
+ if (
794
+ !isCollectionQueryDataSource(context.dataSource) ||
795
+ !context.dataSource.Query
796
+ ) {
797
+ return null
798
+ }
799
+
800
+ const localValue = resolveLocalValue?.(context)
801
+ if (localValue) {
802
+ return createTargetInterpretedLocalValueDataSourceBinding(
803
+ context,
804
+ targetInterpretation,
805
+ localValue,
806
+ )
807
+ }
808
+
809
+ const endpointId = readPresentationDataSourceEndpointId(context.binding)
810
+ if (!endpointId) {
811
+ return null
812
+ }
813
+
814
+ return createDataSourceEndpointQueryBinding({
815
+ context,
816
+ endpointId,
817
+ paginationRequest: paginationRequestsByDataSourceId[context.dataSource.Id],
818
+ queryKeyParts: resolveQueryKeyParts(queryKeyParts, context),
819
+ targetInterpretation,
820
+ transforms: resolveTransforms?.(context),
821
+ value:
822
+ resolveValue?.(context) ??
823
+ readPresentationQueryFormAppliedValue(context.context, context.dataSource.Id),
824
+ })
825
+ },
826
+ }
827
+ }
828
+
829
+ /** Creates a default binding registry for backend-declared aggregate-query data sources. */
830
+ export function createAggregateQueryDataSourceBindingProjectionRegistry({
831
+ queryKeyParts = [],
832
+ resolveTransforms,
833
+ resolveValue,
834
+ targetInterpretation,
835
+ }: CreateAggregateQueryDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
836
+ return {
837
+ fallback: (context) => {
838
+ if (
839
+ !isAggregateQueryDataSource(context.dataSource) ||
840
+ !context.dataSource.Aggregation
841
+ ) {
842
+ return null
843
+ }
844
+
845
+ return createDataSourceAggregateQueryBinding({
846
+ context,
847
+ queryKeyParts: resolveQueryKeyParts(queryKeyParts, context),
848
+ targetInterpretation,
849
+ transforms: resolveTransforms?.(context),
850
+ value: resolveValue?.(context),
851
+ })
852
+ },
853
+ }
854
+ }
855
+
856
+ /** Creates a default fetch binding registry for endpoint-backed data sources. */
857
+ export function createApiEndpointFetchDataSourceBindingProjectionRegistry({
858
+ queryKeyParts = [],
859
+ targetInterpretation,
860
+ }: CreateApiEndpointFetchDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
861
+ return {
862
+ apiEndpoint: (context) => {
863
+ if (context.dataSource.Query || isPromptPreviewDataSource(context.dataSource)) {
864
+ return null
865
+ }
866
+
867
+ const endpointId = readPresentationDataSourceEndpointId(context.binding)
868
+ if (!endpointId) {
869
+ return null
870
+ }
871
+
872
+ return createDataSourceEndpointFetchBinding({
873
+ context,
874
+ endpointId,
875
+ queryKeyParts: resolveQueryKeyParts(queryKeyParts, context),
876
+ targetInterpretation,
877
+ })
878
+ },
879
+ }
880
+ }
881
+
882
+ /** Creates a default binding registry for frontend-owned local-state data sources. */
883
+ export function createLocalStateDataSourceBindingProjectionRegistry({
884
+ resolveLocalValue,
885
+ targetInterpretation,
886
+ }: CreateLocalStateDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
887
+ return {
888
+ fallback: (context) => {
889
+ if (!isLocalStateDataSource(context.dataSource)) {
890
+ return null
891
+ }
892
+
893
+ const localValue = resolveLocalValue(context)
894
+ return localValue
895
+ ? createTargetInterpretedLocalValueDataSourceBinding(
896
+ context,
897
+ targetInterpretation,
898
+ localValue,
899
+ )
900
+ : null
901
+ },
902
+ }
903
+ }
904
+
905
+ /**
906
+ * Creates a binding registry that exposes action-result state writes as local
907
+ * values for their target data sources.
908
+ */
909
+ export function createActionResultStateDataSourceBindingProjectionRegistry({
910
+ targetInterpretation,
911
+ values = {},
912
+ }: CreateActionResultStateDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
913
+ return {
914
+ fallback: (context) => {
915
+ if (!hasOwn(values, context.dataSource.Id)) {
916
+ return null
917
+ }
918
+
919
+ return createTargetInterpretedLocalValueDataSourceBinding(
920
+ context,
921
+ targetInterpretation,
922
+ {
923
+ data: values[context.dataSource.Id],
924
+ dataSourceId: context.dataSource.Id,
925
+ },
926
+ )
927
+ },
928
+ }
929
+ }
930
+
931
+ /** Adapts data-source query interpretation metadata to collection/aggregate projector hooks. */
932
+ export function createDataSourceQueryInterpretationResolvers({
933
+ byDataSourceId = {},
934
+ defaultQueryKeyParts = [],
935
+ transforms,
936
+ }: DataSourceQueryInterpretationRegistry): DataSourceQueryInterpretationResolvers {
937
+ return {
938
+ queryKeyParts: (context) =>
939
+ resolveQueryKeyParts(
940
+ byDataSourceId[context.dataSource.Id]?.queryKeyParts ?? defaultQueryKeyParts,
941
+ context,
942
+ ),
943
+ resolveLocalValue: (context) =>
944
+ byDataSourceId[context.dataSource.Id]?.localValue?.(context),
945
+ resolveTransforms: (context) =>
946
+ resolveDataSourceQueryInterpretationTransforms(
947
+ byDataSourceId[context.dataSource.Id],
948
+ transforms,
949
+ context,
950
+ ),
951
+ resolveValue: (context) =>
952
+ resolveDataSourceQueryInterpretationValue(
953
+ byDataSourceId[context.dataSource.Id],
954
+ context,
955
+ ),
956
+ }
957
+ }
958
+
959
+ /** Creates endpoint-fetch binding input from an API endpoint data source. */
960
+ export function createDataSourceEndpointFetchBindingInput<TResult = unknown>({
961
+ context,
962
+ emptyMessage,
963
+ enabled,
964
+ endpointId,
965
+ fallbackData,
966
+ pendingLabel,
967
+ queryKeyParts = [],
968
+ refetchInterval,
969
+ retry,
970
+ routeParameters,
971
+ staleTime,
972
+ targetInterpretation,
973
+ }: CreateDataSourceEndpointFetchBindingInputOptions): PresentationTargetInterpretedTanStackQueryDataSourceBindingInput {
974
+ const runtimeOptions = readDataSourceBindingRuntimeOptions(context.dataSource)
975
+ const resolvedEndpointId = endpointId ?? readPresentationDataSourceEndpointId(context.binding)
976
+ const resolvedRouteParameters =
977
+ routeParameters ??
978
+ projectDataSourceRouteParameters(
979
+ context.dataSource.Parameters,
980
+ context.context.routeParameters,
981
+ )
982
+ const hasRequiredRouteParameters = hasRequiredDataSourceRouteParameters(
983
+ context.dataSource.Parameters,
984
+ resolvedRouteParameters,
985
+ )
986
+
987
+ return {
988
+ dataSourceId: context.dataSource.Id,
989
+ emptyMessage: emptyMessage ?? runtimeOptions.emptyMessage,
990
+ enabled: Boolean(resolvedEndpointId) && (enabled ?? true) && hasRequiredRouteParameters,
991
+ fallbackData: fallbackData === undefined ? runtimeOptions.fallbackData : fallbackData,
992
+ pendingLabel: pendingLabel ?? runtimeOptions.pendingLabel,
993
+ queryFn: () =>
994
+ resolvedEndpointId
995
+ ? executePresentationDataSourceTargetEndpoint<TResult>(
996
+ targetInterpretation,
997
+ resolvedEndpointId,
998
+ { routeParameters: resolvedRouteParameters },
999
+ { binding: context.binding },
1000
+ )
1001
+ : Promise.reject(
1002
+ new Error(`Data source '${context.dataSource.Id}' is not bound to an API endpoint.`),
1003
+ ),
1004
+ queryKey: [
1005
+ 'presentation-data-source-endpoint-fetch',
1006
+ context.dataSource.Id,
1007
+ resolvedEndpointId,
1008
+ resolvedRouteParameters,
1009
+ ...queryKeyParts,
1010
+ ],
1011
+ refetchInterval: refetchInterval ?? runtimeOptions.refetchInterval,
1012
+ retry: retry ?? runtimeOptions.retry,
1013
+ staleTime: staleTime ?? runtimeOptions.staleTime,
1014
+ }
1015
+ }
1016
+
1017
+ /** Creates a fully wrapped endpoint-fetch binding from an API endpoint data source. */
1018
+ export function createDataSourceEndpointFetchBinding<TResult = unknown>(
1019
+ options: CreateDataSourceEndpointFetchBindingInputOptions,
1020
+ ): PresentationTanStackQueryDataSourceBinding {
1021
+ return createTargetInterpretedTanStackQueryDataSourceBinding(
1022
+ options.context,
1023
+ options.targetInterpretation,
1024
+ createDataSourceEndpointFetchBindingInput<TResult>(options),
1025
+ )
1026
+ }
1027
+
1028
+ /** Creates a binding that materializes a source data source and evaluates aggregate measures. */
1029
+ export function createDataSourceAggregateQueryBinding({
1030
+ context,
1031
+ queryKeyParts = [],
1032
+ targetInterpretation,
1033
+ transforms,
1034
+ value,
1035
+ }: CreateDataSourceAggregateQueryBindingOptions): PresentationTanStackQueryDataSourceBinding | null {
1036
+ const aggregation = context.dataSource.Aggregation
1037
+ if (!aggregation) {
1038
+ return null
1039
+ }
1040
+
1041
+ const sourceDataSource = findPresentationDataSource(
1042
+ context.module,
1043
+ aggregation.SourceDataSourceId,
1044
+ )
1045
+ const sourceEndpointId = readPresentationDataSourceEndpointId(sourceDataSource?.Binding)
1046
+ if (!sourceDataSource || !sourceEndpointId) {
1047
+ return createTargetInterpretedTanStackQueryDataSourceBinding(
1048
+ context,
1049
+ targetInterpretation,
1050
+ {
1051
+ authorization: presentationDataSourceAuthorization.required({
1052
+ blockedLabel: `Aggregate data source '${context.dataSource.Id}' cannot resolve source '${aggregation.SourceDataSourceId}'.`,
1053
+ isAuthorized: false,
1054
+ }),
1055
+ dataSourceId: context.dataSource.Id,
1056
+ queryFn: () => Promise.resolve(evaluateDataSourceAggregateQuery(aggregation, [])),
1057
+ queryKey: [
1058
+ 'presentation-data-source-aggregate-query',
1059
+ context.dataSource.Id,
1060
+ aggregation.SourceDataSourceId,
1061
+ 'missing-source',
1062
+ ...queryKeyParts,
1063
+ ],
1064
+ },
1065
+ )
1066
+ }
1067
+
1068
+ const appliedValue =
1069
+ value ?? readPresentationQueryFormAppliedValue(context.context, context.dataSource.Id)
1070
+ const runtimeOptions = readDataSourceBindingRuntimeOptions(context.dataSource)
1071
+ const fallbackData =
1072
+ runtimeOptions.fallbackData === undefined
1073
+ ? evaluateDataSourceAggregateQuery(aggregation, [])
1074
+ : runtimeOptions.fallbackData
1075
+ const sourceAuthorization = resolvePresentationDataSourceTargetAuthorization(
1076
+ targetInterpretation,
1077
+ {
1078
+ ...context,
1079
+ binding: sourceDataSource.Binding ?? null,
1080
+ dataSource: sourceDataSource,
1081
+ },
1082
+ )
1083
+ const loweredTransforms = mergeDataSourceQueryLoweringTransforms(
1084
+ targetInterpretation.queryLowering?.transformsById,
1085
+ transforms,
1086
+ )
1087
+
1088
+ return createTargetInterpretedTanStackQueryDataSourceBinding(
1089
+ context,
1090
+ targetInterpretation,
1091
+ {
1092
+ authorization: sourceAuthorization,
1093
+ dataSourceId: context.dataSource.Id,
1094
+ fallbackData,
1095
+ pendingLabel: runtimeOptions.pendingLabel,
1096
+ queryFn: async () => {
1097
+ const items = await materializeDataSourceAggregateItems({
1098
+ aggregation,
1099
+ sourceDataSource,
1100
+ sourceEndpointId,
1101
+ targetInterpretation,
1102
+ transforms: loweredTransforms,
1103
+ value: appliedValue,
1104
+ })
1105
+ return evaluateDataSourceAggregateQuery(aggregation, items)
1106
+ },
1107
+ queryKey: [
1108
+ 'presentation-data-source-aggregate-query',
1109
+ context.dataSource.Id,
1110
+ sourceDataSource.Id,
1111
+ appliedValue ?? {},
1112
+ aggregation,
1113
+ ...queryKeyParts,
1114
+ ],
1115
+ refetchInterval: runtimeOptions.refetchInterval,
1116
+ retry: runtimeOptions.retry,
1117
+ staleTime: runtimeOptions.staleTime,
1118
+ },
1119
+ )
1120
+ }
1121
+
1122
+ /** Executes an API endpoint through the active target interpretation. */
1123
+ export function executePresentationDataSourceTargetEndpoint<TResult = unknown>(
1124
+ targetInterpretation: PresentationDataSourceTargetInterpretation,
1125
+ endpointId: string,
1126
+ request: PresentationDataSourceEndpointExecutionRequest = {},
1127
+ options: ExecutePresentationDataSourceTargetEndpointOptions = {},
1128
+ ): Promise<TResult> {
1129
+ const executeEndpoint = resolvePresentationDataSourceTargetEndpointExecutor(
1130
+ targetInterpretation,
1131
+ options.binding,
1132
+ )
1133
+ if (!executeEndpoint) {
1134
+ const executionTargetId = readPresentationDataSourceTargetBindingOptions(
1135
+ options.binding,
1136
+ ).executionTargetId
1137
+ return Promise.reject(
1138
+ new Error(
1139
+ executionTargetId
1140
+ ? `No API endpoint executor is registered for presentation data-source execution target '${executionTargetId}'.`
1141
+ : `No API endpoint executor is registered for presentation data-source endpoint '${endpointId}'.`,
1142
+ ),
1143
+ )
1144
+ }
1145
+
1146
+ return executeEndpoint<TResult>(endpointId, request)
1147
+ }
1148
+
1149
+ /**
1150
+ * Composes independently owned data-source binding registries into one
1151
+ * projection registry. Later registries override earlier factories for the same
1152
+ * data-source or endpoint id so app-level composition can replace defaults at
1153
+ * narrower ownership boundaries.
1154
+ */
1155
+ export function mergePresentationDataSourceBindingProjectionRegistries(
1156
+ ...registries: readonly PresentationDataSourceBindingProjectionRegistry[]
1157
+ ): PresentationDataSourceBindingProjectionRegistry {
1158
+ let defaultAuthorization: PresentationDataSourceBindingProjectionRegistry['defaultAuthorization']
1159
+ for (const registry of registries) {
1160
+ defaultAuthorization = registry.defaultAuthorization ?? defaultAuthorization
1161
+ }
1162
+
1163
+ return {
1164
+ apiEndpoint: resolveApiEndpointFactory(registries),
1165
+ byDataSourceId: Object.assign(
1166
+ {},
1167
+ ...registries.map((registry) => registry.byDataSourceId ?? {}),
1168
+ ),
1169
+ byEndpointId: Object.assign(
1170
+ {},
1171
+ ...registries.map((registry) => registry.byEndpointId ?? {}),
1172
+ ),
1173
+ defaultAuthorization,
1174
+ fallback: resolveFallbackFactory(registries),
1175
+ }
1176
+ }
1177
+
1178
+ /**
1179
+ * Projects semantic data-source definitions onto concrete frontend binding
1180
+ * plans. React hooks are deliberately not used here; hook-backed realization is
1181
+ * handled later by PresentationDataSourceBinder.
1182
+ */
1183
+ export function projectPresentationDataSourceBindings({
1184
+ context = {},
1185
+ dataSourceDefinitions = [],
1186
+ dataSourceIds,
1187
+ module,
1188
+ registry,
1189
+ }: ProjectPresentationDataSourceBindingsOptions): readonly PresentationDataSourceBinding[] {
1190
+ const uniqueDataSourceIds = Array.from(new Set(dataSourceIds))
1191
+ const fallbackDataSourcesById = new Map(
1192
+ dataSourceDefinitions.map((dataSource) => [dataSource.Id, dataSource] as const),
1193
+ )
1194
+
1195
+ return uniqueDataSourceIds.flatMap((dataSourceId) => {
1196
+ const dataSource =
1197
+ findPresentationDataSource(module, dataSourceId) ??
1198
+ fallbackDataSourcesById.get(dataSourceId) ??
1199
+ null
1200
+ if (!dataSource) {
1201
+ return []
1202
+ }
1203
+
1204
+ const binding = dataSource.Binding ?? null
1205
+ const factoryContext = {
1206
+ binding,
1207
+ context,
1208
+ dataSource,
1209
+ module,
1210
+ } satisfies PresentationDataSourceBindingFactoryContext
1211
+ const factory = resolveDataSourceBindingFactory(registry, dataSource)
1212
+ const projectedBinding =
1213
+ factory?.(factoryContext) ??
1214
+ createUnboundDataSourceBinding(dataSource, registry.defaultAuthorization?.(factoryContext))
1215
+
1216
+ return [applyDataSourceDefaults(projectedBinding, dataSource)]
1217
+ })
1218
+ }
1219
+
1220
+ /**
1221
+ * Adapts TanStack Query binding-input factories into a full projection
1222
+ * registry by applying target-level authorization to every produced binding.
1223
+ */
1224
+ export function createTanStackQueryDataSourceBindingProjectionRegistry({
1225
+ apiEndpoint,
1226
+ byDataSourceId,
1227
+ byEndpointId,
1228
+ defaultAuthorization,
1229
+ targetInterpretation,
1230
+ }: TanStackQueryDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
1231
+ return {
1232
+ apiEndpoint: apiEndpoint
1233
+ ? (context) => {
1234
+ const binding = apiEndpoint(context)
1235
+ return binding
1236
+ ? createTargetInterpretedTanStackQueryDataSourceBinding(
1237
+ context,
1238
+ targetInterpretation,
1239
+ binding,
1240
+ defaultAuthorization,
1241
+ )
1242
+ : binding
1243
+ }
1244
+ : undefined,
1245
+ byDataSourceId,
1246
+ byEndpointId: mapFactories(byEndpointId, (factory) => (context) => {
1247
+ const binding = factory(context)
1248
+ return binding
1249
+ ? createTargetInterpretedTanStackQueryDataSourceBinding(
1250
+ context,
1251
+ targetInterpretation,
1252
+ binding,
1253
+ defaultAuthorization,
1254
+ )
1255
+ : binding
1256
+ }),
1257
+ defaultAuthorization,
1258
+ }
1259
+ }
1260
+
1261
+ /**
1262
+ * Creates a generic TanStack Query projection registry for API endpoint data
1263
+ * sources. The registry resolves endpoint ids from backend bindings, projects
1264
+ * route parameters, applies runtime annotations, and executes through the
1265
+ * active target interpretation.
1266
+ */
1267
+ export function createApiEndpointTanStackQueryDataSourceBindingProjectionRegistry({
1268
+ createQueryKey,
1269
+ defaultAuthorization,
1270
+ executeEndpoint,
1271
+ isEnabled,
1272
+ pendingLabel,
1273
+ retry,
1274
+ targetInterpretation,
1275
+ }: ApiEndpointTanStackQueryDataSourceBindingProjectionRegistryOptions): PresentationDataSourceBindingProjectionRegistry {
1276
+ return createTanStackQueryDataSourceBindingProjectionRegistry({
1277
+ apiEndpoint: (context) => {
1278
+ const endpointId = readPresentationDataSourceEndpointId(context.binding)
1279
+ if (!endpointId) {
1280
+ return null
1281
+ }
1282
+
1283
+ const endpointExecutor =
1284
+ executeEndpoint ??
1285
+ resolvePresentationDataSourceTargetEndpointExecutor(
1286
+ targetInterpretation,
1287
+ context.binding,
1288
+ )
1289
+ if (!endpointExecutor) {
1290
+ return null
1291
+ }
1292
+
1293
+ const routeParameters = projectDataSourceRouteParameters(
1294
+ context.dataSource.Parameters,
1295
+ context.context.routeParameters,
1296
+ )
1297
+ const apiContext = {
1298
+ ...context,
1299
+ endpointId,
1300
+ routeParameters,
1301
+ } satisfies PresentationDataSourceApiEndpointFactoryContext
1302
+ const runtimeOptions = readDataSourceBindingRuntimeOptions(context.dataSource)
1303
+ const targetIsEnabled = targetInterpretation?.apiEndpoint?.isEnabled?.(apiContext)
1304
+ const projectedIsEnabled = isEnabled?.(apiContext)
1305
+ return {
1306
+ dataSourceId: context.dataSource.Id,
1307
+ enabled:
1308
+ (targetIsEnabled ?? true) &&
1309
+ (projectedIsEnabled ?? true) &&
1310
+ hasRequiredDataSourceRouteParameters(context.dataSource.Parameters, routeParameters),
1311
+ emptyMessage: runtimeOptions.emptyMessage,
1312
+ fallbackData: runtimeOptions.fallbackData,
1313
+ pendingLabel: resolveApiEndpointDataSourcePendingLabel(
1314
+ pendingLabel ??
1315
+ runtimeOptions.pendingLabel ??
1316
+ targetInterpretation?.apiEndpoint?.pendingLabel,
1317
+ apiContext,
1318
+ ),
1319
+ queryFn: () => endpointExecutor(endpointId, { routeParameters }),
1320
+ queryKey:
1321
+ createQueryKey?.(apiContext) ??
1322
+ targetInterpretation?.apiEndpoint?.createQueryKey?.(apiContext) ??
1323
+ createDefaultApiEndpointDataSourceQueryKey(apiContext),
1324
+ refetchInterval: runtimeOptions.refetchInterval,
1325
+ retry: retry ?? runtimeOptions.retry ?? targetInterpretation?.apiEndpoint?.retry ?? false,
1326
+ staleTime: runtimeOptions.staleTime,
1327
+ }
1328
+ },
1329
+ defaultAuthorization,
1330
+ targetInterpretation,
1331
+ })
1332
+ }
1333
+
1334
+ function resolveApiEndpointFactory(
1335
+ registries: readonly PresentationDataSourceBindingProjectionRegistry[],
1336
+ ): PresentationDataSourceBindingFactory | undefined {
1337
+ const factories = registries.flatMap((registry) =>
1338
+ registry.apiEndpoint ? [registry.apiEndpoint] : [],
1339
+ )
1340
+ if (factories.length === 0) {
1341
+ return undefined
1342
+ }
1343
+
1344
+ return (context) => {
1345
+ for (let i = factories.length - 1; i >= 0; i -= 1) {
1346
+ const binding = factories[i]?.(context)
1347
+ if (binding) {
1348
+ return binding
1349
+ }
1350
+ }
1351
+
1352
+ return null
1353
+ }
1354
+ }
1355
+
1356
+ function resolveFallbackFactory(
1357
+ registries: readonly PresentationDataSourceBindingProjectionRegistry[],
1358
+ ): PresentationDataSourceBindingFactory | undefined {
1359
+ const factories = registries.flatMap((registry) =>
1360
+ registry.fallback ? [registry.fallback] : [],
1361
+ )
1362
+ if (factories.length === 0) {
1363
+ return undefined
1364
+ }
1365
+
1366
+ return (context) => {
1367
+ for (let i = factories.length - 1; i >= 0; i -= 1) {
1368
+ const binding = factories[i]?.(context)
1369
+ if (binding) {
1370
+ return binding
1371
+ }
1372
+ }
1373
+
1374
+ return null
1375
+ }
1376
+ }
1377
+
1378
+ function resolveDataSourceBindingFactory(
1379
+ registry: PresentationDataSourceBindingProjectionRegistry,
1380
+ dataSource: DataSourceDefinition,
1381
+ ): PresentationDataSourceBindingFactory | undefined {
1382
+ const endpointId = isApiEndpointBinding(dataSource.Binding)
1383
+ ? dataSource.Binding?.EndpointId
1384
+ : null
1385
+ const exactFactory =
1386
+ registry.byDataSourceId?.[dataSource.Id] ??
1387
+ (endpointId ? registry.byEndpointId?.[endpointId] : undefined)
1388
+ if (exactFactory) {
1389
+ return exactFactory
1390
+ }
1391
+
1392
+ const genericFactories = [
1393
+ endpointId ? registry.apiEndpoint : undefined,
1394
+ registry.fallback,
1395
+ ].filter((factory): factory is PresentationDataSourceBindingFactory => Boolean(factory))
1396
+ if (genericFactories.length === 0) {
1397
+ return undefined
1398
+ }
1399
+
1400
+ return (context) => {
1401
+ for (const factory of genericFactories) {
1402
+ const binding = factory(context)
1403
+ if (binding) {
1404
+ return binding
1405
+ }
1406
+ }
1407
+
1408
+ return null
1409
+ }
1410
+ }
1411
+
1412
+ function isAggregateQueryDataSource(
1413
+ dataSource: Pick<DataSourceDefinition, 'Kind'>,
1414
+ ) {
1415
+ return matchesDataSourceKind(
1416
+ dataSource.Kind,
1417
+ dataSourceKinds.aggregateQuery,
1418
+ 'aggregateQuery',
1419
+ )
1420
+ }
1421
+
1422
+ function isCollectionQueryDataSource(
1423
+ dataSource: Pick<DataSourceDefinition, 'Kind'>,
1424
+ ) {
1425
+ return matchesDataSourceKind(
1426
+ dataSource.Kind,
1427
+ dataSourceKinds.collectionQuery,
1428
+ 'collectionQuery',
1429
+ )
1430
+ }
1431
+
1432
+ function isLocalStateDataSource(
1433
+ dataSource: Pick<DataSourceDefinition, 'Kind'>,
1434
+ ) {
1435
+ return matchesDataSourceKind(
1436
+ dataSource.Kind,
1437
+ dataSourceKinds.localState,
1438
+ 'localState',
1439
+ )
1440
+ }
1441
+
1442
+ function isPromptPreviewDataSource(
1443
+ dataSource: Pick<DataSourceDefinition, 'Kind'>,
1444
+ ) {
1445
+ return matchesDataSourceKind(
1446
+ dataSource.Kind,
1447
+ dataSourceKinds.promptPreview,
1448
+ 'promptPreview',
1449
+ )
1450
+ }
1451
+
1452
+ function matchesDataSourceKind(
1453
+ value: unknown,
1454
+ numericValue: DataSourceKind,
1455
+ camelLabel: string,
1456
+ ) {
1457
+ const pascalLabel = dataSourceKindLabels[numericValue]
1458
+ return (
1459
+ value === numericValue ||
1460
+ String(value) === String(numericValue) ||
1461
+ String(value) === pascalLabel ||
1462
+ String(value).toLocaleLowerCase() === camelLabel.toLocaleLowerCase()
1463
+ )
1464
+ }
1465
+
1466
+ function resolveQueryKeyParts(
1467
+ queryKeyParts:
1468
+ | readonly unknown[]
1469
+ | ((context: PresentationDataSourceBindingFactoryContext) => readonly unknown[]),
1470
+ context: PresentationDataSourceBindingFactoryContext,
1471
+ ) {
1472
+ return typeof queryKeyParts === 'function'
1473
+ ? queryKeyParts(context)
1474
+ : queryKeyParts
1475
+ }
1476
+
1477
+ function resolveDataSourceQueryInterpretationTransforms(
1478
+ interpretation: DataSourceQueryInterpretation | undefined,
1479
+ registryTransforms: DataSourceQueryInterpretationRegistry['transforms'],
1480
+ context: PresentationDataSourceBindingFactoryContext,
1481
+ ) {
1482
+ const resolvedRegistryTransforms = resolveDataSourceQueryTransforms(
1483
+ registryTransforms,
1484
+ context,
1485
+ )
1486
+ const resolvedInterpretationTransforms = resolveDataSourceQueryTransforms(
1487
+ interpretation?.transforms,
1488
+ context,
1489
+ )
1490
+
1491
+ if (!resolvedRegistryTransforms) {
1492
+ return resolvedInterpretationTransforms
1493
+ }
1494
+
1495
+ if (!resolvedInterpretationTransforms) {
1496
+ return resolvedRegistryTransforms
1497
+ }
1498
+
1499
+ return {
1500
+ ...resolvedRegistryTransforms,
1501
+ ...resolvedInterpretationTransforms,
1502
+ }
1503
+ }
1504
+
1505
+ function resolveDataSourceQueryTransforms(
1506
+ transforms: DataSourceQueryInterpretationRegistry['transforms'],
1507
+ context: PresentationDataSourceBindingFactoryContext,
1508
+ ) {
1509
+ return typeof transforms === 'function'
1510
+ ? transforms(context)
1511
+ : transforms
1512
+ }
1513
+
1514
+ function mergeDataSourceQueryLoweringTransforms(
1515
+ targetTransforms:
1516
+ | Readonly<Record<string, DataSourceQueryLoweringTransform>>
1517
+ | undefined,
1518
+ localTransforms:
1519
+ | Readonly<Record<string, DataSourceQueryLoweringTransform>>
1520
+ | undefined,
1521
+ ) {
1522
+ if (!targetTransforms) {
1523
+ return localTransforms
1524
+ }
1525
+
1526
+ if (!localTransforms) {
1527
+ return targetTransforms
1528
+ }
1529
+
1530
+ return {
1531
+ ...targetTransforms,
1532
+ ...localTransforms,
1533
+ }
1534
+ }
1535
+
1536
+ function resolveDataSourceQueryInterpretationValue(
1537
+ interpretation: DataSourceQueryInterpretation | undefined,
1538
+ context: PresentationDataSourceBindingFactoryContext,
1539
+ ) {
1540
+ if (!interpretation?.normalizeValue && !interpretation?.readValue) {
1541
+ return undefined
1542
+ }
1543
+
1544
+ const value = interpretation.readValue
1545
+ ? interpretation.readValue(context)
1546
+ : readPresentationQueryFormAppliedValue(context.context, context.dataSource.Id)
1547
+ return interpretation.normalizeValue
1548
+ ? interpretation.normalizeValue(value, context)
1549
+ : value
1550
+ }
1551
+
1552
+ /**
1553
+ * Reads target binding options from a backend presentation binding.
1554
+ *
1555
+ * Option names are matched case-insensitively and may use either camelCase or
1556
+ * PascalCase.
1557
+ */
1558
+ export function readPresentationDataSourceTargetBindingOptions(
1559
+ binding: PresentationBindingDefinition | null | undefined,
1560
+ ): PresentationDataSourceTargetBindingOptions {
1561
+ return {
1562
+ authorizationPolicyId: readPresentationBindingStringOption(
1563
+ binding?.Options,
1564
+ 'authorizationPolicyId',
1565
+ ),
1566
+ executionTargetId: readPresentationBindingStringOption(
1567
+ binding?.Options,
1568
+ 'executionTargetId',
1569
+ ),
1570
+ }
1571
+ }
1572
+
1573
+ /**
1574
+ * Reads runtime query defaults from the standard
1575
+ * `cohesive.presentation.data-source.runtime` data-source annotation.
1576
+ */
1577
+ export function readDataSourceBindingRuntimeOptions(
1578
+ dataSource: Pick<DataSourceDefinition, 'Annotations'> | null | undefined,
1579
+ ): PresentationDataSourceBindingRuntimeOptions {
1580
+ const annotation = dataSource?.Annotations.find(
1581
+ (candidate) =>
1582
+ candidate.Name === 'cohesive.presentation.data-source.runtime' ||
1583
+ candidate.Name.toLocaleLowerCase() === 'cohesive.presentation.data-source.runtime',
1584
+ )
1585
+ if (!annotation || !annotation.Value || typeof annotation.Value !== 'object') {
1586
+ return {}
1587
+ }
1588
+
1589
+ const options = annotation.Value as Readonly<Record<string, unknown>>
1590
+ const refetchInterval =
1591
+ readNumberOption(options, 'refetchIntervalMs') ??
1592
+ readSecondsOptionAsMilliseconds(options, 'refetchIntervalSeconds')
1593
+ const staleTime =
1594
+ readNumberOption(options, 'staleTimeMs') ??
1595
+ readSecondsOptionAsMilliseconds(options, 'staleTimeSeconds')
1596
+
1597
+ return {
1598
+ emptyMessage: readStringOption(options, 'emptyMessage'),
1599
+ fallbackData: readObjectOption(options, 'fallbackData'),
1600
+ pendingLabel: readStringOption(options, 'pendingLabel'),
1601
+ refetchInterval,
1602
+ retry: readRetryOption(options, 'retry'),
1603
+ staleTime,
1604
+ }
1605
+ }
1606
+
1607
+ /**
1608
+ * Resolves the endpoint executor selected by a binding's `executionTargetId`,
1609
+ * falling back to the default API endpoint executor on the target
1610
+ * interpretation.
1611
+ */
1612
+ export function resolvePresentationDataSourceTargetEndpointExecutor(
1613
+ targetInterpretation: PresentationDataSourceTargetInterpretation | undefined,
1614
+ binding: PresentationBindingDefinition | null | undefined,
1615
+ ): PresentationDataSourceEndpointExecutor | undefined {
1616
+ const executionTargetId = readPresentationDataSourceTargetBindingOptions(
1617
+ binding,
1618
+ ).executionTargetId
1619
+ if (executionTargetId) {
1620
+ return targetInterpretation?.apiEndpoint?.executeEndpointByTargetId?.[executionTargetId]
1621
+ }
1622
+
1623
+ return targetInterpretation?.apiEndpoint?.executeEndpoint
1624
+ }
1625
+
1626
+ async function materializeDataSourceAggregateItems({
1627
+ aggregation,
1628
+ sourceDataSource,
1629
+ sourceEndpointId,
1630
+ targetInterpretation,
1631
+ transforms,
1632
+ value,
1633
+ }: {
1634
+ readonly aggregation: DataSourceAggregateQuery
1635
+ readonly sourceDataSource: DataSourceDefinition
1636
+ readonly sourceEndpointId: string
1637
+ readonly targetInterpretation: PresentationDataSourceTargetInterpretation
1638
+ readonly transforms?: Readonly<Record<string, DataSourceQueryLoweringTransform>>
1639
+ readonly value: unknown
1640
+ }): Promise<readonly unknown[]> {
1641
+ const materializeAllPages = matchesDataSourceAggregateMaterializationKind(
1642
+ aggregation.Materialization.Kind,
1643
+ dataSourceAggregateMaterializationKinds.allPages,
1644
+ 'allPages',
1645
+ )
1646
+ const pageSize =
1647
+ aggregation.Materialization.PageSize ??
1648
+ sourceDataSource.Query?.Pagination?.DefaultPageSize ??
1649
+ 100
1650
+ const endpointBinding = findDataSourceQueryEndpointBinding(
1651
+ sourceDataSource,
1652
+ sourceEndpointId,
1653
+ )
1654
+ const items: unknown[] = []
1655
+ const seenCursors = new Set<string>()
1656
+ let cursor: string | null | undefined = null
1657
+
1658
+ do {
1659
+ const paginationRequest = materializeAllPages
1660
+ ? createDataSourcePaginationRequest(sourceDataSource, {
1661
+ cursor,
1662
+ limit: pageSize,
1663
+ })
1664
+ : null
1665
+ const query = createDataSourceEndpointQueryRequest<Record<string, unknown>>({
1666
+ dataSource: sourceDataSource,
1667
+ endpointId: sourceEndpointId,
1668
+ paginationRequest,
1669
+ transforms,
1670
+ value,
1671
+ })
1672
+ const response = await executePresentationDataSourceTargetEndpoint(
1673
+ targetInterpretation,
1674
+ sourceEndpointId,
1675
+ { query },
1676
+ { binding: sourceDataSource.Binding ?? null },
1677
+ )
1678
+ const pageItems = readAggregateResponseItems(response, endpointBinding?.ItemsPath)
1679
+ items.push(...pageItems)
1680
+
1681
+ const nextCursor = readStringObjectPath(
1682
+ response,
1683
+ sourceDataSource.Query?.Pagination?.Response.CursorField,
1684
+ )
1685
+ cursor = materializeAllPages && nextCursor && !seenCursors.has(nextCursor)
1686
+ ? nextCursor
1687
+ : null
1688
+ if (cursor) {
1689
+ seenCursors.add(cursor)
1690
+ }
1691
+ } while (cursor)
1692
+
1693
+ return items
1694
+ }
1695
+
1696
+ function evaluateDataSourceAggregateQuery(
1697
+ aggregation: DataSourceAggregateQuery,
1698
+ items: readonly unknown[],
1699
+ ) {
1700
+ const result: Record<string, unknown> = {}
1701
+ for (const measure of aggregation.Measures) {
1702
+ const predicate = measure.Predicate
1703
+ const matchingItems = predicate
1704
+ ? items.filter((item) => evaluateDataSourceAggregatePredicate(predicate, item))
1705
+ : items
1706
+ writeObjectPath(
1707
+ result,
1708
+ measure.TargetPath,
1709
+ evaluateDataSourceAggregateMeasure(measure.Operator, measure.SourceField, matchingItems),
1710
+ )
1711
+ }
1712
+
1713
+ return result
1714
+ }
1715
+
1716
+ function evaluateDataSourceAggregateMeasure(
1717
+ operator: AggregateOperator,
1718
+ sourceField: DataSourceAggregateQuery['Measures'][number]['SourceField'],
1719
+ items: readonly unknown[],
1720
+ ) {
1721
+ if (matchesAggregateOperator(operator, aggregateOperators.count, 'count')) {
1722
+ return items.length
1723
+ }
1724
+
1725
+ const values: readonly unknown[] = sourceField
1726
+ ? items.map((item) => readObjectPath(item, fieldPathToString(sourceField)))
1727
+ : items
1728
+
1729
+ if (matchesAggregateOperator(operator, aggregateOperators.sum, 'sum')) {
1730
+ return values.reduce<number>(
1731
+ (sum, value) => sum + (typeof value === 'number' ? value : 0),
1732
+ 0,
1733
+ )
1734
+ }
1735
+
1736
+ if (matchesAggregateOperator(operator, aggregateOperators.min, 'min')) {
1737
+ return values
1738
+ .filter((value): value is number => typeof value === 'number')
1739
+ .reduce<number | null>((min, value) => min === null ? value : Math.min(min, value), null)
1740
+ }
1741
+
1742
+ if (matchesAggregateOperator(operator, aggregateOperators.max, 'max')) {
1743
+ return values
1744
+ .filter((value): value is number => typeof value === 'number')
1745
+ .reduce<number | null>((max, value) => max === null ? value : Math.max(max, value), null)
1746
+ }
1747
+
1748
+ if (matchesAggregateOperator(operator, aggregateOperators.any, 'any')) {
1749
+ return values.some(Boolean)
1750
+ }
1751
+
1752
+ if (matchesAggregateOperator(operator, aggregateOperators.all, 'all')) {
1753
+ return values.every(Boolean)
1754
+ }
1755
+
1756
+ return null
1757
+ }
1758
+
1759
+ function evaluateDataSourceAggregatePredicate(
1760
+ predicate: DataSourceAggregatePredicate,
1761
+ item: unknown,
1762
+ ): boolean {
1763
+ if (
1764
+ matchesDataSourceAggregatePredicateKind(
1765
+ predicate.Kind,
1766
+ dataSourceAggregatePredicateKinds.and,
1767
+ 'and',
1768
+ )
1769
+ ) {
1770
+ return (predicate.Terms ?? []).every((term) =>
1771
+ evaluateDataSourceAggregatePredicate(term, item))
1772
+ }
1773
+
1774
+ if (
1775
+ matchesDataSourceAggregatePredicateKind(
1776
+ predicate.Kind,
1777
+ dataSourceAggregatePredicateKinds.or,
1778
+ 'or',
1779
+ )
1780
+ ) {
1781
+ return (predicate.Terms ?? []).some((term) =>
1782
+ evaluateDataSourceAggregatePredicate(term, item))
1783
+ }
1784
+
1785
+ if (
1786
+ matchesDataSourceAggregatePredicateKind(
1787
+ predicate.Kind,
1788
+ dataSourceAggregatePredicateKinds.not,
1789
+ 'not',
1790
+ )
1791
+ ) {
1792
+ const [term] = predicate.Terms ?? []
1793
+ return term ? !evaluateDataSourceAggregatePredicate(term, item) : true
1794
+ }
1795
+
1796
+ const value = readObjectPath(item, fieldPathToString(predicate.Field))
1797
+ if (
1798
+ matchesDataSourceAggregatePredicateKind(
1799
+ predicate.Kind,
1800
+ dataSourceAggregatePredicateKinds.fieldEquals,
1801
+ 'fieldEquals',
1802
+ )
1803
+ ) {
1804
+ return String(value) === predicate.Value
1805
+ }
1806
+
1807
+ if (
1808
+ matchesDataSourceAggregatePredicateKind(
1809
+ predicate.Kind,
1810
+ dataSourceAggregatePredicateKinds.fieldNotEquals,
1811
+ 'fieldNotEquals',
1812
+ )
1813
+ ) {
1814
+ return String(value) !== predicate.Value
1815
+ }
1816
+
1817
+ if (
1818
+ matchesDataSourceAggregatePredicateKind(
1819
+ predicate.Kind,
1820
+ dataSourceAggregatePredicateKinds.fieldHasValue,
1821
+ 'fieldHasValue',
1822
+ )
1823
+ ) {
1824
+ return hasAggregateValue(value)
1825
+ }
1826
+
1827
+ return false
1828
+ }
1829
+
1830
+ function readPresentationDataSourceEndpointId(
1831
+ binding: PresentationBindingDefinition | null | undefined,
1832
+ ) {
1833
+ return isApiEndpointBinding(binding) && binding?.EndpointId
1834
+ ? binding.EndpointId
1835
+ : null
1836
+ }
1837
+
1838
+ function applyDataSourceDefaults(
1839
+ binding: PresentationDataSourceBinding,
1840
+ dataSource: DataSourceDefinition,
1841
+ ): PresentationDataSourceBinding {
1842
+ if (!isTanStackQueryBinding(binding)) {
1843
+ return binding
1844
+ }
1845
+
1846
+ return {
1847
+ ...binding,
1848
+ staleTime: binding.staleTime ?? readDataSourceStaleTime(dataSource),
1849
+ }
1850
+ }
1851
+
1852
+ function createUnboundDataSourceBinding(
1853
+ dataSource: DataSourceDefinition,
1854
+ authorization: PresentationDataSourceAuthorizationRequirement | undefined,
1855
+ ): PresentationDataSourceBinding {
1856
+ return presentationDataSourceBindings.localValue({
1857
+ authorization:
1858
+ authorization ??
1859
+ presentationDataSourceAuthorization.required({
1860
+ blockedLabel: `No frontend binding is registered for '${dataSource.Name}'.`,
1861
+ isAuthorized: false,
1862
+ }),
1863
+ data: undefined,
1864
+ dataSourceId: dataSource.Id,
1865
+ })
1866
+ }
1867
+
1868
+ function readDataSourceStaleTime(dataSource: DataSourceDefinition) {
1869
+ const cache = dataSource.Cache
1870
+ if (!cache) {
1871
+ return undefined
1872
+ }
1873
+
1874
+ if (
1875
+ cache.Kind === cachePolicyKinds.reactQuery ||
1876
+ String(cache.Kind).toLocaleLowerCase() === 'reactquery'
1877
+ ) {
1878
+ return cache.StaleAfterSeconds === null ||
1879
+ cache.StaleAfterSeconds === undefined
1880
+ ? undefined
1881
+ : cache.StaleAfterSeconds * 1000
1882
+ }
1883
+
1884
+ return undefined
1885
+ }
1886
+
1887
+ function isApiEndpointBinding(
1888
+ binding: PresentationBindingDefinition | null | undefined,
1889
+ ) {
1890
+ return (
1891
+ binding?.Kind === presentationBindingKinds.apiEndpoint ||
1892
+ String(binding?.Kind).toLocaleLowerCase() === 'apiendpoint'
1893
+ )
1894
+ }
1895
+
1896
+ function isLocalStateBinding(
1897
+ binding: PresentationBindingDefinition | null | undefined,
1898
+ ) {
1899
+ return (
1900
+ binding?.Kind === presentationBindingKinds.localState ||
1901
+ String(binding?.Kind).toLocaleLowerCase() === 'localstate'
1902
+ )
1903
+ }
1904
+
1905
+ function readPresentationBindingStringOption(
1906
+ options: unknown,
1907
+ key: string,
1908
+ ): string | null {
1909
+ if (!options || typeof options !== 'object') {
1910
+ return null
1911
+ }
1912
+
1913
+ const record = options as Readonly<Record<string, unknown>>
1914
+ const value =
1915
+ record[key] ??
1916
+ record[capitalizeFirstCharacter(key)] ??
1917
+ readCaseInsensitiveProperty(record, key)
1918
+ return typeof value === 'string' && value.trim().length > 0
1919
+ ? value
1920
+ : null
1921
+ }
1922
+
1923
+ function readAggregateResponseItems(response: unknown, itemsPath: string | null | undefined) {
1924
+ const value = itemsPath ? readObjectPath(response, itemsPath) : response
1925
+ if (Array.isArray(value)) {
1926
+ return value
1927
+ }
1928
+
1929
+ const items = readObjectPath(response, 'Items')
1930
+ return Array.isArray(items) ? items : []
1931
+ }
1932
+
1933
+ function readStringObjectPath(value: unknown, path: string | null | undefined) {
1934
+ const raw = readObjectPath(value, path)
1935
+ return typeof raw === 'string' && raw.trim().length > 0 ? raw.trim() : null
1936
+ }
1937
+
1938
+ function fieldPathToString(
1939
+ field: DataSourceAggregatePredicate['Field'] | NonNullable<DataSourceAggregateQuery['Measures'][number]['SourceField']>,
1940
+ ) {
1941
+ return field?.Segments.map((segment) => segment.Segment).filter(Boolean).join('.') ?? ''
1942
+ }
1943
+
1944
+ function hasAggregateValue(value: unknown) {
1945
+ if (value === null || value === undefined) {
1946
+ return false
1947
+ }
1948
+
1949
+ if (typeof value === 'string') {
1950
+ return value.trim().length > 0
1951
+ }
1952
+
1953
+ if (Array.isArray(value)) {
1954
+ return value.length > 0
1955
+ }
1956
+
1957
+ return true
1958
+ }
1959
+
1960
+ function matchesAggregateOperator(
1961
+ value: unknown,
1962
+ numericValue: AggregateOperator,
1963
+ camelLabel: string,
1964
+ ) {
1965
+ return matchesGeneratedEnum(value, numericValue, camelLabel)
1966
+ }
1967
+
1968
+ function matchesDataSourceAggregateMaterializationKind(
1969
+ value: unknown,
1970
+ numericValue: number,
1971
+ camelLabel: string,
1972
+ ) {
1973
+ return matchesGeneratedEnum(value, numericValue, camelLabel)
1974
+ }
1975
+
1976
+ function matchesDataSourceAggregatePredicateKind(
1977
+ value: unknown,
1978
+ numericValue: number,
1979
+ camelLabel: string,
1980
+ ) {
1981
+ return matchesGeneratedEnum(value, numericValue, camelLabel)
1982
+ }
1983
+
1984
+ function matchesGeneratedEnum(
1985
+ value: unknown,
1986
+ numericValue: number,
1987
+ camelLabel: string,
1988
+ ) {
1989
+ return (
1990
+ value === numericValue ||
1991
+ String(value) === String(numericValue) ||
1992
+ String(value).toLocaleLowerCase() === camelLabel.toLocaleLowerCase()
1993
+ )
1994
+ }
1995
+
1996
+ function readStringOption(
1997
+ options: Readonly<Record<string, unknown>>,
1998
+ key: string,
1999
+ ) {
2000
+ const value = readObjectOption(options, key)
2001
+ return typeof value === 'string' && value.trim().length > 0
2002
+ ? value
2003
+ : undefined
2004
+ }
2005
+
2006
+ function readObjectOption(
2007
+ options: Readonly<Record<string, unknown>>,
2008
+ key: string,
2009
+ ) {
2010
+ return Object.prototype.hasOwnProperty.call(options, key)
2011
+ ? options[key]
2012
+ : readCaseInsensitiveProperty(options, key)
2013
+ }
2014
+
2015
+ function readNumberOption(
2016
+ options: Readonly<Record<string, unknown>>,
2017
+ key: string,
2018
+ ) {
2019
+ const value = readObjectOption(options, key)
2020
+ return typeof value === 'number' && Number.isFinite(value)
2021
+ ? value
2022
+ : undefined
2023
+ }
2024
+
2025
+ function readSecondsOptionAsMilliseconds(
2026
+ options: Readonly<Record<string, unknown>>,
2027
+ key: string,
2028
+ ) {
2029
+ const seconds = readNumberOption(options, key)
2030
+ return seconds === undefined ? undefined : seconds * 1000
2031
+ }
2032
+
2033
+ function readRetryOption(
2034
+ options: Readonly<Record<string, unknown>>,
2035
+ key: string,
2036
+ ) {
2037
+ const value = readObjectOption(options, key)
2038
+ return typeof value === 'boolean' || typeof value === 'number'
2039
+ ? value
2040
+ : undefined
2041
+ }
2042
+
2043
+ function readCaseInsensitiveProperty(
2044
+ record: Readonly<Record<string, unknown>>,
2045
+ key: string,
2046
+ ) {
2047
+ const normalizedKey = key.toLocaleLowerCase()
2048
+ const match = Object.keys(record).find(
2049
+ (candidate) => candidate.toLocaleLowerCase() === normalizedKey,
2050
+ )
2051
+ return match ? record[match] : undefined
2052
+ }
2053
+
2054
+ function capitalizeFirstCharacter(value: string) {
2055
+ return value.length > 0
2056
+ ? `${value.slice(0, 1).toLocaleUpperCase()}${value.slice(1)}`
2057
+ : value
2058
+ }
2059
+
2060
+ function projectDataSourceRouteParameters(
2061
+ parameters: readonly ParameterDefinition[],
2062
+ routeParameters: Readonly<Record<string, string | undefined>> | undefined,
2063
+ ) {
2064
+ return Object.fromEntries(
2065
+ parameters.map((parameter) => [
2066
+ parameter.Name,
2067
+ readRouteParameterValue(routeParameters, parameter.Name),
2068
+ ]),
2069
+ )
2070
+ }
2071
+
2072
+ function hasRequiredDataSourceRouteParameters(
2073
+ parameters: readonly ParameterDefinition[],
2074
+ routeParameters: Readonly<Record<string, string | null | undefined>>,
2075
+ ) {
2076
+ return parameters.every(
2077
+ (parameter) =>
2078
+ !parameter.IsRequired ||
2079
+ typeof routeParameters[parameter.Name] === 'string' &&
2080
+ routeParameters[parameter.Name]!.length > 0,
2081
+ )
2082
+ }
2083
+
2084
+ function readRouteParameterValue(
2085
+ routeParameters: Readonly<Record<string, string | undefined>> | undefined,
2086
+ parameterName: string,
2087
+ ) {
2088
+ if (!routeParameters) {
2089
+ return undefined
2090
+ }
2091
+
2092
+ if (Object.prototype.hasOwnProperty.call(routeParameters, parameterName)) {
2093
+ return routeParameters[parameterName]
2094
+ }
2095
+
2096
+ const match = Object.keys(routeParameters).find(
2097
+ (candidate) => candidate.toLocaleLowerCase() === parameterName.toLocaleLowerCase(),
2098
+ )
2099
+ return match ? routeParameters[match] : undefined
2100
+ }
2101
+
2102
+ function hasOwn<TValue>(
2103
+ values: Readonly<Record<string, TValue>>,
2104
+ key: string,
2105
+ ) {
2106
+ return Object.prototype.hasOwnProperty.call(values, key)
2107
+ }
2108
+
2109
+ function resolveApiEndpointDataSourcePendingLabel(
2110
+ label: ApiEndpointTanStackQueryDataSourceBindingProjectionRegistryOptions['pendingLabel'],
2111
+ context: PresentationDataSourceApiEndpointFactoryContext,
2112
+ ) {
2113
+ if (typeof label === 'function') {
2114
+ return label(context)
2115
+ }
2116
+
2117
+ return label ?? `Loading ${context.dataSource.Name.toLocaleLowerCase()}...`
2118
+ }
2119
+
2120
+ function createDefaultApiEndpointDataSourceQueryKey({
2121
+ context,
2122
+ dataSource,
2123
+ endpointId,
2124
+ routeParameters,
2125
+ }: PresentationDataSourceApiEndpointFactoryContext) {
2126
+ return [
2127
+ 'presentation-data-source',
2128
+ dataSource.Id,
2129
+ endpointId,
2130
+ routeParameters,
2131
+ ...(context.queryKeyParts ?? []),
2132
+ ] as const
2133
+ }
2134
+
2135
+ function mapFactories<TFactory, TMappedFactory>(
2136
+ factories: Readonly<Record<string, TFactory>> | undefined,
2137
+ mapFactory: (factory: TFactory) => TMappedFactory,
2138
+ ) {
2139
+ if (!factories) {
2140
+ return undefined
2141
+ }
2142
+
2143
+ return Object.fromEntries(
2144
+ Object.entries(factories).map(([key, factory]) => [
2145
+ key,
2146
+ mapFactory(factory as TFactory),
2147
+ ]),
2148
+ )
2149
+ }