@k3-universe/react-kit 0.0.27 → 0.0.29

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 (422) hide show
  1. package/.storybook/main.ts +1 -1
  2. package/.storybook/preview.ts +18 -10
  3. package/biome.json +10 -0
  4. package/dist/index.js +2319 -1227
  5. package/dist/kit/builder/auth/AuthProvider.d.ts +36 -0
  6. package/dist/kit/builder/auth/AuthProvider.d.ts.map +1 -0
  7. package/dist/kit/builder/auth/adapter.d.ts +14 -0
  8. package/dist/kit/builder/auth/adapter.d.ts.map +1 -0
  9. package/dist/kit/builder/auth/client-adapters.d.ts +149 -0
  10. package/dist/kit/builder/auth/client-adapters.d.ts.map +1 -0
  11. package/dist/kit/builder/auth/components.d.ts +119 -0
  12. package/dist/kit/builder/auth/components.d.ts.map +1 -0
  13. package/dist/kit/builder/auth/hooks.d.ts +158 -0
  14. package/dist/kit/builder/auth/hooks.d.ts.map +1 -0
  15. package/dist/kit/builder/auth/index.d.ts +11 -0
  16. package/dist/kit/builder/auth/index.d.ts.map +1 -0
  17. package/dist/kit/builder/auth/permission-checker.d.ts +31 -0
  18. package/dist/kit/builder/auth/permission-checker.d.ts.map +1 -0
  19. package/dist/kit/builder/auth/storage.d.ts +17 -0
  20. package/dist/kit/builder/auth/storage.d.ts.map +1 -0
  21. package/dist/kit/builder/auth/token-manager.d.ts +9 -0
  22. package/dist/kit/builder/auth/token-manager.d.ts.map +1 -0
  23. package/dist/kit/builder/auth/types.d.ts +183 -0
  24. package/dist/kit/builder/auth/types.d.ts.map +1 -0
  25. package/dist/kit/builder/data-table/components/DataTable.d.ts +2 -1
  26. package/dist/kit/builder/data-table/components/DataTable.d.ts.map +1 -1
  27. package/dist/kit/builder/data-table/components/DataTableColumnHeader.d.ts +2 -2
  28. package/dist/kit/builder/data-table/components/DataTableColumnHeader.d.ts.map +1 -1
  29. package/dist/kit/builder/data-table/components/DataTablePagination.d.ts +2 -1
  30. package/dist/kit/builder/data-table/components/DataTablePagination.d.ts.map +1 -1
  31. package/dist/kit/builder/data-table/components/DataTableViewOptions.d.ts +1 -1
  32. package/dist/kit/builder/data-table/components/DataTableViewOptions.d.ts.map +1 -1
  33. package/dist/kit/builder/data-table/types.d.ts.map +1 -1
  34. package/dist/kit/builder/dialog/index.d.ts +1 -1
  35. package/dist/kit/builder/dialog/index.d.ts.map +1 -1
  36. package/dist/kit/builder/dialog/provider.d.ts +0 -1
  37. package/dist/kit/builder/dialog/provider.d.ts.map +1 -1
  38. package/dist/kit/builder/form/components/FormBuilder.d.ts.map +1 -1
  39. package/dist/kit/builder/form/components/FormBuilderActions.d.ts.map +1 -1
  40. package/dist/kit/builder/form/components/FormBuilderContext.d.ts.map +1 -1
  41. package/dist/kit/builder/form/components/FormBuilderField.d.ts +1 -1
  42. package/dist/kit/builder/form/components/FormBuilderField.d.ts.map +1 -1
  43. package/dist/kit/builder/form/components/fields/ArrayField.d.ts +1 -1
  44. package/dist/kit/builder/form/components/fields/ArrayField.d.ts.map +1 -1
  45. package/dist/kit/builder/form/components/fields/AutocompleteField.d.ts +1 -1
  46. package/dist/kit/builder/form/components/fields/AutocompleteField.d.ts.map +1 -1
  47. package/dist/kit/builder/form/components/fields/CheckboxField.d.ts +1 -1
  48. package/dist/kit/builder/form/components/fields/CheckboxField.d.ts.map +1 -1
  49. package/dist/kit/builder/form/components/fields/DateField.d.ts +1 -1
  50. package/dist/kit/builder/form/components/fields/DateField.d.ts.map +1 -1
  51. package/dist/kit/builder/form/components/fields/DatePickerField.d.ts +1 -1
  52. package/dist/kit/builder/form/components/fields/DatePickerField.d.ts.map +1 -1
  53. package/dist/kit/builder/form/components/fields/DateRangePickerField.d.ts +1 -1
  54. package/dist/kit/builder/form/components/fields/DateRangePickerField.d.ts.map +1 -1
  55. package/dist/kit/builder/form/components/fields/DateTimePickerField.d.ts +1 -1
  56. package/dist/kit/builder/form/components/fields/DateTimePickerField.d.ts.map +1 -1
  57. package/dist/kit/builder/form/components/fields/DateTimeRangePickerField.d.ts +1 -1
  58. package/dist/kit/builder/form/components/fields/DateTimeRangePickerField.d.ts.map +1 -1
  59. package/dist/kit/builder/form/components/fields/FileField.d.ts +1 -1
  60. package/dist/kit/builder/form/components/fields/FileField.d.ts.map +1 -1
  61. package/dist/kit/builder/form/components/fields/MonthPickerField.d.ts +1 -1
  62. package/dist/kit/builder/form/components/fields/MonthPickerField.d.ts.map +1 -1
  63. package/dist/kit/builder/form/components/fields/MonthRangePickerField.d.ts +1 -1
  64. package/dist/kit/builder/form/components/fields/MonthRangePickerField.d.ts.map +1 -1
  65. package/dist/kit/builder/form/components/fields/NumberField.d.ts +1 -1
  66. package/dist/kit/builder/form/components/fields/NumberField.d.ts.map +1 -1
  67. package/dist/kit/builder/form/components/fields/ObjectField.d.ts.map +1 -1
  68. package/dist/kit/builder/form/components/fields/RadioField.d.ts +1 -1
  69. package/dist/kit/builder/form/components/fields/RadioField.d.ts.map +1 -1
  70. package/dist/kit/builder/form/components/fields/SelectField.d.ts +1 -1
  71. package/dist/kit/builder/form/components/fields/SelectField.d.ts.map +1 -1
  72. package/dist/kit/builder/form/components/fields/SwitchField.d.ts +1 -1
  73. package/dist/kit/builder/form/components/fields/SwitchField.d.ts.map +1 -1
  74. package/dist/kit/builder/form/components/fields/TextField.d.ts +1 -1
  75. package/dist/kit/builder/form/components/fields/TextField.d.ts.map +1 -1
  76. package/dist/kit/builder/form/components/fields/TextareaField.d.ts +1 -1
  77. package/dist/kit/builder/form/components/fields/TextareaField.d.ts.map +1 -1
  78. package/dist/kit/builder/form/components/fields/TimePickerField.d.ts +1 -1
  79. package/dist/kit/builder/form/components/fields/TimePickerField.d.ts.map +1 -1
  80. package/dist/kit/builder/form/components/fields/TimeRangePickerField.d.ts +1 -1
  81. package/dist/kit/builder/form/components/fields/TimeRangePickerField.d.ts.map +1 -1
  82. package/dist/kit/builder/form/components/fields/index.d.ts.map +1 -1
  83. package/dist/kit/builder/form/components/fields/types.d.ts.map +1 -1
  84. package/dist/kit/builder/form/components/sectionNodes.d.ts.map +1 -1
  85. package/dist/kit/builder/form/hooks/useFormBuilder.d.ts.map +1 -1
  86. package/dist/kit/builder/form/types.d.ts.map +1 -1
  87. package/dist/kit/builder/form/utils/section-factories.d.ts.map +1 -1
  88. package/dist/kit/builder/page/Page.d.ts.map +1 -1
  89. package/dist/kit/builder/page/index.d.ts.map +1 -1
  90. package/dist/kit/builder/section/SectionBuilder.d.ts +1 -1
  91. package/dist/kit/builder/section/SectionBuilder.d.ts.map +1 -1
  92. package/dist/kit/builder/section/SectionContainer.d.ts +14 -0
  93. package/dist/kit/builder/section/SectionContainer.d.ts.map +1 -0
  94. package/dist/kit/builder/stack-dialog/context.d.ts.map +1 -1
  95. package/dist/kit/builder/stack-dialog/hooks.d.ts.map +1 -1
  96. package/dist/kit/builder/stack-dialog/index.d.ts +3 -3
  97. package/dist/kit/builder/stack-dialog/index.d.ts.map +1 -1
  98. package/dist/kit/builder/stack-dialog/provider.d.ts.map +1 -1
  99. package/dist/kit/builder/stack-dialog/renderer.d.ts.map +1 -1
  100. package/dist/kit/builder/stack-dialog/types.d.ts +1 -1
  101. package/dist/kit/builder/stack-dialog/types.d.ts.map +1 -1
  102. package/dist/kit/components/autocomplete/Autocomplete.d.ts +1 -1
  103. package/dist/kit/components/autocomplete/Autocomplete.d.ts.map +1 -1
  104. package/dist/kit/components/autocomplete/types.d.ts.map +1 -1
  105. package/dist/kit/components/datepicker/DatePicker.d.ts.map +1 -1
  106. package/dist/kit/components/datepicker/DateRangePicker.d.ts.map +1 -1
  107. package/dist/kit/components/datetimepicker/DateTimePicker.d.ts.map +1 -1
  108. package/dist/kit/components/datetimepicker/DateTimeRangePicker.d.ts.map +1 -1
  109. package/dist/kit/components/datetimepicker/index.d.ts.map +1 -1
  110. package/dist/kit/components/fileuploader/FileUploader.d.ts.map +1 -1
  111. package/dist/kit/components/fileuploader/types.d.ts +2 -2
  112. package/dist/kit/components/forminfo/FormInfoError.d.ts.map +1 -1
  113. package/dist/kit/components/login/Login.d.ts +1 -1
  114. package/dist/kit/components/login/Login.d.ts.map +1 -1
  115. package/dist/kit/components/monthpicker/MonthInput.d.ts.map +1 -1
  116. package/dist/kit/components/monthpicker/MonthPicker.d.ts.map +1 -1
  117. package/dist/kit/components/monthpicker/MonthRangeInput.d.ts.map +1 -1
  118. package/dist/kit/components/monthpicker/MonthRangePicker.d.ts.map +1 -1
  119. package/dist/kit/components/timepicker/TimePicker.d.ts.map +1 -1
  120. package/dist/kit/components/timepicker/TimeRangePicker.d.ts.map +1 -1
  121. package/dist/kit/components/timepicker/index.d.ts.map +1 -1
  122. package/dist/kit/layouts/admin/components/AdminLayout.d.ts.map +1 -1
  123. package/dist/kit/layouts/admin/components/ThemeToggle.d.ts.map +1 -1
  124. package/dist/kit/layouts/admin/hooks/menu.d.ts.map +1 -1
  125. package/dist/kit/layouts/admin/providers/AdminMenuProvider.d.ts +1 -1
  126. package/dist/kit/layouts/admin/providers/AdminMenuProvider.d.ts.map +1 -1
  127. package/dist/shadcn/hooks/use-mobile.d.ts.map +1 -1
  128. package/dist/shadcn/ui/accordion.d.ts +2 -2
  129. package/dist/shadcn/ui/accordion.d.ts.map +1 -1
  130. package/dist/shadcn/ui/alert-dialog.d.ts +4 -4
  131. package/dist/shadcn/ui/alert-dialog.d.ts.map +1 -1
  132. package/dist/shadcn/ui/alert.d.ts +4 -4
  133. package/dist/shadcn/ui/alert.d.ts.map +1 -1
  134. package/dist/shadcn/ui/aspect-ratio.d.ts +1 -1
  135. package/dist/shadcn/ui/aspect-ratio.d.ts.map +1 -1
  136. package/dist/shadcn/ui/avatar.d.ts +2 -2
  137. package/dist/shadcn/ui/avatar.d.ts.map +1 -1
  138. package/dist/shadcn/ui/badge.d.ts +2 -2
  139. package/dist/shadcn/ui/badge.d.ts.map +1 -1
  140. package/dist/shadcn/ui/breadcrumb.d.ts +8 -8
  141. package/dist/shadcn/ui/breadcrumb.d.ts.map +1 -1
  142. package/dist/shadcn/ui/button.d.ts +2 -2
  143. package/dist/shadcn/ui/button.d.ts.map +1 -1
  144. package/dist/shadcn/ui/calendar.d.ts +2 -2
  145. package/dist/shadcn/ui/calendar.d.ts.map +1 -1
  146. package/dist/shadcn/ui/card.d.ts +8 -8
  147. package/dist/shadcn/ui/card.d.ts.map +1 -1
  148. package/dist/shadcn/ui/carousel.d.ts +5 -5
  149. package/dist/shadcn/ui/carousel.d.ts.map +1 -1
  150. package/dist/shadcn/ui/chart.d.ts +7 -7
  151. package/dist/shadcn/ui/chart.d.ts.map +1 -1
  152. package/dist/shadcn/ui/checkbox.d.ts +2 -2
  153. package/dist/shadcn/ui/checkbox.d.ts.map +1 -1
  154. package/dist/shadcn/ui/collapsible.d.ts +1 -1
  155. package/dist/shadcn/ui/collapsible.d.ts.map +1 -1
  156. package/dist/shadcn/ui/command.d.ts +2 -2
  157. package/dist/shadcn/ui/command.d.ts.map +1 -1
  158. package/dist/shadcn/ui/context-menu.d.ts +4 -4
  159. package/dist/shadcn/ui/context-menu.d.ts.map +1 -1
  160. package/dist/shadcn/ui/dialog.d.ts +4 -4
  161. package/dist/shadcn/ui/dialog.d.ts.map +1 -1
  162. package/dist/shadcn/ui/drawer.d.ts +3 -3
  163. package/dist/shadcn/ui/drawer.d.ts.map +1 -1
  164. package/dist/shadcn/ui/dropdown-menu.d.ts +4 -4
  165. package/dist/shadcn/ui/dropdown-menu.d.ts.map +1 -1
  166. package/dist/shadcn/ui/form.d.ts +5 -5
  167. package/dist/shadcn/ui/form.d.ts.map +1 -1
  168. package/dist/shadcn/ui/hover-card.d.ts +2 -2
  169. package/dist/shadcn/ui/hover-card.d.ts.map +1 -1
  170. package/dist/shadcn/ui/input-otp.d.ts +4 -4
  171. package/dist/shadcn/ui/input-otp.d.ts.map +1 -1
  172. package/dist/shadcn/ui/input.d.ts +2 -2
  173. package/dist/shadcn/ui/input.d.ts.map +1 -1
  174. package/dist/shadcn/ui/label.d.ts +2 -2
  175. package/dist/shadcn/ui/label.d.ts.map +1 -1
  176. package/dist/shadcn/ui/menubar.d.ts +4 -4
  177. package/dist/shadcn/ui/menubar.d.ts.map +1 -1
  178. package/dist/shadcn/ui/navigation-menu.d.ts +2 -2
  179. package/dist/shadcn/ui/navigation-menu.d.ts.map +1 -1
  180. package/dist/shadcn/ui/pagination.d.ts +6 -6
  181. package/dist/shadcn/ui/pagination.d.ts.map +1 -1
  182. package/dist/shadcn/ui/popover.d.ts +2 -2
  183. package/dist/shadcn/ui/popover.d.ts.map +1 -1
  184. package/dist/shadcn/ui/progress.d.ts +2 -2
  185. package/dist/shadcn/ui/progress.d.ts.map +1 -1
  186. package/dist/shadcn/ui/radio-group.d.ts +2 -2
  187. package/dist/shadcn/ui/radio-group.d.ts.map +1 -1
  188. package/dist/shadcn/ui/resizable.d.ts +2 -2
  189. package/dist/shadcn/ui/resizable.d.ts.map +1 -1
  190. package/dist/shadcn/ui/scroll-area.d.ts +2 -2
  191. package/dist/shadcn/ui/scroll-area.d.ts.map +1 -1
  192. package/dist/shadcn/ui/select.d.ts +3 -3
  193. package/dist/shadcn/ui/select.d.ts.map +1 -1
  194. package/dist/shadcn/ui/separator.d.ts +2 -2
  195. package/dist/shadcn/ui/separator.d.ts.map +1 -1
  196. package/dist/shadcn/ui/sheet.d.ts +5 -5
  197. package/dist/shadcn/ui/sheet.d.ts.map +1 -1
  198. package/dist/shadcn/ui/sidebar.d.ts +26 -26
  199. package/dist/shadcn/ui/sidebar.d.ts.map +1 -1
  200. package/dist/shadcn/ui/skeleton.d.ts +1 -1
  201. package/dist/shadcn/ui/skeleton.d.ts.map +1 -1
  202. package/dist/shadcn/ui/slider.d.ts +2 -2
  203. package/dist/shadcn/ui/slider.d.ts.map +1 -1
  204. package/dist/shadcn/ui/sonner.d.ts.map +1 -1
  205. package/dist/shadcn/ui/switch.d.ts +2 -2
  206. package/dist/shadcn/ui/switch.d.ts.map +1 -1
  207. package/dist/shadcn/ui/table.d.ts +9 -9
  208. package/dist/shadcn/ui/table.d.ts.map +1 -1
  209. package/dist/shadcn/ui/tabs.d.ts +2 -2
  210. package/dist/shadcn/ui/tabs.d.ts.map +1 -1
  211. package/dist/shadcn/ui/textarea.d.ts +2 -2
  212. package/dist/shadcn/ui/textarea.d.ts.map +1 -1
  213. package/dist/shadcn/ui/toggle-group.d.ts +2 -2
  214. package/dist/shadcn/ui/toggle-group.d.ts.map +1 -1
  215. package/dist/shadcn/ui/toggle.d.ts +2 -2
  216. package/dist/shadcn/ui/toggle.d.ts.map +1 -1
  217. package/dist/shadcn/ui/tooltip.d.ts +2 -2
  218. package/dist/shadcn/ui/tooltip.d.ts.map +1 -1
  219. package/package.json +2 -2
  220. package/src/index.ts +1 -1
  221. package/src/kit/builder/auth/AuthProvider.tsx +131 -0
  222. package/src/kit/builder/auth/adapter.ts +436 -0
  223. package/src/kit/builder/auth/client-adapters.ts +398 -0
  224. package/src/kit/builder/auth/components.tsx +221 -0
  225. package/src/kit/builder/auth/hooks.ts +237 -0
  226. package/src/kit/builder/auth/index.ts +134 -0
  227. package/src/kit/builder/auth/permission-checker.ts +150 -0
  228. package/src/kit/builder/auth/storage.ts +366 -0
  229. package/src/kit/builder/auth/token-manager.ts +55 -0
  230. package/src/kit/builder/auth/types.ts +393 -0
  231. package/src/kit/builder/data-table/components/DataTable.tsx +216 -82
  232. package/src/kit/builder/data-table/components/DataTableColumnHeader.tsx +9 -5
  233. package/src/kit/builder/data-table/components/DataTablePagination.tsx +49 -27
  234. package/src/kit/builder/data-table/components/DataTableViewOptions.tsx +13 -4
  235. package/src/kit/builder/data-table/types.ts +18 -3
  236. package/src/kit/builder/dialog/index.ts +5 -1
  237. package/src/kit/builder/dialog/provider.tsx +56 -27
  238. package/src/kit/builder/form/components/FormBuilder.tsx +10 -14
  239. package/src/kit/builder/form/components/FormBuilderActions.tsx +1 -1
  240. package/src/kit/builder/form/components/FormBuilderContext.tsx +13 -6
  241. package/src/kit/builder/form/components/FormBuilderField.tsx +70 -20
  242. package/src/kit/builder/form/components/fields/ArrayField.tsx +148 -62
  243. package/src/kit/builder/form/components/fields/AutocompleteField.tsx +53 -18
  244. package/src/kit/builder/form/components/fields/CheckboxField.tsx +20 -11
  245. package/src/kit/builder/form/components/fields/DateField.tsx +17 -6
  246. package/src/kit/builder/form/components/fields/DatePickerField.tsx +15 -10
  247. package/src/kit/builder/form/components/fields/DateRangePickerField.tsx +20 -15
  248. package/src/kit/builder/form/components/fields/DateTimePickerField.tsx +16 -11
  249. package/src/kit/builder/form/components/fields/DateTimeRangePickerField.tsx +23 -17
  250. package/src/kit/builder/form/components/fields/FileField.tsx +10 -5
  251. package/src/kit/builder/form/components/fields/MonthPickerField.tsx +18 -11
  252. package/src/kit/builder/form/components/fields/MonthRangePickerField.tsx +23 -17
  253. package/src/kit/builder/form/components/fields/NumberField.tsx +9 -4
  254. package/src/kit/builder/form/components/fields/ObjectField.tsx +12 -7
  255. package/src/kit/builder/form/components/fields/RadioField.tsx +32 -14
  256. package/src/kit/builder/form/components/fields/SelectField.tsx +26 -11
  257. package/src/kit/builder/form/components/fields/SwitchField.tsx +20 -11
  258. package/src/kit/builder/form/components/fields/TextField.tsx +11 -5
  259. package/src/kit/builder/form/components/fields/TextareaField.tsx +9 -4
  260. package/src/kit/builder/form/components/fields/TimePickerField.tsx +16 -11
  261. package/src/kit/builder/form/components/fields/TimeRangePickerField.tsx +23 -17
  262. package/src/kit/builder/form/components/fields/index.ts +21 -21
  263. package/src/kit/builder/form/components/fields/types.ts +15 -11
  264. package/src/kit/builder/form/components/sectionNodes.tsx +63 -40
  265. package/src/kit/builder/form/hooks/useFormBuilder.ts +83 -34
  266. package/src/kit/builder/form/types.ts +173 -148
  267. package/src/kit/builder/form/utils/section-factories.ts +4 -1
  268. package/src/kit/builder/form/utils/transformers.ts +4 -4
  269. package/src/kit/builder/form/utils/validations.ts +1 -1
  270. package/src/kit/builder/page/Page.tsx +26 -6
  271. package/src/kit/builder/page/index.ts +1 -1
  272. package/src/kit/builder/section/SectionBuilder.tsx +252 -127
  273. package/src/kit/builder/section/SectionContainer.tsx +85 -0
  274. package/src/kit/builder/stack-dialog/context.ts +10 -4
  275. package/src/kit/builder/stack-dialog/hooks.ts +4 -3
  276. package/src/kit/builder/stack-dialog/index.ts +5 -11
  277. package/src/kit/builder/stack-dialog/provider.tsx +11 -11
  278. package/src/kit/builder/stack-dialog/renderer.tsx +23 -26
  279. package/src/kit/builder/stack-dialog/types.ts +18 -18
  280. package/src/kit/components/autocomplete/Autocomplete.tsx +631 -549
  281. package/src/kit/components/autocomplete/types.ts +17 -17
  282. package/src/kit/components/datepicker/DatePicker.tsx +33 -9
  283. package/src/kit/components/datepicker/DateRangePicker.tsx +159 -87
  284. package/src/kit/components/datetimepicker/DateTimePicker.tsx +136 -30
  285. package/src/kit/components/datetimepicker/DateTimeRangePicker.tsx +257 -67
  286. package/src/kit/components/datetimepicker/index.ts +3 -3
  287. package/src/kit/components/fileuploader/FileUploader.tsx +315 -180
  288. package/src/kit/components/fileuploader/index.ts +3 -3
  289. package/src/kit/components/fileuploader/types.ts +3 -3
  290. package/src/kit/components/forminfo/FormInfoError.tsx +26 -11
  291. package/src/kit/components/login/Login.tsx +13 -4
  292. package/src/kit/components/monthpicker/MonthInput.tsx +13 -4
  293. package/src/kit/components/monthpicker/MonthPicker.tsx +12 -11
  294. package/src/kit/components/monthpicker/MonthRangeInput.tsx +29 -8
  295. package/src/kit/components/monthpicker/MonthRangePicker.tsx +23 -21
  296. package/src/kit/components/timepicker/TimePicker.tsx +19 -11
  297. package/src/kit/components/timepicker/TimeRangePicker.tsx +106 -29
  298. package/src/kit/components/timepicker/index.ts +3 -3
  299. package/src/kit/layouts/admin/components/AdminLayout.tsx +53 -24
  300. package/src/kit/layouts/admin/components/ThemeToggle.tsx +3 -9
  301. package/src/kit/layouts/admin/hooks/menu.ts +11 -5
  302. package/src/kit/layouts/admin/providers/AdminMenuProvider.tsx +59 -39
  303. package/src/kit/layouts/admin/types/index.ts +1 -1
  304. package/src/kit/themes/base.css +1 -1
  305. package/src/kit/themes/clean-slate.css +40 -32
  306. package/src/kit/themes/default.css +34 -24
  307. package/src/kit/themes/minimal-modern.css +37 -29
  308. package/src/kit/themes/spotify.css +56 -39
  309. package/src/shadcn/hooks/use-mobile.ts +13 -11
  310. package/src/shadcn/lib/utils.ts +2 -2
  311. package/src/shadcn/ui/accordion.tsx +14 -14
  312. package/src/shadcn/ui/alert-dialog.tsx +29 -29
  313. package/src/shadcn/ui/alert.tsx +20 -20
  314. package/src/shadcn/ui/aspect-ratio.tsx +4 -4
  315. package/src/shadcn/ui/avatar.tsx +13 -13
  316. package/src/shadcn/ui/badge.tsx +16 -16
  317. package/src/shadcn/ui/breadcrumb.tsx +28 -28
  318. package/src/shadcn/ui/button.tsx +23 -23
  319. package/src/shadcn/ui/calendar.tsx +82 -78
  320. package/src/shadcn/ui/card.tsx +27 -27
  321. package/src/shadcn/ui/carousel.tsx +93 -93
  322. package/src/shadcn/ui/chart.tsx +103 -103
  323. package/src/shadcn/ui/checkbox.tsx +9 -9
  324. package/src/shadcn/ui/collapsible.tsx +6 -6
  325. package/src/shadcn/ui/command.tsx +36 -36
  326. package/src/shadcn/ui/context-menu.tsx +40 -40
  327. package/src/shadcn/ui/dialog.tsx +28 -28
  328. package/src/shadcn/ui/drawer.tsx +30 -30
  329. package/src/shadcn/ui/dropdown-menu.tsx +41 -41
  330. package/src/shadcn/ui/form.tsx +48 -47
  331. package/src/shadcn/ui/hover-card.tsx +11 -11
  332. package/src/shadcn/ui/input-otp.tsx +23 -23
  333. package/src/shadcn/ui/input.tsx +9 -9
  334. package/src/shadcn/ui/label.tsx +8 -8
  335. package/src/shadcn/ui/menubar.tsx +47 -47
  336. package/src/shadcn/ui/navigation-menu.tsx +33 -33
  337. package/src/shadcn/ui/pagination.tsx +28 -28
  338. package/src/shadcn/ui/popover.tsx +12 -12
  339. package/src/shadcn/ui/progress.tsx +8 -8
  340. package/src/shadcn/ui/radio-group.tsx +11 -11
  341. package/src/shadcn/ui/resizable.tsx +14 -14
  342. package/src/shadcn/ui/scroll-area.tsx +15 -15
  343. package/src/shadcn/ui/select.tsx +34 -34
  344. package/src/shadcn/ui/separator.tsx +9 -9
  345. package/src/shadcn/ui/sheet.tsx +36 -36
  346. package/src/shadcn/ui/sidebar.tsx +227 -227
  347. package/src/shadcn/ui/skeleton.tsx +5 -5
  348. package/src/shadcn/ui/slider.tsx +12 -12
  349. package/src/shadcn/ui/sonner.tsx +11 -11
  350. package/src/shadcn/ui/switch.tsx +9 -9
  351. package/src/shadcn/ui/table.tsx +32 -32
  352. package/src/shadcn/ui/tabs.tsx +14 -14
  353. package/src/shadcn/ui/textarea.tsx +7 -7
  354. package/src/shadcn/ui/toggle-group.tsx +17 -17
  355. package/src/shadcn/ui/toggle.tsx +16 -16
  356. package/src/shadcn/ui/tooltip.tsx +11 -11
  357. package/src/stories/FileUploader.stories.tsx +23 -4
  358. package/src/stories/kit/builder/DataTable.Basic.stories.tsx +14 -4
  359. package/src/stories/kit/builder/DataTable.Filters.stories.tsx +36 -14
  360. package/src/stories/kit/builder/DataTable.Pagination.stories.tsx +3 -2
  361. package/src/stories/kit/builder/DataTable.SelectionAndActions.stories.tsx +18 -4
  362. package/src/stories/kit/builder/DataTable.Sorting.stories.tsx +18 -7
  363. package/src/stories/kit/builder/Dialog.stories.tsx +19 -13
  364. package/src/stories/kit/builder/Form.ArrayLayouts.stories.tsx +40 -16
  365. package/src/stories/kit/builder/Form.Autocomplete.stories.tsx +34 -22
  366. package/src/stories/kit/builder/Form.Basic.stories.tsx +38 -6
  367. package/src/stories/kit/builder/Form.Complex.stories.tsx +356 -111
  368. package/src/stories/kit/builder/Form.DateTime.stories.tsx +12 -8
  369. package/src/stories/kit/builder/Form.Dynamic.stories.tsx +695 -132
  370. package/src/stories/kit/builder/Form.Files.stories.tsx +37 -26
  371. package/src/stories/kit/builder/Form.MultipleFormBuilder.stories.tsx +46 -42
  372. package/src/stories/kit/builder/Form.Pickers.stories.tsx +12 -8
  373. package/src/stories/kit/builder/Form.Simple.stories.tsx +15 -6
  374. package/src/stories/kit/builder/Form.Time.stories.tsx +12 -8
  375. package/src/stories/kit/builder/Page.stories.tsx +32 -6
  376. package/src/stories/kit/builder/Section.stories.tsx +58 -11
  377. package/src/stories/kit/components/Autocomplete.stories.tsx +55 -22
  378. package/src/stories/kit/components/DatePicker.stories.tsx +80 -13
  379. package/src/stories/kit/components/DateRangePicker.stories.tsx +52 -11
  380. package/src/stories/kit/components/Login.stories.tsx +8 -2
  381. package/src/stories/kit/components/MonthPicker.stories.tsx +26 -6
  382. package/src/stories/kit/components/MonthRangePicker.stories.tsx +24 -5
  383. package/src/stories/kit/components/TimePicker.stories.tsx +18 -16
  384. package/src/stories/kit/components/TimeRangePicker.stories.tsx +18 -12
  385. package/src/stories/kit/layouts/admin/AdminLayout.Basic.stories.tsx +29 -6
  386. package/src/stories/kit/layouts/admin/AdminLayout.Collapsible.stories.tsx +26 -5
  387. package/src/stories/kit/layouts/admin/AdminLayout.Complex.stories.tsx +101 -18
  388. package/src/stories/kit/layouts/admin/AdminLayout.CustomSidebarHeaderComponent.stories.tsx +18 -4
  389. package/src/stories/kit/layouts/admin/AdminLayout.CustomSidebarTitleAndIcon.stories.tsx +17 -4
  390. package/src/stories/kit/layouts/admin/AdminLayout.HeaderSlots.stories.tsx +28 -6
  391. package/src/stories/shadcn/ui/Accordion.stories.tsx +33 -10
  392. package/src/stories/shadcn/ui/AlertDialog.stories.tsx +3 -1
  393. package/src/stories/shadcn/ui/Button.stories.tsx +3 -1
  394. package/src/stories/shadcn/ui/Calendar.stories.tsx +6 -1
  395. package/src/stories/shadcn/ui/Card.stories.tsx +11 -2
  396. package/src/stories/shadcn/ui/Checkbox.stories.tsx +11 -3
  397. package/src/stories/shadcn/ui/Collapsible.stories.tsx +12 -5
  398. package/src/stories/shadcn/ui/ContextMenu.stories.tsx +12 -4
  399. package/src/stories/shadcn/ui/Dialog.stories.tsx +15 -3
  400. package/src/stories/shadcn/ui/Drawer.stories.tsx +5 -2
  401. package/src/stories/shadcn/ui/DropdownMenu.stories.tsx +15 -5
  402. package/src/stories/shadcn/ui/Form.stories.tsx +5 -2
  403. package/src/stories/shadcn/ui/HoverCard.stories.tsx +8 -2
  404. package/src/stories/shadcn/ui/Input.stories.tsx +3 -1
  405. package/src/stories/shadcn/ui/InputOtp.stories.tsx +9 -2
  406. package/src/stories/shadcn/ui/Menubar.stories.tsx +21 -7
  407. package/src/stories/shadcn/ui/NavigationMenu.stories.tsx +30 -5
  408. package/src/stories/shadcn/ui/Popover.stories.tsx +8 -2
  409. package/src/stories/shadcn/ui/Resizable.stories.tsx +17 -5
  410. package/src/stories/shadcn/ui/ScrollArea.stories.tsx +54 -2
  411. package/src/stories/shadcn/ui/Select.stories.tsx +7 -1
  412. package/src/stories/shadcn/ui/Sheet.stories.tsx +2 -1
  413. package/src/stories/shadcn/ui/Sidebar.stories.tsx +13 -2
  414. package/src/stories/shadcn/ui/Sonner.stories.tsx +12 -2
  415. package/src/stories/shadcn/ui/Table.stories.tsx +86 -27
  416. package/src/stories/shadcn/ui/Tabs.stories.tsx +9 -2
  417. package/src/stories/shadcn/ui/Textarea.stories.tsx +3 -1
  418. package/src/stories/shadcn/ui/Toggle.stories.tsx +10 -2
  419. package/src/stories/shadcn/ui/Tooltip.stories.tsx +6 -1
  420. package/tsconfig.json +1 -5
  421. package/tsconfig.tsbuildinfo +1 -0
  422. package/eslint.config.mjs +0 -19
