firstly 0.3.0 → 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 (163) hide show
  1. package/CHANGELOG.md +52 -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 -5
  5. package/esm/core/helper.d.ts +2 -0
  6. package/esm/core/helper.js +3 -0
  7. package/esm/core/index.d.ts +0 -0
  8. package/esm/core/index.js +5 -0
  9. package/esm/core/tailwind.d.ts +21 -0
  10. package/esm/core/tailwind.js +22 -0
  11. package/esm/core/tryCatch.d.ts +44 -0
  12. package/esm/core/tryCatch.js +34 -0
  13. package/esm/cron/server/index.js +1 -1
  14. package/esm/feedback/FeedbackController.js +3 -2
  15. package/esm/feedback/index.d.ts +7 -2
  16. package/esm/feedback/index.js +1 -2
  17. package/esm/feedback/server/index.d.ts +0 -5
  18. package/esm/feedback/server/index.js +1 -1
  19. package/esm/formats/strings.js +2 -2
  20. package/esm/index.d.ts +16 -0
  21. package/esm/index.js +13 -0
  22. package/esm/svelte/FF_Repo.svelte.d.ts +0 -2
  23. package/esm/svelte/FF_Repo.svelte.js +1 -17
  24. package/esm/svelte/helpers/debounce.js +1 -1
  25. package/esm/svelte/index.d.ts +2 -24
  26. package/esm/svelte/index.js +2 -22
  27. package/esm/{ui → svelte/ui}/Icon.svelte +1 -1
  28. package/esm/virtual/StateDemoEnum.d.ts +3 -3
  29. package/esm/virtual/StateDemoEnum.js +3 -3
  30. package/esm/virtual/UIEntity.js +1 -2
  31. package/package.json +6 -24
  32. package/esm/bin/cmd.d.ts +0 -1
  33. package/esm/bin/cmd.js +0 -638
  34. package/esm/feedback/ui/DialogIssue.svelte +0 -149
  35. package/esm/feedback/ui/DialogIssue.svelte.d.ts +0 -22
  36. package/esm/feedback/ui/DialogIssues.svelte +0 -114
  37. package/esm/feedback/ui/DialogIssues.svelte.d.ts +0 -22
  38. package/esm/feedback/ui/DialogMilestones.svelte +0 -43
  39. package/esm/feedback/ui/DialogMilestones.svelte.d.ts +0 -20
  40. package/esm/feedback/ui/Feedback.svelte +0 -16
  41. package/esm/feedback/ui/Feedback.svelte.d.ts +0 -18
  42. package/esm/internals/FF_Entity.d.ts +0 -2
  43. package/esm/internals/FF_Fields.d.ts +0 -11
  44. package/esm/internals/FF_Fields.js +0 -144
  45. package/esm/internals/cellsBuildor.d.ts +0 -47
  46. package/esm/internals/cellsBuildor.js +0 -141
  47. package/esm/internals/helper.d.ts +0 -49
  48. package/esm/internals/helper.js +0 -162
  49. package/esm/internals/index.d.ts +0 -78
  50. package/esm/internals/index.js +0 -45
  51. package/esm/internals/storeItem.d.ts +0 -19
  52. package/esm/internals/storeItem.js +0 -190
  53. package/esm/internals/storeList.d.ts +0 -34
  54. package/esm/internals/storeList.js +0 -108
  55. package/esm/internals/theme.d.ts +0 -4
  56. package/esm/internals/theme.js +0 -4
  57. package/esm/server/index.d.ts +0 -52
  58. package/esm/server/index.js +0 -87
  59. package/esm/svelte/FF_Cell.svelte +0 -103
  60. package/esm/svelte/FF_Cell.svelte.d.ts +0 -33
  61. package/esm/svelte/FF_Cell_Caption.svelte +0 -20
  62. package/esm/svelte/FF_Cell_Caption.svelte.d.ts +0 -31
  63. package/esm/svelte/FF_Cell_Display.svelte +0 -61
  64. package/esm/svelte/FF_Cell_Display.svelte.d.ts +0 -29
  65. package/esm/svelte/FF_Cell_Edit.svelte +0 -104
  66. package/esm/svelte/FF_Cell_Edit.svelte.d.ts +0 -32
  67. package/esm/svelte/FF_Cell_Error.svelte +0 -20
  68. package/esm/svelte/FF_Cell_Error.svelte.d.ts +0 -31
  69. package/esm/svelte/FF_Cell_Hint.svelte +0 -20
  70. package/esm/svelte/FF_Cell_Hint.svelte.d.ts +0 -31
  71. package/esm/svelte/FF_Config.svelte +0 -29
  72. package/esm/svelte/FF_Config.svelte.d.ts +0 -9
  73. package/esm/svelte/FF_Form.svelte +0 -155
  74. package/esm/svelte/FF_Form.svelte.d.ts +0 -37
  75. package/esm/svelte/FF_Grid.svelte +0 -257
  76. package/esm/svelte/FF_Grid.svelte.d.ts +0 -37
  77. package/esm/svelte/FF_Layout.svelte +0 -62
  78. package/esm/svelte/FF_Layout.svelte.d.ts +0 -31
  79. package/esm/svelte/actions/intersection.d.ts +0 -6
  80. package/esm/svelte/actions/intersection.js +0 -17
  81. package/esm/svelte/customField.d.ts +0 -69
  82. package/esm/svelte/customField.js +0 -4
  83. package/esm/svelte/dialog/DialogManagement.svelte +0 -98
  84. package/esm/svelte/dialog/DialogManagement.svelte.d.ts +0 -18
  85. package/esm/svelte/dialog/DialogPrimitive.svelte +0 -156
  86. package/esm/svelte/dialog/DialogPrimitive.svelte.d.ts +0 -38
  87. package/esm/svelte/dialog/dialog.d.ts +0 -58
  88. package/esm/svelte/dialog/dialog.js +0 -130
  89. package/esm/svelte/ff_Config.svelte.d.ts +0 -91
  90. package/esm/svelte/ff_Config.svelte.js +0 -111
  91. package/esm/svelte/firstly.css +0 -14
  92. package/esm/svelte/helpers.d.ts +0 -30
  93. package/esm/svelte/helpers.js +0 -38
  94. package/esm/svelte/tryCatch.d.ts +0 -12
  95. package/esm/svelte/tryCatch.js +0 -18
  96. package/esm/sveltekit/server/index.d.ts +0 -5
  97. package/esm/sveltekit/server/index.js +0 -24
  98. package/esm/ui/Button.svelte +0 -90
  99. package/esm/ui/Button.svelte.d.ts +0 -11
  100. package/esm/ui/Clipboardable.svelte +0 -25
  101. package/esm/ui/Clipboardable.svelte.d.ts +0 -12
  102. package/esm/ui/Field.svelte +0 -391
  103. package/esm/ui/Field.svelte.d.ts +0 -40
  104. package/esm/ui/FieldGroup.svelte +0 -117
  105. package/esm/ui/FieldGroup.svelte.d.ts +0 -44
  106. package/esm/ui/Grid.svelte +0 -262
  107. package/esm/ui/Grid.svelte.d.ts +0 -57
  108. package/esm/ui/Grid2.svelte +0 -290
  109. package/esm/ui/Grid2.svelte.d.ts +0 -57
  110. package/esm/ui/GridLoading.svelte +0 -58
  111. package/esm/ui/GridLoading.svelte.d.ts +0 -23
  112. package/esm/ui/GridPaginate.svelte +0 -69
  113. package/esm/ui/GridPaginate.svelte.d.ts +0 -23
  114. package/esm/ui/GridPaginate2.svelte +0 -25
  115. package/esm/ui/GridPaginate2.svelte.d.ts +0 -7
  116. package/esm/ui/Loading.svelte +0 -16
  117. package/esm/ui/Loading.svelte.d.ts +0 -31
  118. package/esm/ui/Tooltip.svelte +0 -45
  119. package/esm/ui/Tooltip.svelte.d.ts +0 -32
  120. package/esm/ui/dialog/DialogForm.svelte +0 -76
  121. package/esm/ui/dialog/DialogForm.svelte.d.ts +0 -21
  122. package/esm/ui/dialog/DialogManagement.svelte +0 -96
  123. package/esm/ui/dialog/DialogManagement.svelte.d.ts +0 -26
  124. package/esm/ui/dialog/DialogPrimitive.svelte +0 -90
  125. package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +0 -38
  126. package/esm/ui/dialog/FormEditAction.svelte +0 -62
  127. package/esm/ui/dialog/FormEditAction.svelte.d.ts +0 -31
  128. package/esm/ui/dialog/dialog.d.ts +0 -60
  129. package/esm/ui/dialog/dialog.js +0 -100
  130. package/esm/ui/index.d.ts +0 -6
  131. package/esm/ui/index.js +0 -20
  132. package/esm/ui/internals/FieldContainer.svelte +0 -39
  133. package/esm/ui/internals/FieldContainer.svelte.d.ts +0 -18
  134. package/esm/ui/internals/Input.svelte +0 -143
  135. package/esm/ui/internals/Input.svelte.d.ts +0 -37
  136. package/esm/ui/internals/Textarea.svelte +0 -66
  137. package/esm/ui/internals/Textarea.svelte.d.ts +0 -33
  138. package/esm/ui/internals/select/MultiSelectMelt.svelte +0 -260
  139. package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +0 -32
  140. package/esm/ui/internals/select/Select2.svelte +0 -88
  141. package/esm/ui/internals/select/Select2.svelte.d.ts +0 -12
  142. package/esm/ui/internals/select/SelectMelt.svelte +0 -289
  143. package/esm/ui/internals/select/SelectMelt.svelte.d.ts +0 -40
  144. package/esm/ui/internals/select/SelectRadio.svelte +0 -43
  145. package/esm/ui/internals/select/SelectRadio.svelte.d.ts +0 -27
  146. package/esm/ui/link/Link.svelte +0 -33
  147. package/esm/ui/link/Link.svelte.d.ts +0 -33
  148. package/esm/ui/link/LinkPlus.svelte +0 -63
  149. package/esm/ui/link/LinkPlus.svelte.d.ts +0 -9
  150. package/esm/utils/tailwind.d.ts +0 -2
  151. package/esm/utils/tailwind.js +0 -3
  152. package/esm/utils/transition.d.ts +0 -9
  153. package/esm/utils/transition.js +0 -33
  154. /package/esm/{internals → core}/BaseEnum.d.ts +0 -0
  155. /package/esm/{internals → core}/BaseEnum.js +0 -0
  156. /package/esm/{internals → core}/FF_Entity.js +0 -0
  157. /package/esm/{internals → core}/common.d.ts +0 -0
  158. /package/esm/{internals → core}/common.js +0 -0
  159. /package/esm/{utils → core}/types.d.ts +0 -0
  160. /package/esm/{utils → core}/types.js +0 -0
  161. /package/esm/{ui → svelte/ui}/Icon.svelte.d.ts +0 -0
  162. /package/esm/{ui → svelte/ui}/LibIcon.d.ts +0 -0
  163. /package/esm/{ui → svelte/ui}/LibIcon.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
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
+
3
55
  ## 0.3.0
