@pilotiq/pilotiq 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1409) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/CHANGELOG.md +11 -0
  3. package/CLAUDE.md +207 -0
  4. package/LICENSE +21 -0
  5. package/dist/Cluster.d.ts +56 -0
  6. package/dist/Cluster.d.ts.map +1 -0
  7. package/dist/Cluster.js +62 -0
  8. package/dist/Cluster.js.map +1 -0
  9. package/dist/Column.d.ts +378 -0
  10. package/dist/Column.d.ts.map +1 -0
  11. package/dist/Column.js +434 -0
  12. package/dist/Column.js.map +1 -0
  13. package/dist/Global.d.ts +123 -0
  14. package/dist/Global.d.ts.map +1 -0
  15. package/dist/Global.js +124 -0
  16. package/dist/Global.js.map +1 -0
  17. package/dist/Page.d.ts +90 -0
  18. package/dist/Page.d.ts.map +1 -0
  19. package/dist/Page.js +107 -0
  20. package/dist/Page.js.map +1 -0
  21. package/dist/Pilotiq.d.ts +505 -0
  22. package/dist/Pilotiq.d.ts.map +1 -0
  23. package/dist/Pilotiq.js +463 -0
  24. package/dist/Pilotiq.js.map +1 -0
  25. package/dist/PilotiqRegistry.d.ts +10 -0
  26. package/dist/PilotiqRegistry.d.ts.map +1 -0
  27. package/dist/PilotiqRegistry.js +32 -0
  28. package/dist/PilotiqRegistry.js.map +1 -0
  29. package/dist/PilotiqServiceProvider.d.ts +16 -0
  30. package/dist/PilotiqServiceProvider.d.ts.map +1 -0
  31. package/dist/PilotiqServiceProvider.js +57 -0
  32. package/dist/PilotiqServiceProvider.js.map +1 -0
  33. package/dist/RelationManager.d.ts +372 -0
  34. package/dist/RelationManager.d.ts.map +1 -0
  35. package/dist/RelationManager.js +342 -0
  36. package/dist/RelationManager.js.map +1 -0
  37. package/dist/RenderHook.d.ts +86 -0
  38. package/dist/RenderHook.d.ts.map +1 -0
  39. package/dist/RenderHook.js +116 -0
  40. package/dist/RenderHook.js.map +1 -0
  41. package/dist/Resource.d.ts +290 -0
  42. package/dist/Resource.d.ts.map +1 -0
  43. package/dist/Resource.js +362 -0
  44. package/dist/Resource.js.map +1 -0
  45. package/dist/RightPanel.d.ts +92 -0
  46. package/dist/RightPanel.d.ts.map +1 -0
  47. package/dist/RightPanel.js +61 -0
  48. package/dist/RightPanel.js.map +1 -0
  49. package/dist/Tab.d.ts +92 -0
  50. package/dist/Tab.d.ts.map +1 -0
  51. package/dist/Tab.js +93 -0
  52. package/dist/Tab.js.map +1 -0
  53. package/dist/UserMenuItem.d.ts +76 -0
  54. package/dist/UserMenuItem.d.ts.map +1 -0
  55. package/dist/UserMenuItem.js +87 -0
  56. package/dist/UserMenuItem.js.map +1 -0
  57. package/dist/actions/Action.d.ts +888 -0
  58. package/dist/actions/Action.d.ts.map +1 -0
  59. package/dist/actions/Action.js +1652 -0
  60. package/dist/actions/Action.js.map +1 -0
  61. package/dist/actions/ActionGroup.d.ts +85 -0
  62. package/dist/actions/ActionGroup.d.ts.map +1 -0
  63. package/dist/actions/ActionGroup.js +132 -0
  64. package/dist/actions/ActionGroup.js.map +1 -0
  65. package/dist/actions/attachFactory.d.ts +67 -0
  66. package/dist/actions/attachFactory.d.ts.map +1 -0
  67. package/dist/actions/attachFactory.js +115 -0
  68. package/dist/actions/attachFactory.js.map +1 -0
  69. package/dist/actions/exportFactory.d.ts +88 -0
  70. package/dist/actions/exportFactory.d.ts.map +1 -0
  71. package/dist/actions/exportFactory.js +144 -0
  72. package/dist/actions/exportFactory.js.map +1 -0
  73. package/dist/actions/importFactory.d.ts +97 -0
  74. package/dist/actions/importFactory.d.ts.map +1 -0
  75. package/dist/actions/importFactory.js +143 -0
  76. package/dist/actions/importFactory.js.map +1 -0
  77. package/dist/actions/index.d.ts +3 -0
  78. package/dist/actions/index.d.ts.map +1 -0
  79. package/dist/actions/index.js +3 -0
  80. package/dist/actions/index.js.map +1 -0
  81. package/dist/applyPageHooks.d.ts +54 -0
  82. package/dist/applyPageHooks.d.ts.map +1 -0
  83. package/dist/applyPageHooks.js +149 -0
  84. package/dist/applyPageHooks.js.map +1 -0
  85. package/dist/cells/coerce.d.ts +25 -0
  86. package/dist/cells/coerce.d.ts.map +1 -0
  87. package/dist/cells/coerce.js +87 -0
  88. package/dist/cells/coerce.js.map +1 -0
  89. package/dist/clusterPaths.d.ts +9 -0
  90. package/dist/clusterPaths.d.ts.map +1 -0
  91. package/dist/clusterPaths.js +19 -0
  92. package/dist/clusterPaths.js.map +1 -0
  93. package/dist/columns/BadgeColumn.d.ts +16 -0
  94. package/dist/columns/BadgeColumn.d.ts.map +1 -0
  95. package/dist/columns/BadgeColumn.js +25 -0
  96. package/dist/columns/BadgeColumn.js.map +1 -0
  97. package/dist/columns/BooleanColumn.d.ts +10 -0
  98. package/dist/columns/BooleanColumn.d.ts.map +1 -0
  99. package/dist/columns/BooleanColumn.js +18 -0
  100. package/dist/columns/BooleanColumn.js.map +1 -0
  101. package/dist/columns/ColorColumn.d.ts +27 -0
  102. package/dist/columns/ColorColumn.d.ts.map +1 -0
  103. package/dist/columns/ColorColumn.js +35 -0
  104. package/dist/columns/ColorColumn.js.map +1 -0
  105. package/dist/columns/IconColumn.d.ts +22 -0
  106. package/dist/columns/IconColumn.d.ts.map +1 -0
  107. package/dist/columns/IconColumn.js +28 -0
  108. package/dist/columns/IconColumn.js.map +1 -0
  109. package/dist/columns/ImageColumn.d.ts +17 -0
  110. package/dist/columns/ImageColumn.d.ts.map +1 -0
  111. package/dist/columns/ImageColumn.js +24 -0
  112. package/dist/columns/ImageColumn.js.map +1 -0
  113. package/dist/columns/SelectColumn.d.ts +36 -0
  114. package/dist/columns/SelectColumn.d.ts.map +1 -0
  115. package/dist/columns/SelectColumn.js +52 -0
  116. package/dist/columns/SelectColumn.js.map +1 -0
  117. package/dist/columns/TextColumn.d.ts +18 -0
  118. package/dist/columns/TextColumn.d.ts.map +1 -0
  119. package/dist/columns/TextColumn.js +20 -0
  120. package/dist/columns/TextColumn.js.map +1 -0
  121. package/dist/columns/TextInputColumn.d.ts +47 -0
  122. package/dist/columns/TextInputColumn.d.ts.map +1 -0
  123. package/dist/columns/TextInputColumn.js +60 -0
  124. package/dist/columns/TextInputColumn.js.map +1 -0
  125. package/dist/columns/ToggleColumn.d.ts +32 -0
  126. package/dist/columns/ToggleColumn.d.ts.map +1 -0
  127. package/dist/columns/ToggleColumn.js +45 -0
  128. package/dist/columns/ToggleColumn.js.map +1 -0
  129. package/dist/columns/index.d.ts +10 -0
  130. package/dist/columns/index.d.ts.map +1 -0
  131. package/dist/columns/index.js +10 -0
  132. package/dist/columns/index.js.map +1 -0
  133. package/dist/defaultGlobalPages.d.ts +11 -0
  134. package/dist/defaultGlobalPages.d.ts.map +1 -0
  135. package/dist/defaultGlobalPages.js +87 -0
  136. package/dist/defaultGlobalPages.js.map +1 -0
  137. package/dist/defaultPages.d.ts +247 -0
  138. package/dist/defaultPages.d.ts.map +1 -0
  139. package/dist/defaultPages.js +558 -0
  140. package/dist/defaultPages.js.map +1 -0
  141. package/dist/elements/Form.d.ts +219 -0
  142. package/dist/elements/Form.d.ts.map +1 -0
  143. package/dist/elements/Form.js +259 -0
  144. package/dist/elements/Form.js.map +1 -0
  145. package/dist/elements/ListTabs.d.ts +17 -0
  146. package/dist/elements/ListTabs.d.ts.map +1 -0
  147. package/dist/elements/ListTabs.js +23 -0
  148. package/dist/elements/ListTabs.js.map +1 -0
  149. package/dist/elements/Table.d.ts +535 -0
  150. package/dist/elements/Table.d.ts.map +1 -0
  151. package/dist/elements/Table.js +481 -0
  152. package/dist/elements/Table.js.map +1 -0
  153. package/dist/elements/TableGroup.d.ts +121 -0
  154. package/dist/elements/TableGroup.d.ts.map +1 -0
  155. package/dist/elements/TableGroup.js +162 -0
  156. package/dist/elements/TableGroup.js.map +1 -0
  157. package/dist/elements/dispatchAction.d.ts +127 -0
  158. package/dist/elements/dispatchAction.d.ts.map +1 -0
  159. package/dist/elements/dispatchAction.js +254 -0
  160. package/dist/elements/dispatchAction.js.map +1 -0
  161. package/dist/elements/dispatchForm.d.ts +220 -0
  162. package/dist/elements/dispatchForm.d.ts.map +1 -0
  163. package/dist/elements/dispatchForm.js +1645 -0
  164. package/dist/elements/dispatchForm.js.map +1 -0
  165. package/dist/elements/dispatchTable.d.ts +69 -0
  166. package/dist/elements/dispatchTable.d.ts.map +1 -0
  167. package/dist/elements/dispatchTable.js +606 -0
  168. package/dist/elements/dispatchTable.js.map +1 -0
  169. package/dist/elements/index.d.ts +3 -0
  170. package/dist/elements/index.d.ts.map +1 -0
  171. package/dist/elements/index.js +3 -0
  172. package/dist/elements/index.js.map +1 -0
  173. package/dist/entries/BadgeEntry.d.ts +21 -0
  174. package/dist/entries/BadgeEntry.d.ts.map +1 -0
  175. package/dist/entries/BadgeEntry.js +32 -0
  176. package/dist/entries/BadgeEntry.js.map +1 -0
  177. package/dist/entries/CodeEntry.d.ts +38 -0
  178. package/dist/entries/CodeEntry.d.ts.map +1 -0
  179. package/dist/entries/CodeEntry.js +44 -0
  180. package/dist/entries/CodeEntry.js.map +1 -0
  181. package/dist/entries/ColorEntry.d.ts +32 -0
  182. package/dist/entries/ColorEntry.d.ts.map +1 -0
  183. package/dist/entries/ColorEntry.js +48 -0
  184. package/dist/entries/ColorEntry.js.map +1 -0
  185. package/dist/entries/ComponentEntry.d.ts +66 -0
  186. package/dist/entries/ComponentEntry.d.ts.map +1 -0
  187. package/dist/entries/ComponentEntry.js +86 -0
  188. package/dist/entries/ComponentEntry.js.map +1 -0
  189. package/dist/entries/Entry.d.ts +175 -0
  190. package/dist/entries/Entry.d.ts.map +1 -0
  191. package/dist/entries/Entry.js +233 -0
  192. package/dist/entries/Entry.js.map +1 -0
  193. package/dist/entries/IconEntry.d.ts +30 -0
  194. package/dist/entries/IconEntry.d.ts.map +1 -0
  195. package/dist/entries/IconEntry.js +34 -0
  196. package/dist/entries/IconEntry.js.map +1 -0
  197. package/dist/entries/ImageEntry.d.ts +33 -0
  198. package/dist/entries/ImageEntry.d.ts.map +1 -0
  199. package/dist/entries/ImageEntry.js +47 -0
  200. package/dist/entries/ImageEntry.js.map +1 -0
  201. package/dist/entries/KeyValueEntry.d.ts +30 -0
  202. package/dist/entries/KeyValueEntry.d.ts.map +1 -0
  203. package/dist/entries/KeyValueEntry.js +38 -0
  204. package/dist/entries/KeyValueEntry.js.map +1 -0
  205. package/dist/entries/RepeatableEntry.d.ts +122 -0
  206. package/dist/entries/RepeatableEntry.d.ts.map +1 -0
  207. package/dist/entries/RepeatableEntry.js +121 -0
  208. package/dist/entries/RepeatableEntry.js.map +1 -0
  209. package/dist/entries/TextEntry.d.ts +38 -0
  210. package/dist/entries/TextEntry.d.ts.map +1 -0
  211. package/dist/entries/TextEntry.js +49 -0
  212. package/dist/entries/TextEntry.js.map +1 -0
  213. package/dist/entries/index.d.ts +2 -0
  214. package/dist/entries/index.d.ts.map +1 -0
  215. package/dist/entries/index.js +8 -0
  216. package/dist/entries/index.js.map +1 -0
  217. package/dist/entries/registry.d.ts +41 -0
  218. package/dist/entries/registry.d.ts.map +1 -0
  219. package/dist/entries/registry.js +17 -0
  220. package/dist/entries/registry.js.map +1 -0
  221. package/dist/fields/BuilderField.d.ts +420 -0
  222. package/dist/fields/BuilderField.d.ts.map +1 -0
  223. package/dist/fields/BuilderField.js +359 -0
  224. package/dist/fields/BuilderField.js.map +1 -0
  225. package/dist/fields/CheckboxField.d.ts +18 -0
  226. package/dist/fields/CheckboxField.d.ts.map +1 -0
  227. package/dist/fields/CheckboxField.js +23 -0
  228. package/dist/fields/CheckboxField.js.map +1 -0
  229. package/dist/fields/CheckboxListField.d.ts +25 -0
  230. package/dist/fields/CheckboxListField.d.ts.map +1 -0
  231. package/dist/fields/CheckboxListField.js +46 -0
  232. package/dist/fields/CheckboxListField.js.map +1 -0
  233. package/dist/fields/ColorPickerField.d.ts +16 -0
  234. package/dist/fields/ColorPickerField.d.ts.map +1 -0
  235. package/dist/fields/ColorPickerField.js +21 -0
  236. package/dist/fields/ColorPickerField.js.map +1 -0
  237. package/dist/fields/DateField.d.ts +29 -0
  238. package/dist/fields/DateField.d.ts.map +1 -0
  239. package/dist/fields/DateField.js +45 -0
  240. package/dist/fields/DateField.js.map +1 -0
  241. package/dist/fields/EmailField.d.ts +8 -0
  242. package/dist/fields/EmailField.d.ts.map +1 -0
  243. package/dist/fields/EmailField.js +13 -0
  244. package/dist/fields/EmailField.js.map +1 -0
  245. package/dist/fields/Field.d.ts +485 -0
  246. package/dist/fields/Field.d.ts.map +1 -0
  247. package/dist/fields/Field.js +539 -0
  248. package/dist/fields/Field.js.map +1 -0
  249. package/dist/fields/FileUploadField.d.ts +43 -0
  250. package/dist/fields/FileUploadField.d.ts.map +1 -0
  251. package/dist/fields/FileUploadField.js +60 -0
  252. package/dist/fields/FileUploadField.js.map +1 -0
  253. package/dist/fields/HiddenField.d.ts +19 -0
  254. package/dist/fields/HiddenField.d.ts.map +1 -0
  255. package/dist/fields/HiddenField.js +24 -0
  256. package/dist/fields/HiddenField.js.map +1 -0
  257. package/dist/fields/KeyValueField.d.ts +36 -0
  258. package/dist/fields/KeyValueField.d.ts.map +1 -0
  259. package/dist/fields/KeyValueField.js +47 -0
  260. package/dist/fields/KeyValueField.js.map +1 -0
  261. package/dist/fields/MarkdownField.d.ts +79 -0
  262. package/dist/fields/MarkdownField.d.ts.map +1 -0
  263. package/dist/fields/MarkdownField.js +117 -0
  264. package/dist/fields/MarkdownField.js.map +1 -0
  265. package/dist/fields/NumberField.d.ts +17 -0
  266. package/dist/fields/NumberField.d.ts.map +1 -0
  267. package/dist/fields/NumberField.js +27 -0
  268. package/dist/fields/NumberField.js.map +1 -0
  269. package/dist/fields/RadioField.d.ts +26 -0
  270. package/dist/fields/RadioField.d.ts.map +1 -0
  271. package/dist/fields/RadioField.js +47 -0
  272. package/dist/fields/RadioField.js.map +1 -0
  273. package/dist/fields/RepeaterField.d.ts +594 -0
  274. package/dist/fields/RepeaterField.d.ts.map +1 -0
  275. package/dist/fields/RepeaterField.js +504 -0
  276. package/dist/fields/RepeaterField.js.map +1 -0
  277. package/dist/fields/RowButton.d.ts +86 -0
  278. package/dist/fields/RowButton.d.ts.map +1 -0
  279. package/dist/fields/RowButton.js +85 -0
  280. package/dist/fields/RowButton.js.map +1 -0
  281. package/dist/fields/SelectField.d.ts +127 -0
  282. package/dist/fields/SelectField.d.ts.map +1 -0
  283. package/dist/fields/SelectField.js +160 -0
  284. package/dist/fields/SelectField.js.map +1 -0
  285. package/dist/fields/SliderField.d.ts +31 -0
  286. package/dist/fields/SliderField.d.ts.map +1 -0
  287. package/dist/fields/SliderField.js +45 -0
  288. package/dist/fields/SliderField.js.map +1 -0
  289. package/dist/fields/SlugField.d.ts +11 -0
  290. package/dist/fields/SlugField.d.ts.map +1 -0
  291. package/dist/fields/SlugField.js +19 -0
  292. package/dist/fields/SlugField.js.map +1 -0
  293. package/dist/fields/TagsInputField.d.ts +65 -0
  294. package/dist/fields/TagsInputField.d.ts.map +1 -0
  295. package/dist/fields/TagsInputField.js +104 -0
  296. package/dist/fields/TagsInputField.js.map +1 -0
  297. package/dist/fields/TextField.d.ts +11 -0
  298. package/dist/fields/TextField.d.ts.map +1 -0
  299. package/dist/fields/TextField.js +19 -0
  300. package/dist/fields/TextField.js.map +1 -0
  301. package/dist/fields/TextareaField.d.ts +40 -0
  302. package/dist/fields/TextareaField.d.ts.map +1 -0
  303. package/dist/fields/TextareaField.js +51 -0
  304. package/dist/fields/TextareaField.js.map +1 -0
  305. package/dist/fields/ToggleButtonsField.d.ts +24 -0
  306. package/dist/fields/ToggleButtonsField.d.ts.map +1 -0
  307. package/dist/fields/ToggleButtonsField.js +41 -0
  308. package/dist/fields/ToggleButtonsField.js.map +1 -0
  309. package/dist/fields/ToggleField.d.ts +8 -0
  310. package/dist/fields/ToggleField.d.ts.map +1 -0
  311. package/dist/fields/ToggleField.js +13 -0
  312. package/dist/fields/ToggleField.js.map +1 -0
  313. package/dist/fields/optionsResolver.d.ts +54 -0
  314. package/dist/fields/optionsResolver.d.ts.map +1 -0
  315. package/dist/fields/optionsResolver.js +62 -0
  316. package/dist/fields/optionsResolver.js.map +1 -0
  317. package/dist/fields/resolveField.d.ts +21 -0
  318. package/dist/fields/resolveField.d.ts.map +1 -0
  319. package/dist/fields/resolveField.js +26 -0
  320. package/dist/fields/resolveField.js.map +1 -0
  321. package/dist/filters/BooleanFilter.d.ts +20 -0
  322. package/dist/filters/BooleanFilter.d.ts.map +1 -0
  323. package/dist/filters/BooleanFilter.js +31 -0
  324. package/dist/filters/BooleanFilter.js.map +1 -0
  325. package/dist/filters/DateRangeFilter.d.ts +68 -0
  326. package/dist/filters/DateRangeFilter.d.ts.map +1 -0
  327. package/dist/filters/DateRangeFilter.js +137 -0
  328. package/dist/filters/DateRangeFilter.js.map +1 -0
  329. package/dist/filters/Filter.d.ts +140 -0
  330. package/dist/filters/Filter.d.ts.map +1 -0
  331. package/dist/filters/Filter.js +99 -0
  332. package/dist/filters/Filter.js.map +1 -0
  333. package/dist/filters/FormFilter.d.ts +103 -0
  334. package/dist/filters/FormFilter.d.ts.map +1 -0
  335. package/dist/filters/FormFilter.js +180 -0
  336. package/dist/filters/FormFilter.js.map +1 -0
  337. package/dist/filters/MultiSelectFilter.d.ts +41 -0
  338. package/dist/filters/MultiSelectFilter.d.ts.map +1 -0
  339. package/dist/filters/MultiSelectFilter.js +67 -0
  340. package/dist/filters/MultiSelectFilter.js.map +1 -0
  341. package/dist/filters/QueryBuilderFilter.d.ts +145 -0
  342. package/dist/filters/QueryBuilderFilter.d.ts.map +1 -0
  343. package/dist/filters/QueryBuilderFilter.js +323 -0
  344. package/dist/filters/QueryBuilderFilter.js.map +1 -0
  345. package/dist/filters/SelectFilter.d.ts +26 -0
  346. package/dist/filters/SelectFilter.d.ts.map +1 -0
  347. package/dist/filters/SelectFilter.js +35 -0
  348. package/dist/filters/SelectFilter.js.map +1 -0
  349. package/dist/filters/TernaryFilter.d.ts +35 -0
  350. package/dist/filters/TernaryFilter.d.ts.map +1 -0
  351. package/dist/filters/TernaryFilter.js +71 -0
  352. package/dist/filters/TernaryFilter.js.map +1 -0
  353. package/dist/filters/TrashedFilter.d.ts +28 -0
  354. package/dist/filters/TrashedFilter.d.ts.map +1 -0
  355. package/dist/filters/TrashedFilter.js +52 -0
  356. package/dist/filters/TrashedFilter.js.map +1 -0
  357. package/dist/filters/queryBuilder/BooleanConstraint.d.ts +13 -0
  358. package/dist/filters/queryBuilder/BooleanConstraint.d.ts.map +1 -0
  359. package/dist/filters/queryBuilder/BooleanConstraint.js +27 -0
  360. package/dist/filters/queryBuilder/BooleanConstraint.js.map +1 -0
  361. package/dist/filters/queryBuilder/Constraint.d.ts +74 -0
  362. package/dist/filters/queryBuilder/Constraint.d.ts.map +1 -0
  363. package/dist/filters/queryBuilder/Constraint.js +45 -0
  364. package/dist/filters/queryBuilder/Constraint.js.map +1 -0
  365. package/dist/filters/queryBuilder/DateConstraint.d.ts +18 -0
  366. package/dist/filters/queryBuilder/DateConstraint.d.ts.map +1 -0
  367. package/dist/filters/queryBuilder/DateConstraint.js +63 -0
  368. package/dist/filters/queryBuilder/DateConstraint.js.map +1 -0
  369. package/dist/filters/queryBuilder/NumberConstraint.d.ts +12 -0
  370. package/dist/filters/queryBuilder/NumberConstraint.d.ts.map +1 -0
  371. package/dist/filters/queryBuilder/NumberConstraint.js +61 -0
  372. package/dist/filters/queryBuilder/NumberConstraint.js.map +1 -0
  373. package/dist/filters/queryBuilder/SelectConstraint.d.ts +22 -0
  374. package/dist/filters/queryBuilder/SelectConstraint.d.ts.map +1 -0
  375. package/dist/filters/queryBuilder/SelectConstraint.js +66 -0
  376. package/dist/filters/queryBuilder/SelectConstraint.js.map +1 -0
  377. package/dist/filters/queryBuilder/TextConstraint.d.ts +18 -0
  378. package/dist/filters/queryBuilder/TextConstraint.d.ts.map +1 -0
  379. package/dist/filters/queryBuilder/TextConstraint.js +58 -0
  380. package/dist/filters/queryBuilder/TextConstraint.js.map +1 -0
  381. package/dist/filters/queryBuilder/index.d.ts +7 -0
  382. package/dist/filters/queryBuilder/index.d.ts.map +1 -0
  383. package/dist/filters/queryBuilder/index.js +7 -0
  384. package/dist/filters/queryBuilder/index.js.map +1 -0
  385. package/dist/icons/index.d.ts +3 -0
  386. package/dist/icons/index.d.ts.map +1 -0
  387. package/dist/icons/index.js +3 -0
  388. package/dist/icons/index.js.map +1 -0
  389. package/dist/icons/lucide.d.ts +16 -0
  390. package/dist/icons/lucide.d.ts.map +1 -0
  391. package/dist/icons/lucide.js +173 -0
  392. package/dist/icons/lucide.js.map +1 -0
  393. package/dist/icons/registry.d.ts +27 -0
  394. package/dist/icons/registry.d.ts.map +1 -0
  395. package/dist/icons/registry.js +35 -0
  396. package/dist/icons/registry.js.map +1 -0
  397. package/dist/icons/types.d.ts +38 -0
  398. package/dist/icons/types.d.ts.map +1 -0
  399. package/dist/icons/types.js +23 -0
  400. package/dist/icons/types.js.map +1 -0
  401. package/dist/index.d.ts +118 -0
  402. package/dist/index.d.ts.map +1 -0
  403. package/dist/index.js +135 -0
  404. package/dist/index.js.map +1 -0
  405. package/dist/io/csv.d.ts +51 -0
  406. package/dist/io/csv.d.ts.map +1 -0
  407. package/dist/io/csv.js +168 -0
  408. package/dist/io/csv.js.map +1 -0
  409. package/dist/notifications/Notification.d.ts +181 -0
  410. package/dist/notifications/Notification.d.ts.map +1 -0
  411. package/dist/notifications/Notification.js +290 -0
  412. package/dist/notifications/Notification.js.map +1 -0
  413. package/dist/notifications/broadcast.d.ts +58 -0
  414. package/dist/notifications/broadcast.d.ts.map +1 -0
  415. package/dist/notifications/broadcast.js +72 -0
  416. package/dist/notifications/broadcast.js.map +1 -0
  417. package/dist/notifications/database.d.ts +164 -0
  418. package/dist/notifications/database.d.ts.map +1 -0
  419. package/dist/notifications/database.js +321 -0
  420. package/dist/notifications/database.js.map +1 -0
  421. package/dist/notifications/dispatchNotificationAction.d.ts +48 -0
  422. package/dist/notifications/dispatchNotificationAction.d.ts.map +1 -0
  423. package/dist/notifications/dispatchNotificationAction.js +100 -0
  424. package/dist/notifications/dispatchNotificationAction.js.map +1 -0
  425. package/dist/notifications/flash.d.ts +34 -0
  426. package/dist/notifications/flash.d.ts.map +1 -0
  427. package/dist/notifications/flash.js +51 -0
  428. package/dist/notifications/flash.js.map +1 -0
  429. package/dist/notifications/index.d.ts +8 -0
  430. package/dist/notifications/index.d.ts.map +1 -0
  431. package/dist/notifications/index.js +6 -0
  432. package/dist/notifications/index.js.map +1 -0
  433. package/dist/notifications/registerBroadcastAuth.d.ts +45 -0
  434. package/dist/notifications/registerBroadcastAuth.d.ts.map +1 -0
  435. package/dist/notifications/registerBroadcastAuth.js +86 -0
  436. package/dist/notifications/registerBroadcastAuth.js.map +1 -0
  437. package/dist/notifications/resolveSavedNotification.d.ts +21 -0
  438. package/dist/notifications/resolveSavedNotification.d.ts.map +1 -0
  439. package/dist/notifications/resolveSavedNotification.js +43 -0
  440. package/dist/notifications/resolveSavedNotification.js.map +1 -0
  441. package/dist/notifications/types.d.ts +87 -0
  442. package/dist/notifications/types.d.ts.map +1 -0
  443. package/dist/notifications/types.js +2 -0
  444. package/dist/notifications/types.js.map +1 -0
  445. package/dist/orm/m2mAccessor.d.ts +49 -0
  446. package/dist/orm/m2mAccessor.d.ts.map +1 -0
  447. package/dist/orm/m2mAccessor.js +45 -0
  448. package/dist/orm/m2mAccessor.js.map +1 -0
  449. package/dist/orm/modelDefaults.d.ts +347 -0
  450. package/dist/orm/modelDefaults.d.ts.map +1 -0
  451. package/dist/orm/modelDefaults.js +375 -0
  452. package/dist/orm/modelDefaults.js.map +1 -0
  453. package/dist/pageData.d.ts +778 -0
  454. package/dist/pageData.d.ts.map +1 -0
  455. package/dist/pageData.js +3725 -0
  456. package/dist/pageData.js.map +1 -0
  457. package/dist/plugins/index.d.ts +2 -0
  458. package/dist/plugins/index.d.ts.map +1 -0
  459. package/dist/plugins/index.js +2 -0
  460. package/dist/plugins/index.js.map +1 -0
  461. package/dist/plugins/themeEditor.d.ts +17 -0
  462. package/dist/plugins/themeEditor.d.ts.map +1 -0
  463. package/dist/plugins/themeEditor.js +23 -0
  464. package/dist/plugins/themeEditor.js.map +1 -0
  465. package/dist/react/AppShell.d.ts +58 -0
  466. package/dist/react/AppShell.d.ts.map +1 -0
  467. package/dist/react/AppShell.js +58 -0
  468. package/dist/react/AppShell.js.map +1 -0
  469. package/dist/react/CommandPalette.d.ts +21 -0
  470. package/dist/react/CommandPalette.d.ts.map +1 -0
  471. package/dist/react/CommandPalette.js +236 -0
  472. package/dist/react/CommandPalette.js.map +1 -0
  473. package/dist/react/FormStateContext.d.ts +83 -0
  474. package/dist/react/FormStateContext.d.ts.map +1 -0
  475. package/dist/react/FormStateContext.js +284 -0
  476. package/dist/react/FormStateContext.js.map +1 -0
  477. package/dist/react/HeadHooks.d.ts +26 -0
  478. package/dist/react/HeadHooks.d.ts.map +1 -0
  479. package/dist/react/HeadHooks.js +141 -0
  480. package/dist/react/HeadHooks.js.map +1 -0
  481. package/dist/react/NotificationActionStrip.d.ts +39 -0
  482. package/dist/react/NotificationActionStrip.d.ts.map +1 -0
  483. package/dist/react/NotificationActionStrip.js +129 -0
  484. package/dist/react/NotificationActionStrip.js.map +1 -0
  485. package/dist/react/NotificationBell.d.ts +20 -0
  486. package/dist/react/NotificationBell.d.ts.map +1 -0
  487. package/dist/react/NotificationBell.js +273 -0
  488. package/dist/react/NotificationBell.js.map +1 -0
  489. package/dist/react/RenderHookSlot.d.ts +20 -0
  490. package/dist/react/RenderHookSlot.d.ts.map +1 -0
  491. package/dist/react/RenderHookSlot.js +24 -0
  492. package/dist/react/RenderHookSlot.js.map +1 -0
  493. package/dist/react/RightSidebar.d.ts +33 -0
  494. package/dist/react/RightSidebar.d.ts.map +1 -0
  495. package/dist/react/RightSidebar.js +82 -0
  496. package/dist/react/RightSidebar.js.map +1 -0
  497. package/dist/react/RightSidebarContext.d.ts +62 -0
  498. package/dist/react/RightSidebarContext.d.ts.map +1 -0
  499. package/dist/react/RightSidebarContext.js +178 -0
  500. package/dist/react/RightSidebarContext.js.map +1 -0
  501. package/dist/react/RightSidebarTrigger.d.ts +16 -0
  502. package/dist/react/RightSidebarTrigger.d.ts.map +1 -0
  503. package/dist/react/RightSidebarTrigger.js +24 -0
  504. package/dist/react/RightSidebarTrigger.js.map +1 -0
  505. package/dist/react/SchemaRenderer.d.ts +63 -0
  506. package/dist/react/SchemaRenderer.d.ts.map +1 -0
  507. package/dist/react/SchemaRenderer.js +3458 -0
  508. package/dist/react/SchemaRenderer.js.map +1 -0
  509. package/dist/react/SearchTrigger.d.ts +13 -0
  510. package/dist/react/SearchTrigger.d.ts.map +1 -0
  511. package/dist/react/SearchTrigger.js +30 -0
  512. package/dist/react/SearchTrigger.js.map +1 -0
  513. package/dist/react/ThemeProvider.d.ts +18 -0
  514. package/dist/react/ThemeProvider.d.ts.map +1 -0
  515. package/dist/react/ThemeProvider.js +66 -0
  516. package/dist/react/ThemeProvider.js.map +1 -0
  517. package/dist/react/ThemeSettingsPage.d.ts +10 -0
  518. package/dist/react/ThemeSettingsPage.d.ts.map +1 -0
  519. package/dist/react/ThemeSettingsPage.js +293 -0
  520. package/dist/react/ThemeSettingsPage.js.map +1 -0
  521. package/dist/react/ThemeToggle.d.ts +2 -0
  522. package/dist/react/ThemeToggle.d.ts.map +1 -0
  523. package/dist/react/ThemeToggle.js +8 -0
  524. package/dist/react/ThemeToggle.js.map +1 -0
  525. package/dist/react/Toaster.d.ts +25 -0
  526. package/dist/react/Toaster.d.ts.map +1 -0
  527. package/dist/react/Toaster.js +89 -0
  528. package/dist/react/Toaster.js.map +1 -0
  529. package/dist/react/UserMenu.d.ts +23 -0
  530. package/dist/react/UserMenu.d.ts.map +1 -0
  531. package/dist/react/UserMenu.js +78 -0
  532. package/dist/react/UserMenu.js.map +1 -0
  533. package/dist/react/WidgetDataContext.d.ts +64 -0
  534. package/dist/react/WidgetDataContext.d.ts.map +1 -0
  535. package/dist/react/WidgetDataContext.js +89 -0
  536. package/dist/react/WidgetDataContext.js.map +1 -0
  537. package/dist/react/cells/EditableCell.d.ts +20 -0
  538. package/dist/react/cells/EditableCell.d.ts.map +1 -0
  539. package/dist/react/cells/EditableCell.js +251 -0
  540. package/dist/react/cells/EditableCell.js.map +1 -0
  541. package/dist/react/fieldJsHandler.d.ts +33 -0
  542. package/dist/react/fieldJsHandler.d.ts.map +1 -0
  543. package/dist/react/fieldJsHandler.js +61 -0
  544. package/dist/react/fieldJsHandler.js.map +1 -0
  545. package/dist/react/fields/BuilderInput.d.ts +21 -0
  546. package/dist/react/fields/BuilderInput.d.ts.map +1 -0
  547. package/dist/react/fields/BuilderInput.js +553 -0
  548. package/dist/react/fields/BuilderInput.js.map +1 -0
  549. package/dist/react/fields/CheckboxInput.d.ts +9 -0
  550. package/dist/react/fields/CheckboxInput.d.ts.map +1 -0
  551. package/dist/react/fields/CheckboxInput.js +23 -0
  552. package/dist/react/fields/CheckboxInput.js.map +1 -0
  553. package/dist/react/fields/CheckboxListInput.d.ts +19 -0
  554. package/dist/react/fields/CheckboxListInput.d.ts.map +1 -0
  555. package/dist/react/fields/CheckboxListInput.js +53 -0
  556. package/dist/react/fields/CheckboxListInput.js.map +1 -0
  557. package/dist/react/fields/ColorInput.d.ts +12 -0
  558. package/dist/react/fields/ColorInput.d.ts.map +1 -0
  559. package/dist/react/fields/ColorInput.js +29 -0
  560. package/dist/react/fields/ColorInput.js.map +1 -0
  561. package/dist/react/fields/DateFieldInput.d.ts +8 -0
  562. package/dist/react/fields/DateFieldInput.d.ts.map +1 -0
  563. package/dist/react/fields/DateFieldInput.js +39 -0
  564. package/dist/react/fields/DateFieldInput.js.map +1 -0
  565. package/dist/react/fields/DateTimeInput.d.ts +13 -0
  566. package/dist/react/fields/DateTimeInput.d.ts.map +1 -0
  567. package/dist/react/fields/DateTimeInput.js +29 -0
  568. package/dist/react/fields/DateTimeInput.js.map +1 -0
  569. package/dist/react/fields/FieldShell.d.ts +23 -0
  570. package/dist/react/fields/FieldShell.d.ts.map +1 -0
  571. package/dist/react/fields/FieldShell.js +46 -0
  572. package/dist/react/fields/FieldShell.js.map +1 -0
  573. package/dist/react/fields/FileUploadInput.d.ts +21 -0
  574. package/dist/react/fields/FileUploadInput.d.ts.map +1 -0
  575. package/dist/react/fields/FileUploadInput.js +120 -0
  576. package/dist/react/fields/FileUploadInput.js.map +1 -0
  577. package/dist/react/fields/HiddenInput.d.ts +11 -0
  578. package/dist/react/fields/HiddenInput.d.ts.map +1 -0
  579. package/dist/react/fields/HiddenInput.js +14 -0
  580. package/dist/react/fields/HiddenInput.js.map +1 -0
  581. package/dist/react/fields/KeyValueInput.d.ts +18 -0
  582. package/dist/react/fields/KeyValueInput.d.ts.map +1 -0
  583. package/dist/react/fields/KeyValueInput.js +122 -0
  584. package/dist/react/fields/KeyValueInput.js.map +1 -0
  585. package/dist/react/fields/MarkdownInput.d.ts +29 -0
  586. package/dist/react/fields/MarkdownInput.d.ts.map +1 -0
  587. package/dist/react/fields/MarkdownInput.js +250 -0
  588. package/dist/react/fields/MarkdownInput.js.map +1 -0
  589. package/dist/react/fields/RadioInput.d.ts +18 -0
  590. package/dist/react/fields/RadioInput.d.ts.map +1 -0
  591. package/dist/react/fields/RadioInput.js +34 -0
  592. package/dist/react/fields/RadioInput.js.map +1 -0
  593. package/dist/react/fields/RepeaterInput.d.ts +92 -0
  594. package/dist/react/fields/RepeaterInput.d.ts.map +1 -0
  595. package/dist/react/fields/RepeaterInput.js +705 -0
  596. package/dist/react/fields/RepeaterInput.js.map +1 -0
  597. package/dist/react/fields/SelectFieldInput.d.ts +23 -0
  598. package/dist/react/fields/SelectFieldInput.d.ts.map +1 -0
  599. package/dist/react/fields/SelectFieldInput.js +146 -0
  600. package/dist/react/fields/SelectFieldInput.js.map +1 -0
  601. package/dist/react/fields/SliderInput.d.ts +16 -0
  602. package/dist/react/fields/SliderInput.d.ts.map +1 -0
  603. package/dist/react/fields/SliderInput.js +37 -0
  604. package/dist/react/fields/SliderInput.js.map +1 -0
  605. package/dist/react/fields/TagsInput.d.ts +27 -0
  606. package/dist/react/fields/TagsInput.d.ts.map +1 -0
  607. package/dist/react/fields/TagsInput.js +189 -0
  608. package/dist/react/fields/TagsInput.js.map +1 -0
  609. package/dist/react/fields/TextLikeInput.d.ts +18 -0
  610. package/dist/react/fields/TextLikeInput.d.ts.map +1 -0
  611. package/dist/react/fields/TextLikeInput.js +46 -0
  612. package/dist/react/fields/TextLikeInput.js.map +1 -0
  613. package/dist/react/fields/ToggleButtonsInput.d.ts +20 -0
  614. package/dist/react/fields/ToggleButtonsInput.d.ts.map +1 -0
  615. package/dist/react/fields/ToggleButtonsInput.js +42 -0
  616. package/dist/react/fields/ToggleButtonsInput.js.map +1 -0
  617. package/dist/react/fields/ToggleFieldInput.d.ts +7 -0
  618. package/dist/react/fields/ToggleFieldInput.d.ts.map +1 -0
  619. package/dist/react/fields/ToggleFieldInput.js +30 -0
  620. package/dist/react/fields/ToggleFieldInput.js.map +1 -0
  621. package/dist/react/fields/rowChromeButton.d.ts +84 -0
  622. package/dist/react/fields/rowChromeButton.d.ts.map +1 -0
  623. package/dist/react/fields/rowChromeButton.js +111 -0
  624. package/dist/react/fields/rowChromeButton.js.map +1 -0
  625. package/dist/react/fields/syncRowGates.d.ts +11 -0
  626. package/dist/react/fields/syncRowGates.d.ts.map +1 -0
  627. package/dist/react/fields/syncRowGates.js +55 -0
  628. package/dist/react/fields/syncRowGates.js.map +1 -0
  629. package/dist/react/formStateHelpers.d.ts +44 -0
  630. package/dist/react/formStateHelpers.d.ts.map +1 -0
  631. package/dist/react/formStateHelpers.js +230 -0
  632. package/dist/react/formStateHelpers.js.map +1 -0
  633. package/dist/react/hooks/use-mobile.d.ts +2 -0
  634. package/dist/react/hooks/use-mobile.d.ts.map +1 -0
  635. package/dist/react/hooks/use-mobile.js +16 -0
  636. package/dist/react/hooks/use-mobile.js.map +1 -0
  637. package/dist/react/icon-context.d.ts +35 -0
  638. package/dist/react/icon-context.d.ts.map +1 -0
  639. package/dist/react/icon-context.js +45 -0
  640. package/dist/react/icon-context.js.map +1 -0
  641. package/dist/react/index.d.ts +26 -0
  642. package/dist/react/index.d.ts.map +1 -0
  643. package/dist/react/index.js +28 -0
  644. package/dist/react/index.js.map +1 -0
  645. package/dist/react/layouts/SidebarLayout.d.ts +3 -0
  646. package/dist/react/layouts/SidebarLayout.d.ts.map +1 -0
  647. package/dist/react/layouts/SidebarLayout.js +85 -0
  648. package/dist/react/layouts/SidebarLayout.js.map +1 -0
  649. package/dist/react/layouts/TopbarLayout.d.ts +3 -0
  650. package/dist/react/layouts/TopbarLayout.d.ts.map +1 -0
  651. package/dist/react/layouts/TopbarLayout.js +103 -0
  652. package/dist/react/layouts/TopbarLayout.js.map +1 -0
  653. package/dist/react/navigate.d.ts +22 -0
  654. package/dist/react/navigate.d.ts.map +1 -0
  655. package/dist/react/navigate.js +30 -0
  656. package/dist/react/navigate.js.map +1 -0
  657. package/dist/react/registry.d.ts +35 -0
  658. package/dist/react/registry.d.ts.map +1 -0
  659. package/dist/react/registry.js +22 -0
  660. package/dist/react/registry.js.map +1 -0
  661. package/dist/react/right-panel-registry.d.ts +32 -0
  662. package/dist/react/right-panel-registry.d.ts.map +1 -0
  663. package/dist/react/right-panel-registry.js +20 -0
  664. package/dist/react/right-panel-registry.js.map +1 -0
  665. package/dist/react/theme-preview/apply.d.ts +11 -0
  666. package/dist/react/theme-preview/apply.d.ts.map +1 -0
  667. package/dist/react/theme-preview/apply.js +93 -0
  668. package/dist/react/theme-preview/apply.js.map +1 -0
  669. package/dist/react/theme-preview/build-html.d.ts +3 -0
  670. package/dist/react/theme-preview/build-html.d.ts.map +1 -0
  671. package/dist/react/theme-preview/build-html.js +437 -0
  672. package/dist/react/theme-preview/build-html.js.map +1 -0
  673. package/dist/react/ui/button.d.ts +9 -0
  674. package/dist/react/ui/button.d.ts.map +1 -0
  675. package/dist/react/ui/button.js +35 -0
  676. package/dist/react/ui/button.js.map +1 -0
  677. package/dist/react/ui/calendar.d.ts +5 -0
  678. package/dist/react/ui/calendar.d.ts.map +1 -0
  679. package/dist/react/ui/calendar.js +34 -0
  680. package/dist/react/ui/calendar.js.map +1 -0
  681. package/dist/react/ui/checkbox.d.ts +4 -0
  682. package/dist/react/ui/checkbox.d.ts.map +1 -0
  683. package/dist/react/ui/checkbox.js +9 -0
  684. package/dist/react/ui/checkbox.js.map +1 -0
  685. package/dist/react/ui/dialog.d.ts +12 -0
  686. package/dist/react/ui/dialog.d.ts.map +1 -0
  687. package/dist/react/ui/dialog.js +34 -0
  688. package/dist/react/ui/dialog.js.map +1 -0
  689. package/dist/react/ui/dropdown-menu.d.ts +12 -0
  690. package/dist/react/ui/dropdown-menu.d.ts.map +1 -0
  691. package/dist/react/ui/dropdown-menu.js +23 -0
  692. package/dist/react/ui/dropdown-menu.js.map +1 -0
  693. package/dist/react/ui/input.d.ts +4 -0
  694. package/dist/react/ui/input.d.ts.map +1 -0
  695. package/dist/react/ui/input.js +8 -0
  696. package/dist/react/ui/input.js.map +1 -0
  697. package/dist/react/ui/label.d.ts +4 -0
  698. package/dist/react/ui/label.d.ts.map +1 -0
  699. package/dist/react/ui/label.js +7 -0
  700. package/dist/react/ui/label.js.map +1 -0
  701. package/dist/react/ui/popover.d.ts +6 -0
  702. package/dist/react/ui/popover.d.ts.map +1 -0
  703. package/dist/react/ui/popover.js +14 -0
  704. package/dist/react/ui/popover.js.map +1 -0
  705. package/dist/react/ui/select.d.ts +17 -0
  706. package/dist/react/ui/select.d.ts.map +1 -0
  707. package/dist/react/ui/select.js +39 -0
  708. package/dist/react/ui/select.js.map +1 -0
  709. package/dist/react/ui/separator.d.ts +4 -0
  710. package/dist/react/ui/separator.d.ts.map +1 -0
  711. package/dist/react/ui/separator.js +9 -0
  712. package/dist/react/ui/separator.js.map +1 -0
  713. package/dist/react/ui/sheet.d.ts +15 -0
  714. package/dist/react/ui/sheet.d.ts.map +1 -0
  715. package/dist/react/ui/sheet.js +37 -0
  716. package/dist/react/ui/sheet.js.map +1 -0
  717. package/dist/react/ui/sidebar.d.ts +64 -0
  718. package/dist/react/ui/sidebar.d.ts.map +1 -0
  719. package/dist/react/ui/sidebar.js +257 -0
  720. package/dist/react/ui/sidebar.js.map +1 -0
  721. package/dist/react/ui/skeleton.d.ts +3 -0
  722. package/dist/react/ui/skeleton.d.ts.map +1 -0
  723. package/dist/react/ui/skeleton.js +7 -0
  724. package/dist/react/ui/skeleton.js.map +1 -0
  725. package/dist/react/ui/slider.d.ts +4 -0
  726. package/dist/react/ui/slider.d.ts.map +1 -0
  727. package/dist/react/ui/slider.js +8 -0
  728. package/dist/react/ui/slider.js.map +1 -0
  729. package/dist/react/ui/switch.d.ts +4 -0
  730. package/dist/react/ui/switch.d.ts.map +1 -0
  731. package/dist/react/ui/switch.js +8 -0
  732. package/dist/react/ui/switch.js.map +1 -0
  733. package/dist/react/ui/table.d.ts +11 -0
  734. package/dist/react/ui/table.d.ts.map +1 -0
  735. package/dist/react/ui/table.js +28 -0
  736. package/dist/react/ui/table.js.map +1 -0
  737. package/dist/react/ui/tabs.d.ts +7 -0
  738. package/dist/react/ui/tabs.d.ts.map +1 -0
  739. package/dist/react/ui/tabs.js +17 -0
  740. package/dist/react/ui/tabs.js.map +1 -0
  741. package/dist/react/ui/textarea.d.ts +4 -0
  742. package/dist/react/ui/textarea.d.ts.map +1 -0
  743. package/dist/react/ui/textarea.js +7 -0
  744. package/dist/react/ui/textarea.js.map +1 -0
  745. package/dist/react/ui/tooltip.d.ts +7 -0
  746. package/dist/react/ui/tooltip.d.ts.map +1 -0
  747. package/dist/react/ui/tooltip.js +17 -0
  748. package/dist/react/ui/tooltip.js.map +1 -0
  749. package/dist/react/useResizableWidth.d.ts +47 -0
  750. package/dist/react/useResizableWidth.d.ts.map +1 -0
  751. package/dist/react/useResizableWidth.js +99 -0
  752. package/dist/react/useResizableWidth.js.map +1 -0
  753. package/dist/react/utils.d.ts +3 -0
  754. package/dist/react/utils.d.ts.map +1 -0
  755. package/dist/react/utils.js +6 -0
  756. package/dist/react/utils.js.map +1 -0
  757. package/dist/react/widgetRegistry.d.ts +33 -0
  758. package/dist/react/widgetRegistry.d.ts.map +1 -0
  759. package/dist/react/widgetRegistry.js +15 -0
  760. package/dist/react/widgetRegistry.js.map +1 -0
  761. package/dist/react/widgets/StatsOverviewRenderer.d.ts +6 -0
  762. package/dist/react/widgets/StatsOverviewRenderer.d.ts.map +1 -0
  763. package/dist/react/widgets/StatsOverviewRenderer.js +124 -0
  764. package/dist/react/widgets/StatsOverviewRenderer.js.map +1 -0
  765. package/dist/react/widgets/TableWidgetRenderer.d.ts +6 -0
  766. package/dist/react/widgets/TableWidgetRenderer.d.ts.map +1 -0
  767. package/dist/react/widgets/TableWidgetRenderer.js +123 -0
  768. package/dist/react/widgets/TableWidgetRenderer.js.map +1 -0
  769. package/dist/react/widgets/ViewRenderer.d.ts +16 -0
  770. package/dist/react/widgets/ViewRenderer.d.ts.map +1 -0
  771. package/dist/react/widgets/ViewRenderer.js +26 -0
  772. package/dist/react/widgets/ViewRenderer.js.map +1 -0
  773. package/dist/richtext/index.d.ts +2 -0
  774. package/dist/richtext/index.d.ts.map +1 -0
  775. package/dist/richtext/index.js +2 -0
  776. package/dist/richtext/index.js.map +1 -0
  777. package/dist/richtext/registry.d.ts +55 -0
  778. package/dist/richtext/registry.d.ts.map +1 -0
  779. package/dist/richtext/registry.js +66 -0
  780. package/dist/richtext/registry.js.map +1 -0
  781. package/dist/routes.d.ts +9 -0
  782. package/dist/routes.d.ts.map +1 -0
  783. package/dist/routes.js +3116 -0
  784. package/dist/routes.js.map +1 -0
  785. package/dist/schema/Alert.d.ts +33 -0
  786. package/dist/schema/Alert.d.ts.map +1 -0
  787. package/dist/schema/Alert.js +41 -0
  788. package/dist/schema/Alert.js.map +1 -0
  789. package/dist/schema/Block.d.ts +112 -0
  790. package/dist/schema/Block.d.ts.map +1 -0
  791. package/dist/schema/Block.js +136 -0
  792. package/dist/schema/Block.js.map +1 -0
  793. package/dist/schema/Breadcrumbs.d.ts +31 -0
  794. package/dist/schema/Breadcrumbs.d.ts.map +1 -0
  795. package/dist/schema/Breadcrumbs.js +30 -0
  796. package/dist/schema/Breadcrumbs.js.map +1 -0
  797. package/dist/schema/Card.d.ts +17 -0
  798. package/dist/schema/Card.d.ts.map +1 -0
  799. package/dist/schema/Card.js +31 -0
  800. package/dist/schema/Card.js.map +1 -0
  801. package/dist/schema/Divider.d.ts +12 -0
  802. package/dist/schema/Divider.d.ts.map +1 -0
  803. package/dist/schema/Divider.js +19 -0
  804. package/dist/schema/Divider.js.map +1 -0
  805. package/dist/schema/Element.d.ts +150 -0
  806. package/dist/schema/Element.d.ts.map +1 -0
  807. package/dist/schema/Element.js +124 -0
  808. package/dist/schema/Element.js.map +1 -0
  809. package/dist/schema/EmptyState.d.ts +48 -0
  810. package/dist/schema/EmptyState.d.ts.map +1 -0
  811. package/dist/schema/EmptyState.js +57 -0
  812. package/dist/schema/EmptyState.js.map +1 -0
  813. package/dist/schema/Fieldset.d.ts +25 -0
  814. package/dist/schema/Fieldset.d.ts.map +1 -0
  815. package/dist/schema/Fieldset.js +39 -0
  816. package/dist/schema/Fieldset.js.map +1 -0
  817. package/dist/schema/Grid.d.ts +23 -0
  818. package/dist/schema/Grid.d.ts.map +1 -0
  819. package/dist/schema/Grid.js +36 -0
  820. package/dist/schema/Grid.js.map +1 -0
  821. package/dist/schema/Group.d.ts +19 -0
  822. package/dist/schema/Group.d.ts.map +1 -0
  823. package/dist/schema/Group.js +26 -0
  824. package/dist/schema/Group.js.map +1 -0
  825. package/dist/schema/Heading.d.ts +25 -0
  826. package/dist/schema/Heading.d.ts.map +1 -0
  827. package/dist/schema/Heading.js +34 -0
  828. package/dist/schema/Heading.js.map +1 -0
  829. package/dist/schema/Html.d.ts +48 -0
  830. package/dist/schema/Html.d.ts.map +1 -0
  831. package/dist/schema/Html.js +60 -0
  832. package/dist/schema/Html.js.map +1 -0
  833. package/dist/schema/Icon.d.ts +34 -0
  834. package/dist/schema/Icon.d.ts.map +1 -0
  835. package/dist/schema/Icon.js +40 -0
  836. package/dist/schema/Icon.js.map +1 -0
  837. package/dist/schema/Image.d.ts +38 -0
  838. package/dist/schema/Image.d.ts.map +1 -0
  839. package/dist/schema/Image.js +48 -0
  840. package/dist/schema/Image.js.map +1 -0
  841. package/dist/schema/LinkTag.d.ts +48 -0
  842. package/dist/schema/LinkTag.d.ts.map +1 -0
  843. package/dist/schema/LinkTag.js +16 -0
  844. package/dist/schema/LinkTag.js.map +1 -0
  845. package/dist/schema/Markdown.d.ts +57 -0
  846. package/dist/schema/Markdown.d.ts.map +1 -0
  847. package/dist/schema/Markdown.js +75 -0
  848. package/dist/schema/Markdown.js.map +1 -0
  849. package/dist/schema/MetaTag.d.ts +41 -0
  850. package/dist/schema/MetaTag.d.ts.map +1 -0
  851. package/dist/schema/MetaTag.js +16 -0
  852. package/dist/schema/MetaTag.js.map +1 -0
  853. package/dist/schema/RelationTabs.d.ts +50 -0
  854. package/dist/schema/RelationTabs.d.ts.map +1 -0
  855. package/dist/schema/RelationTabs.js +48 -0
  856. package/dist/schema/RelationTabs.js.map +1 -0
  857. package/dist/schema/ScriptTag.d.ts +63 -0
  858. package/dist/schema/ScriptTag.d.ts.map +1 -0
  859. package/dist/schema/ScriptTag.js +16 -0
  860. package/dist/schema/ScriptTag.js.map +1 -0
  861. package/dist/schema/Section.d.ts +93 -0
  862. package/dist/schema/Section.d.ts.map +1 -0
  863. package/dist/schema/Section.js +127 -0
  864. package/dist/schema/Section.js.map +1 -0
  865. package/dist/schema/ServerDataElement.d.ts +101 -0
  866. package/dist/schema/ServerDataElement.d.ts.map +1 -0
  867. package/dist/schema/ServerDataElement.js +135 -0
  868. package/dist/schema/ServerDataElement.js.map +1 -0
  869. package/dist/schema/Split.d.ts +31 -0
  870. package/dist/schema/Split.d.ts.map +1 -0
  871. package/dist/schema/Split.js +41 -0
  872. package/dist/schema/Split.js.map +1 -0
  873. package/dist/schema/Stat.d.ts +92 -0
  874. package/dist/schema/Stat.d.ts.map +1 -0
  875. package/dist/schema/Stat.js +116 -0
  876. package/dist/schema/Stat.js.map +1 -0
  877. package/dist/schema/StatsOverview.d.ts +76 -0
  878. package/dist/schema/StatsOverview.d.ts.map +1 -0
  879. package/dist/schema/StatsOverview.js +71 -0
  880. package/dist/schema/StatsOverview.js.map +1 -0
  881. package/dist/schema/StyleTag.d.ts +32 -0
  882. package/dist/schema/StyleTag.d.ts.map +1 -0
  883. package/dist/schema/StyleTag.js +38 -0
  884. package/dist/schema/StyleTag.js.map +1 -0
  885. package/dist/schema/TableWidget.d.ts +148 -0
  886. package/dist/schema/TableWidget.d.ts.map +1 -0
  887. package/dist/schema/TableWidget.js +190 -0
  888. package/dist/schema/TableWidget.js.map +1 -0
  889. package/dist/schema/Tabs.d.ts +40 -0
  890. package/dist/schema/Tabs.d.ts.map +1 -0
  891. package/dist/schema/Tabs.js +66 -0
  892. package/dist/schema/Tabs.js.map +1 -0
  893. package/dist/schema/Text.d.ts +33 -0
  894. package/dist/schema/Text.d.ts.map +1 -0
  895. package/dist/schema/Text.js +40 -0
  896. package/dist/schema/Text.js.map +1 -0
  897. package/dist/schema/UnorderedList.d.ts +36 -0
  898. package/dist/schema/UnorderedList.d.ts.map +1 -0
  899. package/dist/schema/UnorderedList.js +42 -0
  900. package/dist/schema/UnorderedList.js.map +1 -0
  901. package/dist/schema/View.d.ts +81 -0
  902. package/dist/schema/View.d.ts.map +1 -0
  903. package/dist/schema/View.js +81 -0
  904. package/dist/schema/View.js.map +1 -0
  905. package/dist/schema/Wizard.d.ts +67 -0
  906. package/dist/schema/Wizard.d.ts.map +1 -0
  907. package/dist/schema/Wizard.js +94 -0
  908. package/dist/schema/Wizard.js.map +1 -0
  909. package/dist/schema/index.d.ts +26 -0
  910. package/dist/schema/index.d.ts.map +1 -0
  911. package/dist/schema/index.js +26 -0
  912. package/dist/schema/index.js.map +1 -0
  913. package/dist/schema/resolveSchema.d.ts +122 -0
  914. package/dist/schema/resolveSchema.d.ts.map +1 -0
  915. package/dist/schema/resolveSchema.js +648 -0
  916. package/dist/schema/resolveSchema.js.map +1 -0
  917. package/dist/schema/sanitize.d.ts +21 -0
  918. package/dist/schema/sanitize.d.ts.map +1 -0
  919. package/dist/schema/sanitize.js +46 -0
  920. package/dist/schema/sanitize.js.map +1 -0
  921. package/dist/search.d.ts +53 -0
  922. package/dist/search.d.ts.map +1 -0
  923. package/dist/search.js +114 -0
  924. package/dist/search.js.map +1 -0
  925. package/dist/sessionFilters.d.ts +8 -0
  926. package/dist/sessionFilters.d.ts.map +1 -0
  927. package/dist/sessionFilters.js +115 -0
  928. package/dist/sessionFilters.js.map +1 -0
  929. package/dist/summarizers/Summarizer.d.ts +65 -0
  930. package/dist/summarizers/Summarizer.d.ts.map +1 -0
  931. package/dist/summarizers/Summarizer.js +98 -0
  932. package/dist/summarizers/Summarizer.js.map +1 -0
  933. package/dist/summarizers/index.d.ts +2 -0
  934. package/dist/summarizers/index.d.ts.map +1 -0
  935. package/dist/summarizers/index.js +2 -0
  936. package/dist/summarizers/index.js.map +1 -0
  937. package/dist/theme/base-colors.d.ts +3 -0
  938. package/dist/theme/base-colors.d.ts.map +1 -0
  939. package/dist/theme/base-colors.js +64 -0
  940. package/dist/theme/base-colors.js.map +1 -0
  941. package/dist/theme/chart-colors.d.ts +3 -0
  942. package/dist/theme/chart-colors.d.ts.map +1 -0
  943. package/dist/theme/chart-colors.js +46 -0
  944. package/dist/theme/chart-colors.js.map +1 -0
  945. package/dist/theme/colors.d.ts +56 -0
  946. package/dist/theme/colors.d.ts.map +1 -0
  947. package/dist/theme/colors.js +410 -0
  948. package/dist/theme/colors.js.map +1 -0
  949. package/dist/theme/generate-css.d.ts +9 -0
  950. package/dist/theme/generate-css.d.ts.map +1 -0
  951. package/dist/theme/generate-css.js +36 -0
  952. package/dist/theme/generate-css.js.map +1 -0
  953. package/dist/theme/generate-scale.d.ts +3 -0
  954. package/dist/theme/generate-scale.d.ts.map +1 -0
  955. package/dist/theme/generate-scale.js +89 -0
  956. package/dist/theme/generate-scale.js.map +1 -0
  957. package/dist/theme/icon-map.d.ts +9 -0
  958. package/dist/theme/icon-map.d.ts.map +1 -0
  959. package/dist/theme/icon-map.js +40 -0
  960. package/dist/theme/icon-map.js.map +1 -0
  961. package/dist/theme/index.d.ts +15 -0
  962. package/dist/theme/index.d.ts.map +1 -0
  963. package/dist/theme/index.js +13 -0
  964. package/dist/theme/index.js.map +1 -0
  965. package/dist/theme/migrate.d.ts +14 -0
  966. package/dist/theme/migrate.d.ts.map +1 -0
  967. package/dist/theme/migrate.js +79 -0
  968. package/dist/theme/migrate.js.map +1 -0
  969. package/dist/theme/presets.d.ts +30 -0
  970. package/dist/theme/presets.d.ts.map +1 -0
  971. package/dist/theme/presets.js +128 -0
  972. package/dist/theme/presets.js.map +1 -0
  973. package/dist/theme/radius.d.ts +11 -0
  974. package/dist/theme/radius.d.ts.map +1 -0
  975. package/dist/theme/radius.js +17 -0
  976. package/dist/theme/radius.js.map +1 -0
  977. package/dist/theme/resolve.d.ts +13 -0
  978. package/dist/theme/resolve.d.ts.map +1 -0
  979. package/dist/theme/resolve.js +91 -0
  980. package/dist/theme/resolve.js.map +1 -0
  981. package/dist/theme/spacing.d.ts +14 -0
  982. package/dist/theme/spacing.d.ts.map +1 -0
  983. package/dist/theme/spacing.js +17 -0
  984. package/dist/theme/spacing.js.map +1 -0
  985. package/dist/theme/theme-colors.d.ts +9 -0
  986. package/dist/theme/theme-colors.d.ts.map +1 -0
  987. package/dist/theme/theme-colors.js +84 -0
  988. package/dist/theme/theme-colors.js.map +1 -0
  989. package/dist/theme/types.d.ts +94 -0
  990. package/dist/theme/types.d.ts.map +1 -0
  991. package/dist/theme/types.js +2 -0
  992. package/dist/theme/types.js.map +1 -0
  993. package/dist/uploads/UploadAdapter.d.ts +34 -0
  994. package/dist/uploads/UploadAdapter.d.ts.map +1 -0
  995. package/dist/uploads/UploadAdapter.js +2 -0
  996. package/dist/uploads/UploadAdapter.js.map +1 -0
  997. package/dist/uploads/index.d.ts +3 -0
  998. package/dist/uploads/index.d.ts.map +1 -0
  999. package/dist/uploads/index.js +2 -0
  1000. package/dist/uploads/index.js.map +1 -0
  1001. package/dist/uploads/localUpload.d.ts +25 -0
  1002. package/dist/uploads/localUpload.d.ts.map +1 -0
  1003. package/dist/uploads/localUpload.js +65 -0
  1004. package/dist/uploads/localUpload.js.map +1 -0
  1005. package/dist/validation/Validator.d.ts +40 -0
  1006. package/dist/validation/Validator.d.ts.map +1 -0
  1007. package/dist/validation/Validator.js +25 -0
  1008. package/dist/validation/Validator.js.map +1 -0
  1009. package/dist/validation/index.d.ts +5 -0
  1010. package/dist/validation/index.d.ts.map +1 -0
  1011. package/dist/validation/index.js +5 -0
  1012. package/dist/validation/index.js.map +1 -0
  1013. package/dist/validation/rules.d.ts +9 -0
  1014. package/dist/validation/rules.d.ts.map +1 -0
  1015. package/dist/validation/rules.js +61 -0
  1016. package/dist/validation/rules.js.map +1 -0
  1017. package/dist/validation/runValidators.d.ts +30 -0
  1018. package/dist/validation/runValidators.d.ts.map +1 -0
  1019. package/dist/validation/runValidators.js +438 -0
  1020. package/dist/validation/runValidators.js.map +1 -0
  1021. package/dist/validation/uniqueValidator.d.ts +61 -0
  1022. package/dist/validation/uniqueValidator.d.ts.map +1 -0
  1023. package/dist/validation/uniqueValidator.js +80 -0
  1024. package/dist/validation/uniqueValidator.js.map +1 -0
  1025. package/dist/vite.d.ts +19 -0
  1026. package/dist/vite.d.ts.map +1 -0
  1027. package/dist/vite.js +696 -0
  1028. package/dist/vite.js.map +1 -0
  1029. package/dist/widgets/index.d.ts +2 -0
  1030. package/dist/widgets/index.d.ts.map +1 -0
  1031. package/dist/widgets/index.js +7 -0
  1032. package/dist/widgets/index.js.map +1 -0
  1033. package/dist/widgets/registry.d.ts +32 -0
  1034. package/dist/widgets/registry.d.ts.map +1 -0
  1035. package/dist/widgets/registry.js +17 -0
  1036. package/dist/widgets/registry.js.map +1 -0
  1037. package/package.json +101 -0
  1038. package/src/Cluster.test.ts +283 -0
  1039. package/src/Cluster.ts +83 -0
  1040. package/src/Column.test.ts +140 -0
  1041. package/src/Column.ts +612 -0
  1042. package/src/Global.test.ts +367 -0
  1043. package/src/Global.ts +169 -0
  1044. package/src/Page.test.ts +50 -0
  1045. package/src/Page.ts +139 -0
  1046. package/src/Pilotiq.test.ts +47 -0
  1047. package/src/Pilotiq.ts +705 -0
  1048. package/src/PilotiqRegistry.ts +36 -0
  1049. package/src/PilotiqServiceProvider.ts +69 -0
  1050. package/src/RelationManager.test.ts +400 -0
  1051. package/src/RelationManager.ts +527 -0
  1052. package/src/RenderHook.test.ts +252 -0
  1053. package/src/RenderHook.ts +226 -0
  1054. package/src/Resource.test.ts +240 -0
  1055. package/src/Resource.ts +439 -0
  1056. package/src/RightPanel.test.ts +202 -0
  1057. package/src/RightPanel.ts +132 -0
  1058. package/src/Tab.test.ts +91 -0
  1059. package/src/Tab.ts +156 -0
  1060. package/src/UserMenuItem.ts +145 -0
  1061. package/src/actions/Action.test.ts +2479 -0
  1062. package/src/actions/Action.ts +2124 -0
  1063. package/src/actions/ActionGroup.test.ts +112 -0
  1064. package/src/actions/ActionGroup.ts +173 -0
  1065. package/src/actions/attachFactory.ts +172 -0
  1066. package/src/actions/exportFactory.ts +215 -0
  1067. package/src/actions/importFactory.ts +222 -0
  1068. package/src/actions/index.ts +17 -0
  1069. package/src/applyPageHooks.test.ts +298 -0
  1070. package/src/applyPageHooks.ts +242 -0
  1071. package/src/authorization.test.ts +483 -0
  1072. package/src/breadcrumbs.test.ts +238 -0
  1073. package/src/cells/coerce.test.ts +85 -0
  1074. package/src/cells/coerce.ts +84 -0
  1075. package/src/clusterPaths.ts +35 -0
  1076. package/src/columns/BadgeColumn.test.ts +54 -0
  1077. package/src/columns/BadgeColumn.ts +32 -0
  1078. package/src/columns/BooleanColumn.test.ts +41 -0
  1079. package/src/columns/BooleanColumn.ts +18 -0
  1080. package/src/columns/ColorColumn.test.ts +37 -0
  1081. package/src/columns/ColorColumn.ts +38 -0
  1082. package/src/columns/IconColumn.test.ts +54 -0
  1083. package/src/columns/IconColumn.ts +37 -0
  1084. package/src/columns/ImageColumn.test.ts +41 -0
  1085. package/src/columns/ImageColumn.ts +28 -0
  1086. package/src/columns/SelectColumn.ts +60 -0
  1087. package/src/columns/TextColumn.test.ts +190 -0
  1088. package/src/columns/TextColumn.ts +20 -0
  1089. package/src/columns/TextInputColumn.ts +68 -0
  1090. package/src/columns/ToggleColumn.ts +46 -0
  1091. package/src/columns/editableColumns.test.ts +193 -0
  1092. package/src/columns/index.ts +9 -0
  1093. package/src/defaultGlobalPages.ts +95 -0
  1094. package/src/defaultPages.test.ts +634 -0
  1095. package/src/defaultPages.ts +614 -0
  1096. package/src/defaultViewPage.test.ts +147 -0
  1097. package/src/elements/Form.test.ts +223 -0
  1098. package/src/elements/Form.ts +397 -0
  1099. package/src/elements/ListTabs.ts +28 -0
  1100. package/src/elements/Table.test.ts +422 -0
  1101. package/src/elements/Table.ts +816 -0
  1102. package/src/elements/TableGroup.test.ts +149 -0
  1103. package/src/elements/TableGroup.ts +199 -0
  1104. package/src/elements/dispatchAction.test.ts +463 -0
  1105. package/src/elements/dispatchAction.ts +355 -0
  1106. package/src/elements/dispatchForm.test.ts +455 -0
  1107. package/src/elements/dispatchForm.ts +1855 -0
  1108. package/src/elements/dispatchTable.test.ts +1247 -0
  1109. package/src/elements/dispatchTable.ts +666 -0
  1110. package/src/elements/index.ts +21 -0
  1111. package/src/entries/BadgeEntry.ts +39 -0
  1112. package/src/entries/CodeEntry.test.ts +40 -0
  1113. package/src/entries/CodeEntry.ts +52 -0
  1114. package/src/entries/ColorEntry.ts +63 -0
  1115. package/src/entries/ComponentEntry.test.ts +173 -0
  1116. package/src/entries/ComponentEntry.ts +95 -0
  1117. package/src/entries/Entry.ts +304 -0
  1118. package/src/entries/IconEntry.ts +49 -0
  1119. package/src/entries/ImageEntry.ts +61 -0
  1120. package/src/entries/KeyValueEntry.ts +47 -0
  1121. package/src/entries/RepeatableEntry.test.ts +239 -0
  1122. package/src/entries/RepeatableEntry.ts +173 -0
  1123. package/src/entries/TextEntry.test.ts +394 -0
  1124. package/src/entries/TextEntry.ts +60 -0
  1125. package/src/entries/index.ts +12 -0
  1126. package/src/entries/leaves.test.ts +306 -0
  1127. package/src/entries/registry.ts +54 -0
  1128. package/src/fields/BuilderField.test.ts +1188 -0
  1129. package/src/fields/BuilderField.ts +568 -0
  1130. package/src/fields/BuilderRelationship.test.ts +811 -0
  1131. package/src/fields/CheckboxField.test.ts +44 -0
  1132. package/src/fields/CheckboxField.ts +27 -0
  1133. package/src/fields/CheckboxListField.test.ts +99 -0
  1134. package/src/fields/CheckboxListField.ts +66 -0
  1135. package/src/fields/ColorPickerField.test.ts +33 -0
  1136. package/src/fields/ColorPickerField.ts +25 -0
  1137. package/src/fields/DateField.ts +54 -0
  1138. package/src/fields/DateTimeField.test.ts +55 -0
  1139. package/src/fields/EmailField.ts +16 -0
  1140. package/src/fields/Field.test.ts +639 -0
  1141. package/src/fields/Field.ts +773 -0
  1142. package/src/fields/FileUploadField.test.ts +97 -0
  1143. package/src/fields/FileUploadField.ts +71 -0
  1144. package/src/fields/HiddenField.test.ts +27 -0
  1145. package/src/fields/HiddenField.ts +28 -0
  1146. package/src/fields/KeyValueField.test.ts +105 -0
  1147. package/src/fields/KeyValueField.ts +55 -0
  1148. package/src/fields/MarkdownField.test.ts +167 -0
  1149. package/src/fields/MarkdownField.ts +151 -0
  1150. package/src/fields/NumberField.ts +33 -0
  1151. package/src/fields/RadioField.test.ts +94 -0
  1152. package/src/fields/RadioField.ts +67 -0
  1153. package/src/fields/RepeaterField.test.ts +1806 -0
  1154. package/src/fields/RepeaterField.ts +791 -0
  1155. package/src/fields/RepeaterRelationship.test.ts +1630 -0
  1156. package/src/fields/RepeaterSimple.test.ts +248 -0
  1157. package/src/fields/RowButton.test.ts +149 -0
  1158. package/src/fields/RowButton.ts +125 -0
  1159. package/src/fields/SelectField.test.ts +192 -0
  1160. package/src/fields/SelectField.ts +235 -0
  1161. package/src/fields/SliderField.test.ts +50 -0
  1162. package/src/fields/SliderField.ts +53 -0
  1163. package/src/fields/SlugField.ts +24 -0
  1164. package/src/fields/TagsInputField.test.ts +154 -0
  1165. package/src/fields/TagsInputField.ts +133 -0
  1166. package/src/fields/TextField.ts +24 -0
  1167. package/src/fields/TextareaField.test.ts +58 -0
  1168. package/src/fields/TextareaField.ts +59 -0
  1169. package/src/fields/ToggleButtonsField.test.ts +106 -0
  1170. package/src/fields/ToggleButtonsField.ts +59 -0
  1171. package/src/fields/ToggleField.ts +16 -0
  1172. package/src/fields/disableOptionsWhenSelectedInSiblingRepeaterItems.test.ts +319 -0
  1173. package/src/fields/optionsResolver.ts +95 -0
  1174. package/src/fields/resolveField.ts +28 -0
  1175. package/src/filters/BooleanFilter.ts +35 -0
  1176. package/src/filters/DateRangeFilter.test.ts +194 -0
  1177. package/src/filters/DateRangeFilter.ts +148 -0
  1178. package/src/filters/Filter.test.ts +268 -0
  1179. package/src/filters/Filter.ts +184 -0
  1180. package/src/filters/FormFilter.test.ts +238 -0
  1181. package/src/filters/FormFilter.ts +215 -0
  1182. package/src/filters/MultiSelectFilter.test.ts +119 -0
  1183. package/src/filters/MultiSelectFilter.ts +78 -0
  1184. package/src/filters/QueryBuilderFilter.test.ts +644 -0
  1185. package/src/filters/QueryBuilderFilter.ts +398 -0
  1186. package/src/filters/SelectFilter.ts +46 -0
  1187. package/src/filters/TernaryFilter.test.ts +160 -0
  1188. package/src/filters/TernaryFilter.ts +72 -0
  1189. package/src/filters/TrashedFilter.test.ts +149 -0
  1190. package/src/filters/TrashedFilter.ts +55 -0
  1191. package/src/filters/queryBuilder/BooleanConstraint.ts +31 -0
  1192. package/src/filters/queryBuilder/Constraint.ts +115 -0
  1193. package/src/filters/queryBuilder/DateConstraint.ts +69 -0
  1194. package/src/filters/queryBuilder/NumberConstraint.ts +66 -0
  1195. package/src/filters/queryBuilder/SelectConstraint.ts +72 -0
  1196. package/src/filters/queryBuilder/TextConstraint.ts +65 -0
  1197. package/src/filters/queryBuilder/index.ts +12 -0
  1198. package/src/icons/index.ts +2 -0
  1199. package/src/icons/lucide.ts +204 -0
  1200. package/src/icons/registry.test.ts +56 -0
  1201. package/src/icons/registry.ts +41 -0
  1202. package/src/icons/types.ts +47 -0
  1203. package/src/index.ts +521 -0
  1204. package/src/io/csv.test.ts +142 -0
  1205. package/src/io/csv.ts +170 -0
  1206. package/src/nestedRelationManagerData.test.ts +526 -0
  1207. package/src/notifications/Notification.test.ts +210 -0
  1208. package/src/notifications/Notification.ts +354 -0
  1209. package/src/notifications/broadcast.test.ts +110 -0
  1210. package/src/notifications/broadcast.ts +95 -0
  1211. package/src/notifications/database.test.ts +383 -0
  1212. package/src/notifications/database.ts +398 -0
  1213. package/src/notifications/databaseNotifications.test.ts +187 -0
  1214. package/src/notifications/dispatchNotificationAction.test.ts +341 -0
  1215. package/src/notifications/dispatchNotificationAction.ts +142 -0
  1216. package/src/notifications/flash.test.ts +89 -0
  1217. package/src/notifications/flash.ts +71 -0
  1218. package/src/notifications/index.ts +45 -0
  1219. package/src/notifications/registerBroadcastAuth.test.ts +134 -0
  1220. package/src/notifications/registerBroadcastAuth.ts +100 -0
  1221. package/src/notifications/resolveSavedNotification.test.ts +82 -0
  1222. package/src/notifications/resolveSavedNotification.ts +59 -0
  1223. package/src/notifications/types.ts +93 -0
  1224. package/src/orm/m2mAccessor.ts +66 -0
  1225. package/src/orm/modelDefaults.test.ts +633 -0
  1226. package/src/orm/modelDefaults.ts +632 -0
  1227. package/src/pageData.test.ts +1121 -0
  1228. package/src/pageData.ts +4662 -0
  1229. package/src/plugins/index.ts +1 -0
  1230. package/src/plugins/themeEditor.ts +24 -0
  1231. package/src/react/AppShell.tsx +148 -0
  1232. package/src/react/CommandPalette.tsx +375 -0
  1233. package/src/react/FormStateContext.tsx +398 -0
  1234. package/src/react/HeadHooks.tsx +126 -0
  1235. package/src/react/NotificationActionStrip.tsx +263 -0
  1236. package/src/react/NotificationBell.tsx +426 -0
  1237. package/src/react/RenderHookSlot.tsx +32 -0
  1238. package/src/react/RightSidebar.tsx +257 -0
  1239. package/src/react/RightSidebarContext.tsx +211 -0
  1240. package/src/react/RightSidebarTrigger.tsx +53 -0
  1241. package/src/react/SchemaRenderer.tsx +6128 -0
  1242. package/src/react/SearchTrigger.tsx +46 -0
  1243. package/src/react/ThemeProvider.tsx +93 -0
  1244. package/src/react/ThemeSettingsPage.tsx +579 -0
  1245. package/src/react/ThemeToggle.tsx +20 -0
  1246. package/src/react/Toaster.tsx +158 -0
  1247. package/src/react/UserMenu.tsx +196 -0
  1248. package/src/react/WidgetDataContext.tsx +157 -0
  1249. package/src/react/cells/EditableCell.tsx +376 -0
  1250. package/src/react/fieldJsHandler.test.ts +166 -0
  1251. package/src/react/fieldJsHandler.ts +79 -0
  1252. package/src/react/fields/BuilderInput.tsx +995 -0
  1253. package/src/react/fields/CheckboxInput.tsx +39 -0
  1254. package/src/react/fields/CheckboxListInput.tsx +81 -0
  1255. package/src/react/fields/ColorInput.tsx +51 -0
  1256. package/src/react/fields/DateFieldInput.tsx +70 -0
  1257. package/src/react/fields/DateTimeInput.tsx +42 -0
  1258. package/src/react/fields/FieldShell.tsx +107 -0
  1259. package/src/react/fields/FileUploadInput.tsx +189 -0
  1260. package/src/react/fields/HiddenInput.tsx +17 -0
  1261. package/src/react/fields/KeyValueInput.tsx +200 -0
  1262. package/src/react/fields/MarkdownInput.tsx +333 -0
  1263. package/src/react/fields/RadioInput.tsx +60 -0
  1264. package/src/react/fields/RepeaterInput.test.ts +116 -0
  1265. package/src/react/fields/RepeaterInput.tsx +1313 -0
  1266. package/src/react/fields/SelectFieldInput.tsx +257 -0
  1267. package/src/react/fields/SliderInput.tsx +63 -0
  1268. package/src/react/fields/TagsInput.tsx +265 -0
  1269. package/src/react/fields/TextLikeInput.tsx +54 -0
  1270. package/src/react/fields/ToggleButtonsInput.tsx +60 -0
  1271. package/src/react/fields/ToggleFieldInput.tsx +35 -0
  1272. package/src/react/fields/rowChromeButton.tsx +225 -0
  1273. package/src/react/fields/syncRowGates.test.ts +202 -0
  1274. package/src/react/fields/syncRowGates.ts +66 -0
  1275. package/src/react/formStateHelpers.test.ts +295 -0
  1276. package/src/react/formStateHelpers.ts +218 -0
  1277. package/src/react/hooks/use-mobile.ts +19 -0
  1278. package/src/react/icon-context.tsx +60 -0
  1279. package/src/react/index.ts +85 -0
  1280. package/src/react/layouts/SidebarLayout.tsx +239 -0
  1281. package/src/react/layouts/TopbarLayout.tsx +245 -0
  1282. package/src/react/navigate.tsx +37 -0
  1283. package/src/react/registry.ts +48 -0
  1284. package/src/react/right-panel-registry.tsx +47 -0
  1285. package/src/react/theme-preview/apply.ts +99 -0
  1286. package/src/react/theme-preview/build-html.ts +436 -0
  1287. package/src/react/ui/button.tsx +51 -0
  1288. package/src/react/ui/calendar.tsx +67 -0
  1289. package/src/react/ui/checkbox.tsx +29 -0
  1290. package/src/react/ui/dialog.tsx +108 -0
  1291. package/src/react/ui/dropdown-menu.tsx +97 -0
  1292. package/src/react/ui/input.tsx +20 -0
  1293. package/src/react/ui/label.tsx +21 -0
  1294. package/src/react/ui/popover.tsx +50 -0
  1295. package/src/react/ui/select.tsx +169 -0
  1296. package/src/react/ui/separator.tsx +25 -0
  1297. package/src/react/ui/sheet.tsx +136 -0
  1298. package/src/react/ui/sidebar.tsx +723 -0
  1299. package/src/react/ui/skeleton.tsx +13 -0
  1300. package/src/react/ui/slider.tsx +34 -0
  1301. package/src/react/ui/switch.tsx +28 -0
  1302. package/src/react/ui/table.tsx +105 -0
  1303. package/src/react/ui/tabs.tsx +63 -0
  1304. package/src/react/ui/textarea.tsx +18 -0
  1305. package/src/react/ui/tooltip.tsx +64 -0
  1306. package/src/react/useResizableWidth.ts +139 -0
  1307. package/src/react/utils.ts +6 -0
  1308. package/src/react/widgetRegistry.test.ts +43 -0
  1309. package/src/react/widgetRegistry.ts +50 -0
  1310. package/src/react/widgets/StatsOverviewRenderer.tsx +232 -0
  1311. package/src/react/widgets/TableWidgetRenderer.tsx +231 -0
  1312. package/src/react/widgets/ViewRenderer.tsx +71 -0
  1313. package/src/relationManagerData.test.ts +1146 -0
  1314. package/src/richtext/index.ts +8 -0
  1315. package/src/richtext/registry.ts +89 -0
  1316. package/src/routes-nested-relations.test.ts +676 -0
  1317. package/src/routes-relations.test.ts +972 -0
  1318. package/src/routes.test.ts +1886 -0
  1319. package/src/routes.ts +3262 -0
  1320. package/src/schema/Alert.test.ts +63 -0
  1321. package/src/schema/Alert.ts +49 -0
  1322. package/src/schema/Block.ts +169 -0
  1323. package/src/schema/Breadcrumbs.ts +40 -0
  1324. package/src/schema/Card.ts +35 -0
  1325. package/src/schema/Divider.ts +20 -0
  1326. package/src/schema/Element.ts +219 -0
  1327. package/src/schema/EmptyState.test.ts +37 -0
  1328. package/src/schema/EmptyState.ts +63 -0
  1329. package/src/schema/Fieldset.ts +43 -0
  1330. package/src/schema/Grid.ts +43 -0
  1331. package/src/schema/Group.ts +30 -0
  1332. package/src/schema/Heading.ts +39 -0
  1333. package/src/schema/Html.ts +67 -0
  1334. package/src/schema/Icon.ts +54 -0
  1335. package/src/schema/Image.ts +57 -0
  1336. package/src/schema/LinkTag.ts +41 -0
  1337. package/src/schema/Markdown.ts +85 -0
  1338. package/src/schema/MetaTag.ts +41 -0
  1339. package/src/schema/RelationTabs.ts +71 -0
  1340. package/src/schema/ScriptTag.ts +55 -0
  1341. package/src/schema/Section.ts +143 -0
  1342. package/src/schema/ServerDataElement.test.ts +140 -0
  1343. package/src/schema/ServerDataElement.ts +156 -0
  1344. package/src/schema/Split.ts +50 -0
  1345. package/src/schema/Stat.test.ts +118 -0
  1346. package/src/schema/Stat.ts +154 -0
  1347. package/src/schema/StatsOverview.test.ts +141 -0
  1348. package/src/schema/StatsOverview.ts +119 -0
  1349. package/src/schema/StyleTag.ts +35 -0
  1350. package/src/schema/TableWidget.test.ts +297 -0
  1351. package/src/schema/TableWidget.ts +289 -0
  1352. package/src/schema/Tabs.ts +79 -0
  1353. package/src/schema/Text.ts +58 -0
  1354. package/src/schema/UnorderedList.ts +49 -0
  1355. package/src/schema/View.test.ts +111 -0
  1356. package/src/schema/View.ts +127 -0
  1357. package/src/schema/Wizard.ts +108 -0
  1358. package/src/schema/containers.test.ts +446 -0
  1359. package/src/schema/headTags.test.ts +134 -0
  1360. package/src/schema/index.ts +39 -0
  1361. package/src/schema/primes.test.ts +269 -0
  1362. package/src/schema/resolveSchema.test.ts +329 -0
  1363. package/src/schema/resolveSchema.ts +807 -0
  1364. package/src/schema/sanitize.ts +49 -0
  1365. package/src/search.test.ts +446 -0
  1366. package/src/search.ts +178 -0
  1367. package/src/sessionFilters.test.ts +352 -0
  1368. package/src/sessionFilters.ts +133 -0
  1369. package/src/summarizers/Summarizer.test.ts +84 -0
  1370. package/src/summarizers/Summarizer.ts +123 -0
  1371. package/src/summarizers/index.ts +11 -0
  1372. package/src/theme/base-colors.ts +68 -0
  1373. package/src/theme/chart-colors.ts +50 -0
  1374. package/src/theme/colors.ts +447 -0
  1375. package/src/theme/generate-css.test.ts +139 -0
  1376. package/src/theme/generate-css.ts +44 -0
  1377. package/src/theme/generate-scale.test.ts +106 -0
  1378. package/src/theme/generate-scale.ts +97 -0
  1379. package/src/theme/icon-map.ts +42 -0
  1380. package/src/theme/index.ts +28 -0
  1381. package/src/theme/migrate.ts +81 -0
  1382. package/src/theme/presets.ts +135 -0
  1383. package/src/theme/radius.ts +18 -0
  1384. package/src/theme/resolve.test.ts +238 -0
  1385. package/src/theme/resolve.ts +96 -0
  1386. package/src/theme/spacing.ts +18 -0
  1387. package/src/theme/theme-colors.ts +88 -0
  1388. package/src/theme/types.ts +125 -0
  1389. package/src/uploads/UploadAdapter.ts +35 -0
  1390. package/src/uploads/index.ts +2 -0
  1391. package/src/uploads/localUpload.test.ts +70 -0
  1392. package/src/uploads/localUpload.ts +84 -0
  1393. package/src/validation/Validator.ts +49 -0
  1394. package/src/validation/index.ts +28 -0
  1395. package/src/validation/rules.ts +78 -0
  1396. package/src/validation/runValidators.ts +435 -0
  1397. package/src/validation/uniqueValidator.test.ts +196 -0
  1398. package/src/validation/uniqueValidator.ts +133 -0
  1399. package/src/validation/validators.test.ts +268 -0
  1400. package/src/vite.ts +758 -0
  1401. package/src/widgets/index.ts +10 -0
  1402. package/src/widgets/registry.ts +45 -0
  1403. package/src/widgets.test.ts +592 -0
  1404. package/tsconfig.build.json +11 -0
  1405. package/tsconfig.json +4 -0
  1406. package/tsconfig.test.json +10 -0
  1407. package/views/react/Dashboard.tsx +27 -0
  1408. package/views/react/Resources/Form.tsx +102 -0
  1409. package/views/react/Resources/Index.tsx +49 -0
