firstly 0.0.13 → 0.0.15

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 (109) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/esm/ROUTES.d.ts +2 -0
  3. package/esm/ROUTES.js +1 -0
  4. package/esm/auth/AuthController.d.ts +12 -23
  5. package/esm/auth/AuthController.js +12 -31
  6. package/esm/auth/server/AuthController.server.d.ts +11 -11
  7. package/esm/auth/server/AuthController.server.js +84 -18
  8. package/esm/auth/server/helperFirstly.d.ts +1 -1
  9. package/esm/auth/server/helperFirstly.js +1 -0
  10. package/esm/auth/server/module.d.ts +4 -7
  11. package/esm/auth/server/module.js +1 -1
  12. package/esm/auth/server/providers/github.d.ts +2 -1
  13. package/esm/auth/server/providers/github.js +1 -1
  14. package/esm/auth/static/assets/Page-B1GE_oYi.d.ts +6 -0
  15. package/esm/auth/static/assets/Page-B1GE_oYi.js +1 -0
  16. package/esm/auth/static/assets/Page-CDHFtYuN.d.ts +6 -0
  17. package/esm/auth/static/assets/Page-CDHFtYuN.js +1 -0
  18. package/esm/auth/static/assets/Page-Dh8pvAo6.d.ts +6 -0
  19. package/esm/auth/static/assets/Page-Dh8pvAo6.js +20 -0
  20. package/esm/auth/static/assets/Page-mK42zGEw.css +1 -0
  21. package/esm/auth/static/assets/index-7Nh2ct-y.d.ts +151 -0
  22. package/esm/auth/static/assets/index-7Nh2ct-y.js +42 -0
  23. package/esm/auth/static/index.html +3 -3
  24. package/esm/auth/types.d.ts +26 -3
  25. package/esm/bin/cmd.js +343 -143
  26. package/esm/changeLog/server/index.d.ts +1 -1
  27. package/esm/changeLog/server/index.js +1 -1
  28. package/esm/cron/server/index.d.ts +1 -1
  29. package/esm/cron/server/index.js +1 -1
  30. package/esm/feedback/FeedbackController.js +57 -51
  31. package/esm/feedback/server/index.d.ts +7 -16
  32. package/esm/feedback/server/index.js +5 -6
  33. package/esm/feedback/types.d.ts +14 -0
  34. package/esm/feedback/types.js +4 -0
  35. package/esm/feedback/ui/DialogIssue.svelte +78 -62
  36. package/esm/feedback/ui/DialogIssue.svelte.d.ts +20 -18
  37. package/esm/feedback/ui/DialogIssues.svelte +37 -28
  38. package/esm/feedback/ui/DialogIssues.svelte.d.ts +20 -18
  39. package/esm/feedback/ui/DialogMilestones.svelte +18 -12
  40. package/esm/feedback/ui/DialogMilestones.svelte.d.ts +18 -16
  41. package/esm/feedback/ui/Feedback.svelte +11 -9
  42. package/esm/feedback/ui/Feedback.svelte.d.ts +16 -14
  43. package/esm/mail/server/index.d.ts +9 -2
  44. package/esm/mail/server/index.js +6 -2
  45. package/esm/mail/templates/DefaultMail.svelte +64 -44
  46. package/esm/mail/templates/DefaultMail.svelte.d.ts +28 -26
  47. package/esm/{api → server}/index.d.ts +8 -0
  48. package/esm/storeItem.d.ts +1 -1
  49. package/esm/storeList.d.ts +1 -1
  50. package/esm/sveltekit/server/index.d.ts +1 -10
  51. package/esm/sveltekit/server/index.js +1 -1
  52. package/esm/ui/Button.svelte +79 -56
  53. package/esm/ui/Button.svelte.d.ts +34 -24
  54. package/esm/ui/Clipboardable.svelte +18 -11
  55. package/esm/ui/Clipboardable.svelte.d.ts +34 -23
  56. package/esm/ui/Field.svelte +189 -136
  57. package/esm/ui/Field.svelte.d.ts +13 -6
  58. package/esm/ui/FieldGroup.svelte +74 -53
  59. package/esm/ui/FieldGroup.svelte.d.ts +17 -6
  60. package/esm/ui/Grid.svelte +110 -86
  61. package/esm/ui/Grid.svelte.d.ts +17 -6
  62. package/esm/ui/GridLoading.svelte +10 -5
  63. package/esm/ui/GridLoading.svelte.d.ts +19 -17
  64. package/esm/ui/GridPaginate.svelte +30 -23
  65. package/esm/ui/GridPaginate.svelte.d.ts +21 -19
  66. package/esm/ui/Icon.svelte +67 -32
  67. package/esm/ui/Icon.svelte.d.ts +52 -43
  68. package/esm/ui/Loading.svelte +5 -3
  69. package/esm/ui/Loading.svelte.d.ts +29 -18
  70. package/esm/ui/Tooltip.svelte +22 -19
  71. package/esm/ui/Tooltip.svelte.d.ts +30 -20
  72. package/esm/ui/dialog/DialogForm.svelte +48 -41
  73. package/esm/ui/dialog/DialogForm.svelte.d.ts +18 -16
  74. package/esm/ui/dialog/DialogManagement.svelte.d.ts +22 -21
  75. package/esm/ui/dialog/DialogPrimitive.svelte +32 -26
  76. package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +35 -25
  77. package/esm/ui/dialog/FormEditAction.svelte +20 -12
  78. package/esm/ui/dialog/FormEditAction.svelte.d.ts +13 -6
  79. package/esm/ui/dialog/dialog.d.ts +1 -1
  80. package/esm/ui/internals/FieldContainer.svelte +13 -6
  81. package/esm/ui/internals/FieldContainer.svelte.d.ts +37 -28
  82. package/esm/ui/internals/Input.svelte +110 -76
  83. package/esm/ui/internals/Input.svelte.d.ts +34 -32
  84. package/esm/ui/internals/Textarea.svelte +39 -31
  85. package/esm/ui/internals/Textarea.svelte.d.ts +31 -28
  86. package/esm/ui/internals/select/MultiSelectMelt.svelte +174 -126
  87. package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +29 -27
  88. package/esm/ui/internals/select/SelectMelt.svelte +168 -133
  89. package/esm/ui/internals/select/SelectMelt.svelte.d.ts +34 -32
  90. package/esm/ui/internals/select/SelectRadio.svelte +17 -11
  91. package/esm/ui/internals/select/SelectRadio.svelte.d.ts +24 -22
  92. package/esm/ui/link/Link.svelte +11 -6
  93. package/esm/ui/link/Link.svelte.d.ts +31 -22
  94. package/esm/ui/link/LinkPlus.svelte +19 -16
  95. package/esm/ui/link/LinkPlus.svelte.d.ts +20 -18
  96. package/esm/vite/index.d.ts +2 -3
  97. package/esm/vite/index.js +33 -26
  98. package/package.json +14 -14
  99. package/esm/auth/static/assets/Page-BUfjaN-D.d.ts +0 -5
  100. package/esm/auth/static/assets/Page-BUfjaN-D.js +0 -19
  101. package/esm/auth/static/assets/Page-CJ58H1vl.css +0 -1
  102. package/esm/auth/static/assets/Page-CaDAqmBS.d.ts +0 -5
  103. package/esm/auth/static/assets/Page-CaDAqmBS.js +0 -1
  104. package/esm/auth/static/assets/Page-DhdZddzJ.d.ts +0 -5
  105. package/esm/auth/static/assets/Page-DhdZddzJ.js +0 -1
  106. package/esm/auth/static/assets/index-D-Ztdt2o.d.ts +0 -54
  107. package/esm/auth/static/assets/index-D-Ztdt2o.js +0 -2
  108. /package/esm/auth/static/assets/{index-BDy4A_14.css → index-DKWpA6v7.css} +0 -0
  109. /package/esm/{api → server}/index.js +0 -0
