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/esm/bin/cmd.js DELETED
@@ -1,638 +0,0 @@
1
- import * as p from '@clack/prompts';
2
- import { bold, cyan, gray, green, italic, Log } from '@kitql/helpers';
3
- import { read, write } from '@kitql/internals';
4
- // Need this trick to be be replaced by the real lib alias here ;)
5
- const libAlias = '$' + 'lib';
6
- const serverAlias = '$' + 'server';
7
- const modulesAlias = '$' + 'modules';
8
- const pkgFirstly = JSON.parse(read('./node_modules/firstly/package.json') ?? '{}');
9
- const versionOfRemult = pkgFirstly?.peerDependencies?.['remult'] ?? 'latest';
10
- const pkg = JSON.parse(read('./package.json') ?? '{}');
11
- const version = pkg.devDependencies?.['firstly'] ?? pkg.dependencies?.['firstly'] ?? '???';
12
- console.info('');
13
- p.intro(`${green(`⚡️`)} Welcome to firstly world! ${gray(` - v${version}`)}`);
14
- const options = [
15
- {
16
- value: 'all',
17
- label: 'All',
18
- hint: 'If you are starting a new project, this is for you!',
19
- },
20
- {
21
- value: 'module-demo',
22
- label: 'module task',
23
- hint: 'A default module with a task entity and a controller (you can rename the folder and make it yours)',
24
- },
25
- {
26
- value: 'dependencies',
27
- label: 'dependencies',
28
- hint: 'Add all dependencies that make sense to use with firstly',
29
- },
30
- ];
31
- const res = (await p.multiselect({
32
- message: 'You can generate different things here',
33
- options,
34
- }));
35
- // devDependencies
36
- function mergeAndSort(deps, depsToAdd) {
37
- const prepare = {
38
- ...depsToAdd,
39
- ...deps,
40
- };
41
- // sort by name
42
- const sorted = Object.keys(prepare)
43
- .sort()
44
- .reduce((acc, key) => {
45
- acc[key] = prepare[key];
46
- return acc;
47
- }, {});
48
- return sorted;
49
- }
50
- pkg.devDependencies = mergeAndSort(pkg.devDependencies, {
51
- '@kitql/eslint-config': '0.6.0',
52
- '@kitql/helpers': '0.8.12',
53
- pg: '8.12.0',
54
- remult: versionOfRemult,
55
- });
56
- pkg.dependencies = mergeAndSort(pkg.dependencies, {});
57
- pkg.scripts = {
58
- ...pkg.scripts,
59
- '//// ---- BEST PRACTICES ---- ////': '',
60
- lint: 'kitql-lint -d',
61
- format: 'kitql-lint -f -d',
62
- };
63
- if (res.includes('all') || res.includes('dependencies')) {
64
- write('./package.json', [JSON.stringify(pkg, null, 2)]);
65
- }
66
- const obj = {
67
- // Configs
68
- './.npmrc': [
69
- `engine-strict=true
70
-
71
- public-hoist-pattern[]=*eslint*
72
- public-hoist-pattern[]=*prettier*
73
- public-hoist-pattern[]=*globals*
74
- `,
75
- ],
76
- './.gitignore': [
77
- `node_modules
78
-
79
- # Output
80
- /.svelte-kit
81
- /build
82
-
83
- # Env
84
- .env
85
- .env.*
86
- !.env.example
87
- !.env.test
88
-
89
- # Vite
90
- vite.config.js.timestamp-*
91
- vite.config.ts.timestamp-*
92
-
93
- # Firstly / Remult
94
- /db
95
- `,
96
- ],
97
- './eslint.config.js': [
98
- `import { kitql } from '@kitql/eslint-config'
99
-
100
- /** @type { import("eslint").Linter.Config[] } */
101
- export default [
102
- ...kitql({ pnpmCatalogs: { enable: false } }),
103
- {
104
- name: 'APP:ignores',
105
- ignores: ['**/*.svelte.ts'],
106
- },
107
- ]
108
- `,
109
- ],
110
- './.prettierignore': [
111
- `node_modules/
112
- dist/
113
- build
114
- .vs
115
- .vscode
116
- .bob/
117
- .next/
118
- .idea/
119
- .svelte-kit/
120
- .husky/_/
121
- .changeset/
122
- .DS_Store
123
- coverage/
124
- package.json
125
- pnpm-lock.yaml
126
- README.md
127
-
128
- db/
129
- src/lib/ROUTES.ts
130
- `,
131
- ],
132
- './.prettierrc.mjs': [
133
- `import { kitql } from '@kitql/eslint-config/.prettierrc.mjs'
134
-
135
- export default {
136
- ...kitql(),
137
- // Your overrides here
138
- }
139
- `,
140
- ],
141
- '.env.example': [
142
- `# Enable some roles
143
- # FF_ADMIN = 'JYC'
144
- `,
145
- ],
146
- './tsconfig.json': [
147
- `{
148
- "extends": "./.svelte-kit/tsconfig.json",
149
- "compilerOptions": {
150
- "experimentalDecorators": true,
151
- "allowJs": true,
152
- "checkJs": true,
153
- "esModuleInterop": true,
154
- "forceConsistentCasingInFileNames": true,
155
- "resolveJsonModule": true,
156
- "skipLibCheck": true,
157
- "sourceMap": true,
158
- "strict": true,
159
- "moduleResolution": "bundler"
160
- }
161
- // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
162
- //
163
- // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
164
- // from the referenced tsconfig.json - TypeScript does not merge them in
165
- }
166
- `,
167
- ],
168
- './vite.config.ts': [
169
- `import { sveltekit } from '@sveltejs/kit/vite'
170
- import { defineConfig } from 'vite'
171
-
172
- import { firstly } from '../vite'
173
-
174
- import type { KIT_ROUTES } from '${libAlias}/ROUTES'
175
-
176
- export default defineConfig({
177
- plugins: [
178
- // @ts-ignore JYC TODO (vite 5 / vite 6...)
179
- firstly<KIT_ROUTES>({
180
- kitRoutes: {
181
- LINKS: {
182
- github: 'https://github.com/[owner]/[repo]',
183
- remult_admin: 'api/admin',
184
- },
185
- }
186
- }),
187
- sveltekit(),
188
- ],
189
- })
190
- `,
191
- ],
192
- './svelte.config.js': [
193
- `import adapter from '@sveltejs/adapter-auto'
194
-
195
- /** @type {import('@sveltejs/kit').Config} */
196
- const config = {
197
-
198
- kit: {
199
- // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
200
- // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
201
- // See https://svelte.dev/docs/kit/adapters for more information about adapters.
202
- adapter: adapter(),
203
- alias: {
204
- $modules: './src/modules',
205
- $server: './src/server',
206
- },
207
- },
208
- }
209
-
210
- export default config
211
- `,
212
- ],
213
- // App files
214
- './src/app.d.ts': [
215
- `// See https://svelte.dev/docs/kit/types#app.d.ts
216
- // for information about these interfaces
217
- declare global {
218
- namespace App {
219
- // interface Error {}
220
- // interface Locals {}
221
- // interface PageData {}
222
- // interface PageState {}
223
- // interface Platform {}
224
- }
225
- }
226
-
227
- declare module 'remult' {
228
- export interface UserInfo {
229
- // Your custom user info
230
- }
231
-
232
- export interface FieldOptions<entityType, valueType> {
233
- placeholder?: string
234
- }
235
- }
236
-
237
- export { }
238
- `,
239
- ],
240
- './src/server/index.ts': [
241
- `import { FF_Role } from '../internals'
242
- import { firstly, Module } from '../server'
243
- import { mail } from '../mail/server'
244
- import { changeLog } from '../changeLog/server'
245
-
246
- import { log, Role } from '${libAlias}'
247
- import { task } from '${modulesAlias}/task/server'
248
-
249
- export const api = firstly({
250
- modules: [
251
- //----------------------------------------
252
- // Core Module: mail
253
- //----------------------------------------
254
- mail({
255
- // options
256
- }),
257
-
258
- //----------------------------------------
259
- // example of a userland module
260
- //----------------------------------------
261
- task({ specialInfo: 'hello from userland' }),
262
-
263
- //----------------------------------------
264
- // example of a userland inline module
265
- //----------------------------------------
266
- new Module({
267
- name: 'app',
268
- entities: [],
269
- controllers: [],
270
- initApi: async () => {
271
- log.success('App is ready! 🚀')
272
- },
273
- }),
274
-
275
- //----------------------------------------
276
- // Replace @Entity by @FF_Entity in your entities to enable changeLog on this entity
277
- //----------------------------------------
278
- changeLog(),
279
- ],
280
- })
281
- `,
282
- ],
283
- './src/hooks.server.ts': [
284
- `import { sequence } from '@sveltejs/kit/hooks'
285
-
286
- import { api as handleRemult } from '${serverAlias}'
287
-
288
- export const handle = sequence(
289
- handleRemult,
290
- )
291
- `,
292
- ],
293
- './src/routes/api/[...remult]/+server.ts': [
294
- `import { api } from '${serverAlias}'
295
-
296
- export const { GET, POST, PUT, DELETE } = api
297
- `,
298
- ],
299
- './src/routes/+layout.server.ts': [
300
- `import { remult } from 'remult'
301
-
302
- import type { LayoutServerLoad } from './$types'
303
-
304
- export const load = (async () => {
305
- return { user: remult.user }
306
- }) satisfies LayoutServerLoad
307
- `,
308
- ],
309
- './src/routes/+layout.ts': [
310
- `import { remult } from 'remult'
311
- import type { LayoutLoad } from './$types'
312
-
313
- export const load = (async (event) => {
314
- // Instruct remult to use the special svelte fetch
315
- // Like this univeral load will work in SSR & CSR
316
- remult.useFetch(event.fetch)
317
- // return repo(Task).find()
318
- return { ...event.data }
319
- }) satisfies LayoutLoad
320
- `,
321
- ],
322
- './src/routes/+layout.svelte': [
323
- `<script lang="ts">
324
- import { untrack } from 'svelte'
325
- import { createSubscriber } from 'svelte/reactivity'
326
-
327
- import { Remult, remult } from 'remult'
328
-
329
- import { route } from '${libAlias}/ROUTES'
330
-
331
- import type { LayoutData } from './$types'
332
-
333
- interface Props {
334
- data: LayoutData
335
- children?: import('svelte').Snippet
336
- }
337
-
338
- let { data, children }: Props = $props()
339
-
340
- $effect(() => {
341
- // Trigger the effect only on data.user update
342
- data.user
343
- untrack(() => {
344
- remult.user = data.user
345
- })
346
- })
347
-
348
- // To be done once in the application.
349
- function initRemultSvelteReactivity() {
350
- // Auth reactivity (remult.user, remult.authenticated(), ...)
351
- {
352
- let update = () => {}
353
- let s = createSubscriber((u) => {
354
- update = u
355
- })
356
- remult.subscribeAuth({
357
- reportObserved: () => s(),
358
- reportChanged: () => update(),
359
- })
360
- }
361
-
362
- // Entities reactivity
363
- {
364
- Remult.entityRefInit = (x) => {
365
- let update = () => {}
366
- let s = createSubscriber((u) => {
367
- update = u
368
- })
369
- x.subscribe({
370
- reportObserved: () => s(),
371
- reportChanged: () => update(),
372
- })
373
- }
374
- }
375
- }
376
- initRemultSvelteReactivity()
377
- </script>
378
-
379
- <svelte:head>
380
- <title>${pkg.name}</title>
381
- <link
382
- rel="icon"
383
- href="https://raw.githubusercontent.com/jycouet/firstly/main/assets/firstly.png"
384
- />
385
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/dark.css" />
386
- </svelte:head>
387
-
388
- <h1>${pkg.name}</h1>
389
-
390
- {#if remult.authenticated()}
391
- <span>{remult.user?.name} ({remult.user?.roles})<br /><br /></span>
392
- {/if}
393
-
394
- <a href={route('/')}>Home</a> |
395
- <a href={route('/demo/task')}>Demo task</a>
396
-
397
- <hr />
398
-
399
- {@render children?.()}
400
-
401
- <hr />
402
-
403
- <div style="float: right; text-align: right;">
404
- <a href={route('remult_admin')} target="_blank">🚀 admin</a>
405
- <p style="font-size: small;">
406
- <i>Login as <b>JYC</b> to get admin rights ☝️</i>
407
- </p>
408
- </div>
409
- <a href={route('github', { owner: 'jycouet', repo: 'firstly' })} target="_blank"> ⭐️ firstly </a>
410
- |
411
- <a href={route('github', { owner: 'remult', repo: 'remult' })} target="_blank">⭐️ remult</a>
412
- `,
413
- ],
414
- './src/routes/+page.ts': [
415
- `import { remult } from 'remult'
416
- import type { PageLoad } from './$types'
417
-
418
- export const load = (async (event) => {
419
- // Instruct remult to use the special svelte fetch
420
- // Like this univeral load will work in SSR & CSR
421
- remult.useFetch(event.fetch)
422
- // return repo(Task).find()
423
- }) satisfies PageLoad
424
- `,
425
- ],
426
- './src/routes/+page.svelte': [
427
- `<h1>Home</h1>
428
-
429
- <p>
430
- Welcome here
431
- </p>`,
432
- ],
433
- './src/routes/app/+page.svelte': [
434
- `<h1>App</h1>
435
-
436
- <p>
437
- Only autenticated users can see this page!
438
- </p>
439
-
440
- `,
441
- ],
442
- // Lib files
443
- './src/lib/index.ts': [
444
- `import { FF_Role } from '../internals'
445
- import { Log } from '@kitql/helpers'
446
-
447
- /**
448
- * Your logs with a nice prefix, use \`log.info("Hello")\` / \`log.success("Yeah")\` / \`log.error("Ho nooo!")\` and see !
449
- */
450
- export const log = new Log('${pkg.name}')
451
-
452
- /**
453
- * Your roles, use them in your app !
454
- */
455
- export const Role = {
456
- Boss: 'Boss',
457
- ...FF_Role,
458
- } as const
459
- `,
460
- ],
461
- // Task module
462
- './src/modules/task/index.ts': [
463
- `import { Log } from '@kitql/helpers'
464
-
465
- export const log = new Log("Custom Task Log")`,
466
- ],
467
- './src/modules/task/server/index.ts': [
468
- `import { Module } from '../server'
469
-
470
- import { Task } from '../Task'
471
- import { TaskController } from '../TaskController'
472
-
473
- export const task: (o: { specialInfo: string }) => Module = ({ specialInfo }) => {
474
- const m = new Module({
475
- name: 'task',
476
- entities: [Task],
477
- controllers: [TaskController],
478
- initApi: async () => {
479
- m.log.success(\`Task module is ready! 🚀 (specialInfo: \${specialInfo})\`)
480
- },
481
- })
482
-
483
- return m
484
- }
485
- `,
486
- ],
487
- './src/modules/task/Task.ts': [
488
- `import { Allow, Entity, Field, Fields, ValueListFieldType } from 'remult'
489
- import { BaseEnum, LibIcon_Add, LibIcon_Delete, type BaseEnumOptions } from '../internals'
490
-
491
- @Entity('task', {
492
- allowApiCrud: Allow.authenticated,
493
- })
494
- export class Task {
495
- @Fields.id()
496
- id!: string
497
-
498
- @Fields.createdAt()
499
- createdAt?: Date
500
-
501
- @Fields.string<Task>({
502
- validate: (task) => {
503
- if (task.title.length < 3) throw 'The title must be at least 3 characters long'
504
- },
505
- })
506
- title: string = ''
507
-
508
- @Fields.boolean()
509
- completed: boolean = false
510
-
511
- @Field(() => TypeOfTaskEnum, { inputType: 'selectEnum' })
512
- typeOfTask = TypeOfTaskEnum.EASY
513
- }
514
-
515
- @ValueListFieldType()
516
- export class TypeOfTaskEnum extends BaseEnum {
517
- static EASY = new TypeOfTaskEnum('EASY', {
518
- caption: 'Easy',
519
- icon: { data: LibIcon_Add },
520
- })
521
- static HARD = new TypeOfTaskEnum('HARD', {
522
- caption: 'Hard',
523
- icon: { data: LibIcon_Delete },
524
- })
525
- constructor(id: string, o?: BaseEnumOptions<TypeOfTaskEnum>) {
526
- super(id, o)
527
- }
528
- }
529
- `,
530
- ],
531
- './src/modules/task/TaskController.ts': [
532
- `import { BackendMethod } from 'remult'
533
-
534
- import { log } from '${libAlias}'
535
-
536
- /**
537
- * await TaskController.sayHiFromTask("JYC")
538
- */
539
- export class TaskController {
540
- @BackendMethod({ allowed: true })
541
- static async sayHiFromTask(name: string) {
542
- log.info(\`hello \${name} 👋\`)
543
- }
544
- }
545
- `,
546
- ],
547
- './src/modules/task/ui/TaskAdd.svelte': [
548
- `<script lang="ts">
549
- import { EntityError, repo } from 'remult'
550
-
551
- import { Task } from '${modulesAlias}/task/Task'
552
-
553
- let task = $state(repo(Task).create())
554
- let error = $state<EntityError<Task> | null>(null)
555
-
556
- const add = async (e: Event) => {
557
- e.preventDefault()
558
- error = null
559
- try {
560
- await repo(Task).insert(task)
561
- task = repo(Task).create()
562
- } catch (e) {
563
- if (e instanceof EntityError) {
564
- error = e
565
- }
566
- }
567
- }
568
- </script>
569
-
570
- <form onsubmit={add}>
571
- <p>
572
- {error?.modelState?.title}
573
- </p>
574
- <label for={repo(Task).fields.title.key}>{repo(Task).fields.title.caption}</label>
575
- <input id={repo(Task).fields.title.key} type="text" bind:value={task.title} />
576
- <button disabled={!repo(Task).metadata.apiInsertAllowed()}>Add</button>
577
- </form>
578
- `,
579
- ],
580
- './src/modules/task/ui/TaskList.svelte': [
581
- `<script lang="ts">
582
- import { repo } from 'remult'
583
-
584
- import { Task } from '${modulesAlias}/task/Task'
585
-
586
- let list: Task[] = $state([])
587
-
588
- $effect(() => {
589
- if (repo(Task).metadata.apiReadAllowed) {
590
- return repo(Task)
591
- .liveQuery()
592
- .subscribe((info) => {
593
- list = info.applyChanges(list)
594
- })
595
- }
596
- })
597
- </script>
598
-
599
- {#if repo(Task).metadata.apiReadAllowed}
600
- <ul>
601
- {#each list as task (task.id)}
602
- <li>{task.title}</li>
603
- {/each}
604
- </ul>
605
- {:else}
606
- <p>Login to see the task list!</p>
607
- {/if}
608
- `,
609
- ],
610
- './src/routes/demo/task/+page.svelte': [
611
- `<script lang="ts">
612
- import TaskAdd from '${modulesAlias}/task/ui/TaskAdd.svelte'
613
- import TaskList from '${modulesAlias}/task/ui/TaskList.svelte'
614
- </script>
615
-
616
- <h1>Task Module</h1>
617
-
618
- <TaskAdd />
619
- <TaskList />
620
- `,
621
- ],
622
- };
623
- for (const [path, content] of Object.entries(obj)) {
624
- if (res.includes('all')) {
625
- write(path, content);
626
- }
627
- else {
628
- if (res.includes('module-demo')) {
629
- if (path.startsWith('./src/modules/task')) {
630
- write(path, content);
631
- }
632
- }
633
- }
634
- }
635
- p.outro(`🎉 Everything is ok, happy coding!`);
636
- new Log('').info(gray(italic(`${bold('❔ More help')} ` +
637
- `at ${cyan('https://github.com/jycouet/firstly')} ` +
638
- `(📄 Docs, ⭐ Github, 📣 Discord, ...)\n`)));