@pilotiq/pilotiq 0.24.1 → 0.24.3

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 (518) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/boost/guidelines.md +571 -0
  3. package/boost/skills/pilotiq-actions/SKILL.md +49 -0
  4. package/boost/skills/pilotiq-actions/rules/dispatch-modes.md +177 -0
  5. package/boost/skills/pilotiq-actions/rules/factories.md +130 -0
  6. package/boost/skills/pilotiq-actions/rules/visibility-and-authorization.md +125 -0
  7. package/boost/skills/pilotiq-fields/SKILL.md +47 -0
  8. package/boost/skills/pilotiq-fields/rules/field-catalog.md +288 -0
  9. package/boost/skills/pilotiq-fields/rules/reactive-fields.md +199 -0
  10. package/boost/skills/pilotiq-fields/rules/validation.md +198 -0
  11. package/boost/skills/pilotiq-relations/SKILL.md +47 -0
  12. package/boost/skills/pilotiq-relations/rules/relation-managers.md +256 -0
  13. package/boost/skills/pilotiq-relations/rules/repeater-relationship.md +177 -0
  14. package/boost/skills/pilotiq-resource/SKILL.md +61 -0
  15. package/boost/skills/pilotiq-resource/rules/authorization.md +242 -0
  16. package/boost/skills/pilotiq-resource/rules/defining-resources.md +228 -0
  17. package/boost/skills/pilotiq-resource/rules/page-overrides.md +296 -0
  18. package/dist/Pilotiq.d.ts +31 -0
  19. package/dist/Pilotiq.d.ts.map +1 -1
  20. package/dist/Pilotiq.js +3 -1
  21. package/dist/Pilotiq.js.map +1 -1
  22. package/dist/PilotiqRegistry.d.ts +13 -0
  23. package/dist/PilotiqRegistry.d.ts.map +1 -1
  24. package/dist/PilotiqRegistry.js +15 -0
  25. package/dist/PilotiqRegistry.js.map +1 -1
  26. package/dist/pageData/misc.d.ts.map +1 -1
  27. package/dist/pageData/misc.js +6 -0
  28. package/dist/pageData/misc.js.map +1 -1
  29. package/dist/pageData/navigation.d.ts +1 -0
  30. package/dist/pageData/navigation.d.ts.map +1 -1
  31. package/dist/pageData/navigation.js +3 -0
  32. package/dist/pageData/navigation.js.map +1 -1
  33. package/dist/pageData/relationPages.d.ts.map +1 -1
  34. package/dist/pageData/relationPages.js +3 -0
  35. package/dist/pageData/relationPages.js.map +1 -1
  36. package/dist/pageData/resourcePages.d.ts.map +1 -1
  37. package/dist/pageData/resourcePages.js +8 -0
  38. package/dist/pageData/resourcePages.js.map +1 -1
  39. package/dist/react/AppShell.d.ts +8 -0
  40. package/dist/react/AppShell.d.ts.map +1 -1
  41. package/dist/react/AppShell.js.map +1 -1
  42. package/dist/react/layouts/SidebarLayout.d.ts.map +1 -1
  43. package/dist/react/layouts/SidebarLayout.js +10 -2
  44. package/dist/react/layouts/SidebarLayout.js.map +1 -1
  45. package/dist/react/widgets/StatsOverviewRenderer.d.ts.map +1 -1
  46. package/dist/react/widgets/StatsOverviewRenderer.js +32 -18
  47. package/dist/react/widgets/StatsOverviewRenderer.js.map +1 -1
  48. package/dist/routes/relations.d.ts.map +1 -1
  49. package/dist/routes/relations.js +25 -18
  50. package/dist/routes/relations.js.map +1 -1
  51. package/dist/routes/resources.js.map +1 -1
  52. package/package.json +10 -5
  53. package/.turbo/turbo-build.log +0 -8
  54. package/CLAUDE.md +0 -265
  55. package/src/Cluster.test.ts +0 -283
  56. package/src/Cluster.ts +0 -83
  57. package/src/Column.test.ts +0 -199
  58. package/src/Column.ts +0 -710
  59. package/src/Global.test.ts +0 -367
  60. package/src/Global.ts +0 -169
  61. package/src/Page.test.ts +0 -114
  62. package/src/Page.ts +0 -208
  63. package/src/Pilotiq.perf.test.ts +0 -252
  64. package/src/Pilotiq.test.ts +0 -129
  65. package/src/Pilotiq.ts +0 -1158
  66. package/src/PilotiqRegistry.ts +0 -36
  67. package/src/PilotiqServiceProvider.ts +0 -121
  68. package/src/RelationManager.test.ts +0 -400
  69. package/src/RelationManager.ts +0 -527
  70. package/src/RenderHook.test.ts +0 -252
  71. package/src/RenderHook.ts +0 -242
  72. package/src/Resource.test.ts +0 -284
  73. package/src/Resource.ts +0 -526
  74. package/src/RightPanel.test.ts +0 -202
  75. package/src/RightPanel.ts +0 -132
  76. package/src/Tab.test.ts +0 -91
  77. package/src/Tab.ts +0 -156
  78. package/src/UserMenuItem.ts +0 -145
  79. package/src/actions/Action.test.ts +0 -2526
  80. package/src/actions/Action.ts +0 -1515
  81. package/src/actions/ActionGroup.test.ts +0 -112
  82. package/src/actions/ActionGroup.ts +0 -173
  83. package/src/actions/attachFactory.ts +0 -172
  84. package/src/actions/bulkFactories.ts +0 -168
  85. package/src/actions/crudFactories.ts +0 -220
  86. package/src/actions/exportFactory.ts +0 -225
  87. package/src/actions/factoryHelpers.ts +0 -177
  88. package/src/actions/importFactory.ts +0 -243
  89. package/src/actions/index.ts +0 -17
  90. package/src/actions/m2mFactories.ts +0 -193
  91. package/src/actions/relationFactories.ts +0 -372
  92. package/src/applyPageHooks.test.ts +0 -463
  93. package/src/applyPageHooks.ts +0 -330
  94. package/src/authorization.test.ts +0 -483
  95. package/src/breadcrumbs.test.ts +0 -238
  96. package/src/cells/coerce.test.ts +0 -85
  97. package/src/cells/coerce.ts +0 -84
  98. package/src/clusterPaths.ts +0 -35
  99. package/src/columns/BadgeColumn.test.ts +0 -54
  100. package/src/columns/BadgeColumn.ts +0 -32
  101. package/src/columns/BooleanColumn.test.ts +0 -41
  102. package/src/columns/BooleanColumn.ts +0 -18
  103. package/src/columns/ColorColumn.test.ts +0 -37
  104. package/src/columns/ColorColumn.ts +0 -38
  105. package/src/columns/IconColumn.test.ts +0 -54
  106. package/src/columns/IconColumn.ts +0 -37
  107. package/src/columns/ImageColumn.test.ts +0 -41
  108. package/src/columns/ImageColumn.ts +0 -28
  109. package/src/columns/SelectColumn.ts +0 -98
  110. package/src/columns/TextColumn.test.ts +0 -190
  111. package/src/columns/TextColumn.ts +0 -20
  112. package/src/columns/TextInputColumn.ts +0 -68
  113. package/src/columns/ToggleColumn.ts +0 -46
  114. package/src/columns/editableColumns.test.ts +0 -238
  115. package/src/columns/index.ts +0 -9
  116. package/src/defaultGlobalPages.ts +0 -95
  117. package/src/defaultPages.test.ts +0 -634
  118. package/src/defaultPages.ts +0 -617
  119. package/src/defaultViewPage.test.ts +0 -147
  120. package/src/elements/Form.test.ts +0 -223
  121. package/src/elements/Form.ts +0 -416
  122. package/src/elements/ListTabs.ts +0 -28
  123. package/src/elements/Table.test.ts +0 -422
  124. package/src/elements/Table.ts +0 -850
  125. package/src/elements/TableGroup.test.ts +0 -260
  126. package/src/elements/TableGroup.ts +0 -334
  127. package/src/elements/dispatchAction.test.ts +0 -463
  128. package/src/elements/dispatchAction.ts +0 -355
  129. package/src/elements/dispatchForm.test.ts +0 -477
  130. package/src/elements/dispatchForm.ts +0 -1993
  131. package/src/elements/dispatchTable.test.ts +0 -1514
  132. package/src/elements/dispatchTable.ts +0 -745
  133. package/src/elements/index.ts +0 -21
  134. package/src/entries/BadgeEntry.ts +0 -39
  135. package/src/entries/CodeEntry.test.ts +0 -40
  136. package/src/entries/CodeEntry.ts +0 -52
  137. package/src/entries/ColorEntry.ts +0 -63
  138. package/src/entries/ComponentEntry.test.ts +0 -173
  139. package/src/entries/ComponentEntry.ts +0 -95
  140. package/src/entries/Entry.ts +0 -304
  141. package/src/entries/IconEntry.ts +0 -49
  142. package/src/entries/ImageEntry.ts +0 -61
  143. package/src/entries/KeyValueEntry.ts +0 -47
  144. package/src/entries/RepeatableEntry.test.ts +0 -239
  145. package/src/entries/RepeatableEntry.ts +0 -173
  146. package/src/entries/TextEntry.test.ts +0 -394
  147. package/src/entries/TextEntry.ts +0 -60
  148. package/src/entries/index.ts +0 -12
  149. package/src/entries/leaves.test.ts +0 -306
  150. package/src/entries/registry.ts +0 -54
  151. package/src/fields/BuilderField.test.ts +0 -1188
  152. package/src/fields/BuilderField.ts +0 -605
  153. package/src/fields/BuilderRelationship.test.ts +0 -811
  154. package/src/fields/CheckboxField.test.ts +0 -44
  155. package/src/fields/CheckboxField.ts +0 -27
  156. package/src/fields/CheckboxListField.test.ts +0 -99
  157. package/src/fields/CheckboxListField.ts +0 -66
  158. package/src/fields/ColorPickerField.test.ts +0 -33
  159. package/src/fields/ColorPickerField.ts +0 -25
  160. package/src/fields/DateField.ts +0 -54
  161. package/src/fields/DateTimeField.test.ts +0 -55
  162. package/src/fields/EmailField.ts +0 -16
  163. package/src/fields/Field.test.ts +0 -654
  164. package/src/fields/Field.ts +0 -817
  165. package/src/fields/FileUploadField.test.ts +0 -143
  166. package/src/fields/FileUploadField.ts +0 -159
  167. package/src/fields/HiddenField.test.ts +0 -27
  168. package/src/fields/HiddenField.ts +0 -28
  169. package/src/fields/KeyValueField.test.ts +0 -105
  170. package/src/fields/KeyValueField.ts +0 -55
  171. package/src/fields/MarkdownField.test.ts +0 -167
  172. package/src/fields/MarkdownField.ts +0 -162
  173. package/src/fields/NumberField.ts +0 -33
  174. package/src/fields/RadioField.test.ts +0 -94
  175. package/src/fields/RadioField.ts +0 -67
  176. package/src/fields/RepeaterField.test.ts +0 -1806
  177. package/src/fields/RepeaterField.ts +0 -939
  178. package/src/fields/RepeaterRelationship.test.ts +0 -1923
  179. package/src/fields/RepeaterSimple.test.ts +0 -248
  180. package/src/fields/RowButton.test.ts +0 -219
  181. package/src/fields/RowButton.ts +0 -135
  182. package/src/fields/SelectField.test.ts +0 -192
  183. package/src/fields/SelectField.ts +0 -235
  184. package/src/fields/SliderField.test.ts +0 -50
  185. package/src/fields/SliderField.ts +0 -53
  186. package/src/fields/SlugField.ts +0 -24
  187. package/src/fields/TagsInputField.test.ts +0 -154
  188. package/src/fields/TagsInputField.ts +0 -133
  189. package/src/fields/TextField.test.ts +0 -213
  190. package/src/fields/TextField.ts +0 -177
  191. package/src/fields/TextareaField.test.ts +0 -58
  192. package/src/fields/TextareaField.ts +0 -59
  193. package/src/fields/ToggleButtonsField.test.ts +0 -106
  194. package/src/fields/ToggleButtonsField.ts +0 -59
  195. package/src/fields/ToggleField.ts +0 -16
  196. package/src/fields/disableOptionsWhenSelectedInSiblingRepeaterItems.test.ts +0 -319
  197. package/src/fields/optionsResolver.ts +0 -95
  198. package/src/fields/resolveField.ts +0 -28
  199. package/src/filters/BooleanFilter.ts +0 -35
  200. package/src/filters/DateRangeFilter.test.ts +0 -194
  201. package/src/filters/DateRangeFilter.ts +0 -148
  202. package/src/filters/Filter.test.ts +0 -268
  203. package/src/filters/Filter.ts +0 -184
  204. package/src/filters/FormFilter.test.ts +0 -238
  205. package/src/filters/FormFilter.ts +0 -215
  206. package/src/filters/MultiSelectFilter.test.ts +0 -119
  207. package/src/filters/MultiSelectFilter.ts +0 -78
  208. package/src/filters/QueryBuilderFilter.test.ts +0 -662
  209. package/src/filters/QueryBuilderFilter.ts +0 -398
  210. package/src/filters/SelectFilter.ts +0 -46
  211. package/src/filters/TernaryFilter.test.ts +0 -160
  212. package/src/filters/TernaryFilter.ts +0 -72
  213. package/src/filters/TrashedFilter.test.ts +0 -149
  214. package/src/filters/TrashedFilter.ts +0 -55
  215. package/src/filters/queryBuilder/BooleanConstraint.ts +0 -31
  216. package/src/filters/queryBuilder/Constraint.ts +0 -115
  217. package/src/filters/queryBuilder/DateConstraint.ts +0 -69
  218. package/src/filters/queryBuilder/NumberConstraint.ts +0 -66
  219. package/src/filters/queryBuilder/SelectConstraint.ts +0 -72
  220. package/src/filters/queryBuilder/TextConstraint.ts +0 -64
  221. package/src/filters/queryBuilder/index.ts +0 -12
  222. package/src/icons/index.ts +0 -2
  223. package/src/icons/lucide.ts +0 -204
  224. package/src/icons/registry.test.ts +0 -56
  225. package/src/icons/registry.ts +0 -41
  226. package/src/icons/types.ts +0 -47
  227. package/src/index.ts +0 -525
  228. package/src/io/csv.test.ts +0 -142
  229. package/src/io/csv.ts +0 -170
  230. package/src/nestedRelationManagerData.test.ts +0 -547
  231. package/src/notifications/Notification.test.ts +0 -210
  232. package/src/notifications/Notification.ts +0 -354
  233. package/src/notifications/broadcast.test.ts +0 -110
  234. package/src/notifications/broadcast.ts +0 -95
  235. package/src/notifications/database.test.ts +0 -383
  236. package/src/notifications/database.ts +0 -398
  237. package/src/notifications/databaseNotifications.test.ts +0 -187
  238. package/src/notifications/dispatchNotificationAction.test.ts +0 -341
  239. package/src/notifications/dispatchNotificationAction.ts +0 -142
  240. package/src/notifications/flash.test.ts +0 -89
  241. package/src/notifications/flash.ts +0 -71
  242. package/src/notifications/index.ts +0 -45
  243. package/src/notifications/registerBroadcastAuth.test.ts +0 -134
  244. package/src/notifications/registerBroadcastAuth.ts +0 -100
  245. package/src/notifications/resolveSavedNotification.test.ts +0 -82
  246. package/src/notifications/resolveSavedNotification.ts +0 -59
  247. package/src/notifications/types.ts +0 -93
  248. package/src/orm/m2mAccessor.ts +0 -66
  249. package/src/orm/modelDefaults.test.ts +0 -633
  250. package/src/orm/modelDefaults.ts +0 -666
  251. package/src/pageData/breadcrumbs.ts +0 -288
  252. package/src/pageData/forms.ts +0 -578
  253. package/src/pageData/helpers.ts +0 -857
  254. package/src/pageData/misc.ts +0 -347
  255. package/src/pageData/navigation.ts +0 -842
  256. package/src/pageData/relationPages.ts +0 -1248
  257. package/src/pageData/relationTabs.ts +0 -286
  258. package/src/pageData/resourcePages.ts +0 -609
  259. package/src/pageData.test.ts +0 -1545
  260. package/src/pageData.ts +0 -341
  261. package/src/plugins/index.ts +0 -8
  262. package/src/plugins/themeEditor.test.ts +0 -36
  263. package/src/plugins/themeEditor.ts +0 -45
  264. package/src/react/AppShell.tsx +0 -251
  265. package/src/react/CollabExtensionFactoryRegistry.ts +0 -55
  266. package/src/react/CollabRoomContext.ts +0 -98
  267. package/src/react/CollabTextRendererRegistry.ts +0 -102
  268. package/src/react/CommandPalette.tsx +0 -375
  269. package/src/react/CurrentUserContext.tsx +0 -50
  270. package/src/react/CustomPageWrapperGate.tsx +0 -69
  271. package/src/react/CustomPageWrapperRegistry.ts +0 -45
  272. package/src/react/FieldFocusReporterRegistry.ts +0 -37
  273. package/src/react/FieldLabelSlotRegistry.ts +0 -30
  274. package/src/react/FieldPresenceRegistry.ts +0 -46
  275. package/src/react/FormCollabBindingRegistry.ts +0 -242
  276. package/src/react/FormStateContext.tsx +0 -591
  277. package/src/react/HeadHooks.tsx +0 -126
  278. package/src/react/MarkdownEditorRegistry.test.ts +0 -38
  279. package/src/react/MarkdownEditorRegistry.ts +0 -107
  280. package/src/react/NotificationActionStrip.tsx +0 -263
  281. package/src/react/NotificationBell.tsx +0 -426
  282. package/src/react/PendingSuggestionApplierRegistry.test.ts +0 -97
  283. package/src/react/PendingSuggestionApplierRegistry.ts +0 -98
  284. package/src/react/PendingSuggestionOverlayRegistry.ts +0 -54
  285. package/src/react/PendingSuggestionsContext.tsx +0 -172
  286. package/src/react/RecordWrapperGate.tsx +0 -58
  287. package/src/react/RecordWrapperRegistry.ts +0 -39
  288. package/src/react/RenderHookSlot.tsx +0 -32
  289. package/src/react/RightSidebar.tsx +0 -257
  290. package/src/react/RightSidebarContext.tsx +0 -234
  291. package/src/react/RightSidebarTrigger.tsx +0 -53
  292. package/src/react/RowCoordsContext.tsx +0 -23
  293. package/src/react/SchemaRenderer.tsx +0 -549
  294. package/src/react/SearchTrigger.tsx +0 -46
  295. package/src/react/ThemeProvider.tsx +0 -93
  296. package/src/react/ThemeSettingsPage.tsx +0 -579
  297. package/src/react/ThemeToggle.tsx +0 -20
  298. package/src/react/Toaster.tsx +0 -158
  299. package/src/react/UserMenu.tsx +0 -196
  300. package/src/react/WidgetDataContext.tsx +0 -157
  301. package/src/react/cells/EditableCell.tsx +0 -389
  302. package/src/react/component-slots.test.ts +0 -103
  303. package/src/react/component-slots.ts +0 -116
  304. package/src/react/fieldJsHandler.test.ts +0 -166
  305. package/src/react/fieldJsHandler.ts +0 -79
  306. package/src/react/fields/BuilderInput.tsx +0 -1078
  307. package/src/react/fields/CheckboxInput.tsx +0 -39
  308. package/src/react/fields/CheckboxListInput.tsx +0 -102
  309. package/src/react/fields/ColorInput.tsx +0 -71
  310. package/src/react/fields/DateFieldInput.tsx +0 -70
  311. package/src/react/fields/DateTimeInput.tsx +0 -62
  312. package/src/react/fields/FieldShell.tsx +0 -348
  313. package/src/react/fields/FileUploadInput.tsx +0 -639
  314. package/src/react/fields/HiddenInput.tsx +0 -17
  315. package/src/react/fields/KeyValueInput.tsx +0 -230
  316. package/src/react/fields/MarkdownInput.tsx +0 -560
  317. package/src/react/fields/RadioInput.tsx +0 -81
  318. package/src/react/fields/RepeaterInput.test.ts +0 -116
  319. package/src/react/fields/RepeaterInput.tsx +0 -1420
  320. package/src/react/fields/SelectFieldInput.tsx +0 -280
  321. package/src/react/fields/SliderInput.tsx +0 -81
  322. package/src/react/fields/TagsInput.tsx +0 -283
  323. package/src/react/fields/TextLikeInput.tsx +0 -256
  324. package/src/react/fields/ToggleButtonsInput.tsx +0 -60
  325. package/src/react/fields/ToggleFieldInput.tsx +0 -56
  326. package/src/react/fields/relationshipRenameDispatch.test.ts +0 -106
  327. package/src/react/fields/relationshipRenameDispatch.ts +0 -97
  328. package/src/react/fields/repeaterReconcile.test.ts +0 -114
  329. package/src/react/fields/repeaterReconcile.ts +0 -104
  330. package/src/react/fields/rowChromeButton.tsx +0 -336
  331. package/src/react/fields/rowState.ts +0 -106
  332. package/src/react/fields/syncRowGates.test.ts +0 -202
  333. package/src/react/fields/syncRowGates.ts +0 -66
  334. package/src/react/fields/textInputControls.tsx +0 -238
  335. package/src/react/fields/useRowReorderDnd.ts +0 -78
  336. package/src/react/formStateHelpers.test.ts +0 -508
  337. package/src/react/formStateHelpers.ts +0 -381
  338. package/src/react/hooks/use-mobile.ts +0 -19
  339. package/src/react/icon-context.tsx +0 -60
  340. package/src/react/index.ts +0 -194
  341. package/src/react/layouts/SidebarLayout.tsx +0 -250
  342. package/src/react/layouts/TopbarLayout.tsx +0 -258
  343. package/src/react/navigate.tsx +0 -37
  344. package/src/react/onProviderSynced.test.ts +0 -90
  345. package/src/react/parseRecordEditUrl.test.ts +0 -122
  346. package/src/react/parseRecordEditUrl.ts +0 -94
  347. package/src/react/persistedState.ts +0 -40
  348. package/src/react/registry.ts +0 -48
  349. package/src/react/right-panel-registry.tsx +0 -47
  350. package/src/react/schemaRenderer/AlertRenderer.tsx +0 -112
  351. package/src/react/schemaRenderer/EntryRenderer.tsx +0 -501
  352. package/src/react/schemaRenderer/SectionRenderer.tsx +0 -120
  353. package/src/react/schemaRenderer/SimpleElements.tsx +0 -306
  354. package/src/react/schemaRenderer/TabsRenderer.tsx +0 -62
  355. package/src/react/schemaRenderer/WizardRenderer.tsx +0 -338
  356. package/src/react/schemaRenderer/action/ActionGroupTrigger.tsx +0 -177
  357. package/src/react/schemaRenderer/action/ActionModalDialog.tsx +0 -273
  358. package/src/react/schemaRenderer/action/ConfirmActionDialog.tsx +0 -61
  359. package/src/react/schemaRenderer/action/HandlerActionButton.tsx +0 -43
  360. package/src/react/schemaRenderer/action/MethodActionButton.tsx +0 -64
  361. package/src/react/schemaRenderer/action/buttons.tsx +0 -99
  362. package/src/react/schemaRenderer/action/helpers.ts +0 -140
  363. package/src/react/schemaRenderer/action/renderAction.tsx +0 -245
  364. package/src/react/schemaRenderer/columnFormat.ts +0 -65
  365. package/src/react/schemaRenderer/constants.ts +0 -50
  366. package/src/react/schemaRenderer/form/FormRenderer.tsx +0 -274
  367. package/src/react/schemaRenderer/form/renderField.tsx +0 -511
  368. package/src/react/schemaRenderer/helpers.tsx +0 -81
  369. package/src/react/schemaRenderer/table/CardsLayoutBody.tsx +0 -308
  370. package/src/react/schemaRenderer/table/TableRenderer.tsx +0 -123
  371. package/src/react/schemaRenderer/table/TableRendererBody.tsx +0 -974
  372. package/src/react/schemaRenderer/table/filters.tsx +0 -1233
  373. package/src/react/schemaRenderer/table/formatCell.tsx +0 -264
  374. package/src/react/schemaRenderer/table/links.tsx +0 -112
  375. package/src/react/schemaRenderer/table/renderRowActions.tsx +0 -52
  376. package/src/react/schemaRenderer/table/url.tsx +0 -143
  377. package/src/react/theme-preview/apply.ts +0 -99
  378. package/src/react/theme-preview/build-html.ts +0 -436
  379. package/src/react/ui/button.tsx +0 -51
  380. package/src/react/ui/calendar.tsx +0 -67
  381. package/src/react/ui/checkbox.tsx +0 -29
  382. package/src/react/ui/dialog.tsx +0 -108
  383. package/src/react/ui/dropdown-menu.tsx +0 -97
  384. package/src/react/ui/input.tsx +0 -20
  385. package/src/react/ui/label.tsx +0 -21
  386. package/src/react/ui/popover.tsx +0 -50
  387. package/src/react/ui/select.tsx +0 -169
  388. package/src/react/ui/separator.tsx +0 -25
  389. package/src/react/ui/sheet.tsx +0 -136
  390. package/src/react/ui/sidebar.tsx +0 -723
  391. package/src/react/ui/skeleton.tsx +0 -13
  392. package/src/react/ui/slider.tsx +0 -34
  393. package/src/react/ui/switch.tsx +0 -28
  394. package/src/react/ui/table.tsx +0 -105
  395. package/src/react/ui/tabs.tsx +0 -63
  396. package/src/react/ui/textarea.tsx +0 -18
  397. package/src/react/ui/tooltip.tsx +0 -64
  398. package/src/react/useResizableWidth.ts +0 -139
  399. package/src/react/utils.ts +0 -6
  400. package/src/react/widgetRegistry.test.ts +0 -43
  401. package/src/react/widgetRegistry.ts +0 -50
  402. package/src/react/widgets/StatsOverviewRenderer.tsx +0 -232
  403. package/src/react/widgets/TableWidgetRenderer.tsx +0 -231
  404. package/src/react/widgets/ViewRenderer.tsx +0 -71
  405. package/src/relationManagerData.test.ts +0 -1595
  406. package/src/richtext/index.ts +0 -8
  407. package/src/richtext/registry.ts +0 -89
  408. package/src/routes/globals.ts +0 -148
  409. package/src/routes/guard.test.ts +0 -325
  410. package/src/routes/helpers.ts +0 -704
  411. package/src/routes/pages.ts +0 -175
  412. package/src/routes/panel.ts +0 -204
  413. package/src/routes/relations.ts +0 -1243
  414. package/src/routes/resources.ts +0 -781
  415. package/src/routes/theme.ts +0 -91
  416. package/src/routes-nested-relations.test.ts +0 -676
  417. package/src/routes-relations.test.ts +0 -972
  418. package/src/routes.test.ts +0 -2027
  419. package/src/routes.ts +0 -303
  420. package/src/schema/Alert.test.ts +0 -109
  421. package/src/schema/Alert.ts +0 -131
  422. package/src/schema/Block.ts +0 -169
  423. package/src/schema/Breadcrumbs.ts +0 -40
  424. package/src/schema/Card.ts +0 -35
  425. package/src/schema/Divider.ts +0 -20
  426. package/src/schema/Element.ts +0 -219
  427. package/src/schema/EmptyState.test.ts +0 -37
  428. package/src/schema/EmptyState.ts +0 -63
  429. package/src/schema/Fieldset.ts +0 -43
  430. package/src/schema/Grid.ts +0 -43
  431. package/src/schema/Group.ts +0 -30
  432. package/src/schema/Heading.ts +0 -39
  433. package/src/schema/Html.ts +0 -67
  434. package/src/schema/Icon.ts +0 -54
  435. package/src/schema/Image.ts +0 -57
  436. package/src/schema/LinkTag.ts +0 -41
  437. package/src/schema/Markdown.ts +0 -85
  438. package/src/schema/MetaTag.ts +0 -41
  439. package/src/schema/RelationTabs.ts +0 -71
  440. package/src/schema/ScriptTag.ts +0 -55
  441. package/src/schema/Section.ts +0 -160
  442. package/src/schema/ServerDataElement.test.ts +0 -140
  443. package/src/schema/ServerDataElement.ts +0 -156
  444. package/src/schema/SlotComponent.test.ts +0 -77
  445. package/src/schema/SlotComponent.ts +0 -71
  446. package/src/schema/Split.ts +0 -50
  447. package/src/schema/Stat.test.ts +0 -118
  448. package/src/schema/Stat.ts +0 -154
  449. package/src/schema/StatsOverview.test.ts +0 -141
  450. package/src/schema/StatsOverview.ts +0 -119
  451. package/src/schema/StyleTag.ts +0 -35
  452. package/src/schema/TableWidget.test.ts +0 -297
  453. package/src/schema/TableWidget.ts +0 -289
  454. package/src/schema/Tabs.ts +0 -79
  455. package/src/schema/Text.ts +0 -58
  456. package/src/schema/UnorderedList.ts +0 -49
  457. package/src/schema/View.test.ts +0 -111
  458. package/src/schema/View.ts +0 -127
  459. package/src/schema/Wizard.ts +0 -220
  460. package/src/schema/containers.test.ts +0 -564
  461. package/src/schema/headTags.test.ts +0 -134
  462. package/src/schema/index.ts +0 -40
  463. package/src/schema/primes.test.ts +0 -269
  464. package/src/schema/resolveSchema.test.ts +0 -379
  465. package/src/schema/resolveSchema.ts +0 -917
  466. package/src/schema/sanitize.ts +0 -58
  467. package/src/search.test.ts +0 -446
  468. package/src/search.ts +0 -178
  469. package/src/sessionFilters.test.ts +0 -375
  470. package/src/sessionFilters.ts +0 -143
  471. package/src/slot-components/index.ts +0 -10
  472. package/src/slot-components/registry.ts +0 -56
  473. package/src/styles/file-upload.css +0 -13
  474. package/src/summarizers/Summarizer.test.ts +0 -84
  475. package/src/summarizers/Summarizer.ts +0 -123
  476. package/src/summarizers/index.ts +0 -11
  477. package/src/theme/base-colors.ts +0 -68
  478. package/src/theme/chart-colors.ts +0 -50
  479. package/src/theme/colors.ts +0 -447
  480. package/src/theme/generate-css.test.ts +0 -139
  481. package/src/theme/generate-css.ts +0 -44
  482. package/src/theme/generate-scale.test.ts +0 -106
  483. package/src/theme/generate-scale.ts +0 -97
  484. package/src/theme/icon-map.ts +0 -42
  485. package/src/theme/index.ts +0 -34
  486. package/src/theme/migrate.test.ts +0 -178
  487. package/src/theme/migrate.ts +0 -81
  488. package/src/theme/presets.ts +0 -135
  489. package/src/theme/radius.ts +0 -18
  490. package/src/theme/resolve.test.ts +0 -238
  491. package/src/theme/resolve.ts +0 -96
  492. package/src/theme/spacing.ts +0 -18
  493. package/src/theme/storage.test.ts +0 -126
  494. package/src/theme/storage.ts +0 -106
  495. package/src/theme/theme-colors.ts +0 -88
  496. package/src/theme/types.ts +0 -125
  497. package/src/uploads/UploadAdapter.ts +0 -35
  498. package/src/uploads/index.ts +0 -2
  499. package/src/uploads/localUpload.test.ts +0 -70
  500. package/src/uploads/localUpload.ts +0 -84
  501. package/src/validation/Validator.ts +0 -49
  502. package/src/validation/index.ts +0 -28
  503. package/src/validation/rules.ts +0 -78
  504. package/src/validation/runValidators.ts +0 -435
  505. package/src/validation/uniqueValidator.test.ts +0 -196
  506. package/src/validation/uniqueValidator.ts +0 -133
  507. package/src/validation/validators.test.ts +0 -268
  508. package/src/vite.test.ts +0 -184
  509. package/src/vite.ts +0 -787
  510. package/src/widgets/index.ts +0 -10
  511. package/src/widgets/registry.ts +0 -45
  512. package/src/widgets.test.ts +0 -592
  513. package/tsconfig.build.json +0 -11
  514. package/tsconfig.json +0 -4
  515. package/tsconfig.test.json +0 -10
  516. package/views/react/Dashboard.tsx +0 -27
  517. package/views/react/Resources/Form.tsx +0 -102
  518. package/views/react/Resources/Index.tsx +0 -49