package/esm/bin/cmd.js CHANGED
@@ -3,8 +3,10 @@ import { bold, cyan, gray, green, italic, Log } from '@kitql/helpers';
3
3
  import { read, write } from '@kitql/internals';
4
4
  // Need this trick to be be replaced by the real lib alias here ;)
5
5
  const libAlias = '$' + 'lib';
6
+ const serverAlias = '$' + 'server';
7
+ const modulesAlias = '$' + 'modules';
6
8
  const pkgFirstly = JSON.parse(read('./node_modules/firstly/package.json') ?? '{}');
7
- const versionFirstly = pkgFirstly?.peerDependencies?.['remult'] ?? 'latest';
9
+ const versionOfRemult = pkgFirstly?.peerDependencies?.['remult'] ?? 'latest';
8
10
  const pkg = JSON.parse(read('./package.json') ?? '{}');
9
11
  const version = pkg.devDependencies?.['firstly'] ?? pkg.dependencies?.['firstly'] ?? '???';
10
12
  console.info('');
@@ -47,10 +49,10 @@ function mergeAndSort(deps, depsToAdd) {
47
49
  return sorted;
48
50
  }
49
51
  pkg.devDependencies = mergeAndSort(pkg.devDependencies, {
50
- '@kitql/eslint-config': '0.5.8',
52
+ '@kitql/eslint-config': '0.6.0',
51
53
  '@kitql/helpers': '0.8.12',
52
54
  pg: '8.12.0',
53
- remult: versionFirstly,
55
+ remult: versionOfRemult,
54
56
  });
