firstly 0.2.1 → 0.4.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 (210) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/esm/SqlDatabase/FF_LogToConsole.js +9 -14
  3. package/esm/carbone/CarboneController.js +2 -1
  4. package/esm/changeLog/index.d.ts +0 -10
  5. package/esm/{internals → core}/BaseEnum.d.ts +1 -1
  6. package/esm/core/FF_Entity.js +5 -0
  7. package/esm/core/helper.d.ts +2 -0
  8. package/esm/core/helper.js +3 -0
  9. package/esm/core/index.d.ts +0 -0
  10. package/esm/core/index.js +5 -0
  11. package/esm/core/tailwind.d.ts +21 -0
  12. package/esm/core/tailwind.js +22 -0
  13. package/esm/core/tryCatch.d.ts +44 -0
  14. package/esm/core/tryCatch.js +34 -0
  15. package/esm/cron/server/index.js +1 -1
  16. package/esm/feedback/FeedbackController.js +3 -2
  17. package/esm/feedback/index.d.ts +7 -2
  18. package/esm/feedback/index.js +1 -2
  19. package/esm/feedback/server/index.d.ts +0 -5
  20. package/esm/feedback/server/index.js +1 -1
  21. package/esm/formats/strings.js +2 -2
  22. package/esm/index.d.ts +16 -0
  23. package/esm/index.js +13 -0
  24. package/esm/svelte/FF_Repo.svelte.d.ts +9 -2
  25. package/esm/svelte/FF_Repo.svelte.js +40 -17
  26. package/esm/svelte/class/SP.svelte.js +14 -2
  27. package/esm/svelte/helpers/debounce.js +1 -1
  28. package/esm/svelte/index.d.ts +2 -24
  29. package/esm/svelte/index.js +2 -22
  30. package/esm/{ui → svelte/ui}/Icon.svelte +1 -1
  31. package/esm/virtual/StateDemoEnum.d.ts +3 -3
  32. package/esm/virtual/StateDemoEnum.js +3 -3
  33. package/esm/virtual/UIEntity.js +1 -2
  34. package/package.json +8 -39
  35. package/esm/auth/AuthController.d.ts +0 -58
  36. package/esm/auth/AuthController.js +0 -114
  37. package/esm/auth/Entities.d.ts +0 -47
  38. package/esm/auth/Entities.js +0 -182
  39. package/esm/auth/README.md +0 -3
  40. package/esm/auth/index.d.ts +0 -5
  41. package/esm/auth/index.js +0 -5
  42. package/esm/auth/server/AuthController.server.d.ts +0 -58
  43. package/esm/auth/server/AuthController.server.js +0 -518
  44. package/esm/auth/server/handleAuth.d.ts +0 -4
  45. package/esm/auth/server/handleAuth.js +0 -142
  46. package/esm/auth/server/handleGuard.d.ts +0 -22
  47. package/esm/auth/server/handleGuard.js +0 -34
  48. package/esm/auth/server/helperDb.d.ts +0 -10
  49. package/esm/auth/server/helperDb.js +0 -56
  50. package/esm/auth/server/helperFirstly.d.ts +0 -1
  51. package/esm/auth/server/helperFirstly.js +0 -9
  52. package/esm/auth/server/helperOslo.d.ts +0 -7
  53. package/esm/auth/server/helperOslo.js +0 -24
  54. package/esm/auth/server/helperRemultServer.d.ts +0 -5
  55. package/esm/auth/server/helperRemultServer.js +0 -44
  56. package/esm/auth/server/helperRole.d.ts +0 -19
  57. package/esm/auth/server/helperRole.js +0 -57
  58. package/esm/auth/server/index.d.ts +0 -8
  59. package/esm/auth/server/index.js +0 -8
  60. package/esm/auth/server/module.d.ts +0 -300
  61. package/esm/auth/server/module.js +0 -230
  62. package/esm/auth/server/providers/github.d.ts +0 -33
  63. package/esm/auth/server/providers/github.js +0 -87
  64. package/esm/auth/server/providers/helperProvider.d.ts +0 -1
  65. package/esm/auth/server/providers/helperProvider.js +0 -25
  66. package/esm/auth/static/assets/Page-BHW08QWz.css +0 -1
  67. package/esm/auth/static/assets/Page-BRNWcY5Z.d.ts +0 -2
  68. package/esm/auth/static/assets/Page-BRNWcY5Z.js +0 -1
  69. package/esm/auth/static/assets/Page-CFcEsGK8.d.ts +0 -2
  70. package/esm/auth/static/assets/Page-CFcEsGK8.js +0 -7
  71. package/esm/auth/static/assets/Page-tLVs5slF.d.ts +0 -2
  72. package/esm/auth/static/assets/Page-tLVs5slF.js +0 -1
  73. package/esm/auth/static/assets/index-D38rqu4x.d.ts +0 -201
  74. package/esm/auth/static/assets/index-D38rqu4x.js +0 -2
  75. package/esm/auth/static/assets/index-DKWpA6v7.css +0 -4
  76. package/esm/auth/static/favicon.svg +0 -79
  77. package/esm/auth/static/index.html +0 -13
  78. package/esm/auth/types.d.ts +0 -73
  79. package/esm/bin/cmd.d.ts +0 -1
  80. package/esm/bin/cmd.js +0 -793
  81. package/esm/feedback/ui/DialogIssue.svelte +0 -149
  82. package/esm/feedback/ui/DialogIssue.svelte.d.ts +0 -22
  83. package/esm/feedback/ui/DialogIssues.svelte +0 -114
  84. package/esm/feedback/ui/DialogIssues.svelte.d.ts +0 -22
  85. package/esm/feedback/ui/DialogMilestones.svelte +0 -43
  86. package/esm/feedback/ui/DialogMilestones.svelte.d.ts +0 -20
  87. package/esm/feedback/ui/Feedback.svelte +0 -16
  88. package/esm/feedback/ui/Feedback.svelte.d.ts +0 -18
  89. package/esm/internals/FF_Entity.d.ts +0 -2
  90. package/esm/internals/FF_Entity.js +0 -21
  91. package/esm/internals/FF_Fields.d.ts +0 -11
  92. package/esm/internals/FF_Fields.js +0 -144
  93. package/esm/internals/cellsBuildor.d.ts +0 -47
  94. package/esm/internals/cellsBuildor.js +0 -140
  95. package/esm/internals/helper.d.ts +0 -49
  96. package/esm/internals/helper.js +0 -162
  97. package/esm/internals/index.d.ts +0 -82
  98. package/esm/internals/index.js +0 -45
  99. package/esm/internals/storeItem.d.ts +0 -28
  100. package/esm/internals/storeItem.js +0 -176
  101. package/esm/internals/storeList.d.ts +0 -34
  102. package/esm/internals/storeList.js +0 -108
  103. package/esm/internals/theme.d.ts +0 -4
  104. package/esm/internals/theme.js +0 -4
  105. package/esm/server/index.d.ts +0 -52
  106. package/esm/server/index.js +0 -87
  107. package/esm/svelte/FF_Cell.svelte +0 -103
  108. package/esm/svelte/FF_Cell.svelte.d.ts +0 -33
  109. package/esm/svelte/FF_Cell_Caption.svelte +0 -20
  110. package/esm/svelte/FF_Cell_Caption.svelte.d.ts +0 -31
  111. package/esm/svelte/FF_Cell_Display.svelte +0 -61
  112. package/esm/svelte/FF_Cell_Display.svelte.d.ts +0 -29
  113. package/esm/svelte/FF_Cell_Edit.svelte +0 -104
  114. package/esm/svelte/FF_Cell_Edit.svelte.d.ts +0 -32
  115. package/esm/svelte/FF_Cell_Error.svelte +0 -20
  116. package/esm/svelte/FF_Cell_Error.svelte.d.ts +0 -31
  117. package/esm/svelte/FF_Cell_Hint.svelte +0 -20
  118. package/esm/svelte/FF_Cell_Hint.svelte.d.ts +0 -31
  119. package/esm/svelte/FF_Config.svelte +0 -29
  120. package/esm/svelte/FF_Config.svelte.d.ts +0 -9
  121. package/esm/svelte/FF_Form.svelte +0 -155
  122. package/esm/svelte/FF_Form.svelte.d.ts +0 -37
  123. package/esm/svelte/FF_Grid.svelte +0 -257
  124. package/esm/svelte/FF_Grid.svelte.d.ts +0 -37
  125. package/esm/svelte/FF_Layout.svelte +0 -62
  126. package/esm/svelte/FF_Layout.svelte.d.ts +0 -31
  127. package/esm/svelte/actions/intersection.d.ts +0 -6
  128. package/esm/svelte/actions/intersection.js +0 -17
  129. package/esm/svelte/customField.d.ts +0 -69
  130. package/esm/svelte/customField.js +0 -4
  131. package/esm/svelte/dialog/DialogManagement.svelte +0 -98
  132. package/esm/svelte/dialog/DialogManagement.svelte.d.ts +0 -18
  133. package/esm/svelte/dialog/DialogPrimitive.svelte +0 -156
  134. package/esm/svelte/dialog/DialogPrimitive.svelte.d.ts +0 -38
  135. package/esm/svelte/dialog/dialog.d.ts +0 -58
  136. package/esm/svelte/dialog/dialog.js +0 -130
  137. package/esm/svelte/ff_Config.svelte.d.ts +0 -91
  138. package/esm/svelte/ff_Config.svelte.js +0 -111
  139. package/esm/svelte/firstly.css +0 -14
  140. package/esm/svelte/helpers.d.ts +0 -30
  141. package/esm/svelte/helpers.js +0 -38
  142. package/esm/svelte/tryCatch.d.ts +0 -12
  143. package/esm/svelte/tryCatch.js +0 -18
  144. package/esm/sveltekit/server/index.d.ts +0 -5
  145. package/esm/sveltekit/server/index.js +0 -24
  146. package/esm/ui/Button.svelte +0 -138
  147. package/esm/ui/Button.svelte.d.ts +0 -13
  148. package/esm/ui/Clipboardable.svelte +0 -25
  149. package/esm/ui/Clipboardable.svelte.d.ts +0 -12
  150. package/esm/ui/Field.svelte +0 -382
  151. package/esm/ui/Field.svelte.d.ts +0 -40
  152. package/esm/ui/FieldGroup.svelte +0 -117
  153. package/esm/ui/FieldGroup.svelte.d.ts +0 -44
  154. package/esm/ui/Grid.svelte +0 -265
  155. package/esm/ui/Grid.svelte.d.ts +0 -57
  156. package/esm/ui/Grid2.svelte +0 -293
  157. package/esm/ui/Grid2.svelte.d.ts +0 -57
  158. package/esm/ui/GridLoading.svelte +0 -58
  159. package/esm/ui/GridLoading.svelte.d.ts +0 -23
  160. package/esm/ui/GridPaginate.svelte +0 -69
  161. package/esm/ui/GridPaginate.svelte.d.ts +0 -23
  162. package/esm/ui/GridPaginate2.svelte +0 -25
  163. package/esm/ui/GridPaginate2.svelte.d.ts +0 -7
  164. package/esm/ui/Loading.svelte +0 -16
  165. package/esm/ui/Loading.svelte.d.ts +0 -31
  166. package/esm/ui/Tooltip.svelte +0 -45
  167. package/esm/ui/Tooltip.svelte.d.ts +0 -32
  168. package/esm/ui/dialog/DialogForm.svelte +0 -76
  169. package/esm/ui/dialog/DialogForm.svelte.d.ts +0 -21
  170. package/esm/ui/dialog/DialogManagement.svelte +0 -96
  171. package/esm/ui/dialog/DialogManagement.svelte.d.ts +0 -26
  172. package/esm/ui/dialog/DialogPrimitive.svelte +0 -90
  173. package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +0 -38
  174. package/esm/ui/dialog/FormEditAction.svelte +0 -62
  175. package/esm/ui/dialog/FormEditAction.svelte.d.ts +0 -31
  176. package/esm/ui/dialog/dialog.d.ts +0 -60
  177. package/esm/ui/dialog/dialog.js +0 -100
  178. package/esm/ui/index.d.ts +0 -6
  179. package/esm/ui/index.js +0 -20
  180. package/esm/ui/internals/FieldContainer.svelte +0 -39
  181. package/esm/ui/internals/FieldContainer.svelte.d.ts +0 -18
  182. package/esm/ui/internals/Input.svelte +0 -143
  183. package/esm/ui/internals/Input.svelte.d.ts +0 -37
  184. package/esm/ui/internals/Textarea.svelte +0 -66
  185. package/esm/ui/internals/Textarea.svelte.d.ts +0 -33
  186. package/esm/ui/internals/select/MultiSelectMelt.svelte +0 -260
  187. package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +0 -32
  188. package/esm/ui/internals/select/Select2.svelte +0 -88
  189. package/esm/ui/internals/select/Select2.svelte.d.ts +0 -12
  190. package/esm/ui/internals/select/SelectMelt.svelte +0 -280
  191. package/esm/ui/internals/select/SelectMelt.svelte.d.ts +0 -40
  192. package/esm/ui/internals/select/SelectRadio.svelte +0 -43
  193. package/esm/ui/internals/select/SelectRadio.svelte.d.ts +0 -27
  194. package/esm/ui/link/Link.svelte +0 -33
  195. package/esm/ui/link/Link.svelte.d.ts +0 -33
  196. package/esm/ui/link/LinkPlus.svelte +0 -63
  197. package/esm/ui/link/LinkPlus.svelte.d.ts +0 -9
  198. package/esm/utils/tailwind.d.ts +0 -2
  199. package/esm/utils/tailwind.js +0 -3
  200. package/esm/utils/transition.d.ts +0 -9
  201. package/esm/utils/transition.js +0 -33
  202. package/esm/utils/types.js +0 -1
  203. /package/esm/{internals → core}/BaseEnum.js +0 -0
  204. /package/esm/{internals → core}/common.d.ts +0 -0
  205. /package/esm/{internals → core}/common.js +0 -0
  206. /package/esm/{utils → core}/types.d.ts +0 -0
  207. /package/esm/{auth → core}/types.js +0 -0
  208. /package/esm/{ui → svelte/ui}/Icon.svelte.d.ts +0 -0
  209. /package/esm/{ui → svelte/ui}/LibIcon.d.ts +0 -0
  210. /package/esm/{ui → svelte/ui}/LibIcon.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,70 @@