4
56
 
5
57
  ### Minor 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';
@@ -46,9 +46,4 @@ export declare const withChangeLog: <entityType>(options?: EntityOptions<entityT
46
46
  apiRequireId?: import("remult").Allowed;
47
47
  dataProvider?: ((defaultDataProvider: import("remult").DataProvider) => import("remult").DataProvider | Promise<import("remult").DataProvider> | undefined | null) | undefined;
48
48
  changeLog?: false | ColumnDeciderArgs<entityType> | undefined;
49
- ui?: {
50
- getLayout?: import("../svelte/customField").getLayout<entityType> | undefined;
51
- } | undefined;
52
- searchableFind?: ((str: string) => import("remult").FindOptionsBase<entityType>) | undefined;
53
- displayValue?: ((item: entityType) => import("../internals").BaseItem) | undefined;
54
49
  };
@@ -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
  };
@@ -73,6 +72,5 @@ export declare class FF_Repo<Entity, QueryOptions extends QueryOptionsHelper<Ent
73
72
  } | undefined>;
74
73
  create(...args: Parameters<Repository<Entity>['create']>): Entity;
75
74
  delete(...args: Parameters<Repository<Entity>['delete']>): Promise<undefined>;
76
- getLayout: getLayoutStrict<Entity>;
77
75
  }