55
57
  pkg.dependencies = mergeAndSort(pkg.dependencies, {});
56
58
  pkg.scripts = {
@@ -63,12 +65,34 @@ if (res.includes('all') || res.includes('dependencies')) {
63
65
  write('./package.json', [JSON.stringify(pkg, null, 2)]);
64
66
  }
65
67
  const obj = {
68
+ // Configs
66
69
  './.npmrc': [
67
70
  `engine-strict=true
68
71
 
69
72
  public-hoist-pattern[]=*eslint*
70
73
  public-hoist-pattern[]=*prettier*
71
74
  public-hoist-pattern[]=*globals*
75
+ `,
76
+ ],
77
+ './.gitignore': [
78
+ `node_modules
79
+
80
+ # Output
81
+ /.svelte-kit
82
+ /build
83
+
84
+ # Env
85
+ .env
86
+ .env.*
87
+ !.env.example
88
+ !.env.test
89
+
90
+ # Vite
91
+ vite.config.js.timestamp-*
92
+ vite.config.ts.timestamp-*
93
+
94
+ # Firstly / Remult
95
+ /db
72
96
  `,
73
97
  ],
74
98
  './eslint.config.js': [
@@ -125,26 +149,114 @@ export default {
125
149
  # GITHUB_CLIENT_SECRET = ''
126
150
  `,
127
151
  ],
128
- './src/lib/firstly/index.ts': [
129
- `import { FF_Role } from 'firstly'
130
- import { firstly, Module } from 'firstly/api'
131
- import { auth } from 'firstly/auth/server'
132
- import { changeLog } from 'firstly/changeLog/server'
133
- import { Log } from '@kitql/helpers'
152
+ './tsconfig.json': [
153
+ `{
154
+ "extends": "./.svelte-kit/tsconfig.json",
155
+ "compilerOptions": {
156
+ "experimentalDecorators": true,
157
+ "allowJs": true,
158
+ "checkJs": true,
159
+ "esModuleInterop": true,
160
+ "forceConsistentCasingInFileNames": true,
161
+ "resolveJsonModule": true,
162
+ "skipLibCheck": true,
163
+ "sourceMap": true,
164
+ "strict": true,
165
+ "moduleResolution": "bundler"
166
+ }
167
+ // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
168
+ //
169
+ // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
170
+ // from the referenced tsconfig.json - TypeScript does not merge them in
171
+ }
172
+ `,
173
+ ],
174
+ './vite.config.ts': [
175
+ `import { sveltekit } from '@sveltejs/kit/vite'
176
+ import { defineConfig } from 'vite'
134
177
 
135
- import { task } from './modules/task'
178
+ import { firstly } from 'firstly/vite'
136
179
 
137
- /**
138
- * Your roles, use them in your app !
139
- */
140
- export const Role = {
141
- Boss: 'Boss',
180
+ import type { KIT_ROUTES } from '${libAlias}/ROUTES'
181
+
182
+ export default defineConfig({
183
+ plugins: [
184
+ // @ts-ignore JYC TODO (vite 5 / vite 6...)
185
+ firstly<KIT_ROUTES>({
186
+ kitRoutes: {
187
+ LINKS: {
188
+ login: 'ff/auth/sign-in',
189
+ github: 'https://github.com/[owner]/[repo]',
190
+ remult_admin: 'api/admin',
191
+ },
192
+ }
193
+ }),
194
+ sveltekit(),
195
+ ],
196
+ })
197
+ `,
198
+ ],
199
+ './svelte.config.js': [
200
+ `import adapter from '@sveltejs/adapter-auto'
201
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
202
+
203
+ /** @type {import('@sveltejs/kit').Config} */
204
+ const config = {
205
+ // Consult https://svelte.dev/docs/kit/integrations
206
+ // for more information about preprocessors
207
+ preprocess: vitePreprocess(),
208
+
209
+ kit: {
210
+ // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
211
+ // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
212
+ // See https://svelte.dev/docs/kit/adapters for more information about adapters.
213
+ adapter: adapter(),
214
+ alias: {
215
+ $modules: './src/modules',
216
+ $server: './src/server',
217
+ },
218
+ },
142
219
  }
143
220
 
144
- /**
145
- * Your logs with a nice prefix, use \`log.info("Hello")\` / \`log.success("Yeah")\` / \`log.error("Ho nooo!")\` and see !
146
- */
147
- export const log = new Log('${pkg.name}')
221
+ export default config
222
+ `,
223
+ ],
224
+ // App files
225
+ './src/app.d.ts': [
226
+ `// See https://svelte.dev/docs/kit/types#app.d.ts
227
+ // for information about these interfaces
228
+ declare global {
229
+ namespace App {
230
+ // interface Error {}
231
+ // interface Locals {}
232
+ // interface PageData {}
233
+ // interface PageState {}
234
+ // interface Platform {}
235
+ }
236
+ }
237
+
238
+ declare module 'remult' {
239
+ export interface UserInfo {
240
+ // Your custom user info
241
+ }
242
+
243
+ export interface FieldOptions<entityType, valueType> {
244
+ placeholder?: string
245
+ }
246
+ }
247
+
248
+ export { }
249
+ `,
250
+ ],
251
+ './src/server/index.ts': [
252
+ `import { FF_Role } from 'firstly'
253
+ import { firstly, Module } from 'firstly/server'
254
+ import { auth } from 'firstly/auth/server'
255
+ import { mail } from 'firstly/mail/server'
256
+ import { changeLog } from 'firstly/changeLog/server'
257
+
258
+ import { log, Role } from '${libAlias}'
259
+ import { task } from '${modulesAlias}/task/server'
148
260
 
149
261
  export const api = firstly({
150
262
  //----------------------------------------
@@ -185,6 +297,13 @@ export const api = firstly({
185
297
  },
186
298
  }),
187
299
 
300
+ //----------------------------------------
301
+ // Core Module: mail
302
+ //----------------------------------------
303
+ mail({
304
+ // options
305
+ }),
306
+
188
307
  //----------------------------------------
189
308
  // example of a userland module
190
309
  //----------------------------------------
@@ -215,8 +334,8 @@ export const api = firstly({
215
334
  import { redirect } from '@sveltejs/kit'
216
335
 
217
336
  import { handleAuth, handleGuard } from 'firstly/auth/server'
218
- import { api as handleRemult } from '${libAlias}/firstly'
219
337
  import { route } from '${libAlias}/ROUTES'
338
+ import { api as handleRemult } from '${serverAlias}'
220
339
 
221
340
  export const handle = sequence(
222
341
  //
@@ -235,25 +354,9 @@ export const handle = sequence(
235
354
  `,
236
355
  ],
237
356
  './src/routes/api/[...remult]/+server.ts': [
238
- `import { api } from '${libAlias}/firstly'
357
+ `import { api } from '${serverAlias}'
239
358
 
240
359
  export const { GET, POST, PUT, DELETE } = api
241
- `,
242
- ],
243
- './src/routes/+page.svelte': [
244
- `<h1>Home</h1>
245
-
246
- <p>
247
- Welcome here
248
- </p>`,
249
- ],
250
- './src/routes/app/+page.svelte': [
251
- `<h1>App</h1>
252
-
253
- <p>
254
- Only autenticated users can see this page!
255
- </p>
256
-
257
360
  `,
258
361
  ],
259
362
  './src/routes/+layout.server.ts': [
@@ -277,32 +380,65 @@ export const load = (async (event) => {
277
380
  // return repo(Task).find()
278
381
  return { ...event.data }
279
382
  }) satisfies LayoutLoad
280
- `,
281
- ],
282
- './src/routes/+page.ts': [
283
- `import { remult } from 'remult'
284
- import type { PageLoad } from './$types'
285
-
286
- export const load = (async (event) => {
287
- // Instruct remult to use the special svelte fetch
288
- // Like this univeral load will work in SSR & CSR
289
- remult.useFetch(event.fetch)
290
- // return repo(Task).find()
291
- }) satisfies PageLoad
292
383
  `,
293
384
  ],
294
385
  './src/routes/+layout.svelte': [
295
386
  `<script lang="ts">
296
- import { remult } from 'remult'
387
+ import { untrack } from 'svelte'
388
+ import { createSubscriber } from 'svelte/reactivity'
389
+
390
+ import { Remult, remult } from 'remult'
297
391
 
298
392
  import { route } from '${libAlias}/ROUTES'
299
393
  import SignIn from '${libAlias}/ui/SignIn.svelte'
300
394
  import SignOut from '${libAlias}/ui/SignOut.svelte'
301
395
 
302
- import type { LayoutData } from './$types'
396
+ import type { LayoutData } from './$types'
397
+
398
+ interface Props {
399
+ data: LayoutData
400
+ children?: import('svelte').Snippet
401
+ }
402
+
403
+ let { data, children }: Props = $props()
404
+
405
+ $effect(() => {
406
+ // Trigger the effect only on data.user update
407
+ data.user
408
+ untrack(() => {
409
+ remult.user = data.user
410
+ })
411
+ })
303
412
 
304
- export let data: LayoutData
305
- $: remult.user = data.user
413
+ // To be done once in the application.
414
+ function initRemultSvelteReactivity() {
415
+ // Auth reactivity (remult.user, remult.authenticated(), ...)
416
+ {
417
+ let update = () => {}
418
+ let s = createSubscriber((u) => {
419
+ update = u
420
+ })
421
+ remult.subscribeAuth({
422
+ reportObserved: () => s(),
423
+ reportChanged: () => update(),
424
+ })
425
+ }
426
+
427
+ // Entities reactivity
428
+ {
429
+ Remult.entityRefInit = (x) => {
430
+ let update = () => {}
431
+ let s = createSubscriber((u) => {
432
+ update = u
433
+ })
434
+ x.subscribe({
435
+ reportObserved: () => s(),
436
+ reportChanged: () => update(),
437
+ })
438
+ }
439
+ }
440
+ }
441
+ initRemultSvelteReactivity()
306
442
  </script>
307
443
 
308
444
  <svelte:head>
@@ -335,12 +471,13 @@ export const load = (async (event) => {
335
471
 
336
472
  <a href={route('/')}>Home</a> |
337
473
  {#if remult.authenticated()}
338
- <a href={route('/app')}>App (Protected route)</a>
474
+ <a href={route('/app')}>App (Protected route)</a> |
339
475
  {/if}
476
+ <a href={route('/demo/task')}>Demo task</a>
340
477
 
341
478
  <hr />
342
479
 
343
- <slot />
480
+ {@render children?.()}
344
481
 
345
482
  <hr />
346
483
 
@@ -353,12 +490,61 @@ export const load = (async (event) => {
353
490
  <a href={route('github', { owner: 'jycouet', repo: 'firstly' })} target="_blank"> ⭐️ firstly </a>
354
491
  |
355
492
  <a href={route('github', { owner: 'remult', repo: 'remult' })} target="_blank">⭐️ remult</a>
493
+ `,
494
+ ],
495
+ './src/routes/+page.ts': [
496
+ `import { remult } from 'remult'
497
+ import type { PageLoad } from './$types'
498
+
499
+ export const load = (async (event) => {
500
+ // Instruct remult to use the special svelte fetch
501
+ // Like this univeral load will work in SSR & CSR
502
+ remult.useFetch(event.fetch)
503
+ // return repo(Task).find()
504
+ }) satisfies PageLoad
505
+ `,
506
+ ],
507
+ './src/routes/+page.svelte': [
508
+ `<h1>Home</h1>
509
+
510
+ <p>
511
+ Welcome here
512
+ </p>`,
513
+ ],
514
+ './src/routes/app/+page.svelte': [
515
+ `<h1>App</h1>
516
+
517
+ <p>
518
+ Only autenticated users can see this page!
519
+ </p>
520
+
521
+ `,
522
+ ],
523
+ // Lib files
524
+ './src/lib/index.ts': [
525
+ `import { FF_Role } from 'firstly'
526
+ import { FF_Role_Auth } from 'firstly/auth'
527
+ import { Log } from '@kitql/helpers'
528
+
529
+ /**
530
+ * Your logs with a nice prefix, use \`log.info("Hello")\` / \`log.success("Yeah")\` / \`log.error("Ho nooo!")\` and see !
531
+ */
532
+ export const log = new Log('${pkg.name}')
533
+
534
+ /**
535
+ * Your roles, use them in your app !
536
+ */
537
+ export const Role = {
538
+ Boss: 'Boss',
539
+ ...FF_Role_Auth,
540
+ ...FF_Role,
541
+ } as const
356
542
  `,
357
543
  ],
358
544
  './src/lib/ui/SignIn.svelte': [
359
545
  `<script lang="ts">
360
546
  import { isError } from 'firstly'
361
- import { AuthController } from 'firstly/auth/client'
547
+ import { AuthController } from 'firstly/auth'
362
548
 
363
549
  import { goto, invalidateAll } from '$app/navigation'
364
550
 
@@ -408,7 +594,7 @@ export const load = (async (event) => {
408
594
  './src/lib/ui/SignOut.svelte': [
409
595
  `<script lang="ts">
410
596
  import { isError } from 'firstly'
411
- import { AuthController } from 'firstly/auth/client'
597
+ import { AuthController } from 'firstly/auth'
412
598
 
413
599
  import { invalidateAll } from '$app/navigation'
414
600
 
@@ -427,99 +613,38 @@ export const load = (async (event) => {
427
613
  <button on:click={logout}>Logout</button>
428
614
  `,
429
615
  ],
430
- './tsconfig.json': [
431
- `{
432
- "extends": "./.svelte-kit/tsconfig.json",
433
- "compilerOptions": {
434
- "experimentalDecorators": true,
435
- "allowJs": true,
436
- "checkJs": true,
437
- "esModuleInterop": true,
438
- "forceConsistentCasingInFileNames": true,
439
- "resolveJsonModule": true,
440
- "skipLibCheck": true,
441
- "sourceMap": true,
442
- "strict": true,
443
- "moduleResolution": "bundler"
444
- }
445
- // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias
446
- //
447
- // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
448
- // from the referenced tsconfig.json - TypeScript does not merge them in
449
- }
450
- `,
451
- ],
452
- './vite.config.ts': [
453
- `import { sveltekit } from '@sveltejs/kit/vite'
454
- import { defineConfig } from 'vite'
455
-
456
- import { firstly } from 'firstly/vite'
616
+ // Task module
617
+ './src/modules/task/index.ts': [
618
+ `import { Log } from '@kitql/helpers'
457
619
 
458
- import type { KIT_ROUTES } from '${libAlias}/ROUTES'
459
-
460
- export default defineConfig({
461
- plugins: [
462
- // @ts-ignore JYC TODO (vite 5 / vite 6...)
463
- firstly<KIT_ROUTES>({
464
- kitRoutes: {
465
- LINKS: {
466
- login: 'ff/auth/sign-in',
467
- github: 'https://github.com/[owner]/[repo]',
468
- remult_admin: 'api/admin',
469
- },
470
- }
471
- }),
472
- sveltekit(),
473
- ],
474
- })
475
- `,
620
+ export const log = new Log("Custom Task Log")`,
476
621
  ],
477
- './.gitignore': [
478
- `node_modules
479
-
480
- # Output
481
- /.svelte-kit
482
- /build
622
+ './src/modules/task/server/index.ts': [
623
+ `import { Module } from 'firstly/server'
483
624
 
484
- # Env
485
- .env
486
- .env.*
487
- !.env.example
488
- !.env.test
625
+ import { Task } from '../Task'
626
+ import { TaskController } from '../TaskController'
489
627
 
490
- # Vite
491
- vite.config.js.timestamp-*
492
- vite.config.ts.timestamp-*
628
+ export const task: (o: { specialInfo: string }) => Module = ({ specialInfo }) => {
629
+ const m = new Module({
630
+ name: 'task',
631
+ entities: [Task],
632
+ controllers: [TaskController],
633
+ initApi: async () => {
634
+ m.log.success(\`Task module is ready! 🚀 (specialInfo: \${specialInfo})\`)
635
+ },
636
+ })
493
637
 
494
- # Firstly / Remult
495
- /db
638
+ return m
639
+ }
496
640
  `,
497
641
  ],
498
- './src/lib/firstly/modules/task/index.ts': [
499
- `import { Module } from 'firstly/api'
500
-
501
- import { log } from '${libAlias}/firstly'
502
-
503
- import { Task } from './Task'
504
- import { TaskController } from './TaskController'
505
-
506
- export const task: (o: { specialInfo: string }) => Module = ({ specialInfo }) => {
507
- return new Module({
508
- name: 'task',
509
- entities: [Task],
510
- controllers: [TaskController],
511
- initApi: async () => {
512
- log.success(\`Task module is ready! 🚀 (specialInfo: \${specialInfo})\`)
513
- },
514
- })
515
- }`,
516
- ],
517
- './src/lib/firstly/modules/task/Task.ts': [
518
- `import { Entity, Field, Fields, ValueListFieldType } from 'remult'
642
+ './src/modules/task/Task.ts': [
643
+ `import { Allow, Entity, Field, Fields, ValueListFieldType } from 'remult'
519
644
  import { BaseEnum, LibIcon_Add, LibIcon_Delete, type BaseEnumOptions } from 'firstly'
520
645
 
521
646
  @Entity('task', {
522
- allowApiCrud: true,
647
+ allowApiCrud: Allow.authenticated,
523
648
  })
524
649
  export class Task {
525
650
  @Fields.cuid()
@@ -558,10 +683,10 @@ export class TypeOfTaskEnum extends BaseEnum {
558
683
  }
559
684
  `,
560
685
  ],
561
- './src/lib/firstly/modules/task/TaskController.ts': [
686
+ './src/modules/task/TaskController.ts': [
562
687
  `import { BackendMethod } from 'remult'
563
688
 
564
- import { log } from '${libAlias}/firstly'
689
+ import { log } from '${libAlias}'
565
690
 
566
691
  /**
567
692
  * await TaskController.sayHiFromTask("JYC")
@@ -572,6 +697,81 @@ export class TaskController {
572
697
  log.info(\`hello \${name} 👋\`)
573
698
  }
574
699
  }
700
+ `,
701
+ ],
702
+ './src/modules/task/ui/TaskAdd.svelte': [
703
+ `<script lang="ts">
704
+ import { EntityError, repo } from 'remult'
705
+
706
+ import { Task } from '${modulesAlias}/task/Task'
707
+
708
+ let task = $state(repo(Task).create())
709
+ let error = $state<EntityError<Task> | null>(null)
710
+
711
+ const add = async (e: Event) => {
712
+ e.preventDefault()
713
+ error = null
714
+ try {
715
+ await repo(Task).insert(task)
716
+ task = repo(Task).create()
717
+ } catch (e) {
718
+ if (e instanceof EntityError) {
719
+ error = e
720
+ }
721
+ }
722
+ }
723
+ </script>
724
+
725
+ <form onsubmit={add}>
726
+ <p>
727
+ {error?.modelState?.title}
728
+ </p>
729
+ <label for={repo(Task).fields.title.key}>{repo(Task).fields.title.caption}</label>
730
+ <input id={repo(Task).fields.title.key} type="text" bind:value={task.title} />
731
+ <button disabled={!repo(Task).metadata.apiInsertAllowed()}>Add</button>
732
+ </form>
733
+ `,
734
+ ],
735
+ './src/modules/task/ui/TaskList.svelte': [
736
+ `<script lang="ts">
737
+ import { repo } from 'remult'
738
+
739
+ import { Task } from '${modulesAlias}/task/Task'
740
+
741
+ let list: Task[] = $state([])
742
+
743
+ $effect(() => {
744
+ if (repo(Task).metadata.apiReadAllowed) {
745
+ return repo(Task)
746
+ .liveQuery()
747
+ .subscribe((info) => {
748
+ list = info.applyChanges(list)
749
+ })
750
+ }
751
+ })
752
+ </script>
753
+
754
+ {#if repo(Task).metadata.apiReadAllowed}
755
+ <ul>
756
+ {#each list as task (task.id)}
757
+ <li>{task.title}</li>
758
+ {/each}
759
+ </ul>
760
+ {:else}
761
+ <p>Login to see the task list!</p>
762
+ {/if}
763
+ `,
764
+ ],
765
+ './src/routes/demo/task/+page.svelte': [
766
+ `<script lang="ts">
767
+ import TaskAdd from '${modulesAlias}/task/ui/TaskAdd.svelte'
768
+ import TaskList from '${modulesAlias}/task/ui/TaskList.svelte'
769
+ </script>
770
+
771
+ <h1>Task Module</h1>
772
+
773
+ <TaskAdd />
774
+ <TaskList />
575
775
  `,
576
776
  ],
577
777
  };
@@ -581,7 +781,7 @@ for (const [path, content] of Object.entries(obj)) {
581
781
  }
582
782
  else {
583
783
  if (res.includes('module-demo')) {
584
- if (path.startsWith('./src/lib/firstly/modules/task')) {
784
+ if (path.startsWith('./src/modules/task')) {
585
785
  write(path, content);
586
786
  }
587
787
  }
@@ -1,4 +1,4 @@
1
- import { Module } from '../../api';
1
+ import { Module } from '../../server';
2
2
  /**
3
3
  * ## Default way
4
4
  * The easiest is to switch from `@Entity` to `@FF_Entity` to the entities where you want to log changes.
@@ -1,4 +1,4 @@
1
- import { Module } from '../../api';
1
+ import { Module } from '../../server';
2
2
  import { ChangeLog } from '../index';
3
3
  /**
4
4
  * ## Default way
@@ -1,5 +1,5 @@
1
1
  import { CronJob } from 'cron';
2
- import { Module } from '../../api';
2
+ import { Module } from '../../server';
3
3
  export declare const jobs: Record<string, {
4
4
  job: CronJob<null, unknown> | null;
5
5
  concurrentInProgress: number;
@@ -1,6 +1,6 @@
1
1
  import { CronJob } from 'cron';
2
2
  import { green, magenta, red, yellow } from '@kitql/helpers';
3
- import { Module } from '../../api';
3
+ import { Module } from '../../server';
4
4
  export const jobs = {};
5
5
  /**
6
6
  * Link to a nice Cheatsheet TODO