@@ -1,398 +0,0 @@
1
- /**
2
- * Database-backed notifications — server-side store helpers.
3
- *
4
- * Pilotiq doesn't ship a Prisma model; we read/write the
5
- * `notification` table that `@rudderjs/notification`'s
6
- * `NotificationProvider` publishes (`prisma/schema/notification.prisma`).
7
- * Apps that want bell-icon notifications add `NotificationProvider` to
8
- * their providers list and run `prisma generate`/`db push`; pilotiq
9
- * then queries the same table via `@rudderjs/orm`'s `ModelRegistry`
10
- * adapter so the wire shape matches what
11
- * `Notifier.send(user, new MyNotification())` already writes.
12
- *
13
- * `@rudderjs/orm` is a runtime soft-import — pilotiq has no hard
14
- * dependency on it. When the host app hasn't installed orm (or no
15
- * adapter is registered), every helper resolves to a clean
16
- * "store unavailable" sentinel rather than throwing.
17
- */
18
-
19
- import type { NotificationMeta, NotificationType } from './Notification.js'
20
- import type { NotificationActionMeta } from './types.js'
21
-
22
- /** Wire shape returned by the list endpoint to the bell client. */
23
- export interface DatabaseNotificationMeta {
24
- /** Stable PK from the `notification.id` column. */
25
- id: string
26
- /** Unix-ms timestamp the row was created. */
27
- createdAt: number
28
- /** ISO `read_at` timestamp; absent when unread. */
29
- readAt?: string
30
- /** Display title — read from the `data` JSON `title` key. */
31
- title: string
32
- /** Optional supporting text. */
33
- body?: string
34
- /** Optional UI tint. Mirrors the transient toast types so the bell can
35
- * share badge styling with the toaster. */
36
- type?: NotificationType
37
- /** Optional icon (registry name). */
38
- icon?: string
39
- /** Optional click-through URL. When set, clicking the row navigates
40
- * there + marks the notification as read. */
41
- url?: string
42
- /** Optional action strip rendered below the body. Round-trips
43
- * verbatim through the `data.actions` JSON column (`Notification`
44
- * emits the slim wire shape; `rowToMeta` validates each entry and
45
- * drops malformed ones with a `console.warn` rather than failing
46
- * the dropdown). */
47
- actions?: NotificationActionMeta[]
48
- }
49
-
50
- /** Raw row shape on the `notification` table — matches the schema
51
- * shipped by `@rudderjs/notification`. The `data` column is a
52
- * JSON-encoded string blob. */
53
- interface NotificationRow {
54
- id: string
55
- notifiable_id: string
56
- notifiable_type: string
57
- type: string
58
- data: string | Record<string, unknown>
59
- read_at: string | null
60
- created_at: string
61
- updated_at: string
62
- }
63
-
64
- /** Minimal query surface we use against the orm adapter. */
65
- interface QB {
66
- where(column: string, value: unknown): QB
67
- where(column: string, op: string, value: unknown): QB
68
- orderBy(column: string, dir?: 'ASC' | 'DESC'): QB
69
- paginate(page: number, perPage?: number): Promise<{ data: unknown[]; total: number }>
70
- get?(): Promise<unknown[]>
71
- count?(): Promise<number>
72
- update?(data: Record<string, unknown>): Promise<unknown>
73
- updateAll?(data: Record<string, unknown>): Promise<number>
74
- create?(data: Record<string, unknown>): Promise<unknown>
75
- }
76
-
77
- /** Test-injected adapter override; `null` falls back to dynamic import. */
78
- let _testAdapter: { query: <T>(table: string) => QB } | null | 'unset' = 'unset'
79
-
80
- /** Soft-resolved orm adapter. `null` when no orm adapter is registered.
81
- *
82
- * Prefers the rudder service container (`app().make('db')`) — the
83
- * orm-prisma / orm-drizzle providers register the adapter as a
84
- * globalThis-rooted singleton there, so this resolution path survives
85
- * the Vite SSR module-cache duplication that breaks shared singletons
86
- * in raw ES module land. Falls back to `ModelRegistry.get()` for
87
- * setups that wired the adapter directly.
88
- *
89
- * Both modules are imported indirectly so TypeScript doesn't try to
90
- * resolve them at type-check time — pilotiq doesn't peer-depend on
91
- * `@rudderjs/orm` or `@rudderjs/core` (the bell-icon is opt-in).
92
- */
93
- async function adapter(): Promise<{ query: <T>(table: string) => QB } | null> {
94
- if (_testAdapter !== 'unset') return _testAdapter
95
- const fromContainer = await resolveFromContainer()
96
- if (fromContainer) return fromContainer
97
- return resolveFromOrmModule()
98
- }
99
-
100
- async function resolveFromContainer(): Promise<{ query: <T>(table: string) => QB } | null> {
101
- const moduleName = '@rudderjs/core'
102
- try {
103
- const mod = await import(/* @vite-ignore */ moduleName) as {
104
- app?: () => { make(key: string): unknown }
105
- }
106
- if (!mod.app) return null
107
- const adapter = mod.app().make('db')
108
- if (!adapter || typeof adapter !== 'object') return null
109
- if (typeof (adapter as { query?: unknown }).query !== 'function') return null
110
- return adapter as { query: <T>(table: string) => QB }
111
- } catch {
112
- return null
113
- }
114
- }
115
-
116
- async function resolveFromOrmModule(): Promise<{ query: <T>(table: string) => QB } | null> {
117
- const moduleName = '@rudderjs/orm'
118
- try {
119
- const mod = await import(/* @vite-ignore */ moduleName) as {
120
- ModelRegistry?: { get(): { query: <T>(table: string) => QB } | null }
121
- }
122
- return mod.ModelRegistry?.get() ?? null
123
- } catch {
124
- return null
125
- }
126
- }
127
-
128
- /** Notification-table row JSON-decoded `data` payload. We always store
129
- * pilotiq's `NotificationMeta` shape; rows written by
130
- * `@rudderjs/notification.Notifier.send(...)` may carry arbitrary
131
- * application keys — we surface what we can recognize and ignore the rest. */
132
- function parseRowData(raw: string | Record<string, unknown>): Record<string, unknown> {
133
- if (typeof raw !== 'string') return raw
134
- try { return JSON.parse(raw) as Record<string, unknown> }
135
- catch { return {} }
136
- }
137
-
138
- function rowToMeta(row: NotificationRow): DatabaseNotificationMeta {
139
- const data = parseRowData(row.data)
140
- const meta: DatabaseNotificationMeta = {
141
- id: row.id,
142
- createdAt: Date.parse(row.created_at) || Date.now(),
143
- title: typeof data['title'] === 'string' ? (data['title'] as string) : '',
144
- }
145
- if (row.read_at) meta.readAt = row.read_at
146
- if (typeof data['body'] === 'string') meta.body = data['body'] as string
147
- if (typeof data['icon'] === 'string') meta.icon = data['icon'] as string
148
- if (typeof data['url'] === 'string') meta.url = data['url'] as string
149
- if (
150
- data['type'] === 'info' || data['type'] === 'success' ||
151
- data['type'] === 'warning' || data['type'] === 'error'
152
- ) {
153
- meta.type = data['type']
154
- }
155
- const actions = parseStoredActions(data['actions'])
156
- if (actions.length > 0) meta.actions = actions
157
- return meta
158
- }
159
-
160
- /**
161
- * Validate the stored action array shape — the `data.actions` column
162
- * is end-user controllable through the `Notification` builder, so we
163
- * defend in depth: malformed entries are dropped with a warning rather
164
- * than crashing the bell dropdown render.
165
- *
166
- * Required: `name: string`, `label: string`, exactly one of `url` /
167
- * `post` / `handler` set to a string.
168
- */
169
- function parseStoredActions(raw: unknown): NotificationActionMeta[] {
170
- if (!Array.isArray(raw)) return []
171
- const out: NotificationActionMeta[] = []
172
- for (const entry of raw) {
173
- if (!entry || typeof entry !== 'object') continue
174
- const e = entry as Record<string, unknown>
175
- if (typeof e['name'] !== 'string' || !e['name']) { warnDrop(e, 'missing name'); continue }
176
- if (typeof e['label'] !== 'string' || !e['label']) { warnDrop(e, 'missing label'); continue }
177
- const url = typeof e['url'] === 'string' ? e['url'] as string : undefined
178
- const post = typeof e['post'] === 'string' ? e['post'] as string : undefined
179
- const handler = typeof e['handler'] === 'string' ? e['handler'] as string : undefined
180
- const dispatchModes = [url, post, handler].filter(v => v !== undefined).length
181
- if (dispatchModes !== 1) { warnDrop(e, 'must set exactly one of url/post/handler'); continue }
182
-
183
- const action: NotificationActionMeta = { name: e['name'] as string, label: e['label'] as string }
184
- if (url !== undefined) action.url = url
185
- if (post !== undefined) action.post = post
186
- if (handler !== undefined) action.handler = handler
187
- if (e['payload'] && typeof e['payload'] === 'object' && !Array.isArray(e['payload'])) {
188
- action.payload = e['payload'] as Record<string, unknown>
189
- }
190
- if (typeof e['color'] === 'string') action.color = e['color'] as never
191
- if (typeof e['icon'] === 'string') action.icon = e['icon'] as string
192
- if (e['outlined'] === true) action.outlined = true
193
- if (typeof e['size'] === 'string') action.size = e['size'] as never
194
- if (e['openUrlInNewTab'] === true) action.openUrlInNewTab = true
195
- if (e['markAsRead'] === true) action.markAsRead = true
196
- out.push(action)
197
- }
198
- return out
199
- }
200
-
201
- function warnDrop(entry: Record<string, unknown>, reason: string): void {
202
- // Only warn in non-production — keep the bell quiet on prod where
203
- // a dropped row is preferable to console spam.
204
- if (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'production') return
205
-
206
- console.warn(
207
- `[Pilotiq] notification action dropped: ${reason}. Entry:`,
208
- entry,
209
- )
210
- }
211
-
212
- export interface ListOptions {
213
- /** `notifiable_type` column value. */
214
- notifiableType: string
215
- /** `notifiable_id` column value (typically the user's id). */
216
- notifiableId: string
217
- /** Hard cap on rows returned. Default 25. */
218
- limit?: number
219
- /** When true, only rows with `read_at IS NULL` are returned. */
220
- unreadOnly?: boolean
221
- }
222
-
223
- export interface ListResult {
224
- notifications: DatabaseNotificationMeta[]
225
- unreadCount: number
226
- }
227
-
228
- /**
229
- * Fetch the latest notifications for a notifiable + the unread count.
230
- * Returns `{ notifications: [], unreadCount: 0 }` when no orm adapter is
231
- * registered — apps without a database stay quiet rather than 500.
232
- */
233
- export async function listForUser(opts: ListOptions): Promise<ListResult> {
234
- const adp = await adapter()
235
- if (!adp) return { notifications: [], unreadCount: 0 }
236
-
237
- const limit = opts.limit ?? 25
238
- let q: QB = adp.query<NotificationRow>('notification')
239
- .where('notifiable_type', opts.notifiableType)
240
- .where('notifiable_id', opts.notifiableId)
241
- if (opts.unreadOnly) q = q.where('read_at', null)
242
- q = q.orderBy('created_at', 'DESC')
243
-
244
- const [page, count] = await Promise.all([
245
- q.paginate(1, limit),
246
- unreadCount({ notifiableType: opts.notifiableType, notifiableId: opts.notifiableId }),
247
- ])
248
- const rows = (page.data as NotificationRow[]).map(rowToMeta)
249
- return { notifications: rows, unreadCount: count }
250
- }
251
-
252
- /**
253
- * Fetch a single row by id, scoped to the notifiable. Returns
254
- * `undefined` when no row matches (already-deleted / wrong owner /
255
- * store unavailable). Used by the notification action route to look
256
- * up the stored `data.actions` array before dispatching.
257
- */
258
- export async function findOneForUser(
259
- id: string,
260
- opts: { notifiableType: string; notifiableId: string },
261
- ): Promise<DatabaseNotificationMeta | undefined> {
262
- const adp = await adapter()
263
- if (!adp) return undefined
264
- const q = adp.query<NotificationRow>('notification')
265
- .where('notifiable_type', opts.notifiableType)
266
- .where('notifiable_id', opts.notifiableId)
267
- .where('id', id)
268
- const page = await q.paginate(1, 1)
269
- const row = (page.data as NotificationRow[])[0]
270
- if (!row) return undefined
271
- return rowToMeta(row)
272
- }
273
-
274
- /** Count rows with `read_at IS NULL` for the notifiable. */
275
- export async function unreadCount(opts: {
276
- notifiableType: string
277
- notifiableId: string
278
- }): Promise<number> {
279
- const adp = await adapter()
280
- if (!adp) return 0
281
- const q = adp.query<NotificationRow>('notification')
282
- .where('notifiable_type', opts.notifiableType)
283
- .where('notifiable_id', opts.notifiableId)
284
- .where('read_at', null)
285
- // Cheap path when the adapter implements `count()`; fall back to
286
- // paginate(1,1).total which both Prisma and Drizzle adapters support.
287
- if (q.count) return q.count()
288
- const page = await q.paginate(1, 1)
289
- return page.total
290
- }
291
-
292
- /**
293
- * Mark a single notification row as read. Always scoped to
294
- * `notifiableId` so a tampered POST can't mark another user's row.
295
- *
296
- * Returns `true` when a row was updated, `false` when no row matched
297
- * (already-deleted / wrong owner / store unavailable).
298
- */
299
- export async function markAsRead(
300
- id: string,
301
- opts: { notifiableType: string; notifiableId: string },
302
- ): Promise<boolean> {
303
- const adp = await adapter()
304
- if (!adp) return false
305
- const q = adp.query<NotificationRow>('notification')
306
- .where('notifiable_type', opts.notifiableType)
307
- .where('notifiable_id', opts.notifiableId)
308
- .where('id', id)
309
- if (!q.updateAll) return false
310
- const n = await q.updateAll({ read_at: new Date().toISOString() })
311
- return n > 0
312
- }
313
-
314
- /** Mark a row unread again — used by the bell's "mark unread" affordance. */
315
- export async function markAsUnread(
316
- id: string,
317
- opts: { notifiableType: string; notifiableId: string },
318
- ): Promise<boolean> {
319
- const adp = await adapter()
320
- if (!adp) return false
321
- const q = adp.query<NotificationRow>('notification')
322
- .where('notifiable_type', opts.notifiableType)
323
- .where('notifiable_id', opts.notifiableId)
324
- .where('id', id)
325
- if (!q.updateAll) return false
326
- const n = await q.updateAll({ read_at: null })
327
- return n > 0
328
- }
329
-
330
- /** Mark every unread notification for the notifiable as read. */
331
- export async function markAllAsRead(opts: {
332
- notifiableType: string
333
- notifiableId: string
334
- }): Promise<number> {
335
- const adp = await adapter()
336
- if (!adp) return 0
337
- const q = adp.query<NotificationRow>('notification')
338
- .where('notifiable_type', opts.notifiableType)
339
- .where('notifiable_id', opts.notifiableId)
340
- .where('read_at', null)
341
- if (!q.updateAll) return 0
342
- return q.updateAll({ read_at: new Date().toISOString() })
343
- }
344
-
345
- /**
346
- * Insert a notification row directly. Powers
347
- * `Notification.make(...).sendToDatabase(recipient)`. Throws when the
348
- * orm adapter isn't registered — the caller has explicitly asked to
349
- * persist, so silent no-op would hide a real config error.
350
- */
351
- export async function persist(opts: {
352
- notifiableType: string
353
- notifiableId: string
354
- type?: string
355
- data: NotificationMeta & Record<string, unknown>
356
- }): Promise<{ id: string }> {
357
- const adp = await adapter()
358
- if (!adp) {
359
- throw new Error(
360
- '[Pilotiq] sendToDatabase() called but no @rudderjs/orm adapter is registered. ' +
361
- 'Add a database provider (orm-prisma / orm-drizzle) to your providers list, ' +
362
- "or call .sendToDatabase() only when the orm is wired up.",
363
- )
364
- }
365
- const q = adp.query<NotificationRow>('notification')
366
- if (!q.create) {
367
- throw new Error('[Pilotiq] orm adapter does not support `query.create()`.')
368
- }
369
- const id = `pn_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`
370
- const now = new Date().toISOString()
371
- await q.create({
372
- id,
373
- notifiable_id: opts.notifiableId,
374
- notifiable_type: opts.notifiableType,
375
- type: opts.type ?? 'PilotiqNotification',
376
- data: JSON.stringify(opts.data),
377
- read_at: null,
378
- created_at: now,
379
- updated_at: now,
380
- })
381
- return { id }
382
- }
383
-
384
- /** @internal — test seam. Inject a fake adapter (or `null` to mimic
385
- * "store unavailable"). Pass `undefined` to clear and fall back to the
386
- * dynamic `@rudderjs/orm` import. Tests should clear in `afterEach`. */
387
- export function _setTestAdapter(
388
- adp: { query: <T>(table: string) => QB } | null | undefined,
389
- ): void {
390
- _testAdapter = adp === undefined ? 'unset' : adp
391
- }
392
-
393
- /** @internal — exposed for tests; lets a unit test inject a fake
394
- * ModelRegistry without monkey-patching dynamic-import. */
395
- export const _internal = {
396
- parseRowData,
397
- rowToMeta,
398
- }
@@ -1,187 +0,0 @@
1
- /**
2
- * Builder + panelInfo() integration tests for
3
- * `Pilotiq.databaseNotifications()`. The transport layer (the
4
- * `_notifications` route family) is exercised via the storage tests +
5
- * `database.test.ts`; here we lock down the wire shape consumers
6
- * actually depend on.
7
- */
8
- import { describe, it } from 'node:test'
9
- import assert from 'node:assert/strict'
10
-
11
- import { Pilotiq } from '../Pilotiq.js'
12
- import { panelInfo } from '../pageData.js'
13
-
14
- describe('Pilotiq.databaseNotifications() — builder', () => {
15
- it('opt-out by default — cfg.databaseNotifications is undefined', () => {
16
- const cfg = Pilotiq.make('admin').getConfig()
17
- assert.equal(cfg.databaseNotifications, undefined)
18
- })
19
-
20
- it('toggle without options enables with defaults', () => {
21
- const cfg = Pilotiq.make('admin').databaseNotifications().getConfig()
22
- assert.equal(cfg.databaseNotifications?.enabled, true)
23
- assert.equal(cfg.databaseNotifications?.position, undefined)
24
- assert.equal(cfg.databaseNotifications?.polling, undefined)
25
- })
26
-
27
- it('options round-trip', () => {
28
- const cfg = Pilotiq.make('admin').databaseNotifications({
29
- position: 'sidebar',
30
- polling: 10,
31
- pageSize: 50,
32
- badgeColor: 'success',
33
- trigger: { icon: 'bell', label: 'Inbox' },
34
- }).getConfig()
35
- assert.equal(cfg.databaseNotifications?.position, 'sidebar')
36
- assert.equal(cfg.databaseNotifications?.polling, 10)
37
- assert.equal(cfg.databaseNotifications?.pageSize, 50)
38
- assert.equal(cfg.databaseNotifications?.badgeColor, 'success')
39
- assert.equal(cfg.databaseNotifications?.trigger?.icon, 'bell')
40
- })
41
-
42
- it('null polling round-trips (disable auto-poll)', () => {
43
- const cfg = Pilotiq.make('admin').databaseNotifications({ polling: null }).getConfig()
44
- assert.equal(cfg.databaseNotifications?.polling, null)
45
- })
46
-
47
- it('databaseNotificationsPolling sugar updates the slot', () => {
48
- const cfg = Pilotiq.make('admin')
49
- .databaseNotifications()
50
- .databaseNotificationsPolling(120)
51
- .getConfig()
52
- assert.equal(cfg.databaseNotifications?.polling, 120)
53
- })
54
-
55
- it('databaseNotificationsPolling is a no-op when not enabled', () => {
56
- const cfg = Pilotiq.make('admin').databaseNotificationsPolling(5).getConfig()
57
- assert.equal(cfg.databaseNotifications, undefined)
58
- })
59
-
60
- it('databaseNotificationsPosition sugar updates the slot', () => {
61
- const cfg = Pilotiq.make('admin')
62
- .databaseNotifications()
63
- .databaseNotificationsPosition('sidebar')
64
- .getConfig()
65
- assert.equal(cfg.databaseNotifications?.position, 'sidebar')
66
- })
67
- })
68
-
69
- describe('panelInfo() — databaseNotifications meta', () => {
70
- it('absent when never opted in', async () => {
71
- const panel = await panelInfo(Pilotiq.make('admin'))
72
- assert.equal((panel as Record<string, unknown>)['databaseNotifications'], undefined)
73
- })
74
-
75
- it('absent when no user resolves', async () => {
76
- const p = Pilotiq.make('admin').databaseNotifications()
77
- const panel = await panelInfo(p)
78
- assert.equal((panel as Record<string, unknown>)['databaseNotifications'], undefined)
79
- })
80
-
81
- it('present with resolver + defaults', async () => {
82
- const p = Pilotiq.make('admin')
83
- .user(() => ({ id: 1, name: 'Sue' }))
84
- .databaseNotifications()
85
- const panel = await panelInfo(p)
86
- const dn = (panel as any).databaseNotifications
87
- assert.ok(dn, 'databaseNotifications is present')
88
- assert.equal(dn.position, 'topbar')
89
- assert.equal(dn.polling, 30)
90
- assert.equal(dn.pageSize, 25)
91
- assert.equal(dn.badgeColor, 'primary')
92
- assert.equal(dn.listUrl, '/admin/_notifications')
93
- assert.equal(dn.readAllUrl, '/admin/_notifications/read-all')
94
- assert.equal(dn.readUrl, '/admin/_notifications/:id/read')
95
- assert.equal(dn.unreadUrl, '/admin/_notifications/:id/unread')
96
- assert.equal(dn.actionUrl, '/admin/_notifications/:id/_action/:actionName')
97
- })
98
-
99
- it('honors custom path for URL building', async () => {
100
- const p = Pilotiq.make('admin')
101
- .path('/dashboard')
102
- .user(() => ({ id: 1 }))
103
- .databaseNotifications()
104
- const panel = await panelInfo(p)
105
- const dn = (panel as any).databaseNotifications
106
- assert.equal(dn.listUrl, '/dashboard/_notifications')
107
- })
108
-
109
- it('null polling round-trips to the wire', async () => {
110
- const p = Pilotiq.make('admin')
111
- .user(() => ({ id: 1 }))
112
- .databaseNotifications({ polling: null })
113
- const panel = await panelInfo(p)
114
- const dn = (panel as any).databaseNotifications
115
- assert.equal(dn.polling, null)
116
- })
117
-
118
- it('per-call options override defaults', async () => {
119
- const p = Pilotiq.make('admin')
120
- .user(() => ({ id: 1 }))
121
- .databaseNotifications({
122
- position: 'sidebar',
123
- polling: 5,
124
- pageSize: 10,
125
- badgeColor: 'warning',
126
- })
127
- const panel = await panelInfo(p)
128
- const dn = (panel as any).databaseNotifications
129
- assert.equal(dn.position, 'sidebar')
130
- assert.equal(dn.polling, 5)
131
- assert.equal(dn.pageSize, 10)
132
- assert.equal(dn.badgeColor, 'warning')
133
- })
134
-
135
- it('trigger overrides ride through to the wire', async () => {
136
- const p = Pilotiq.make('admin')
137
- .user(() => ({ id: 1 }))
138
- .databaseNotifications({ trigger: { icon: 'bell', label: 'Inbox' } })
139
- const panel = await panelInfo(p)
140
- const dn = (panel as any).databaseNotifications
141
- assert.deepEqual(dn.trigger, { icon: 'bell', label: 'Inbox' })
142
- })
143
- })
144
-
145
- describe('panelInfo() — broadcast (Phase 2)', () => {
146
- it('absent when broadcast wasn\'t enabled', async () => {
147
- const p = Pilotiq.make('admin')
148
- .user(() => ({ id: 1 }))
149
- .databaseNotifications()
150
- const panel = await panelInfo(p)
151
- const dn = (panel as any).databaseNotifications
152
- assert.equal(dn.broadcast, undefined)
153
- })
154
-
155
- it('present when databaseNotificationsBroadcast() is called', async () => {
156
- const p = Pilotiq.make('admin')
157
- .user(() => ({ id: 42 }))
158
- .databaseNotifications()
159
- .databaseNotificationsBroadcast()
160
- const panel = await panelInfo(p)
161
- const dn = (panel as any).databaseNotifications
162
- assert.ok(dn.broadcast, 'broadcast meta is present')
163
- assert.equal(dn.broadcast.channel, 'private-pilotiq-notifications.42')
164
- assert.equal(dn.broadcast.event, 'notification.created')
165
- assert.equal(dn.broadcast.wsUrl, '') // empty -> client falls back to same-origin
166
- })
167
-
168
- it('honors a custom wsUrl', async () => {
169
- const p = Pilotiq.make('admin')
170
- .user(() => ({ id: 'u-1' }))
171
- .databaseNotifications({ broadcast: { wsUrl: 'wss://x.test/ws' } })
172
- const panel = await panelInfo(p)
173
- const dn = (panel as any).databaseNotifications
174
- assert.equal(dn.broadcast.wsUrl, 'wss://x.test/ws')
175
- assert.equal(dn.broadcast.channel, 'private-pilotiq-notifications.u-1')
176
- })
177
-
178
- it('absent when user has no id (channel cannot be scoped)', async () => {
179
- const p = Pilotiq.make('admin')
180
- .user(() => ({ name: 'Anonymous' }) as unknown as { id: string })
181
- .databaseNotifications()
182
- .databaseNotificationsBroadcast()
183
- const panel = await panelInfo(p)
184
- const dn = (panel as any).databaseNotifications
185
- assert.equal(dn?.broadcast, undefined)
186
- })
187
- })