@@ -0,0 +1,131 @@
1
+ import {
2
+ createContext,
3
+ useContext,
4
+ useEffect,
5
+ useMemo,
6
+ useSyncExternalStore,
7
+ } from 'react';
8
+ import type { ReactNode } from 'react';
9
+ import type { AuthAdapter, AuthContextValue, AuthSession } from './types';
10
+
11
+ type AnyAuthContextValue = AuthContextValue<
12
+ unknown,
13
+ string,
14
+ string,
15
+ AuthSession<unknown, string, string>,
16
+ unknown
17
+ >;
18
+
19
+ const AuthContext = createContext<AnyAuthContextValue | undefined>(undefined);
20
+
21
+ type AuthProviderProps<
22
+ TUser = unknown,
23
+ TRole extends string = string,
24
+ TPermission extends string = string,
25
+ TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
26
+ TUser,
27
+ TRole,
28
+ TPermission
29
+ >,
30
+ TCredentials = unknown,
31
+ > = {
32
+ adapter: AuthAdapter<TUser, TRole, TPermission, TSession, TCredentials>;
33
+ children: ReactNode;
34
+ autoSync?: boolean;
35
+ };
36
+
37
+ /**
38
+ * AuthProvider component - wraps your app with authentication context
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * import { AuthProvider, createAuthAdapter } from '@k3mart/react-kit/auth2';
43
+ *
44
+ * const authAdapter = createAuthAdapter({
45
+ * // ... configuration
46
+ * });
47
+ *
48
+ * function App() {
49
+ * return (
50
+ * <AuthProvider adapter={authAdapter}>
51
+ * <YourApp />
52
+ * </AuthProvider>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export function AuthProvider<
58
+ TUser = unknown,
59
+ TRole extends string = string,
60
+ TPermission extends string = string,
61
+ TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
62
+ TUser,
63
+ TRole,
64
+ TPermission
65
+ >,
66
+ TCredentials = unknown,
67
+ >({
68
+ adapter,
69
+ children,
70
+ autoSync = true,
71
+ }: AuthProviderProps<TUser, TRole, TPermission, TSession, TCredentials>) {
72
+ const state = useSyncExternalStore(
73
+ adapter.subscribe,
74
+ adapter.getState,
75
+ adapter.getState,
76
+ );
77
+
78
+ useEffect(() => {
79
+ if (!autoSync) return;
80
+ adapter.sync().catch(() => undefined);
81
+ }, [adapter, autoSync]);
82
+
83
+ const value = useMemo<
84
+ AuthContextValue<TUser, TRole, TPermission, TSession, TCredentials>
85
+ >(() => {
86
+ const login = adapter.login
87
+ ? async (credentials: TCredentials) => {
88
+ if (!adapter.login) {
89
+ throw new Error('Login is not configured');
90
+ }
91
+ return await adapter.login(credentials);
92
+ }
93
+ : undefined;
94
+
95
+ return {
96
+ state,
97
+ status: state.status,
98
+ session: state.session,
99
+ user: state.user,
100
+ roles: state.roles,
101
+ permissions: state.permissions,
102
+ error: state.error,
103
+ login,
104
+ logout: adapter.logout,
105
+ refresh: adapter.refresh,
106
+ setSession: adapter.setSession,
107
+ hasRole: adapter.hasRole,
108
+ hasPermission: adapter.hasPermission,
109
+ can: adapter.can,
110
+ getToken: adapter.getToken,
111
+ isTokenExpired: adapter.isTokenExpired,
112
+ getTimeUntilExpiry: adapter.getTimeUntilExpiry,
113
+ };
114
+ }, [adapter, state]);
115
+
116
+ const contextValue = value as unknown as AnyAuthContextValue;
117
+
118
+ return (
119
+ <AuthContext.Provider value={contextValue}>{children}</AuthContext.Provider>
120
+ );
121
+ }
122
+
123
+ /**
124
+ * Hook to access auth context
125
+ * Must be used within AuthProvider
126
+ */
127
+ export function useAuthContext(): AnyAuthContextValue {
128
+ const ctx = useContext(AuthContext);
129
+ if (!ctx) throw new Error('useAuthContext must be used within AuthProvider');
130
+ return ctx;
131
+ }
@@ -0,0 +1,436 @@
1
+ import { createMemoryStorage } from './storage';
2
+ import { createTokenManager } from './token-manager';
3
+ import {
4
+ checkPermissions,
5
+ checkRoles,
6
+ evaluatePermissionRule,
7
+ expandPermissions,
8
+ expandRoles,
9
+ } from './permission-checker';
10
+ import type {
11
+ AuthAdapter,
12
+ AuthAdapterConfig,
13
+ AuthAdapterState,
14
+ AuthAdapterSubscriber,
15
+ AuthSession,
16
+ AuthStatus,
17
+ PermissionPolicy,
18
+ PermissionRule,
19
+ } from './types';
20
+
21
+ const unique = <T>(values: T[]): T[] => {
22
+ return Array.from(new Set(values));
23
+ };
24
+
25
+ /**
26
+ * Enhanced Authentication Adapter
27
+ *
28
+ * Features:
29
+ * - Token management with auto-refresh
30
+ * - Permission and role hierarchies
31
+ * - Middleware support
32
+ * - Retry logic
33
+ * - Advanced permission checking (AND/OR policies)
34
+ * - Session persistence
35
+ */
36
+ export function createAuthAdapter<
37
+ TUser = unknown,
38
+ TRole extends string = string,
39
+ TPermission extends string = string,
40
+ TSession extends AuthSession<TUser, TRole, TPermission> = AuthSession<
41
+ TUser,
42
+ TRole,
43
+ TPermission
44
+ >,
45
+ TCredentials = unknown,
46
+ >(
47
+ config: AuthAdapterConfig<TUser, TRole, TPermission, TSession, TCredentials>,
48
+ ): AuthAdapter<TUser, TRole, TPermission, TSession, TCredentials> {
49
+ // ============================================================================
50
+ // Configuration & State
51
+ // ============================================================================
52
+
53
+ const storage = config.storage ?? createMemoryStorage<TSession>();
54
+ const tokenManager =
55
+ config.tokenManager ??
56
+ createTokenManager({
57
+ refreshThreshold: config.refreshThreshold ?? 300,
58
+ });
59
+
60
+ const subscribers = new Set<
61
+ AuthAdapterSubscriber<TSession, TUser, TRole, TPermission>
62
+ >();
63
+
64
+ const resolveUser =
65
+ config.resolveUser ?? ((session: TSession | null) => session?.user ?? null);
66
+ const resolveRoles =
67
+ config.resolveRoles ??
68
+ ((session: TSession | null) =>
69
+ session?.roles?.filter((role): role is TRole => role != null) ?? []);
70
+ const resolvePermissions =
71
+ config.resolvePermissions ??
72
+ ((session: TSession | null) =>
73
+ session?.permissions?.filter(
74
+ (permission): permission is TPermission => permission != null,
75
+ ) ?? []);
76
+
77
+ let state: AuthAdapterState<TSession, TUser, TRole, TPermission> = {
78
+ status: 'idle',
79
+ session: null,
80
+ user: null,
81
+ roles: [],
82
+ permissions: [],
83
+ };
84
+
85
+ let autoRefreshCleanup: (() => void) | null = null;
86
+
87
+ // ============================================================================
88
+ // Middleware Execution
89
+ // ============================================================================
90
+
91
+ const executeMiddleware = async <
92
+ T extends keyof NonNullable<typeof config.middleware>[number],
93
+ >(
94
+ hook: T,
95
+ ...args: Parameters<
96
+ NonNullable<NonNullable<typeof config.middleware>[number][T]>
97
+ >
98
+ ): Promise<void> => {
99
+ if (!config.middleware) return;
100
+
101
+ for (const middleware of config.middleware) {
102
+ const fn = middleware[hook];
103
+ if (fn) {
104
+ try {
105
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
106
+ await (fn as any)(...args);
107
+ } catch (error) {
108
+ console.error(`[auth2] Middleware error in ${String(hook)}:`, error);
109
+ if (middleware.onError) {
110
+ await middleware.onError(error);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ };
116
+
117
+ // ============================================================================
118
+ // State Management
119
+ // ============================================================================
120
+
121
+ const notify = () => {
122
+ for (const listener of subscribers) listener(state);
123
+ config.onStateChange?.(state);
124
+ };
125
+
126
+ const setState = (
127
+ next: AuthAdapterState<TSession, TUser, TRole, TPermission>,
128
+ ) => {
129
+ state = next;
130
+ notify();
131
+ };
132
+
133
+ const computeState = (
134
+ session: TSession | null,
135
+ status: AuthStatus,
136
+ error?: unknown,
137
+ ): AuthAdapterState<TSession, TUser, TRole, TPermission> => {
138
+ const user = resolveUser(session);
139
+ const baseRoles = resolveRoles(session);
140
+ const basePermissions = resolvePermissions(session);
141
+
142
+ // Apply hierarchies
143
+ const roles = unique(expandRoles(baseRoles, config.roleHierarchy));
144
+ const permissions = unique(
145
+ expandPermissions(basePermissions, config.permissionHierarchy),
146
+ );
147
+
148
+ const tokenExpiresIn = session?.expiresAt
149
+ ? tokenManager.getTimeUntilExpiry(session.expiresAt)
150
+ : undefined;
151
+
152
+ return {
153
+ status,
154
+ session,
155
+ user,
156
+ roles,
157
+ permissions,
158
+ error,
159
+ lastRefresh: Date.now(),
160
+ tokenExpiresIn,
161
+ };
162
+ };
163
+
164
+ // ============================================================================
165
+ // Storage Operations
166
+ // ============================================================================
167
+
168
+ const readStorage = async () => {
169
+ const stored = await Promise.resolve(storage.get());
170
+ return stored ?? null;
171
+ };
172
+
173
+ const writeStorage = async (next: TSession | null) => {
174
+ if (next === null) {
175
+ await Promise.resolve(storage.clear());
176
+ } else {
177
+ await Promise.resolve(storage.set(next));
178
+ }
179
+ };
180
+
181
+ // ============================================================================
182
+ // Auto-Refresh Management
183
+ // ============================================================================
184
+
185
+ const setupAutoRefresh = () => {
186
+ if (autoRefreshCleanup) {
187
+ autoRefreshCleanup();
188
+ autoRefreshCleanup = null;
189
+ }
190
+
191
+ if (!config.autoRefresh || !config.refresh || !state.session?.expiresAt) {
192
+ return;
193
+ }
194
+
195
+ if (tokenManager.scheduleRefresh) {
196
+ autoRefreshCleanup = tokenManager.scheduleRefresh(() => {
197
+ refresh().catch((error) => {
198
+ console.error('[auth2] Auto-refresh failed:', error);
199
+ });
200
+ }, state.session.expiresAt);
201
+ }
202
+ };
203
+
204
+ // ============================================================================
205
+ // Session Management
206
+ // ============================================================================
207
+
208
+ const setSession = async (
209
+ session: TSession | null,
210
+ statusOverride?: AuthStatus,
211
+ error?: unknown,
212
+ ) => {
213
+ await writeStorage(session);
214
+ const status: AuthStatus =
215
+ statusOverride ?? (session ? 'authenticated' : 'unauthenticated');
216
+ const nextState = computeState(session, status, error);
217
+ setState(nextState);
218
+
219
+ setupAutoRefresh();
220
+
221
+ return nextState;
222
+ };
223
+
224
+ const sync = async () => {
225
+ setState({ ...state, status: 'loading' });
226
+ try {
227
+ const session =
228
+ (await config.loadSession?.()) ?? (await readStorage()) ?? null;
229
+
230
+ // Check if session is expired
231
+ if (session?.expiresAt && tokenManager.isExpired(session.expiresAt)) {
232
+ // Try to refresh if possible
233
+ if (config.refresh && session.refreshToken) {
234
+ try {
235
+ const refreshed = await config.refresh(session);
236
+ return await setSession(refreshed, 'authenticated');
237
+ } catch {
238
+ // Refresh failed, session is expired
239
+ await executeMiddleware('onSessionExpired');
240
+ return await setSession(null, 'unauthenticated');
241
+ }
242
+ }
243
+
244
+ await executeMiddleware('onSessionExpired');
245
+ return await setSession(null, 'unauthenticated');
246
+ }
247
+
248
+ return await setSession(
249
+ session,
250
+ session ? 'authenticated' : 'unauthenticated',
251
+ );
252
+ } catch (error) {
253
+ await executeMiddleware('onError', error);
254
+ return await setSession(null, 'error', error);
255
+ }
256
+ };
257
+
258
+ // ============================================================================
259
+ // Retry Logic
260
+ // ============================================================================
261
+
262
+ const withRetry = async <T>(
263
+ fn: () => Promise<T>,
264
+ context: string,
265
+ ): Promise<T> => {
266
+ const maxRetries = config.retryConfig?.maxRetries ?? 0;
267
+ const retryDelay = config.retryConfig?.retryDelay ?? 1000;
268
+ const shouldRetry = config.retryConfig?.retryOn;
269
+
270
+ let lastError: unknown;
271
+
272
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
273
+ try {
274
+ return await fn();
275
+ } catch (error) {
276
+ lastError = error;
277
+
278
+ const isLastAttempt = attempt === maxRetries;
279
+ const shouldRetryError = shouldRetry ? shouldRetry(error) : false;
280
+
281
+ if (isLastAttempt || !shouldRetryError) {
282
+ throw error;
283
+ }
284
+
285
+ console.warn(
286
+ `[auth2] ${context} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying...`,
287
+ );
288
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
289
+ }
290
+ }
291
+
292
+ throw lastError;
293
+ };
294
+
295
+ // ============================================================================
296
+ // Authentication Operations
297
+ // ============================================================================
298
+
299
+ const refresh = async () => {
300
+ const refreshFn = config.refresh;
301
+ const currentSession = state.session;
302
+
303
+ if (!refreshFn) return state;
304
+ if (!currentSession) return state;
305
+
306
+ try {
307
+ const refreshed = await withRetry(
308
+ () => refreshFn(currentSession),
309
+ 'refresh',
310
+ );
311
+ const nextState = await setSession(refreshed, 'authenticated');
312
+ await executeMiddleware('onRefresh', nextState);
313
+ return nextState;
314
+ } catch (error) {
315
+ await executeMiddleware('onError', error);
316
+ return await setSession(state.session, 'error', error);
317
+ }
318
+ };
319
+
320
+ const login = async (credentials: TCredentials) => {
321
+ const loginFn = config.login;
322
+ if (!loginFn) throw new Error('Auth adapter login is not configured');
323
+
324
+ setState({ ...state, status: 'loading' });
325
+
326
+ try {
327
+ await executeMiddleware('onBeforeLogin', credentials);
328
+
329
+ const session = await withRetry(() => loginFn(credentials), 'login');
330
+
331
+ const nextState = await setSession(session, 'authenticated');
332
+ await executeMiddleware('onAfterLogin', nextState);
333
+
334
+ return nextState;
335
+ } catch (error) {
336
+ await executeMiddleware('onError', error);
337
+ return await setSession(null, 'error', error);
338
+ }
339
+ };
340
+
341
+ const logout = async () => {
342
+ const current = state.session;
343
+
344
+ try {
345
+ await executeMiddleware('onBeforeLogout');
346
+ await config.logout?.(current ?? null);
347
+ } finally {
348
+ if (autoRefreshCleanup) {
349
+ autoRefreshCleanup();
350
+ autoRefreshCleanup = null;
351
+ }
352
+ await setSession(null, 'unauthenticated');
353
+ await executeMiddleware('onAfterLogout');
354
+ }
355
+ };
356
+
357
+ // ============================================================================
358
+ // Permission Checking
359
+ // ============================================================================
360
+
361
+ const hasRole = (
362
+ target: TRole | TRole[],
363
+ options?: { requireAll?: boolean },
364
+ ): boolean => {
365
+ return checkRoles(state.roles, target, options);
366
+ };
367
+
368
+ const hasPermission = (
369
+ target: TPermission | TPermission[] | PermissionPolicy<TPermission>,
370
+ options?: { requireAll?: boolean },
371
+ ): boolean => {
372
+ return checkPermissions(state.permissions, target, options);
373
+ };
374
+
375
+ const can = (rule: PermissionRule<TRole, TPermission>): boolean => {
376
+ return evaluatePermissionRule(state.roles, state.permissions, rule);
377
+ };
378
+
379
+ // ============================================================================
380
+ // Token Management
381
+ // ============================================================================
382
+
383
+ const getToken = (): string | null => {
384
+ return state.session?.accessToken ?? null;
385
+ };
386
+
387
+ const isTokenExpired = (): boolean => {
388
+ return tokenManager.isExpired(state.session?.expiresAt);
389
+ };
390
+
391
+ const getTimeUntilExpiry = (): number => {
392
+ return tokenManager.getTimeUntilExpiry(state.session?.expiresAt);
393
+ };
394
+
395
+ const scheduleAutoRefresh = (): (() => void) => {
396
+ setupAutoRefresh();
397
+ return () => {
398
+ if (autoRefreshCleanup) {
399
+ autoRefreshCleanup();
400
+ autoRefreshCleanup = null;
401
+ }
402
+ };
403
+ };
404
+
405
+ // ============================================================================
406
+ // API
407
+ // ============================================================================
408
+
409
+ const api: AuthAdapter<TUser, TRole, TPermission, TSession, TCredentials> = {
410
+ getState: () => state,
411
+ subscribe: (listener) => {
412
+ subscribers.add(listener);
413
+ return () => {
414
+ subscribers.delete(listener);
415
+ };
416
+ },
417
+ sync,
418
+ login: config.login ? login : undefined,
419
+ logout,
420
+ refresh: async () => {
421
+ return await refresh();
422
+ },
423
+ setSession: async (session) => {
424
+ return await setSession(session);
425
+ },
426
+ hasRole,
427
+ hasPermission,
428
+ can,
429
+ getToken,
430
+ isTokenExpired,
431
+ getTimeUntilExpiry,
432
+ scheduleAutoRefresh,
433
+ };
434
+
435
+ return api;
436
+ }