1
1
  # firstly
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`b70967d`](https://github.com/jycouet/firstly/commit/b70967d0536298ec6659653da45eaa9e8b8e7fb0) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Remove unused legacy components from `firstly/svelte`: `FF_Cell` (+ `FF_Cell_Caption/Display/Edit/Error/Hint`), `FF_Form`, `FF_Grid`, `FF_Layout`, `FF_Config` (+ `ff_Config.svelte.ts` with `daisyTheme`, `defaultTheme`, `emptyTheme`, `getTheme`, `setTheme`, `getDynamicCustomField`, `setDynamicCustomField`, `getClasses`, `FF_Theme`). Also removed `customField.ts` (`DynamicCustomField`, `CellMetadata`, `FieldGroup`, `getLayout`, and the related `FieldOptions.ui` / `EntityOptions.ui.getLayout` Remult module augmentations). Drops the `FF_Repo.getLayout()` instance method and the `internals/select/Select2.svelte` internal.
8
+
9
+ Also deletes the duplicate dead `svelte/dialog/` tree (the canonical `dialog()` API is exported from `firstly/internals` and backed by `ui/dialog/`).
10
+
11
+ Internal: removes the `task` demo module and its demo routes (`demo/FF_Cell`, `demo/FF_Form_Grid`, `demo/FF_Layout`, `demo/FF_Simple`).
12
+
13
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`6589feb`](https://github.com/jycouet/firstly/commit/6589feba930250ffd842891f169faabfa498312b) Thanks [@jycouet](https://github.com/jycouet)! - Move `BaseEnum`, `FF_Entity`, `common` (`FF_Role`) source files from `lib/internals/` to `lib/core/`. The public export path is still `firstly/core`, which now also exports `FF_Role` (previously only available via `firstly/internals`) alongside the existing `BaseEnum`, `BaseEnumOptions`, `FF_Entity`, `isError`, `BaseItem`, `BaseItemLight`, `FF_Icon`. Consumers should migrate remaining `FF_Role` imports from `firstly/internals` to `firstly/core`.
14
+
15
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`c4d2ee4`](https://github.com/jycouet/firstly/commit/c4d2ee4a4b7a1441c985c62b55f9fbacbfe02b9b) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Fold `firstly/core` into the root `firstly` export.
16
+
17
+ `lib/utils/` (types + `tw`) moves into `lib/core/`. The `lib/core/index.ts` barrel is now empty — all core, frontend-safe primitives (`BaseEnum`, `BaseEnumOptions`, `BaseItem`, `BaseItemLight`, `FF_Icon`, `FF_Entity`, `FF_Role`, `isError`, `tryCatch`, `tryCatchSync`, `ResolvedType`, `UnArray`, `RecursivePartial`, `tw`) are re-exported from `lib/index.ts`, so consumers should import them from `'firstly'` directly.
18
+
19
+ The `./core` subpath is removed from `package.json` exports. Migrate `from 'firstly/core'` -> `from 'firstly'`.
20
+
21
+ Also moves the `RemultContext.feedbackOptions` module augmentation from `FeedbackController.ts` into `feedback/index.ts`, because some bundlers mangle `declare module 'remult'` inside a file that also has `@BackendMethod` decorators.
22
+
23
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`b382619`](https://github.com/jycouet/firstly/commit/b3826192a26e529c45f78dffa59f9955e92f3257) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Remove the `firstly` CLI.
24
+
25
+ The `bin` entry, the `./bin` export path, and `src/lib/bin/cmd.ts` are gone. Drops the `@clack/prompts` and `@kitql/internals` deps that only the CLI used.
26
+
27
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`64c4644`](https://github.com/jycouet/firstly/commit/64c4644d8c75d7b757a2d4a4128cd0b4f5799c50) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Remove the `firstly({ ... })` server wrapper and the `./server`, let's now just use remult Modules
28
+
29
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`a784113`](https://github.com/jycouet/firstly/commit/a784113217ba477fc36de3fee7ba6e82c8248cf5) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Remove `ModuleFF` and the `modulesFF` option.
30
+
31
+ Use `Module` from `remult/server` directly (it has all the same features: `key`, `priority`, `entities`, `controllers`, `initApi`, `initRequest`, nested `modules`). Remult also ships its own `modulesFlatAndOrdered`, so firstly's version is gone too. The `firstly({ ... })` wrapper now only accepts remult's native `modules` option.
32
+
33
+ Migration:
34
+
35
+ ```ts
36
+ // before
37
+ import { ModuleFF } from 'firstly/server'
38
+ new ModuleFF({ name: 'foo', modulesFF: [...] })
39
+
40
+ // after
41
+ import { Module } from 'remult/server'
42
+ new Module({ key: 'foo', modules: [...] })
43
+ ```
44
+
45
+ If you used `m.log`, create your own: `const log = new Log(key)` at module scope and reference it from `initApi` / `initRequest`.
46
+
47
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`7e49152`](https://github.com/jycouet/firstly/commit/7e49152d3af4f2ca40635ec0e1112a7ffa0de786) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Remove the deprecated internal `sveltekit` module and the `RemultContext.setHeaders` / `setCookie` / `deleteCookie` augmentation it set up.
48
+
49
+ Nothing consumed those context methods. The module itself was marked `@deprecated` and was only auto-wired through `firstly({ ... })`. `remult.context.request` (the `RequestEvent`) is still augmented, so headers and cookies can be set via `remult.context.request.setHeaders(...)` / `remult.context.request.cookies.set(...)` directly.
50
+
51
+ ### Patch Changes
52
+
53
+ - [#239](https://github.com/jycouet/firstly/pull/239) [`b70967d`](https://github.com/jycouet/firstly/commit/b70967d0536298ec6659653da45eaa9e8b8e7fb0) Thanks [@jycouet](https://github.com/jycouet)! - Bump deps: `nodemailer` 7 → 8 (+ `@types/nodemailer`), `tailwindcss` + `@tailwindcss/vite` 4.1.14 → 4.2.2, `vite-plugin-watch-and-run` 1.7.5 → 1.8.0, `@playwright/test` 1.58.2 → 1.59.1.
54
+
55
+ ## 0.3.0
56
+
57
+ ### Minor Changes
58
+
59
+ - [#232](https://github.com/jycouet/firstly/pull/232) [`fec8bc0`](https://github.com/jycouet/firstly/commit/fec8bc088733d63ce6752b0a764b786f80b736cb) Thanks [@jycouet](https://github.com/jycouet)! - BREAKING: Remove deprecated lucia-style auth module (`firstly/auth`, `firstly/auth/server`).
60
+
61
+ Migrate to `better-auth` (see remult docs). Removed deps: `@oslojs/*`, `arctic`, `bcryptjs`.
62
+ Also removed `packages/ui` (was only used for the auth UI).
63
+
64
+ ### Patch Changes
65
+
66
+ - [#221](https://github.com/jycouet/firstly/pull/221) [`0b08040`](https://github.com/jycouet/firstly/commit/0b0804001c9a5bdff560fbcbb8b511c626d260f8) Thanks [@jycouet](https://github.com/jycouet)! - bump deps
67
+
3
68
  ## 0.2.1
4
69
 
5
70
  ### Patch Changes
@@ -16,7 +16,7 @@ const typeQuery = new Map([
16
16
  ['REVOKE', '🟫'], // Used to take back permissions from a user.
17
17
  ]);
18
18
  const keys = ['FROM', 'WHERE', 'LIMIT', 'OFFSET'];
19
- const typeQueryKey = Array.from(typeQuery.keys());
19
+ const typeQueryKey = [...typeQuery.keys()];
20
20
  const log = new Log('');
21
21
  /**
22
22
  * @example
@@ -110,22 +110,17 @@ export const FF_LogToConsole = (duration, query, args, options) => {
110
110
  // final_s = final_s.replace(arg, yellow(args[arg]))
111
111
  // }
112
112
  const uniqueTables = [...new Set(tables)];
113
- const mainTable = uniqueTables[uniqueTables.length - 1];
113
+ const mainTable = uniqueTables.at(-1) ?? '';
114
114
  const subTables = uniqueTables.slice(0, -1);
115
115
  const time = ` ${bgCyan((duration * 1000).toFixed(0).padStart(3) + ' ms ')}`;
116
- let toLog = '';
117
116
  const withDetails = options?.withDetails === undefined ? true : options?.withDetails;
118
- if (withDetails) {
119
- toLog = `${typeQuery.get(first) || '💢'}` + time + ` ${final_s}`;
120
- }
121
- else {
122
- toLog =
123
- `${typeQuery.get(first) || '💢'}` +
124
- `${time}` +
125
- ` ${cyan(first)} ${green(mainTable?.replaceAll('"', ''))}` +
126
- `${listArgs.length > 0 ? ` { ${listArgs.join(', ')} }` : ``}` +
127
- `${subTables.length > 0 ? magenta(` (sub: ${subTables.join(', ')})`) : ``}`;
128
- }
117
+ const toLog = withDetails
118
+ ? `${typeQuery.get(first) || '💢'}` + time + ` ${final_s}`
119
+ : `${typeQuery.get(first) || '💢'}` +
120
+ `${time}` +
121
+ ` ${cyan(first)} ${green(mainTable?.replaceAll('"', ''))}` +
122
+ `${listArgs.length > 0 ? ` { ${listArgs.join(', ')} }` : ``}` +
123
+ `${subTables.length > 0 ? magenta(` (sub: ${subTables.join(', ')})`) : ``}`;
129
124
  log.info(toLog);
130
125
  if (options?.ending) {
131
126
  options.ending(duration, query, args, tables);
@@ -71,7 +71,7 @@ export class CarboneController {
71
71
  }
72
72
  static async deleteTemplate(config) {
73
73
  const { templateId } = config;
74
- const response = await CarboneController.server.fetch({
74
+ await CarboneController.server.fetch({
75
75
  api: `/template/${templateId}`,
76
76
  method: 'DELETE',
77
77
  });
@@ -84,6 +84,7 @@ export class CarboneController {
84
84
  static async render(config) {
85
85
  const { templateName, templateBase64, data, filename } = config;
86
86
  let { templateId, convertTo } = config;
87
+ // eslint-disable-next-line
87
88
  let mode = '';
88
89
  if (templateBase64) {
89
90
  mode = 'templateBase64';
@@ -45,15 +45,5 @@ export declare const withChangeLog: <entityType>(options?: EntityOptions<entityT
45
45
  entityRefInit?: ((ref: import("remult").EntityRef<entityType>, row: entityType) => void) | undefined;
46
46
  apiRequireId?: import("remult").Allowed;
47
47
  dataProvider?: ((defaultDataProvider: import("remult").DataProvider) => import("remult").DataProvider | Promise<import("remult").DataProvider> | undefined | null) | undefined;
48
- ui?: {
49
- getLayout?: import("../svelte/customField").getLayout<entityType> | undefined;
50
- } | undefined;
51
- searchableFind?: ((str: string) => import("remult").FindOptionsBase<entityType>) | undefined;
52
- displayValue?: ((item: entityType) => import("../internals").BaseItem) | undefined;
53
- permissionApiCrud?: import("../internals").BaseEnum[] | import("../internals").BaseEnum;
54
- permissionApiDelete?: import("../internals").BaseEnum[] | import("../internals").BaseEnum;
55
- permissionApiInsert?: import("../internals").BaseEnum[] | import("../internals").BaseEnum;
56
- permissionApiRead?: import("../internals").BaseEnum[] | import("../internals").BaseEnum;
57
- permissionApiUpdate?: import("../internals").BaseEnum[] | import("../internals").BaseEnum;
58
48
  changeLog?: false | ColumnDeciderArgs<entityType> | undefined;
59
49
  };
@@ -8,7 +8,7 @@ export type FF_Icon = {
8
8
  caption?: string;
9
9
  };
10
10
  export type BaseItem = BaseEnumOptions & {
11
- id: string;
11
+ id: string | null;
12
12
  captionSub?: string | (string | undefined)[];
13
13
  href?: string;
14
14
  repo?: Repository<any>;
@@ -0,0 +1,5 @@
1
+ import { Entity } from 'remult';
2
+ import { withChangeLog } from '../changeLog';
3
+ export function FF_Entity(key, options) {
4
+ return Entity(key, withChangeLog({ ...options }));
5
+ }
@@ -0,0 +1,2 @@
1
+ import type { ErrorInfo } from 'remult';
2
+ export declare function isError<T>(object: any): object is ErrorInfo<T>;
@@ -0,0 +1,3 @@
1
+ export function isError(object) {
2
+ return object;
3
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ // Files under lib/core/ are the pure-TS, frontend-safe primitives.
3
+ // They are re-exported from lib/index.ts (the `firstly` root export).
4
+ // Keep this barrel empty — import sources directly from ./BaseEnum,
5
+ // ./FF_Entity, ./common, ./helper, ./tryCatch, ./types, ./tailwind.
@@ -0,0 +1,21 @@
1
+ import { type ClassValue } from 'clsx';
2
+ /**
3
+ * Merges Tailwind CSS classes using clsx and tailwind-merge.
4
+ * This utility helps combine conditional classes and resolves conflicts.
5
+ *
6
+ * @param inputs - Class values to merge (strings, objects, arrays, etc.)
7
+ * @returns A merged string of Tailwind classes
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { tw } from './tailwind'
12
+ *
13
+ * const buttonClasses = tw(
14
+ * 'btn btn-primary',
15
+ * isDisabled && 'btn-disabled',
16
+ * size === 'lg' && 'btn-lg'
17
+ * )
18
+ * // Result: "btn btn-primary btn-disabled" (if isDisabled is true)
19
+ * ```
20
+ */
21
+ export declare const tw: (...inputs: ClassValue[]) => string;
@@ -0,0 +1,22 @@
1
+ import { clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+ /**
4
+ * Merges Tailwind CSS classes using clsx and tailwind-merge.
5
+ * This utility helps combine conditional classes and resolves conflicts.
6
+ *
7
+ * @param inputs - Class values to merge (strings, objects, arrays, etc.)
8
+ * @returns A merged string of Tailwind classes
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { tw } from './tailwind'
13
+ *
14
+ * const buttonClasses = tw(
15
+ * 'btn btn-primary',
16
+ * isDisabled && 'btn-disabled',
17
+ * size === 'lg' && 'btn-lg'
18
+ * )
19
+ * // Result: "btn btn-primary btn-disabled" (if isDisabled is true)
20
+ * ```
21
+ */
22
+ export const tw = (...inputs) => twMerge(clsx(...inputs));
@@ -0,0 +1,44 @@
1
+ /**
2
+ * A successful result returned by `tryCatch` or `tryCatchSync`.
3
+ *
4
+ * @template T - The type of the resolved value.
5
+ */
6
+ type Success<T> = {
7
+ data: T;
8
+ error: null;
9
+ };
10
+ /**
11
+ * A failure result returned by `tryCatch` or `tryCatchSync`.
12
+ *
13
+ * @template E - The type of the thrown error.
14
+ */
15
+ type Failure<E> = {
16
+ data: null;
17
+ error: E;
18
+ };
19
+ /**
20
+ * A result wrapper that contains either a success value or an error.
21
+ *
22
+ * @template T - The type of the success value.
23
+ * @template E - The type of the error value.
24
+ */
25
+ type Result<T, E = Error> = Success<T> | Failure<E>;
26
+ /**
27
+ * Wraps an async promise and returns a `Result` object instead of throwing.
28
+ *
29
+ * @template T - The type of the resolved value.
30
+ * @template E - The type of the rejected error.
31
+ * @param promise - The promise to execute.
32
+ * @returns A result object with either `data` or `error`.
33
+ */
34
+ export declare function tryCatch<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>>;
35
+ /**
36
+ * Wraps a synchronous function call and returns a `Result` object instead of throwing.
37
+ *
38
+ * @template T - The type of the returned value.
39
+ * @template E - The type of the thrown error.
40
+ * @param func - The synchronous function to execute.
41
+ * @returns A result object with either `data` or `error`.
42
+ */
43
+ export declare function tryCatchSync<T, E = Error>(func: () => T): Result<T, E>;
44
+ export {};
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Wraps an async promise and returns a `Result` object instead of throwing.
3
+ *
4
+ * @template T - The type of the resolved value.
5
+ * @template E - The type of the rejected error.
6
+ * @param promise - The promise to execute.
7
+ * @returns A result object with either `data` or `error`.
8
+ */
9
+ export async function tryCatch(promise) {
10
+ try {
11
+ const data = await promise;
12
+ return { data, error: null };
13
+ }
14
+ catch (error) {
15
+ return { data: null, error: error };
16
+ }
17
+ }
18
+ /**
19
+ * Wraps a synchronous function call and returns a `Result` object instead of throwing.
20
+ *
21
+ * @template T - The type of the returned value.
22
+ * @template E - The type of the thrown error.
23
+ * @param func - The synchronous function to execute.
24
+ * @returns A result object with either `data` or `error`.
25
+ */
26
+ export function tryCatchSync(func) {
27
+ try {
28
+ const data = func();
29
+ return { data, error: null };
30
+ }
31
+ catch (error) {
32
+ return { data: null, error: error };
33
+ }
34
+ }
@@ -98,7 +98,7 @@ export const cron = (jobsInfos) => {
98
98
  jobs[topic].concurrentInProgress = jobs[topic].concurrentInProgress - 1;
99
99
  }
100
100
  else {
101
- const rCron = await repo(Cron).insert({ topic, status: 'skipped' });
101
+ await repo(Cron).insert({ topic, status: 'skipped' });
102
102
  logJobs(topic, job, `skipped because of concurrent limit (${yellow(concurrentToUse.toString())})`, false, false);
103
103
  }
104
104
  };
@@ -204,8 +204,9 @@ repository(name: $repository, owner: $owner) {
204
204
  for (let i = 0; i < comments.length; i++) {
205
205
  if (comments[i].isMinimized) {
206
206
  const parsed = JSON.parse(comments[i].body.replaceAll('<pre>\n', '').replaceAll('\n</pre>', ''));
207
- items[items.length - 1].who = parsed?.author ?? '???';
208
- items[items.length - 1].public = true;
207
+ const last = items.at(-1);
208
+ last.who = parsed?.author ?? '???';
209
+ last.public = true;
209
210
  }
210
211
  else {
211
212
  const nbEye = comments[i].reactionGroups.find((c) => c.content === 'EYES')?.reactors.totalCount;
@@ -1,3 +1,8 @@
1
1
  import { FeedbackController } from './FeedbackController';
2
- import { default as Feedback } from './ui/Feedback.svelte';
3
- export { FeedbackController, Feedback };
2
+ import type { FeedbackOptions } from './types';
3
+ export { FeedbackController };
4
+ declare module 'remult' {
5
+ interface RemultContext {
6
+ feedbackOptions: FeedbackOptions;
7
+ }
8
+ }
@@ -1,3 +1,2 @@
1
1
  import { FeedbackController } from './FeedbackController';
2
- import { default as Feedback } from './ui/Feedback.svelte';
3
- export { FeedbackController, Feedback };
2
+ export { FeedbackController };
@@ -1,8 +1,3 @@
1
1
  import { Module } from 'remult/server';
2
2
  import type { FeedbackOptions } from '../types';
3
3
  export declare const feedback: (o: FeedbackOptions) => Module<unknown>;
4
- declare module 'remult' {
5
- interface RemultContext {
6
- feedbackOptions: FeedbackOptions;
7
- }
8
- }
@@ -5,7 +5,7 @@ export const feedback = (o) => {
5
5
  return new Module({
6
6
  key: 'feedback',
7
7
  controllers: [FeedbackController],
8
- initRequest: async (kitEvent, op) => {
8
+ initRequest: async () => {
9
9
  remult.context.feedbackOptions = o;
10
10
  },
11
11
  });
@@ -60,6 +60,7 @@ export const toTitleCase = (str) => {
60
60
  const rmvChars = (str, chars = ['<', '>', ',']) => {
61
61
  return chars.reduce((acc, char) => acc.replaceAll(char, ''), str).trim();
62
62
  };
63
+ const extractMailRegex = /(.+)\s(.+)\s<(.+)>/i;
63
64
  export const extractMailInfo = (mail, withThrow = true) => {
64
65
  if (!mail) {
65
66
  if (withThrow) {
@@ -71,8 +72,7 @@ export const extractMailInfo = (mail, withThrow = true) => {
71
72
  email: '',
72
73
  };
73
74
  }
74
- const regex = /(.+)\s(.+)\s<(.+)>/i;
75
- const match = mail.match(regex);
75
+ const match = mail.match(extractMailRegex);
76
76
  if (match) {
77
77
  const firstName = toTitleCase(rmvChars(match[1].trim())).replaceAll(' ', '-');
78
78
  const lastName = rmvChars(match[2].trim()).toUpperCase();
package/esm/index.d.ts CHANGED
@@ -3,3 +3,19 @@ export {
3
3
  /** alias for @kitql/helpers */
4
4
  h, };
5
5
  export declare const ff_Log: h.Log;
6
+ export { BaseEnum } from './core/BaseEnum.js';
7
+ export type { BaseEnumOptions, BaseItem, BaseItemLight, FF_Icon } from './core/BaseEnum.js';
8
+ export { FF_Entity } from './core/FF_Entity.js';
9
+ export { FF_Role } from './core/common.js';
10
+ export { isError } from './core/helper.js';
11
+ export { tryCatch, tryCatchSync } from './core/tryCatch.js';
12
+ export type { ResolvedType, UnArray, RecursivePartial } from './core/types.js';
13
+ export { tw } from './core/tailwind.js';
14
+ export { FF_LogToConsole } from './SqlDatabase/FF_LogToConsole.js';
15
+ export { FilterEntity } from './virtual/FilterEntity.js';
16
+ export { UIEntity } from './virtual/UIEntity.js';
17
+ declare module 'remult' {
18
+ interface FieldOptions<entityType, valueType> {
19
+ placeholder?: string;
20
+ }
21
+ }
package/esm/index.js CHANGED
@@ -3,3 +3,16 @@ export {
3
3
  /** alias for @kitql/helpers */
4
4
  h, };
5
5
  export const ff_Log = new h.Log('firstly');
6
+ // ******************************
7
+ // Core (pure TS, frontend-safe) - re-exported from lib/core/
8
+ // ******************************
9
+ export { BaseEnum } from './core/BaseEnum.js';
10
+ export { FF_Entity } from './core/FF_Entity.js';
11
+ export { FF_Role } from './core/common.js';
12
+ export { isError } from './core/helper.js';
13
+ export { tryCatch, tryCatchSync } from './core/tryCatch.js';
14
+ export { tw } from './core/tailwind.js';
15
+ // Misc primitives still exposed from the root.
16
+ export { FF_LogToConsole } from './SqlDatabase/FF_LogToConsole.js';
17
+ export { FilterEntity } from './virtual/FilterEntity.js';
18
+ export { UIEntity } from './virtual/UIEntity.js';
@@ -1,5 +1,4 @@
1
1
  import { type ClassType, type FindOptions, type GroupByOptions, type GroupByResult, type MembersOnly, type NumericKeys, type QueryOptions, type Repository } from 'remult';
2
- import type { getLayoutStrict } from './customField';
3
2
  type EmptyAggregateResult = {
4
3
  $count: number;
5
4
  };
@@ -62,8 +61,16 @@ export declare class FF_Repo<Entity, QueryOptions extends QueryOptionsHelper<Ent
62
61
  aggregates: ExtractAggregateResult<Entity, QueryOptions>;
63
62
  hasNextPage: boolean;
64
63
  } | undefined>;
64
+ /**
65
+ * Refresh query keeping current items count (BIG refresh)
66
+ * Useful after edit/delete to stay at current scroll position
67
+ */
68
+ queryRefresh(options: Pick<QueryOptionsHelper<Entity>, 'where' | 'orderBy'>): Promise<{
69
+ items: Entity[];
70
+ aggregates: ExtractAggregateResult<Entity, QueryOptions>;
71
+ hasNextPage: boolean;
72
+ } | undefined>;
65
73
  create(...args: Parameters<Repository<Entity>['create']>): Entity;
66
74
  delete(...args: Parameters<Repository<Entity>['delete']>): Promise<undefined>;
67
- getLayout: getLayoutStrict<Entity>;
68
75
  }
69
76
  export {};
@@ -1,6 +1,6 @@
1
1
  import { repo as remultRepo, } from 'remult';
2
2
  import { Log } from '@kitql/helpers';
3
- import { tryCatch, tryCatchSync } from './';
3
+ import { tryCatch, tryCatchSync } from '../core/tryCatch.js';
4
4
  export class FF_Repo {
5
5
  ent;
6
6
  #repo;
@@ -132,6 +132,45 @@ export class FF_Repo {
132
132
  hasNextPage: this.hasNextPage,
133
133
  });
134
134
  }
135
+ /**
136
+ * Refresh query keeping current items count (BIG refresh)
137
+ * Useful after edit/delete to stay at current scroll position
138
+ */
139
+ async queryRefresh(options) {
140
+ const currentCount = this.items?.length ?? this.#queryOptions?.pageSize ?? 25;
141
+ this.loading = {
142
+ ...this.loading,
143
+ fetching: true,
144
+ init: this.items === undefined,
145
+ };
146
+ const { data: queryResult, error: queryResultError } = tryCatchSync(() => this.#repo.query({
147
+ ...this.#queryOptions,
148
+ ...options,
149
+ pageSize: currentCount,
150
+ aggregate: {
151
+ ...this.#queryOptions?.aggregate,
152
+ },
153
+ }));
154
+ if (queryResultError) {
155
+ this.globalError = queryResultError.message;
156
+ return this.loadingEnd();
157
+ }
158
+ const { data: paginator, error: paginatorError } = await tryCatch(queryResult.paginator());
159
+ if (paginatorError) {
160
+ this.globalError = paginatorError.message;
161
+ return this.loadingEnd();
162
+ }
163
+ this.#paginator = paginator;
164
+ this.items = this.#paginator.items;
165
+ // @ts-expect-error - We know the structure will match due to how we define the types
166
+ this.aggregates = this.#paginator.aggregates;
167
+ this.hasNextPage = this.#paginator.hasNextPage && this.aggregates.$count > this.items.length;
168
+ return this.loadingEnd({
169
+ items: this.items,
170
+ aggregates: this.aggregates,
171
+ hasNextPage: this.hasNextPage,
172
+ });
173
+ }
135
174
  create(...args) {
136
175
  this.item = this.#repo.create(...args);
137
176
  return this.item;
@@ -151,20 +190,4 @@ export class FF_Repo {
151
190
  }
152
191
  return this.loadingEnd();
153
192
  }
154
- getLayout = (o) => {
155
- const layout = this.metadata.options.ui?.getLayout?.(o);
156
- if (layout) {
157
- return layout;
158
- }
159
- return {
160
- key: o?.key ?? 'default',
161
- type: o?.type ?? 'grid',
162
- groups: [
163
- {
164
- key: o?.key ?? 'default',
165
- fields: this.#repo.fields.toArray().filter((c) => c.apiUpdateAllowed()),
166
- },
167
- ],
168
- };
169
- };
170
193
  }
@@ -7,6 +7,7 @@ import { goto } from '$app/navigation';
7
7
  import { page } from '$app/state';
8
8
  import { debounce } from '../helpers/debounce.js';
9
9
  const CONFIG_DELIMITER = ';';
10
+ const NULL_URL_VALUE = '__null__';
10
11
  /**
11
12
  * SearchParams class for handling URL search parameters with Svelte 5 runes
12
13
  * Provides automatic binding and URL updates
@@ -257,6 +258,12 @@ export class SP {
257
258
  const urlKey = this.keyMap[propKey]; // Get the URL parameter key
258
259
  const paramValue = params.get(urlKey);
259
260
  if (paramValue !== null) {
261
+ // Decode null sentinel from URL
262
+ if (paramValue === NULL_URL_VALUE) {
263
+ this.paramValues[propKey] = null;
264
+ this.debouncedValues[propKey] = null;
265
+ continue;
266
+ }
260
267
  // If there is a decode function, always use it to get the proper object
261
268
  if (def.decode) {
262
269
  const decodedValue = def.decode(paramValue);
@@ -314,11 +321,16 @@ export class SP {
314
321
  }
315
322
  const params = new URLSearchParams(window.location.search);
316
323
  for (const [propKey, value] of Object.entries(this.debouncedValues)) {
317
- // Skip undefined or null values
318
- if (value === undefined || value === null) {
324
+ // Skip undefined values
325
+ if (value === undefined) {
319
326
  params.delete(this.keyMap[propKey]);
320
327
  continue;
321
328
  }
329
+ // Encode null as special URL value
330
+ if (value === null) {
331
+ params.set(this.keyMap[propKey], NULL_URL_VALUE);
332
+ continue;
333
+ }
322
334
  // Get the definition and URL key
323
335
  const def = this.config[propKey];
324
336
  if (!def)
@@ -2,6 +2,6 @@ export const debounce = (fn, delay = 444) => {
2
2
  let timeout;
3
3
  return (...args) => {
4
4
  clearTimeout(timeout);
5
- timeout = setTimeout(() => fn(...args), delay);
5
+ timeout = setTimeout(fn, delay, ...args);
6
6
  };
7
7
  };
@@ -1,28 +1,6 @@
1
- import type { CellMetadata, getLayout } from './customField';
2
- import { default as FF_Cell_Display } from './FF_Cell_Display.svelte';
3
- import { default as FF_Cell } from './FF_Cell.svelte';
4
- import { default as FF_Config } from './FF_Config.svelte';
5
- import { default as FF_Form } from './FF_Form.svelte';
6
- import { default as FF_Grid } from './FF_Grid.svelte';
7
- import { default as FF_Layout } from './FF_Layout.svelte';
8
- export type { FieldTheme, FormTheme, GridTheme, Theme, EditTheme, DisplayTheme, } from './ff_Config.svelte.js';
9
- export { getDynamicCustomField, getTheme, setDynamicCustomField, setTheme, getClasses, daisyTheme, defaultTheme, emptyTheme, FF_Theme, } from './ff_Config.svelte.js';
10
- export { FF_Grid, FF_Form, FF_Config, FF_Layout, FF_Cell, FF_Cell_Display };
11
- export type { DynamicCustomField, FieldGroup } from './customField';
12
1
  export { FF_Repo } from './FF_Repo.svelte.js';
13
- export { tryCatch, tryCatchSync } from './tryCatch';
14
- export { overwriteOptions, deepMerge, isOfType } from './helpers';
15
- export { dialog } from './dialog/dialog';
16
2
  export { SP } from './class/SP.svelte';
17
3
  export type { ParamDefinition } from './class/SP.svelte';
18
4
  export { initRemultSvelteReactivity } from './initRemultSvelteReactivity';
19
- declare module 'remult' {
20
- interface FieldOptions<entityType = unknown, valueType = unknown> {
21
- ui?: CellMetadata<valueType, entityType>['ui'];
22
- }
23
- interface EntityOptions<entityType> {
24
- ui?: {
25
- getLayout?: getLayout<entityType>;
26
- };
27
- }
28
- }
5
+ export { default as Icon } from './ui/Icon.svelte';
6
+ export { LibIcon_Empty, LibIcon_Forbidden, LibIcon_ChevronDown, LibIcon_ChevronUp, LibIcon_ChevronLeft, LibIcon_ChevronRight, LibIcon_Search, LibIcon_Check, LibIcon_MultiCheck, LibIcon_Add, LibIcon_MultiAdd, LibIcon_Edit, LibIcon_Eye, LibIcon_EyeOff, LibIcon_Delete, LibIcon_Cross, LibIcon_Save, LibIcon_Man, LibIcon_Woman, LibIcon_Send, LibIcon_Load, LibIcon_Settings, LibIcon_Sort, LibIcon_SortAsc, LibIcon_SortDesc, } from './ui/LibIcon.js';
@@ -1,25 +1,5 @@
1
- import { default as FF_Cell_Display } from './FF_Cell_Display.svelte';
2
- import { default as FF_Cell } from './FF_Cell.svelte';
3
- import { default as FF_Config } from './FF_Config.svelte';
4
- import { default as FF_Form } from './FF_Form.svelte';
5
- import { default as FF_Grid } from './FF_Grid.svelte';
6
- import { default as FF_Layout } from './FF_Layout.svelte';
7
- export { getDynamicCustomField, getTheme, setDynamicCustomField, setTheme, getClasses, daisyTheme, defaultTheme, emptyTheme, FF_Theme, } from './ff_Config.svelte.js';
8
- export { FF_Grid, FF_Form, FF_Config, FF_Layout, FF_Cell, FF_Cell_Display };
9
1
  export { FF_Repo } from './FF_Repo.svelte.js';
10
- export { tryCatch, tryCatchSync } from './tryCatch';
11
- export { overwriteOptions, deepMerge, isOfType } from './helpers';
12
- export { dialog } from './dialog/dialog';
13
2
  export { SP } from './class/SP.svelte';
14
3
  export { initRemultSvelteReactivity } from './initRemultSvelteReactivity';
15
- // - [ ] Try to pnpm pack to see what css is needed.
16
- // - [ ] let's look at the data-ff-xxx story ?
17
- // - [ ] how lib defaults should be configured ?
18
- // - [ ] What deault css should be provided to the user ?
19
- // - [ ] Add fform in readonly mode (readonly / edit / insert ?)
20
- // - [ ] Add Filter Fields
21
- // - [ ] Add actions form (cancel button to form, global error, ...)
22
- // - [x] Create a dedicated FF_Dialog
23
- // - [ ] switch to data-ff-dialog (https://www.melt-ui.com/docs/builders/dialog example with non tailwind)
24
- // - [ ] Create a [crud] demo ? a [crud]/[detail] demo ?
25
- // - [ ] Add Toast ?
4
+ export { default as Icon } from './ui/Icon.svelte';
5
+ export { LibIcon_Empty, LibIcon_Forbidden, LibIcon_ChevronDown, LibIcon_ChevronUp, LibIcon_ChevronLeft, LibIcon_ChevronRight, LibIcon_Search, LibIcon_Check, LibIcon_MultiCheck, LibIcon_Add, LibIcon_MultiAdd, LibIcon_Edit, LibIcon_Eye, LibIcon_EyeOff, LibIcon_Delete, LibIcon_Cross, LibIcon_Save, LibIcon_Man, LibIcon_Woman, LibIcon_Send, LibIcon_Load, LibIcon_Settings, LibIcon_Sort, LibIcon_SortAsc, LibIcon_SortDesc, } from './ui/LibIcon.js';