@@ -0,0 +1,1652 @@
1
+ import { Element } from '../schema/Element.js';
2
+ import { safeManagerPolicy, } from '../RelationManager.js';
3
+ import { computeMorphPayload, getMorphRelationDescriptor, getParentRelationDescriptor, } from '../orm/modelDefaults.js';
4
+ import { resolveM2MAccessor } from '../orm/m2mAccessor.js';
5
+ import { buildImportSchema as buildImportModalSchema } from './importFactory.js';
6
+ import { buildAttachModalSchema } from './attachFactory.js';
7
+ /** Cluster-aware resource base path. Mirrors `clusterPaths.resourceBasePath`
8
+ * but uses the structural `ResourceLike` shape so `Action.ts` stays
9
+ * cycle-free against `Resource.ts`. */
10
+ function resourceBase(basePath, R) {
11
+ if (R.cluster)
12
+ return `${basePath}/${R.cluster.getSlug()}/${R.getSlug()}`;
13
+ return `${basePath}/${R.getSlug()}`;
14
+ }
15
+ /** Pick the right label form for a count — `labelSingular` for 1,
16
+ * `label` (plural, lowercased) for any other count. Fall back to a
17
+ * naive `${labelSingular}s` when no plural label is set. Used by bulk
18
+ * notification copy so we don't ship "1 posts moved to trash". */
19
+ function labelForCount(R, n) {
20
+ if (n === 1)
21
+ return R.labelSingular.toLowerCase();
22
+ const plural = R.label?.toLowerCase();
23
+ return plural ?? `${R.labelSingular.toLowerCase()}s`;
24
+ }
25
+ /** True when a `RelationManagerContext.mode` denotes a pivot-mutation
26
+ * shape — i.e. a many-to-many relation. All three modes share the
27
+ * `attach` / `detach` / `sync` accessor surface (the rudder ORM stamps
28
+ * + filters the polymorphic discriminator transparently for the morph
29
+ * variants). The `relationCreate / Edit / Delete` factories auto-hide
30
+ * under any of these modes because per-pivot-row create / edit / delete
31
+ * is meaningless — users create the related record via its own Resource,
32
+ * then attach via `relationAttach`. */
33
+ function isM2MMode(mode) {
34
+ return mode === 'belongsToMany' || mode === 'morphToMany' || mode === 'morphedByMany';
35
+ }
36
+ /**
37
+ * Phase B — build the URL prefix for a relation factory action. Without
38
+ * a `chain` (depth-1 manager), this is the familiar
39
+ * `${base}/${parentSlug}/${parentId}/${relationship}`. With a chain
40
+ * (depth-2 nested manager), it threads the outer record + relationship
41
+ * between the parent slug and the leaf parent id:
42
+ *
43
+ * `${base}/${parentSlug}/${chain[0].recordId}/${chain[0].relationship}/${parentId}/${relationship}`
44
+ *
45
+ * Pure; takes a `RelationManagerContext` and emits a string. The leaf
46
+ * record id (and trailing `/edit`, `/delete`, etc.) gets appended by
47
+ * the caller.
48
+ */
49
+ function relationUrlPrefix(ctx) {
50
+ const head = `${ctx.basePath}/${ctx.parentSlug}`;
51
+ const chain = ctx.chain ?? [];
52
+ let mid = '';
53
+ for (const step of chain) {
54
+ mid += `/${step.recordId}/${step.relationship}`;
55
+ }
56
+ return `${head}${mid}/${ctx.parentId}/${ctx.relationship}`;
57
+ }
58
+ /**
59
+ * Compute the parent-attachment payload to force-pin onto a relation
60
+ * replica. For `hasMany`, returns `{ [foreignKey]: parentId }` from the
61
+ * parent's `static relations[name]` descriptor. For `morphMany` /
62
+ * `morphOne`, returns `{ <morphName>Id, <morphName>Type }` via
63
+ * `computeMorphPayload(parentRecord)`. Returns `{}` when no descriptor
64
+ * matches — the route dispatcher already auto-hides under M2M / morphTo,
65
+ * so missing descriptors there are a no-op rather than an error. Pure;
66
+ * exported for tests and re-used by both factories.
67
+ */
68
+ function computeRelationPin(ctx) {
69
+ const parentModel = ctx.parentRecord?.constructor;
70
+ if (!parentModel)
71
+ return {};
72
+ const rel = ctx.relationship;
73
+ // Polymorphic owner side first — `morphMany` carries no foreignKey
74
+ // and would fail the hasMany descriptor's gate.
75
+ if (ctx.mode === 'morphMany') {
76
+ const morph = getMorphRelationDescriptor(parentModel, rel);
77
+ if (!morph)
78
+ return {};
79
+ try {
80
+ return computeMorphPayload(ctx.parentRecord, morph);
81
+ }
82
+ catch {
83
+ return {};
84
+ }
85
+ }
86
+ const desc = getParentRelationDescriptor(parentModel, rel);
87
+ if (!desc)
88
+ return {};
89
+ return { [desc.foreignKey]: ctx.parentId };
90
+ }
91
+ /**
92
+ * Build + persist a single relation replica. Runs the strip set
93
+ * (PK + soft-delete column on the **related** Resource +
94
+ * `opts.excludeAttributes`), force-pins the parent attachment columns,
95
+ * runs the optional `beforeReplicaSaved` hook, and calls
96
+ * `Related.model.create(...)`. Returns the model's create result so
97
+ * callers can read its primary key for redirect targeting.
98
+ *
99
+ * Throws when the related Resource has no model — caller (single-row
100
+ * factory) catches and surfaces an error notification; bulk caller
101
+ * checks the model presence ahead of the loop.
102
+ */
103
+ async function persistRelationReplica(_M, ctx, source, opts) {
104
+ const Related = ctx.related;
105
+ if (!Related?.model || typeof Related.model.create !== 'function') {
106
+ throw new Error('Related Resource has no model.create');
107
+ }
108
+ const M2 = Related.model;
109
+ const pkCol = M2.primaryKey ?? 'id';
110
+ const trashedCol = Related.deletedAtColumn ?? 'deletedAt';
111
+ const skip = new Set([pkCol, trashedCol, ...(opts.excludeAttributes ?? [])]);
112
+ let replica = {};
113
+ for (const [k, v] of Object.entries(source)) {
114
+ if (skip.has(k))
115
+ continue;
116
+ replica[k] = v;
117
+ }
118
+ // Force-pin the parent attachment AFTER the strip but BEFORE the
119
+ // user mutator, so `beforeReplicaSaved` can read / override the FK
120
+ // if it really wants to (rare). Tampered source rows can't slip a
121
+ // different parent in by riding their own FK column — the pin
122
+ // overwrites whatever value was there.
123
+ Object.assign(replica, computeRelationPin(ctx));
124
+ if (opts.beforeReplicaSaved) {
125
+ replica = await opts.beforeReplicaSaved(replica, source);
126
+ }
127
+ return M2.create(replica);
128
+ }
129
+ /**
130
+ * Single-row dispatch for `Action.relationReplicate`. Resolves
131
+ * `ctx.record` (loaded by the route's resolveRecord hook), validates,
132
+ * persists the replica, and shapes the success notification. Errors
133
+ * are caught and surfaced as error toasts.
134
+ */
135
+ async function runRelationReplicateRow(M, ctx, hctx, opts) {
136
+ const source = hctx.record;
137
+ if (!source || typeof source !== 'object') {
138
+ return { notify: { title: 'Replicate failed: source record missing', type: 'error' } };
139
+ }
140
+ const Related = ctx.related;
141
+ if (!Related?.model || typeof Related.model.create !== 'function') {
142
+ return { notify: { title: 'Replicate not configured (related Resource has no model.create)', type: 'error' } };
143
+ }
144
+ let created;
145
+ try {
146
+ created = await persistRelationReplica(M, ctx, source, opts);
147
+ }
148
+ catch (err) {
149
+ return { notify: { title: `Replicate failed: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
150
+ }
151
+ const overrideTitle = opts.getCreatedNotificationTitle
152
+ ? await opts.getCreatedNotificationTitle({ replica: created, source })
153
+ : undefined;
154
+ const title = overrideTitle !== undefined ? overrideTitle : `${M.getLabelSingular()} replicated`;
155
+ // The manager-scoped `_action/:actionName` route falls back to the
156
+ // manager list URL when `result.redirect` is undefined, so we only
157
+ // emit `redirect` when the user override returned a string. That
158
+ // way default behavior (route owns the fallback) is unchanged.
159
+ const overrideRedirect = opts.getRedirectUrl
160
+ ? await opts.getRedirectUrl({ replica: created, source })
161
+ : undefined;
162
+ return {
163
+ ...(overrideRedirect !== undefined ? { redirect: overrideRedirect } : {}),
164
+ notify: { title, type: 'success' },
165
+ };
166
+ }
167
+ /** Read `record[R.deletedAtColumn ?? 'deletedAt']` and return true when
168
+ * the row is currently trashed (soft-deleted). Permissive on shape —
169
+ * bare `null` / `undefined` count as live; any other truthy value is
170
+ * trashed. */
171
+ function isTrashed(record, R) {
172
+ if (!record || typeof record !== 'object')
173
+ return false;
174
+ const col = R.deletedAtColumn ?? 'deletedAt';
175
+ const v = record[col];
176
+ return v !== null && v !== undefined;
177
+ }
178
+ /** Lazy-load the `Table` class for use inside Action handlers. Direct
179
+ * module-level import would cycle (Table → Action → Table); dynamic
180
+ * import inside a handler runs after both modules have finished
181
+ * loading. Cached after first call so we don't pay the import cost
182
+ * on every dispatched export. */
183
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
184
+ let _TableClass;
185
+ async function loadTableClass() {
186
+ if (_TableClass !== undefined)
187
+ return _TableClass.make();
188
+ const mod = await import('../elements/Table.js');
189
+ _TableClass = mod.Table;
190
+ return _TableClass.make();
191
+ }
192
+ /** Call a (possibly undefined) Resource predicate. When unset, the
193
+ * predicate is treated as "allowed" (returns true) so the factory
194
+ * doesn't hide actions on Resources that haven't opted into Plan #10. */
195
+ function callPredicate(fn, user, record) {
196
+ if (!fn)
197
+ return true;
198
+ return fn(user, record);
199
+ }
200
+ /**
201
+ * Action — a button-or-menu-entry that performs work when clicked.
202
+ *
203
+ * One class for all four placements; pick one via `.inline()` / `.row()` /
204
+ * `.bulk()` / `.header()` (or `.placement(...)`). Actions can sit inline
205
+ * inside any container Element (Card, Section, etc.) or attach to a
206
+ * Resource's list page.
207
+ *
208
+ * Phase 1.4 ships the shape + serialization. Handler dispatch and
209
+ * confirmation-form support land in Phase 2 alongside Resource lifecycle.
210
+ */
211
+ export class Action extends Element {
212
+ name;
213
+ _label;
214
+ _icon;
215
+ _placement = 'inline';
216
+ _destructive = false;
217
+ _confirm;
218
+ _handler;
219
+ /**
220
+ * Notification-registry handler key — set by `.handler(string)`. The
221
+ * notification-action route looks this up against
222
+ * `Pilotiq.notificationHandlers({…})` at request time. Mutually
223
+ * exclusive with the closure `_handler` — passing a string clears
224
+ * `_handler`, passing a function clears `_handlerName`. Closures can't
225
+ * round-trip through a `data` JSON column; the registry path is the
226
+ * persisted-notification escape hatch.
227
+ */
228
+ _handlerName;
229
+ /**
230
+ * Per-fire context for registry-handler dispatch. Round-trips through
231
+ * the notification's `data.actions` JSON column verbatim and arrives
232
+ * on the handler's `ctx.payload`.
233
+ */
234
+ _payload;
235
+ /**
236
+ * Filament-style chain modifier — when set on an action used inside a
237
+ * `Notification.actions([…])` slot, firing the action also flips the
238
+ * notification's `read_at`. No-op when the action isn't in a
239
+ * notification context.
240
+ */
241
+ _markAsReadOnFire = false;
242
+ /**
243
+ * When set, click-through opens in a new tab. Honored by the
244
+ * notification action strip renderers (bell + toast); ignored by
245
+ * everything else (Resource action triggers don't expose this knob —
246
+ * use `target` on the underlying anchor if you need it elsewhere).
247
+ */
248
+ _openUrlInNewTab = false;
249
+ _href;
250
+ _method;
251
+ _actionUrl;
252
+ _dispatchUrl;
253
+ _submit = false;
254
+ _formTarget;
255
+ _formField;
256
+ // Modal chrome — present whenever `.schema()` or any of the modal
257
+ // builders below have been called.
258
+ _hasModal = false;
259
+ _modalHeading;
260
+ _modalDescription;
261
+ _modalSubmitLabel;
262
+ _modalCancelLabel;
263
+ _modalIcon;
264
+ _modalIconColor;
265
+ _modalWidth;
266
+ _slideOver = false;
267
+ // Defaults match the existing renderer behaviour (closeable both ways,
268
+ // no sticky chrome, no X button). Setters with a default arg of `false`
269
+ // / `true` mirror Filament's call shapes — `closeModalByClickingAway()`
270
+ // disables pointer dismiss, `stickyModalHeader()` enables sticky.
271
+ _closeModalByClickingAway = true;
272
+ _closeModalByEscaping = true;
273
+ _stickyModalHeader = false;
274
+ _stickyModalFooter = false;
275
+ _modalAutofocus;
276
+ _modalAlignment;
277
+ _modalCloseButton = false;
278
+ // Trigger variants & cosmetics
279
+ _color;
280
+ _size;
281
+ _tooltip;
282
+ _outlined = false;
283
+ _iconOnly = false;
284
+ _badge;
285
+ _badgeColor;
286
+ // Conditional visibility / disabled rules
287
+ _visible;
288
+ _hidden;
289
+ _isDisabled;
290
+ constructor(name) {
291
+ super();
292
+ this.name = name;
293
+ this._label = name.charAt(0).toUpperCase() + name.slice(1);
294
+ }
295
+ static make(name) {
296
+ return new Action(name);
297
+ }
298
+ // ─── Resource-aware factories ─────────────────────────
299
+ //
300
+ // Pre-configured Action shapes that target a Resource's standard CRUD
301
+ // pages. Drop into `Table.recordActions([…])`, `headerActions([…])`,
302
+ // or `ViewPage.getActions(...)` — placement is stamped by the slot.
303
+ // Filament-style: explicit, but ergonomic.
304
+ //
305
+ // Each factory uses `:id` template substitution for row context; the
306
+ // renderer fills in the row's id when rendering. Header / view actions
307
+ // ignore the template (no `:id` needed for create / list URLs).
308
+ //
309
+ // Plan #10 — each factory auto-attaches a visibility rule that
310
+ // delegates to the Resource's matching policy method (`R.canCreate`
311
+ // for `Action.create`, etc). When `R.canX` is unset (default returns
312
+ // `true`) the action stays visible. Pass an explicit `.visible(...)`
313
+ // after the factory to override.
314
+ /** Create-action factory — link to `${basePath}/${R.slug}/create`.
315
+ * Auto-hides when `R.canCreate(user)` returns false. */
316
+ static create(R, basePath) {
317
+ return Action.make('create')
318
+ .label(`New ${R.labelSingular}`)
319
+ .href(`${resourceBase(basePath, R)}/create`)
320
+ .visible(({ user }) => callPredicate(R.canCreate, user));
321
+ }
322
+ /**
323
+ * Edit-action factory — link to the resource's edit page.
324
+ *
325
+ * Pass `recordId` when building actions for a single-record context
326
+ * (e.g. `ViewPage.getActions()`); the URL is baked at config time.
327
+ * Omit `recordId` for row context (`Table.recordActions(...)`); the
328
+ * URL keeps the `:id` template and the renderer substitutes per-row.
329
+ *
330
+ * Auto-hides when `R.canEdit(user, record)` returns false. For row
331
+ * context the per-row record threads in via `loadTableRecords`'s
332
+ * per-row eval; for view-page context, `resolveSchema` provides the
333
+ * resolved record on the eval context.
334
+ */
335
+ static edit(R, basePath, recordId) {
336
+ const id = recordId ?? ':id';
337
+ return Action.make('edit')
338
+ .label('Edit')
339
+ .href(`${resourceBase(basePath, R)}/${id}/edit`)
340
+ .visible(({ user, record }) => callPredicate(R.canEdit, user, record));
341
+ }
342
+ /** View-action factory — link to the resource's view page. See `Action.edit` for the `recordId` semantics.
343
+ * Auto-hides when `R.canView(user, record)` returns false. */
344
+ static view(R, basePath, recordId) {
345
+ const id = recordId ?? ':id';
346
+ return Action.make('view')
347
+ .label('View')
348
+ .href(`${resourceBase(basePath, R)}/${id}`)
349
+ .visible(({ user, record }) => callPredicate(R.canView, user, record));
350
+ }
351
+ /**
352
+ * Delete-action factory — POSTs to the resource's delete route,
353
+ * destructive style, with a confirmation prompt referencing the
354
+ * resource label. Same `recordId` semantics as `Action.edit`.
355
+ * Auto-hides when `R.canDelete(user, record)` returns false.
356
+ *
357
+ * Plan #13 — when `R.softDeletes = true`, additionally hides on
358
+ * rows whose `deletedAtColumn` is set (already-trashed rows get the
359
+ * Restore + ForceDelete pair instead, surfaced via the matching
360
+ * factories below).
361
+ */
362
+ static delete(R, basePath, recordId) {
363
+ const id = recordId ?? ':id';
364
+ return Action.make('delete')
365
+ .label('Delete')
366
+ .destructive()
367
+ .method('post')
368
+ .action(`${resourceBase(basePath, R)}/${id}/delete`)
369
+ .confirm(`Delete this ${R.labelSingular.toLowerCase()}?`)
370
+ .visible(async ({ user, record }) => {
371
+ if (R.softDeletes && isTrashed(record, R))
372
+ return false;
373
+ return callPredicate(R.canDelete, user, record);
374
+ });
375
+ }
376
+ /**
377
+ * Replicate-action factory — handler-style. Loads the source record
378
+ * from `ctx.record` (the `_action/:actionName` route already resolves
379
+ * it through `R.query(ctx)` for row + single-target placements),
380
+ * strips PK + soft-delete column + any `opts.excludeAttributes`,
381
+ * optionally runs `opts.beforeReplicaSaved`, and creates a new row
382
+ * via `R.model.create(...)`. Redirects to the new record's edit page
383
+ * on success so the user can review + tweak before saving again.
384
+ *
385
+ * `recordId` kept in the signature for parity with `delete / edit /
386
+ * view` so users can swap factories without rewriting call sites; the
387
+ * dispatcher resolves the source record from the URL and hands it to
388
+ * the handler as `ctx.record`, so we don't reference `recordId` here.
389
+ *
390
+ * Auto-hides when `R.canCreate(user)` returns false — replicating
391
+ * writes a new row, so the gate is `canCreate`, not `canView`.
392
+ */
393
+ static replicate(R, basePath, recordId, opts = {}) {
394
+ void recordId;
395
+ return Action.make('replicate')
396
+ .label('Replicate')
397
+ .handler(async (ctx) => {
398
+ const source = ctx.record;
399
+ if (!source || typeof source !== 'object') {
400
+ return { notify: { title: 'Replicate failed: source record missing', type: 'error' } };
401
+ }
402
+ const M = R.model;
403
+ if (!M || typeof M.create !== 'function') {
404
+ return { notify: { title: 'Replicate not configured (resource has no model.create)', type: 'error' } };
405
+ }
406
+ const pkCol = M.primaryKey ?? 'id';
407
+ const trashedCol = R.deletedAtColumn ?? 'deletedAt';
408
+ const skip = new Set([pkCol, trashedCol, ...(opts.excludeAttributes ?? [])]);
409
+ let replica = {};
410
+ for (const [k, v] of Object.entries(source)) {
411
+ if (skip.has(k))
412
+ continue;
413
+ replica[k] = v;
414
+ }
415
+ if (opts.beforeReplicaSaved) {
416
+ try {
417
+ replica = await opts.beforeReplicaSaved(replica, source);
418
+ }
419
+ catch (err) {
420
+ return { notify: { title: `Replicate failed: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
421
+ }
422
+ }
423
+ let created;
424
+ try {
425
+ created = await M.create(replica);
426
+ }
427
+ catch (err) {
428
+ return { notify: { title: `Replicate failed: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
429
+ }
430
+ const newId = created?.[pkCol];
431
+ const defaultRedirect = newId !== undefined && newId !== null
432
+ ? `${resourceBase(basePath, R)}/${String(newId)}/edit`
433
+ : `${resourceBase(basePath, R)}`;
434
+ // `!== undefined` rather than `??` so an override returning
435
+ // `null`/empty-string isn't silently swallowed (see
436
+ // feedback_nullish_swallows_explicit_null).
437
+ const overrideRedirect = opts.getRedirectUrl
438
+ ? await opts.getRedirectUrl({ replica: created, source })
439
+ : undefined;
440
+ const redirect = overrideRedirect !== undefined ? overrideRedirect : defaultRedirect;
441
+ const overrideTitle = opts.getCreatedNotificationTitle
442
+ ? await opts.getCreatedNotificationTitle({ replica: created, source })
443
+ : undefined;
444
+ const title = overrideTitle !== undefined ? overrideTitle : `${R.labelSingular} replicated`;
445
+ return {
446
+ redirect,
447
+ notify: { title, type: 'success' },
448
+ };
449
+ })
450
+ .visible(({ user }) => callPredicate(R.canCreate, user));
451
+ }
452
+ /**
453
+ * Plan #13 — Restore factory. POSTs to the resource's restore route,
454
+ * success-styled, no confirm prompt (restoration is reversible).
455
+ * Auto-hides on live (non-trashed) rows AND when `R.canRestore(user,
456
+ * record)` returns false. Same `recordId` semantics as `Action.edit`.
457
+ */
458
+ static restore(R, basePath, recordId) {
459
+ const id = recordId ?? ':id';
460
+ return Action.make('restore')
461
+ .label('Restore')
462
+ .color('success')
463
+ .method('post')
464
+ .action(`${resourceBase(basePath, R)}/${id}/restore`)
465
+ .visible(async ({ user, record }) => {
466
+ if (!isTrashed(record, R))
467
+ return false;
468
+ return callPredicate(R.canRestore, user, record);
469
+ });
470
+ }
471
+ /**
472
+ * Plan #13 — Force-delete factory. POSTs to the resource's
473
+ * force-delete route, destructive-styled, with a stricter confirm
474
+ * prompt referencing permanence. Auto-hides on live (non-trashed)
475
+ * rows AND when `R.canForceDelete(user, record)` returns false.
476
+ */
477
+ static forceDelete(R, basePath, recordId) {
478
+ const id = recordId ?? ':id';
479
+ return Action.make('forceDelete')
480
+ .label('Delete forever')
481
+ .destructive()
482
+ .method('post')
483
+ .action(`${resourceBase(basePath, R)}/${id}/force-delete`)
484
+ .confirm(`Permanently delete this ${R.labelSingular.toLowerCase()}? This cannot be undone.`)
485
+ .visible(async ({ user, record }) => {
486
+ if (!isTrashed(record, R))
487
+ return false;
488
+ return callPredicate(R.canForceDelete, user, record);
489
+ });
490
+ }
491
+ // ─── Notification factories ───────────────────────────────────
492
+ //
493
+ // Pre-configured Action shapes that target the bell-table read /
494
+ // unread endpoints mounted by `Pilotiq.databaseNotifications()`. Use
495
+ // inside a custom notification inbox page's `recordActions(...)` (or
496
+ // alongside a `Notification.actions([…])` slot when one ships) to
497
+ // give end-users explicit "Mark as read" / "Mark as unread" buttons.
498
+ //
499
+ // Filament-style chain modifier `Action::make('view')->markAsRead()`
500
+ // is a separate concern — it'd add an implicit mark-read side-effect
501
+ // to a custom action. v1 ships only the explicit factory; the chain
502
+ // modifier is deferred until a consumer asks.
503
+ /**
504
+ * Mark-as-read factory — POSTs to the panel's notification read
505
+ * endpoint for the given notification id. The endpoint
506
+ * (`${base}/_notifications/:id/read`) is mounted by
507
+ * `Pilotiq.databaseNotifications()`, so calling this without
508
+ * opting into the bell surface produces an Action whose POST 404s.
509
+ *
510
+ * `notificationId` is baked at config time. For row context where
511
+ * the id varies per row, omit it and the URL keeps the `:id`
512
+ * template; the renderer substitutes per-row at render time
513
+ * (parallel to `Action.edit`'s row form).
514
+ *
515
+ * No auto-visibility. Wrap in `.visible(({ record }) => !record.readAt)`
516
+ * to hide on already-read rows.
517
+ */
518
+ static markAsRead(basePath, notificationId) {
519
+ const id = notificationId ?? ':id';
520
+ return Action.make('markAsRead')
521
+ .label('Mark as read')
522
+ .method('post')
523
+ .action(`${basePath}/_notifications/${id}/read`);
524
+ }
525
+ // ─── Bulk factories (Plan #13) ────────────────────────────────
526
+ //
527
+ // Handler-style bulk actions that iterate `ctx.records`, run policy
528
+ // per-row, and call the matching Resource / Model method. No new
529
+ // routes — the existing `/_action/:actionName` dispatcher already
530
+ // handles bulk via `ctx.records`. Drop into `bulkActions([...])`
531
+ // from inside `Resource.table()`.
532
+ //
533
+ // Each returns a notification with the count succeeded; rows whose
534
+ // policy denied (or whose call threw) are silently skipped — surface
535
+ // them via your own logging if needed.
536
+ /** Bulk delete — calls `R.deleteRecord(id)` per row. On a
537
+ * soft-delete resource that hits `Model.delete()` which writes
538
+ * `deletedAt`. Notification: "N posts moved to trash" / "N posts
539
+ * deleted" depending on `R.softDeletes`. */
540
+ static bulkDelete(R, _basePath) {
541
+ return Action.make('bulkDelete')
542
+ .label('Delete selected')
543
+ .destructive()
544
+ .bulk()
545
+ .confirm(`Delete the selected ${labelForCount(R, 0)}?`)
546
+ .handler(async (ctx) => {
547
+ const records = ctx.records ?? [];
548
+ const Rfull = R;
549
+ let n = 0;
550
+ for (const record of records) {
551
+ const id = String(record.id ?? '');
552
+ if (!id)
553
+ continue;
554
+ const allowed = await callPredicate(R.canDelete, ctx.user, record);
555
+ if (!allowed)
556
+ continue;
557
+ try {
558
+ await Rfull.deleteRecord(id);
559
+ n++;
560
+ }
561
+ catch { /* skip — agg notify shows total */ }
562
+ }
563
+ const verb = R.softDeletes ? 'moved to trash' : 'deleted';
564
+ return { notify: { title: `${n} ${labelForCount(R, n)} ${verb}`, type: 'success' } };
565
+ });
566
+ }
567
+ /** Bulk restore — calls `R.model.restore(id)` per row. Visible only
568
+ * on soft-delete resources (the entire bulk-restore concept is
569
+ * specific to them). */
570
+ static bulkRestore(R, _basePath) {
571
+ return Action.make('bulkRestore')
572
+ .label('Restore selected')
573
+ .color('success')
574
+ .bulk()
575
+ .confirm(`Restore the selected ${labelForCount(R, 0)}?`)
576
+ .handler(async (ctx) => {
577
+ const records = ctx.records ?? [];
578
+ const Rfull = R;
579
+ const restore = Rfull.model?.restore;
580
+ if (!restore) {
581
+ return { notify: { title: 'Restore not configured', type: 'error' } };
582
+ }
583
+ let n = 0;
584
+ for (const record of records) {
585
+ const id = String(record.id ?? '');
586
+ if (!id)
587
+ continue;
588
+ const allowed = await callPredicate(R.canRestore, ctx.user, record);
589
+ if (!allowed)
590
+ continue;
591
+ try {
592
+ await restore(id);
593
+ n++;
594
+ }
595
+ catch { /* skip */ }
596
+ }
597
+ return { notify: { title: `${n} ${labelForCount(R, n)} restored`, type: 'success' } };
598
+ });
599
+ }
600
+ /** Bulk force-delete — calls `R.model.forceDelete(id)` per row. Same
601
+ * destructive confirm as the per-row variant. Visible only on
602
+ * soft-delete resources. */
603
+ static bulkForceDelete(R, _basePath) {
604
+ return Action.make('bulkForceDelete')
605
+ .label('Delete forever')
606
+ .destructive()
607
+ .bulk()
608
+ .confirm(`Permanently delete the selected ${labelForCount(R, 0)}? This cannot be undone.`)
609
+ .handler(async (ctx) => {
610
+ const records = ctx.records ?? [];
611
+ const Rfull = R;
612
+ const forceDelete = Rfull.model?.forceDelete;
613
+ if (!forceDelete) {
614
+ return { notify: { title: 'Force-delete not configured', type: 'error' } };
615
+ }
616
+ let n = 0;
617
+ for (const record of records) {
618
+ const id = String(record.id ?? '');
619
+ if (!id)
620
+ continue;
621
+ const allowed = await callPredicate(R.canForceDelete, ctx.user, record);
622
+ if (!allowed)
623
+ continue;
624
+ try {
625
+ await forceDelete(id);
626
+ n++;
627
+ }
628
+ catch { /* skip */ }
629
+ }
630
+ return { notify: { title: `${n} ${labelForCount(R, n)} permanently deleted`, type: 'success' } };
631
+ });
632
+ }
633
+ /**
634
+ * Bulk replicate — calls `R.model.create(...)` once per selected row
635
+ * with the source row's attributes minus PK / soft-delete column /
636
+ * `opts.excludeAttributes`. Optional `opts.beforeReplicaSaved(replica,
637
+ * source)` runs per-row. Rows that throw during create are skipped
638
+ * silently so a single bad row doesn't abort the batch (the user sees
639
+ * the success count on the toast). Visibility delegates to
640
+ * `R.canCreate(user)`.
641
+ *
642
+ * Sibling of `Action.replicate` — same options bag, same strip set,
643
+ * same authorization gate. Stays on the list page (no per-row
644
+ * redirect possible for N rows).
645
+ */
646
+ static bulkReplicate(R, _basePath, opts = {}) {
647
+ return Action.make('bulkReplicate')
648
+ .label('Replicate selected')
649
+ .bulk()
650
+ .confirm(`Replicate the selected ${labelForCount(R, 0)}?`)
651
+ .handler(async (ctx) => {
652
+ const M = R.model;
653
+ if (!M || typeof M.create !== 'function') {
654
+ return { notify: { title: 'Replicate not configured (resource has no model.create)', type: 'error' } };
655
+ }
656
+ const records = ctx.records ?? [];
657
+ const pkCol = M.primaryKey ?? 'id';
658
+ const trashedCol = R.deletedAtColumn ?? 'deletedAt';
659
+ const skip = new Set([pkCol, trashedCol, ...(opts.excludeAttributes ?? [])]);
660
+ let n = 0;
661
+ for (const source of records) {
662
+ if (!source || typeof source !== 'object')
663
+ continue;
664
+ const allowed = await callPredicate(R.canCreate, ctx.user);
665
+ if (!allowed)
666
+ continue;
667
+ let replica = {};
668
+ for (const [k, v] of Object.entries(source)) {
669
+ if (skip.has(k))
670
+ continue;
671
+ replica[k] = v;
672
+ }
673
+ if (opts.beforeReplicaSaved) {
674
+ try {
675
+ replica = await opts.beforeReplicaSaved(replica, source);
676
+ }
677
+ catch {
678
+ continue;
679
+ }
680
+ }
681
+ try {
682
+ await M.create(replica);
683
+ n++;
684
+ }
685
+ catch { /* skip — agg notify shows total */ }
686
+ }
687
+ const defaultTitle = `${n} ${labelForCount(R, n)} replicated`;
688
+ const overrideTitle = opts.getCreatedNotificationTitle
689
+ ? await opts.getCreatedNotificationTitle({ count: n, records })
690
+ : undefined;
691
+ const title = overrideTitle !== undefined ? overrideTitle : defaultTitle;
692
+ return { notify: { title, type: 'success' } };
693
+ })
694
+ .visible(({ user }) => callPredicate(R.canCreate, user));
695
+ }
696
+ // ─── Import / Export factories ────────────────────────────────
697
+ //
698
+ // Pre-built CSV / JSON in/out for any Resource that has `R.model`.
699
+ // `Action.export` walks the configured `R.table()` records handler
700
+ // in pages (so it picks up the active filter/search/sort by default,
701
+ // and stays consistent with what the user is looking at). The bulk
702
+ // variant exports `ctx.records` instead. `Action.import` opens a
703
+ // form-modal with a `FileUpload`, parses the uploaded file, and runs
704
+ // create / upsert through `R.model`.
705
+ //
706
+ // Internals live in `./exportFactory.ts` and `./importFactory.ts`
707
+ // — kept out of this file because they need to import `Table` /
708
+ // field types that themselves import `Action`. Lazy-import inside
709
+ // the handler avoids the cycle (handlers run at request-time, well
710
+ // after module load).
711
+ /** Header-placement export — downloads the table as CSV (default) or
712
+ * JSON. Visibility defaults to `R.canViewAny(user)`. Drop into
713
+ * `headerActions([...])` from inside `Resource.table()`. See
714
+ * `docs/plans/import-export-actions.md` for the full options bag. */
715
+ static export(R, _basePath,
716
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
717
+ opts = {}) {
718
+ return Action.make('export')
719
+ .label('Export')
720
+ .handler(async (ctx) => {
721
+ const ef = await import('./exportFactory.js');
722
+ const tableInst = R.table?.(await loadTableClass());
723
+ if (!tableInst) {
724
+ return { notify: { title: 'Export not configured (resource has no table())', type: 'error' } };
725
+ }
726
+ const cols = ef.resolveExportColumns(opts.columns, R);
727
+ if (cols.length === 0) {
728
+ return { notify: { title: 'Export has no columns', type: 'error' } };
729
+ }
730
+ const maxRows = opts.maxRows ?? 50_000;
731
+ const records = await ef.collectExportRows(tableInst, ctx, opts.scope ?? 'filtered', maxRows, opts.chunkSize);
732
+ if (records.length > maxRows) {
733
+ return { notify: { title: `Export exceeded ${maxRows} rows`, type: 'error' } };
734
+ }
735
+ const rows = records.map(r => ef.buildExportRow(r, cols));
736
+ const format = opts.format ?? 'csv';
737
+ const { body, contentType } = ef.encodeExport(rows, cols, format);
738
+ const filename = typeof opts.filename === 'function'
739
+ ? opts.filename(ctx)
740
+ : (opts.filename ?? ef.defaultExportFilename(R.getSlug(), format));
741
+ return { download: { filename, contentType, body } };
742
+ })
743
+ .visible(({ user }) => callPredicate(R.canViewAny, user));
744
+ }
745
+ /** Bulk-placement export — downloads the rows the user selected via
746
+ * the bulk-select checkboxes. Same options as `Action.export` minus
747
+ * `scope` (always operates on `ctx.records`). Drop into
748
+ * `bulkActions([...])`. */
749
+ static bulkExport(R, _basePath,
750
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
751
+ opts = {}) {
752
+ return Action.make('bulkExport')
753
+ .label('Export selected')
754
+ .bulk()
755
+ .handler(async (ctx) => {
756
+ const ef = await import('./exportFactory.js');
757
+ const cols = ef.resolveExportColumns(opts.columns, R);
758
+ if (cols.length === 0) {
759
+ return { notify: { title: 'Export has no columns', type: 'error' } };
760
+ }
761
+ const records = ctx.records ?? [];
762
+ const maxRows = opts.maxRows ?? 50_000;
763
+ if (records.length > maxRows) {
764
+ return { notify: { title: `Export exceeded ${maxRows} rows`, type: 'error' } };
765
+ }
766
+ const rows = records.map(r => ef.buildExportRow(r, cols));
767
+ const format = opts.format ?? 'csv';
768
+ const { body, contentType } = ef.encodeExport(rows, cols, format);
769
+ const filename = typeof opts.filename === 'function'
770
+ ? opts.filename(ctx)
771
+ : (opts.filename ?? ef.defaultExportFilename(R.getSlug(), format));
772
+ return { download: { filename, contentType, body } };
773
+ })
774
+ .visible(({ user }) => callPredicate(R.canViewAny, user));
775
+ }
776
+ /** Header-placement import — opens a modal with a `FileUpload` (and a
777
+ * Mode select when `upsertBy` is set), parses the uploaded file, and
778
+ * walks each row through `R.model.create` / `R.model.update`.
779
+ * Visibility defaults to `R.canCreate(user)`. Drop into
780
+ * `headerActions([...])` from inside `Resource.table()`. See
781
+ * `docs/plans/import-export-actions.md` for the full options bag. */
782
+ static import(R, _basePath, opts = {}) {
783
+ const upsertable = typeof opts.upsertBy === 'string' && opts.upsertBy.length > 0;
784
+ const a = Action.make('import')
785
+ .label('Import')
786
+ .modalHeading(`Import ${R.label ?? `${R.labelSingular}s`}`)
787
+ .modalSubmitLabel('Import')
788
+ .modalCancelLabel('Cancel')
789
+ .handler(async (ctx) => {
790
+ const M = R.model;
791
+ if (!M || typeof M.create !== 'function') {
792
+ return { notify: { title: 'Import not configured (resource has no model.create)', type: 'error' } };
793
+ }
794
+ if (upsertable && typeof M.update !== 'function') {
795
+ return { notify: { title: 'Upsert import requires model.update', type: 'error' } };
796
+ }
797
+ const fileUrl = String(ctx.values?.['file'] ?? '');
798
+ if (fileUrl.length === 0) {
799
+ return { notify: { title: 'No file uploaded', type: 'error' } };
800
+ }
801
+ const ifac = await import('./importFactory.js');
802
+ let text;
803
+ try {
804
+ const r = await fetch(fileUrl);
805
+ if (!r.ok) {
806
+ return { notify: { title: `Failed to fetch upload (${r.status})`, type: 'error' } };
807
+ }
808
+ text = await r.text();
809
+ }
810
+ catch (err) {
811
+ return { notify: { title: `Failed to read upload: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
812
+ }
813
+ const format = opts.format ?? (fileUrl.toLowerCase().endsWith('.json') ? 'json' : 'csv');
814
+ let rows;
815
+ try {
816
+ rows = ifac.parseImportText(text, format, opts.columns);
817
+ }
818
+ catch (err) {
819
+ return { notify: { title: `Failed to parse ${format.toUpperCase()}: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
820
+ }
821
+ const maxRows = opts.maxRows ?? 10_000;
822
+ if (rows.length > maxRows) {
823
+ return { notify: { title: `Import too large (${rows.length} > ${maxRows})`, type: 'error' } };
824
+ }
825
+ const mode = upsertable && (ctx.values?.['mode'] === 'upsert') ? 'upsert' : 'create';
826
+ const summary = await ifac.runImport(rows, M, mode, opts, ctx);
827
+ return { notify: ifac.buildImportNotification(summary, { upsert: upsertable }) };
828
+ })
829
+ .visible(({ user }) => callPredicate(R.canCreate, user));
830
+ // Build the modal-form schema synchronously. importFactory has no
831
+ // runtime import edge back to Action.ts (only a type-import, erased
832
+ // at compile time), so the top-of-file static import below is
833
+ // cycle-free.
834
+ a.schema(buildImportModalSchema(opts));
835
+ return a;
836
+ }
837
+ // ─── Relation-manager factories (Plan #11 polish) ─────────────
838
+ //
839
+ // Mirror `Action.create / edit / delete` but build URLs under the
840
+ // parent record: `${base}/${parentSlug}/${parentId}/${rel}/...`.
841
+ // Designed to be called inside `RelationManager.static table()` —
842
+ // the page-data builder pipes `RelationManagerContext` into that
843
+ // configurator so users get `basePath`, `parentId`, and the
844
+ // discovered Related resource without threading them by hand.
845
+ //
846
+ // Visibility predicates use `safeManagerPolicy` so the manager's
847
+ // `canX` (when overridden) wins, otherwise falls through to the
848
+ // related Resource's `canX`. Throws absorb as `false`.
849
+ //
850
+ // `:id` template substitution still happens at render time for row
851
+ // context — the same mechanism that drives `Action.edit / delete`.
852
+ // The parent's id is baked into the URL at config time (it's known
853
+ // upfront from `ctx.parentId`), so `:id` unambiguously refers to
854
+ // the row's *child* id.
855
+ /** Relation create-action factory — link to
856
+ * `${base}/${parentSlug}/${parentId}/${relationship}/create`.
857
+ *
858
+ * Visibility delegates to `M.canCreate(user, parentRecord)` (or the
859
+ * related Resource's `canCreate(user)` when the manager hasn't
860
+ * overridden). Drop into `headerActions([...])` from inside
861
+ * `RelationManager.table(table, ctx)`.
862
+ */
863
+ static relationCreate(M, ctx) {
864
+ const labelSingular = M.getLabelSingular();
865
+ return Action.make('create')
866
+ .label(`New ${labelSingular}`)
867
+ .href(`${relationUrlPrefix(ctx)}/create`)
868
+ .visible(({ user }) => {
869
+ // M2M managers don't have a per-pivot-row create surface — the
870
+ // related record is created via its own Resource, then attached
871
+ // via `relationAttach`. Auto-hide so dropping this factory into
872
+ // any M2M manager (belongsToMany / morphToMany / morphedByMany)
873
+ // is a no-op (visible=false) instead of a 404-on-click foot-gun.
874
+ if (isM2MMode(ctx.mode))
875
+ return false;
876
+ return safeManagerPolicy(M, 'canCreate', ctx.related, user, ctx.parentRecord);
877
+ });
878
+ }
879
+ /** Relation edit-action factory — link to
880
+ * `${base}/${parentSlug}/${parentId}/${relationship}/${recordId ?? ':id'}/edit`.
881
+ *
882
+ * Same `recordId` semantics as `Action.edit`: omit for row context
883
+ * so the renderer substitutes `:id` per row; pass explicitly when
884
+ * building actions for a single-record context. Visibility delegates
885
+ * to `M.canEdit(user, child, parentRecord)` with fall-through to the
886
+ * related Resource's `canEdit(user, record)`.
887
+ */
888
+ static relationEdit(M, ctx, recordId) {
889
+ const id = recordId ?? ':id';
890
+ return Action.make('edit')
891
+ .label('Edit')
892
+ .href(`${relationUrlPrefix(ctx)}/${id}/edit`)
893
+ .visible(({ user, record }) => {
894
+ // M2M: per-pivot-row "edit" doesn't exist; users edit the
895
+ // related record via its own Resource. Auto-hide for every M2M
896
+ // mode (belongsToMany / morphToMany / morphedByMany).
897
+ if (isM2MMode(ctx.mode))
898
+ return false;
899
+ return safeManagerPolicy(M, 'canEdit', ctx.related, user, ctx.parentRecord, record);
900
+ });
901
+ }
902
+ /** Relation delete-action factory — POST to
903
+ * `${base}/${parentSlug}/${parentId}/${relationship}/${recordId ?? ':id'}/delete`,
904
+ * destructive style with a labeled confirmation. Visibility delegates
905
+ * to `M.canDelete(user, child, parentRecord)` with fall-through to the
906
+ * related Resource's `canDelete(user, record)`.
907
+ */
908
+ static relationDelete(M, ctx, recordId) {
909
+ const id = recordId ?? ':id';
910
+ const singular = M.getLabelSingular().toLowerCase();
911
+ return Action.make('delete')
912
+ .label('Delete')
913
+ .destructive()
914
+ .method('post')
915
+ .action(`${relationUrlPrefix(ctx)}/${id}/delete`)
916
+ .confirm(`Delete this ${singular}?`)
917
+ .visible(async ({ user, record }) => {
918
+ // M2M: "delete" of the related record is destructive in a way
919
+ // that "detach" isn't — surface only `relationDetach` on every
920
+ // M2M manager (belongsToMany / morphToMany / morphedByMany).
921
+ // Users who genuinely want to delete the related record reach
922
+ // for `Action.delete(R)` on the related Resource instead.
923
+ if (isM2MMode(ctx.mode))
924
+ return false;
925
+ if (ctx.related?.softDeletes && isTrashed(record, ctx.related))
926
+ return false;
927
+ return safeManagerPolicy(M, 'canDelete', ctx.related, user, ctx.parentRecord, record);
928
+ });
929
+ }
930
+ /**
931
+ * Plan #13 polish — Restore factory for relation managers. POSTs to
932
+ * `${base}/${parentSlug}/${parentId}/${relationship}/${recordId ?? ':id'}/restore`,
933
+ * success-styled, no confirm prompt. Auto-hides on live (non-trashed)
934
+ * rows AND when `M.canRestore` (or related Resource fall-through)
935
+ * denies. Drop into `recordActions([...])` from `RelationManager.table(table, ctx)`.
936
+ */
937
+ static relationRestore(M, ctx, recordId) {
938
+ const id = recordId ?? ':id';
939
+ return Action.make('restore')
940
+ .label('Restore')
941
+ .color('success')
942
+ .method('post')
943
+ .action(`${relationUrlPrefix(ctx)}/${id}/restore`)
944
+ .visible(async ({ user, record }) => {
945
+ if (!ctx.related?.softDeletes)
946
+ return false;
947
+ if (!isTrashed(record, ctx.related))
948
+ return false;
949
+ return safeManagerPolicy(M, 'canRestore', ctx.related, user, ctx.parentRecord, record);
950
+ });
951
+ }
952
+ /**
953
+ * Plan #13 polish — Force-delete factory for relation managers. POSTs
954
+ * to `${base}/${parentSlug}/${parentId}/${relationship}/${recordId ?? ':id'}/force-delete`,
955
+ * destructive style with a permanence-aware confirmation. Auto-hides on
956
+ * live (non-trashed) rows and when policy denies.
957
+ */
958
+ static relationForceDelete(M, ctx, recordId) {
959
+ const id = recordId ?? ':id';
960
+ const singular = M.getLabelSingular().toLowerCase();
961
+ return Action.make('forceDelete')
962
+ .label('Delete forever')
963
+ .destructive()
964
+ .method('post')
965
+ .action(`${relationUrlPrefix(ctx)}/${id}/force-delete`)
966
+ .confirm(`Permanently delete this ${singular}? This cannot be undone.`)
967
+ .visible(async ({ user, record }) => {
968
+ if (!ctx.related?.softDeletes)
969
+ return false;
970
+ if (!isTrashed(record, ctx.related))
971
+ return false;
972
+ return safeManagerPolicy(M, 'canForceDelete', ctx.related, user, ctx.parentRecord, record);
973
+ });
974
+ }
975
+ // ─── Relation-manager replicate factories ─────────────────
976
+ //
977
+ // Sibling of `Action.replicate / bulkReplicate` scoped to a
978
+ // RelationManager. Operates on the **related** Resource's model and
979
+ // **forces** the parent attachment back onto the replica:
980
+ //
981
+ // - `hasMany` — re-stamps `<foreignKey> = ctx.parentId` from the
982
+ // parent's `static relations[name]` descriptor. Defends against a
983
+ // tampered POST body (or a source row loaded from a different
984
+ // parent's children) silently re-attaching the new row to a
985
+ // different parent.
986
+ // - `morphMany` — re-stamps `<morphName>Id` + `<morphName>Type` via
987
+ // `computeMorphPayload(parentRecord, descriptor)`, same auto-fill
988
+ // the relation-create POST handler uses on the create form.
989
+ // - M2M (`belongsToMany / morphToMany / morphedByMany`) — auto-hides.
990
+ // Replicate doesn't fit pivot semantics; users create the related
991
+ // record via its own Resource, then attach via `relationAttach`.
992
+ // - `morphTo` — auto-hides. Child-side polymorphic relations don't
993
+ // have a single owner to pin to (the row's existing morph cols
994
+ // already point somewhere; cloning is the user's job, not ours).
995
+ //
996
+ // Both factories dispatch through the manager-scoped
997
+ // `_action/:actionName` route already wired in `routes.ts`. The route
998
+ // resolves `ctx.record` (and `ctx.records` for bulk) via
999
+ // `Related.model.find(id)`, and stamps `ctx.relation = { parent,
1000
+ // parentId, relationship }` so the handlers can read the live parent
1001
+ // without re-loading.
1002
+ //
1003
+ // Visibility delegates to `safeManagerPolicy(M, 'canCreate', Related,
1004
+ // user, parentRecord)` — the manager's `canCreate` (when overridden)
1005
+ // wins, otherwise falls through to the related Resource's `canCreate`.
1006
+ /**
1007
+ * Relation row-replicate factory. Clones the row's child record
1008
+ * inside the manager's parent scope.
1009
+ *
1010
+ * Strips the related model's primary key, soft-delete column, and
1011
+ * `opts.excludeAttributes`. Re-applies the parent attachment columns
1012
+ * after the strip + before the optional `beforeReplicaSaved` hook,
1013
+ * so user code can still mutate non-FK fields without accidentally
1014
+ * unlinking the replica.
1015
+ *
1016
+ * On success the manager-scoped route falls back to the manager
1017
+ * list URL (`${base}/${parentSlug}/${parentId}/${relationship}`)
1018
+ * because no explicit `redirect` is returned — same default as the
1019
+ * other handler-style relation factories.
1020
+ *
1021
+ * `recordId` kept in the signature for parity with the rest of the
1022
+ * relation factory family. The dispatcher resolves the source row
1023
+ * from the request body, so it isn't referenced here.
1024
+ */
1025
+ static relationReplicate(M, ctx, recordId, opts = {}) {
1026
+ void recordId;
1027
+ return Action.make('relationReplicate')
1028
+ .label('Replicate')
1029
+ .row()
1030
+ .handler(async (hctx) => {
1031
+ const result = await runRelationReplicateRow(M, ctx, hctx, opts);
1032
+ return result;
1033
+ })
1034
+ .visible(({ user }) => {
1035
+ if (isM2MMode(ctx.mode) || ctx.mode === 'morphTo')
1036
+ return false;
1037
+ return safeManagerPolicy(M, 'canCreate', ctx.related, user, ctx.parentRecord);
1038
+ });
1039
+ }
1040
+ /**
1041
+ * Bulk sibling — replicates every selected child row inside the
1042
+ * manager's parent scope. Same strip + force-pin pipeline applied
1043
+ * per row. Per-row `safeManagerPolicy(M, 'canCreate', …)` runs
1044
+ * inside the loop so a partially-permitted selection still proceeds
1045
+ * for the rows that pass. Rows that throw are skipped silently —
1046
+ * the toast count reflects only successful creates.
1047
+ */
1048
+ static relationBulkReplicate(M, ctx, opts = {}) {
1049
+ return Action.make('relationBulkReplicate')
1050
+ .label('Replicate selected')
1051
+ .bulk()
1052
+ .confirm(`Replicate the selected ${M.getLabel().toLowerCase()}?`)
1053
+ .handler(async (hctx) => {
1054
+ const Related = ctx.related;
1055
+ if (!Related?.model || typeof Related.model.create !== 'function') {
1056
+ return { notify: { title: 'Replicate not configured (related Resource has no model.create)', type: 'error' } };
1057
+ }
1058
+ const records = hctx.records ?? [];
1059
+ let n = 0;
1060
+ for (const source of records) {
1061
+ if (!source || typeof source !== 'object')
1062
+ continue;
1063
+ const allowed = await safeManagerPolicy(M, 'canCreate', Related, hctx.user, ctx.parentRecord);
1064
+ if (!allowed)
1065
+ continue;
1066
+ try {
1067
+ await persistRelationReplica(M, ctx, source, opts);
1068
+ n++;
1069
+ }
1070
+ catch { /* skip — agg notify shows total */ }
1071
+ }
1072
+ const labelPlural = M.getLabel().toLowerCase();
1073
+ const labelSingular = M.getLabelSingular().toLowerCase();
1074
+ const defaultTitle = `${n} ${n === 1 ? labelSingular : labelPlural} replicated`;
1075
+ const overrideTitle = opts.getCreatedNotificationTitle
1076
+ ? await opts.getCreatedNotificationTitle({ count: n, records })
1077
+ : undefined;
1078
+ const title = overrideTitle !== undefined ? overrideTitle : defaultTitle;
1079
+ return {
1080
+ notify: { title, type: 'success' },
1081
+ };
1082
+ })
1083
+ .visible(({ user }) => {
1084
+ if (isM2MMode(ctx.mode) || ctx.mode === 'morphTo')
1085
+ return false;
1086
+ return safeManagerPolicy(M, 'canCreate', ctx.related, user, ctx.parentRecord);
1087
+ });
1088
+ }
1089
+ // ─── M2M relation factories ───────────────────────────────
1090
+ //
1091
+ // Sibling of `relationCreate / Edit / Delete` for every M2M mode
1092
+ // (`belongsToMany`, `morphToMany` (owning polymorphic side),
1093
+ // `morphedByMany` (inverse polymorphic side)). All three modes share
1094
+ // the same `attach` / `detach` / `sync` accessor surface — the rudder
1095
+ // ORM stamps + filters the polymorphic discriminator on the morph
1096
+ // variants automatically, so pilotiq's pivot factories are mode-agnostic
1097
+ // beyond the visibility gate.
1098
+ //
1099
+ // Three factories: `relationAttach` (header, modal-form picker →
1100
+ // POST `_action/relationAttach`), `relationDetach` (row, direct POST
1101
+ // to `_detach/:childId`), `relationBulkDetach` (bulk, handler-
1102
+ // dispatched). The first and third route through the manager-scoped
1103
+ // `_action/:actionName` endpoint (added in routes.ts) so handlers
1104
+ // see `ctx.relation = { parent, parentId, relationship }`.
1105
+ //
1106
+ // All three auto-hide outside any M2M mode so dropping a factory into
1107
+ // a non-M2M manager is a no-op (visible=false) instead of a confusing
1108
+ // 404.
1109
+ /** Header-placement attach factory — opens a modal with a SelectField
1110
+ * listing related records that aren't already attached, and POSTs the
1111
+ * selected id to the manager's `_action/relationAttach` endpoint.
1112
+ *
1113
+ * Visibility delegates to `M.canAttach(user, parentRecord)` AND
1114
+ * guards against being dropped into a non-M2M manager. */
1115
+ static relationAttach(M, ctx) {
1116
+ const labelSingular = M.getLabelSingular();
1117
+ const a = Action.make('relationAttach')
1118
+ .label(`Attach ${labelSingular}`)
1119
+ .header()
1120
+ .modalHeading(`Attach ${labelSingular}`)
1121
+ .modalSubmitLabel('Attach')
1122
+ .modalCancelLabel('Cancel')
1123
+ .handler(async (hctx) => {
1124
+ const rel = hctx.relation;
1125
+ if (!rel) {
1126
+ return { notify: { title: 'Attach handler missing parent context — manager-scoped _action route not wired', type: 'error' } };
1127
+ }
1128
+ const Related = ctx.related;
1129
+ if (!Related?.model) {
1130
+ return { notify: { title: 'Cannot attach: related Resource has no model', type: 'error' } };
1131
+ }
1132
+ const idStr = String(hctx.values?.['_attachId'] ?? '');
1133
+ if (idStr.length === 0) {
1134
+ return { notify: { title: 'Pick a record to attach', type: 'error' } };
1135
+ }
1136
+ const accessor = resolveM2MAccessor(rel.parent, rel.relationship);
1137
+ if (!accessor || typeof accessor.attach !== 'function') {
1138
+ return { notify: { title: `Pivot accessor missing on ${rel.relationship} — wrong relation type or ORM version?`, type: 'error' } };
1139
+ }
1140
+ try {
1141
+ await accessor.attach([idStr]);
1142
+ }
1143
+ catch (err) {
1144
+ return { notify: { title: `Attach failed: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
1145
+ }
1146
+ return { notify: { title: `${labelSingular} attached`, type: 'success' } };
1147
+ })
1148
+ .visible(({ user }) => {
1149
+ if (!isM2MMode(ctx.mode))
1150
+ return false;
1151
+ return safeManagerPolicy(M, 'canAttach', ctx.related, user, ctx.parentRecord);
1152
+ });
1153
+ // Build the modal-form schema only when this is actually an M2M
1154
+ // manager — non-M2M drops keep the action hidden via the visibility
1155
+ // predicate, but still need a schema-less Action so the meta walker
1156
+ // doesn't blow up. Static import is fine: `attachFactory` only
1157
+ // depends on `SelectField` + ORM helpers, no cycle back to Action.
1158
+ if (isM2MMode(ctx.mode) && ctx.related?.model) {
1159
+ a.schema(buildAttachModalSchema({
1160
+ Related: ctx.related,
1161
+ relationship: ctx.relationship,
1162
+ recordTitleAttr: M.getRecordTitleAttribute() ?? ctx.related.recordTitleAttribute,
1163
+ labelSingular,
1164
+ }));
1165
+ }
1166
+ return a;
1167
+ }
1168
+ /** Row-placement detach factory — POSTs to
1169
+ * `${base}/${parentSlug}/${parentId}/${relationship}/${recordId ?? ':id'}/_detach`,
1170
+ * destructive style with a confirmation prompt that says "Detach"
1171
+ * (not "Delete") so users understand the target record stays.
1172
+ * Visibility delegates to `M.canDetach`. */
1173
+ static relationDetach(M, ctx, recordId) {
1174
+ const id = recordId ?? ':id';
1175
+ const singular = M.getLabelSingular().toLowerCase();
1176
+ return Action.make('relationDetach')
1177
+ .label('Detach')
1178
+ .destructive()
1179
+ .method('post')
1180
+ .action(`${relationUrlPrefix(ctx)}/${id}/_detach`)
1181
+ .confirm(`Detach this ${singular}? The ${singular} record stays in place; only the link is removed.`)
1182
+ .visible(async ({ user, record }) => {
1183
+ if (!isM2MMode(ctx.mode))
1184
+ return false;
1185
+ return safeManagerPolicy(M, 'canDetach', ctx.related, user, ctx.parentRecord, record);
1186
+ });
1187
+ }
1188
+ /** Bulk-placement bulk-detach factory — handler-dispatched. Calls
1189
+ * `parent.related(rel).detach(ids)` for the selected rows. Visibility
1190
+ * delegates to `M.canAttach` (acts like a "manager admin" gate; we
1191
+ * intentionally don't enforce per-row `canDetach` on the visibility
1192
+ * side because the bulk button needs to be visible before the user
1193
+ * has selected anything — per-row gating happens inside the handler). */
1194
+ static relationBulkDetach(M, ctx) {
1195
+ const labelPlural = M.getLabel().toLowerCase();
1196
+ return Action.make('relationBulkDetach')
1197
+ .label('Detach selected')
1198
+ .destructive()
1199
+ .bulk()
1200
+ .confirm(`Detach the selected ${labelPlural}? The records stay in place; only the links are removed.`)
1201
+ .handler(async (hctx) => {
1202
+ const rel = hctx.relation;
1203
+ if (!rel) {
1204
+ return { notify: { title: 'Bulk-detach handler missing parent context — manager-scoped _action route not wired', type: 'error' } };
1205
+ }
1206
+ const records = hctx.records ?? [];
1207
+ const ids = [];
1208
+ for (const r of records) {
1209
+ const id = String(r.id ?? '');
1210
+ if (!id)
1211
+ continue;
1212
+ const allowed = await safeManagerPolicy(M, 'canDetach', ctx.related, hctx.user, ctx.parentRecord, r);
1213
+ if (!allowed)
1214
+ continue;
1215
+ ids.push(id);
1216
+ }
1217
+ if (ids.length === 0) {
1218
+ return { notify: { title: 'Nothing to detach (no permitted rows)', type: 'warning' } };
1219
+ }
1220
+ const accessor = resolveM2MAccessor(rel.parent, rel.relationship);
1221
+ if (!accessor || typeof accessor.detach !== 'function') {
1222
+ return { notify: { title: `Pivot accessor missing on ${rel.relationship} — wrong relation type or ORM version?`, type: 'error' } };
1223
+ }
1224
+ try {
1225
+ await accessor.detach(ids);
1226
+ }
1227
+ catch (err) {
1228
+ return { notify: { title: `Bulk detach failed: ${err instanceof Error ? err.message : String(err)}`, type: 'error' } };
1229
+ }
1230
+ return { notify: { title: `${ids.length} ${labelPlural} detached`, type: 'success' } };
1231
+ })
1232
+ .visible(({ user }) => {
1233
+ if (!isM2MMode(ctx.mode))
1234
+ return false;
1235
+ // Bulk gate uses canAttach as a stand-in for "manager admin" —
1236
+ // per-row canDetach is enforced inside the handler.
1237
+ return safeManagerPolicy(M, 'canAttach', ctx.related, user, ctx.parentRecord);
1238
+ });
1239
+ }
1240
+ label(l) { this._label = l; return this; }
1241
+ icon(i) { this._icon = i; return this; }
1242
+ // ─── Placement ────────────────────────────────────────
1243
+ placement(p) { this._placement = p; return this; }
1244
+ inline() { return this.placement('inline'); }
1245
+ row() { return this.placement('row'); }
1246
+ bulk() { return this.placement('bulk'); }
1247
+ header() { return this.placement('header'); }
1248
+ // ─── Behavior ─────────────────────────────────────────
1249
+ destructive(v = true) {
1250
+ this._destructive = v;
1251
+ if (v && this._color === undefined)
1252
+ this._color = 'destructive';
1253
+ return this;
1254
+ }
1255
+ /** Set the visual color. `destructive` is also set by `.destructive()`. */
1256
+ color(c) { this._color = c; return this; }
1257
+ /** Set the size preset (sm | md | lg). Default is `md`. */
1258
+ size(s) { this._size = s; return this; }
1259
+ /** Hover tooltip. Wraps the button in a Tooltip primitive. */
1260
+ tooltip(t) { this._tooltip = t; return this; }
1261
+ /** Outlined trigger style — border + transparent bg instead of solid color. */
1262
+ outlined(v = true) { this._outlined = v; return this; }
1263
+ /** Icon-only trigger style. Renders a square button with just the icon;
1264
+ * the label is used as `aria-label`. Requires `.icon()` to be set. */
1265
+ iconButton(v = true) { this._iconOnly = v; return this; }
1266
+ /** Show a small badge on the trigger (e.g. unread count). */
1267
+ badge(value) { this._badge = value; return this; }
1268
+ /** Optional color class for the badge (e.g. 'bg-emerald-500'). */
1269
+ badgeColor(c) { this._badgeColor = c; return this; }
1270
+ // ─── Conditional visibility / disabled ───────────────
1271
+ /** Show the action only when `rule` is truthy. Pair with a function for
1272
+ * record-aware visibility (e.g. `({ record }) => !record.archived`).
1273
+ * Row-placement actions are evaluated per-row at table-load time;
1274
+ * other placements are evaluated at schema-resolve time with the
1275
+ * page-level context. */
1276
+ visible(rule) { this._visible = rule; return this; }
1277
+ /** Inverse of `visible` — hide the action when `rule` is truthy.
1278
+ * Both rules combine via AND: visible if `visible !== false` AND
1279
+ * `hidden !== true`. */
1280
+ hidden(rule) { this._hidden = rule; return this; }
1281
+ /** Disable (render greyed-out and skip dispatch) when `rule` is truthy.
1282
+ * Disabled actions still appear in the UI, unlike hidden ones. */
1283
+ disabled(rule) { this._isDisabled = rule; return this; }
1284
+ /** Policy-style alias for `.visible(fn)` — semantically identical
1285
+ * but reads better when guarding by user permissions. */
1286
+ authorize(rule) { return this.visible(rule); }
1287
+ /** Evaluate the visibility / disabled rules with the given context.
1288
+ * Defaults: visible = true, disabled = false. Both `visible` and
1289
+ * `hidden` are folded in: `visible: visible !== false && hidden !== true`.
1290
+ *
1291
+ * Async to support Plan #10 — visibility rules can return Promise<bool>
1292
+ * (for `Resource.canX(user, record)` integration). Throwing rules are
1293
+ * treated as fail-closed (`visible: false` / `disabled: true`). */
1294
+ async evaluate(ctx = {}) {
1295
+ const evalRule = async (rule, fallback) => {
1296
+ if (rule === undefined)
1297
+ return fallback;
1298
+ if (typeof rule !== 'function')
1299
+ return rule;
1300
+ try {
1301
+ return await rule(ctx);
1302
+ }
1303
+ catch {
1304
+ // Fail closed — a throwing rule shouldn't accidentally show a
1305
+ // destructive action.
1306
+ return !fallback;
1307
+ }
1308
+ };
1309
+ const [visibleRaw, hiddenRaw, disabledRaw] = await Promise.all([
1310
+ evalRule(this._visible, true),
1311
+ evalRule(this._hidden, false),
1312
+ evalRule(this._isDisabled, false),
1313
+ ]);
1314
+ return {
1315
+ visible: visibleRaw && !hiddenRaw,
1316
+ disabled: disabledRaw,
1317
+ };
1318
+ }
1319
+ /** True when any visibility / hidden / disabled rule is set. Useful for
1320
+ * the resolver to know whether per-row evaluation is needed for a
1321
+ * row-placement action. */
1322
+ hasVisibilityRules() {
1323
+ return this._visible !== undefined || this._hidden !== undefined || this._isDisabled !== undefined;
1324
+ }
1325
+ /**
1326
+ * Prompt the user before running the handler. Pass a string for a simple
1327
+ * "are you sure?" message, or an object for full control.
1328
+ */
1329
+ confirm(prompt) {
1330
+ this._confirm = typeof prompt === 'string' ? { message: prompt } : prompt;
1331
+ return this;
1332
+ }
1333
+ /**
1334
+ * Server-side handler. Two shapes:
1335
+ *
1336
+ * - **Closure** — `handler(async ctx => …)`. Dispatched against the
1337
+ * current page's `_action/:name` endpoint. Closures don't survive
1338
+ * serialization, so they can't ride a persisted notification —
1339
+ * `Notification.toDatabase()` rejects them with a clear error.
1340
+ *
1341
+ * - **Registry key** — `handler('archive-project')`. Looked up against
1342
+ * `Pilotiq.notificationHandlers({…})` at request time. Round-trips
1343
+ * through a `Notification`'s `data.actions` JSON column, so this is
1344
+ * the path to take when an action lives on a row that may be
1345
+ * clicked days later.
1346
+ *
1347
+ * Mutually exclusive — setting one clears the other.
1348
+ */
1349
+ handler(fnOrName) {
1350
+ if (typeof fnOrName === 'string') {
1351
+ this._handlerName = fnOrName;
1352
+ delete this._handler;
1353
+ }
1354
+ else {
1355
+ this._handler = fnOrName;
1356
+ delete this._handlerName;
1357
+ }
1358
+ return this;
1359
+ }
1360
+ /**
1361
+ * Per-fire context for registry-handler dispatch. JSON-serializable
1362
+ * keys only — values flow through the notification's `data.actions`
1363
+ * column and arrive on the handler's `ctx.payload`.
1364
+ *
1365
+ * Action.make('archive')
1366
+ * .handler('archive-project')
1367
+ * .payload({ projectId: 123 })
1368
+ */
1369
+ payload(data) {
1370
+ this._payload = data;
1371
+ return this;
1372
+ }
1373
+ /**
1374
+ * Filament-style chain modifier — when this action lives inside a
1375
+ * `Notification.actions([…])` slot, firing it also flips the
1376
+ * notification's `read_at`. No-op for actions used outside the
1377
+ * notification context (Resource actions, etc).
1378
+ *
1379
+ * Action.make('view').url('/projects/123').markAsRead()
1380
+ *
1381
+ * On url/post actions the bell client fires the read POST as a
1382
+ * client-side side-effect *before* navigating/submitting; on
1383
+ * registry-handler actions the route flips `read_at` server-side
1384
+ * after the handler runs (one round-trip, not two).
1385
+ */
1386
+ markAsRead(v = true) {
1387
+ this._markAsReadOnFire = v;
1388
+ return this;
1389
+ }
1390
+ /**
1391
+ * Open the action's url in a new tab. Honored by the notification
1392
+ * action-strip renderers; equivalent to `target="_blank"` on the
1393
+ * underlying anchor.
1394
+ */
1395
+ openUrlInNewTab(v = true) {
1396
+ this._openUrlInNewTab = v;
1397
+ return this;
1398
+ }
1399
+ // ─── Modal / form-modal action ────────────────────────
1400
+ /**
1401
+ * Attach a form schema that opens in a modal Dialog when the action is
1402
+ * triggered. The submitted values flow through validation + coercion
1403
+ * server-side and arrive on the handler's `ctx.values`. Triggers modal
1404
+ * chrome (heading / submit button / cancel button) if not configured
1405
+ * via the other modal builders below.
1406
+ */
1407
+ schema(elements) {
1408
+ this._children = elements;
1409
+ this._hasModal = true;
1410
+ return this;
1411
+ }
1412
+ modalHeading(s) { this._modalHeading = s; this._hasModal = true; return this; }
1413
+ modalDescription(s) { this._modalDescription = s; this._hasModal = true; return this; }
1414
+ modalSubmitLabel(s) { this._modalSubmitLabel = s; this._hasModal = true; return this; }
1415
+ modalCancelLabel(s) { this._modalCancelLabel = s; this._hasModal = true; return this; }
1416
+ /** Filament v5 alias for `modalSubmitLabel`. Reads more naturally
1417
+ * alongside `modalCancelActionLabel` when both are set. */
1418
+ modalSubmitActionLabel(s) { return this.modalSubmitLabel(s); }
1419
+ /** Filament v5 alias for `modalCancelLabel`. */
1420
+ modalCancelActionLabel(s) { return this.modalCancelLabel(s); }
1421
+ modalIcon(i) { this._modalIcon = i; this._hasModal = true; return this; }
1422
+ modalIconColor(c) {
1423
+ this._modalIconColor = c;
1424
+ this._hasModal = true;
1425
+ return this;
1426
+ }
1427
+ modalWidth(w) { this._modalWidth = w; this._hasModal = true; return this; }
1428
+ modalAlignment(a) {
1429
+ this._modalAlignment = a;
1430
+ this._hasModal = true;
1431
+ return this;
1432
+ }
1433
+ slideOver(v = true) { this._slideOver = v; this._hasModal = true; return this; }
1434
+ /**
1435
+ * Disable / re-enable closing the modal by clicking outside the popup.
1436
+ * Default: enabled. Calling without an arg disables (matches Filament's
1437
+ * `->closeModalByClickingAway(false)` shape — most uses are to gate
1438
+ * accidental dismissal of important modals).
1439
+ */
1440
+ closeModalByClickingAway(v = false) {
1441
+ this._closeModalByClickingAway = v;
1442
+ this._hasModal = true;
1443
+ return this;
1444
+ }
1445
+ /**
1446
+ * Disable / re-enable closing the modal with the Escape key. Default:
1447
+ * enabled. Same shape as `closeModalByClickingAway`. Useful when a
1448
+ * partially-completed multi-step modal would lose work on a stray Esc.
1449
+ */
1450
+ closeModalByEscaping(v = false) {
1451
+ this._closeModalByEscaping = v;
1452
+ this._hasModal = true;
1453
+ return this;
1454
+ }
1455
+ /** Sticky header inside the modal body. Useful when the body scrolls
1456
+ * past the heading on long forms. Default: off. */
1457
+ stickyModalHeader(v = true) {
1458
+ this._stickyModalHeader = v;
1459
+ this._hasModal = true;
1460
+ return this;
1461
+ }
1462
+ /** Sticky footer inside the modal body. Pairs naturally with
1463
+ * `stickyModalHeader` on long forms — keeps the Submit / Cancel
1464
+ * buttons visible while the user scrolls. Default: off. */
1465
+ stickyModalFooter(v = true) {
1466
+ this._stickyModalFooter = v;
1467
+ this._hasModal = true;
1468
+ return this;
1469
+ }
1470
+ /**
1471
+ * Override the default autofocus behaviour. `true` focuses the first
1472
+ * form input on mount (or the submit button when there is no form);
1473
+ * `false` disables autofocus entirely. Omit to keep the legacy default
1474
+ * (submit button autofocuses for confirm-only modals).
1475
+ */
1476
+ modalAutofocus(v = true) {
1477
+ this._modalAutofocus = v;
1478
+ this._hasModal = true;
1479
+ return this;
1480
+ }
1481
+ /** Render an X close button in the top-right corner of the popup.
1482
+ * Default: off (the Cancel button in the footer is the documented
1483
+ * affordance). Useful for slide-over panels where the footer is
1484
+ * far from the top of the viewport. */
1485
+ modalCloseButton(v = true) {
1486
+ this._modalCloseButton = v;
1487
+ this._hasModal = true;
1488
+ return this;
1489
+ }
1490
+ // ─── Link / form modes ────────────────────────────────
1491
+ /**
1492
+ * Render this action as a link to `url`. Mutually exclusive with
1493
+ * `.method()` — setting `href` clears any prior method/action URL.
1494
+ */
1495
+ href(url) {
1496
+ this._href = url;
1497
+ delete this._method;
1498
+ delete this._actionUrl;
1499
+ return this;
1500
+ }
1501
+ /**
1502
+ * Sugar alias for `.href(url)` — matches Filament's `->url(...)` API
1503
+ * and reads more naturally inside `Notification.actions([…])`.
1504
+ */
1505
+ url(href) { return this.href(href); }
1506
+ /**
1507
+ * Render this action as a form-style submit button using `method`. Pair
1508
+ * with `.action(url)` to set the form's action URL — falls back to the
1509
+ * current page URL otherwise.
1510
+ */
1511
+ method(m) {
1512
+ this._method = m;
1513
+ delete this._href;
1514
+ return this;
1515
+ }
1516
+ /** Form action URL — only meaningful when `.method()` is set. */
1517
+ action(url) {
1518
+ this._actionUrl = url;
1519
+ delete this._href;
1520
+ return this;
1521
+ }
1522
+ /**
1523
+ * Render-time URL the client should POST to when invoking this
1524
+ * action's handler. Set by the route registrar — users don't normally
1525
+ * call this directly. Format: `${pageUrl}/_action/${action.name}`.
1526
+ */
1527
+ dispatchUrl(url) {
1528
+ this._dispatchUrl = url;
1529
+ return this;
1530
+ }
1531
+ /**
1532
+ * Mark this action as the form-submit button for its enclosing
1533
+ * `<form>`. Renders as `<button type="submit">` and relies on the form
1534
+ * itself to carry `action` + `method`. Mutually exclusive with
1535
+ * `.href()` / `.method()` / handler-style.
1536
+ */
1537
+ submit() {
1538
+ this._submit = true;
1539
+ delete this._href;
1540
+ delete this._method;
1541
+ delete this._actionUrl;
1542
+ delete this._dispatchUrl;
1543
+ return this;
1544
+ }
1545
+ /**
1546
+ * Target a specific `<form id="">` when this is a submit action — uses
1547
+ * the HTML `form` attribute so the button can submit a form it doesn't
1548
+ * live inside. Required when the submit action sits in the page
1549
+ * header (outside the form's DOM subtree).
1550
+ */
1551
+ form(formId) {
1552
+ this._formTarget = formId;
1553
+ return this;
1554
+ }
1555
+ /**
1556
+ * Attach a `name`+`value` pair to a submit button so it round-trips
1557
+ * through the form body when this specific button is clicked. Wires
1558
+ * the "Create & create another" pattern: the secondary submit posts
1559
+ * `{ _continueCreate: '1' }` and the server routes the redirect back
1560
+ * to the create page. Browsers natively only include the clicked
1561
+ * submit button's name/value in `FormData`; the FormRenderer threads
1562
+ * `event.submitter` into the `FormData` constructor to preserve that.
1563
+ */
1564
+ formField(name, value = '1') {
1565
+ this._formField = { name, value };
1566
+ return this;
1567
+ }
1568
+ // ─── Getters ──────────────────────────────────────────
1569
+ getLabel() { return this._label; }
1570
+ getPlacement() { return this._placement; }
1571
+ isDestructive() { return this._destructive; }
1572
+ getHandler() { return this._handler; }
1573
+ /** Registry key set by `.handler(string)`; undefined when the handler
1574
+ * is a closure (or unset). Mutually exclusive with `getHandler()`. */
1575
+ getHandlerName() { return this._handlerName; }
1576
+ /** Per-fire context set by `.payload({…})`. Empty `{}` when unset
1577
+ * (callers can spread without a null check). */
1578
+ getPayload() { return this._payload ?? {}; }
1579
+ /** Filament chain modifier — true when `.markAsRead()` was called.
1580
+ * Read by `Notification.actions([…])` serializer; ignored elsewhere. */
1581
+ isMarkAsReadOnFire() { return this._markAsReadOnFire; }
1582
+ /** Honored by the notification action-strip renderers; equivalent to
1583
+ * `target="_blank"` on the underlying anchor. */
1584
+ isOpenUrlInNewTab() { return this._openUrlInNewTab; }
1585
+ getHref() { return this._href; }
1586
+ getMethod() { return this._method; }
1587
+ getActionUrl() { return this._actionUrl; }
1588
+ getDispatchUrl() { return this._dispatchUrl; }
1589
+ isSubmit() { return this._submit; }
1590
+ getFormTarget() { return this._formTarget; }
1591
+ getFormField() { return this._formField; }
1592
+ hasModal() { return this._hasModal; }
1593
+ /** Schema fields stored as children; `getChildren()` returns the same. */
1594
+ getSchema() { return this._children ?? []; }
1595
+ getColor() { return this._color; }
1596
+ getIcon() { return this._icon; }
1597
+ getSize() { return this._size; }
1598
+ getTooltip() { return this._tooltip; }
1599
+ isOutlined() { return this._outlined; }
1600
+ isIconOnly() { return this._iconOnly; }
1601
+ getBadge() { return this._badge; }
1602
+ // ─── Element contract ────────────────────────────────
1603
+ getType() { return 'action'; }
1604
+ toMeta() {
1605
+ const modal = this._hasModal ? {
1606
+ ...(this._modalHeading !== undefined ? { heading: this._modalHeading } : {}),
1607
+ ...(this._modalDescription !== undefined ? { description: this._modalDescription } : {}),
1608
+ ...(this._modalSubmitLabel !== undefined ? { submitLabel: this._modalSubmitLabel } : {}),
1609
+ ...(this._modalCancelLabel !== undefined ? { cancelLabel: this._modalCancelLabel } : {}),
1610
+ ...(this._modalIcon !== undefined ? { icon: this._modalIcon } : {}),
1611
+ ...(this._modalIconColor !== undefined ? { iconColor: this._modalIconColor } : {}),
1612
+ ...(this._modalWidth !== undefined ? { width: this._modalWidth } : {}),
1613
+ ...(this._modalAlignment !== undefined ? { alignment: this._modalAlignment } : {}),
1614
+ ...(this._slideOver ? { slideOver: true } : {}),
1615
+ // Boolean defaults are emitted only when the user has flipped them
1616
+ // away from the default — keeps the wire-shape unchanged for the
1617
+ // common case (no setter ever called).
1618
+ ...(this._closeModalByClickingAway === false ? { closeByClickingAway: false } : {}),
1619
+ ...(this._closeModalByEscaping === false ? { closeByEscaping: false } : {}),
1620
+ ...(this._stickyModalHeader ? { stickyHeader: true } : {}),
1621
+ ...(this._stickyModalFooter ? { stickyFooter: true } : {}),
1622
+ ...(this._modalCloseButton ? { closeButton: true } : {}),
1623
+ ...(this._modalAutofocus !== undefined ? { autofocus: this._modalAutofocus } : {}),
1624
+ } : undefined;
1625
+ return {
1626
+ type: 'action',
1627
+ name: this.name,
1628
+ label: this._label,
1629
+ placement: this._placement,
1630
+ destructive: this._destructive,
1631
+ ...(this._icon ? { icon: this._icon } : {}),
1632
+ ...(this._confirm ? { confirm: this._confirm } : {}),
1633
+ ...(this._href ? { href: this._href } : {}),
1634
+ ...(this._method ? { method: this._method } : {}),
1635
+ ...(this._actionUrl ? { action: this._actionUrl } : {}),
1636
+ ...(this._dispatchUrl ? { dispatchUrl: this._dispatchUrl } : {}),
1637
+ ...(this._submit ? { submit: true } : {}),
1638
+ ...(this._formTarget ? { form: this._formTarget } : {}),
1639
+ ...(this._formField ? { formField: this._formField } : {}),
1640
+ ...(modal ? { modal } : {}),
1641
+ ...(this._color ? { color: this._color } : {}),
1642
+ ...(this._size ? { size: this._size } : {}),
1643
+ ...(this._tooltip ? { tooltip: this._tooltip } : {}),
1644
+ ...(this._outlined ? { outlined: true } : {}),
1645
+ ...(this._iconOnly ? { iconOnly: true } : {}),
1646
+ ...(this._badge !== undefined ? { badge: this._badge } : {}),
1647
+ ...(this._badgeColor ? { badgeColor: this._badgeColor } : {}),
1648
+ ...(this.hasVisibilityRules() ? { conditional: true } : {}),
1649
+ };
1650
+ }
1651
+ }
1652
+ //# sourceMappingURL=Action.js.map