78
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;
@@ -190,20 +190,4 @@ export class FF_Repo {
190
190
  }
191
191
  return this.loadingEnd();
192
192
  }
193
- getLayout = (o) => {
194
- const layout = this.metadata.options.ui?.getLayout?.(o);
195
- if (layout) {
196
- return layout;
197
- }
198
- return {
199
- key: o?.key ?? 'default',
200
- type: o?.type ?? 'grid',
201
- groups: [
202
- {
203
- key: o?.key ?? 'default',
204
- fields: this.#repo.fields.toArray().filter((c) => c.apiUpdateAllowed()),
205
- },
206
- ],
207
- };
208
- };
209
193
  }
@@ -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';
@@ -25,7 +25,7 @@
25
25
  export let size: string | number = '1.5rem'
26
26
 
27
27
  export let caption: string | undefined = undefined
28
- const rmvWarning = caption
28
+ void caption
29
29
 
30
30
  /**
31
31
  * By default, svg are not rendered on the server side.
@@ -1,6 +1,6 @@
1
- import { BaseEnum } from '../internals/BaseEnum';
2
- import type { BaseEnumOptions } from '../internals/BaseEnum';
3
- import '../ui/LibIcon';
1
+ import { BaseEnum } from '../core/BaseEnum';
2
+ import type { BaseEnumOptions } from '../core/BaseEnum';
3
+ import '../svelte/ui/LibIcon';
4
4
  export declare class StateDemoEnum extends BaseEnum {
5
5
  static CHECK: StateDemoEnum;
6
6
  static EDIT: StateDemoEnum;
@@ -6,9 +6,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  var StateDemoEnum_1;
8
8
  import { ValueListFieldType } from 'remult';
9
- import { BaseEnum } from '../internals/BaseEnum';
10
- import '../ui/LibIcon';
11
- import { LibIcon_Add, LibIcon_Delete, LibIcon_Edit } from '../ui/LibIcon';
9
+ import { BaseEnum } from '../core/BaseEnum';
10
+ import '../svelte/ui/LibIcon';
11
+ import { LibIcon_Add, LibIcon_Delete, LibIcon_Edit } from '../svelte/ui/LibIcon';
12
12
  let StateDemoEnum = class StateDemoEnum extends BaseEnum {
13
13
  static { StateDemoEnum_1 = this; }
14
14
  static CHECK = new StateDemoEnum_1('CHECK', {
@@ -42,7 +42,6 @@ __decorate([
42
42
  required: true,
43
43
  caption: "Nom de l'utilisateur",
44
44
  placeholder: 'Jean-Yves',
45
- suffix: 'SUF!',
46
45
  })
47
46
  ], UIEntity.prototype, "username", void 0);
48
47
  __decorate([
@@ -71,7 +70,7 @@ __decorate([
71
70
  Fields.boolean({ allowNull: true })
72
71
  ], UIEntity.prototype, "isSubContractor", void 0);
73
72
  __decorate([
74
- Fields.number({ allowNull: true, suffix: '%' })
73
+ Fields.number({ allowNull: true })
75
74
  ], UIEntity.prototype, "rate", void 0);
76
75
  __decorate([
77
76
  Fields.date({ allowNull: true, allowApiUpdate: false })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firstly",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "description": "Firstly, an opinionated Remult setup!",
6
6
  "funding": "https://github.com/sponsors/jycouet",
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "peerDependencies": {
18
18
  "@sveltejs/kit": ">=1.0.0 <3.0.0",
19
- "remult": ">=3.3.2",
19
+ "remult": ">=3.3.7",
20
20
  "svelte": ">=5"
21
21
  },
22
22
  "peerDependenciesMeta": {
@@ -31,40 +31,25 @@
31
31
  }
32
32
  },
33
33
  "dependencies": {
34
- "@clack/prompts": "0.11.0",
35
- "@kitql/internals": "0.11.0",
36
- "@layerstack/svelte-actions": "1.0.0",
37
34
  "@layerstack/utils": "1.0.0",
38
35
  "@mdi/js": "7.4.47",
39
- "@types/nodemailer": "7.0.2",
40
- "@melt-ui/svelte": "0.86.6",
36
+ "@types/nodemailer": "8.0.0",
41
37
  "clsx": "2.1.1",
42
38
  "cron": "4.4.0",
43
- "daisyui": "5.5.3",
44
39
  "esm-env": "1.2.2",
45
- "nodemailer": "7.0.4",
46
- "svelecte": "5.3.0",
40
+ "nodemailer": "8.0.5",
47
41
  "tailwind-merge": "3.5.0",
48
- "tailwindcss": "4.1.14",
42
+ "tailwindcss": "4.2.2",
49
43
  "vite-plugin-kit-routes": "1.0.3",
50
- "vite-plugin-stripper": "0.10.0"
44
+ "vite-plugin-stripper": "0.10.1"
51
45
  },
52
46
  "sideEffects": false,
53
- "bin": "./esm/bin/cmd.js",
54
47
  "exports": {
55
48
  ".": {
56
49
  "types": "./esm/index.d.ts",
57
50
  "svelte": "./esm/index.js",
58
51
  "default": "./esm/index.js"
59
52
  },
60
- "./internals": {
61
- "types": "./esm/internals/index.d.ts",
62
- "default": "./esm/internals/index.js"
63
- },
64
- "./server": {
65
- "types": "./esm/server/index.d.ts",
66
- "default": "./esm/server/index.js"
67
- },
68
53
  "./svelte": {
69
54
  "types": "./esm/svelte/index.d.ts",
70
55
  "svelte": "./esm/svelte/index.js",
@@ -74,9 +59,6 @@
74
59
  "types": "./esm/vite/index.d.ts",
75
60
  "default": "./esm/vite/index.js"
76
61
  },
77
- "./bin": {
78
- "default": "./esm/bin/cmd.js"
79
- },
80
62
  "./formats": {
81
63
  "types": "./esm/formats/index.d.ts",
82
64
  "default": "./esm/formats/index.js"
package/esm/bin/cmd.d.ts DELETED
@@ -1 +0,0 @@
1
- export {};