firstly 0.3.0 → 0.4.1

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 (177) hide show
  1. package/CHANGELOG.md +60 -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/FF_Allow.d.ts +55 -0
  6. package/esm/core/FF_Allow.js +54 -0
  7. package/esm/core/FF_Filter.d.ts +55 -0
  8. package/esm/core/FF_Filter.js +57 -0
  9. package/esm/core/helper.d.ts +2 -0
  10. package/esm/core/helper.js +3 -0
  11. package/esm/core/index.d.ts +0 -0
  12. package/esm/core/index.js +5 -0
  13. package/esm/core/tailwind.d.ts +21 -0
  14. package/esm/core/tailwind.js +22 -0
  15. package/esm/core/tryCatch.d.ts +44 -0
  16. package/esm/core/tryCatch.js +34 -0
  17. package/esm/cron/server/index.js +1 -1
  18. package/esm/feedback/FeedbackController.js +3 -2
  19. package/esm/feedback/index.d.ts +7 -2
  20. package/esm/feedback/index.js +1 -2
  21. package/esm/feedback/server/index.d.ts +0 -5
  22. package/esm/feedback/server/index.js +1 -1
  23. package/esm/formats/strings.js +2 -2
  24. package/esm/index.d.ts +18 -0
  25. package/esm/index.js +15 -0
  26. package/esm/sqlAdmin/Roles_SqlAdmin.d.ts +3 -0
  27. package/esm/sqlAdmin/Roles_SqlAdmin.js +3 -0
  28. package/esm/sqlAdmin/SqlAdminController.d.ts +9 -0
  29. package/esm/sqlAdmin/SqlAdminController.js +23 -0
  30. package/esm/sqlAdmin/index.d.ts +6 -0
  31. package/esm/sqlAdmin/index.js +6 -0
  32. package/esm/sqlAdmin/server/index.d.ts +40 -0
  33. package/esm/sqlAdmin/server/index.js +40 -0
  34. package/esm/sqlAdmin/ui/SqlAdmin.svelte +146 -0
  35. package/esm/sqlAdmin/ui/SqlAdmin.svelte.d.ts +3 -0
  36. package/esm/svelte/FF_Repo.svelte.d.ts +0 -2
  37. package/esm/svelte/FF_Repo.svelte.js +1 -17
  38. package/esm/svelte/helpers/debounce.js +1 -1
  39. package/esm/svelte/index.d.ts +2 -24
  40. package/esm/svelte/index.js +2 -22
  41. package/esm/{ui → svelte/ui}/Icon.svelte +1 -1
  42. package/esm/virtual/StateDemoEnum.d.ts +3 -3
  43. package/esm/virtual/StateDemoEnum.js +3 -3
  44. package/esm/virtual/UIEntity.js +1 -2
  45. package/package.json +15 -24
  46. package/esm/bin/cmd.d.ts +0 -1
  47. package/esm/bin/cmd.js +0 -638
  48. package/esm/feedback/ui/DialogIssue.svelte +0 -149
  49. package/esm/feedback/ui/DialogIssue.svelte.d.ts +0 -22
  50. package/esm/feedback/ui/DialogIssues.svelte +0 -114
  51. package/esm/feedback/ui/DialogIssues.svelte.d.ts +0 -22
  52. package/esm/feedback/ui/DialogMilestones.svelte +0 -43
  53. package/esm/feedback/ui/DialogMilestones.svelte.d.ts +0 -20
  54. package/esm/feedback/ui/Feedback.svelte +0 -16
  55. package/esm/feedback/ui/Feedback.svelte.d.ts +0 -18
  56. package/esm/internals/FF_Entity.d.ts +0 -2
  57. package/esm/internals/FF_Fields.d.ts +0 -11
  58. package/esm/internals/FF_Fields.js +0 -144
  59. package/esm/internals/cellsBuildor.d.ts +0 -47
  60. package/esm/internals/cellsBuildor.js +0 -141
  61. package/esm/internals/helper.d.ts +0 -49
  62. package/esm/internals/helper.js +0 -162
  63. package/esm/internals/index.d.ts +0 -78
  64. package/esm/internals/index.js +0 -45
  65. package/esm/internals/storeItem.d.ts +0 -19
  66. package/esm/internals/storeItem.js +0 -190
  67. package/esm/internals/storeList.d.ts +0 -34
  68. package/esm/internals/storeList.js +0 -108
  69. package/esm/internals/theme.d.ts +0 -4
  70. package/esm/internals/theme.js +0 -4
  71. package/esm/server/index.d.ts +0 -52
  72. package/esm/server/index.js +0 -87
  73. package/esm/svelte/FF_Cell.svelte +0 -103
  74. package/esm/svelte/FF_Cell.svelte.d.ts +0 -33
  75. package/esm/svelte/FF_Cell_Caption.svelte +0 -20
  76. package/esm/svelte/FF_Cell_Caption.svelte.d.ts +0 -31
  77. package/esm/svelte/FF_Cell_Display.svelte +0 -61
  78. package/esm/svelte/FF_Cell_Display.svelte.d.ts +0 -29
  79. package/esm/svelte/FF_Cell_Edit.svelte +0 -104
  80. package/esm/svelte/FF_Cell_Edit.svelte.d.ts +0 -32
  81. package/esm/svelte/FF_Cell_Error.svelte +0 -20
  82. package/esm/svelte/FF_Cell_Error.svelte.d.ts +0 -31
  83. package/esm/svelte/FF_Cell_Hint.svelte +0 -20
  84. package/esm/svelte/FF_Cell_Hint.svelte.d.ts +0 -31
  85. package/esm/svelte/FF_Config.svelte +0 -29
  86. package/esm/svelte/FF_Config.svelte.d.ts +0 -9
  87. package/esm/svelte/FF_Form.svelte +0 -155
  88. package/esm/svelte/FF_Form.svelte.d.ts +0 -37
  89. package/esm/svelte/FF_Grid.svelte +0 -257
  90. package/esm/svelte/FF_Grid.svelte.d.ts +0 -37
  91. package/esm/svelte/FF_Layout.svelte +0 -62
  92. package/esm/svelte/FF_Layout.svelte.d.ts +0 -31
  93. package/esm/svelte/actions/intersection.d.ts +0 -6
  94. package/esm/svelte/actions/intersection.js +0 -17
  95. package/esm/svelte/customField.d.ts +0 -69
  96. package/esm/svelte/customField.js +0 -4
  97. package/esm/svelte/dialog/DialogManagement.svelte +0 -98
  98. package/esm/svelte/dialog/DialogManagement.svelte.d.ts +0 -18
  99. package/esm/svelte/dialog/DialogPrimitive.svelte +0 -156
  100. package/esm/svelte/dialog/DialogPrimitive.svelte.d.ts +0 -38
  101. package/esm/svelte/dialog/dialog.d.ts +0 -58
  102. package/esm/svelte/dialog/dialog.js +0 -130
  103. package/esm/svelte/ff_Config.svelte.d.ts +0 -91
  104. package/esm/svelte/ff_Config.svelte.js +0 -111
  105. package/esm/svelte/firstly.css +0 -14
  106. package/esm/svelte/helpers.d.ts +0 -30
  107. package/esm/svelte/helpers.js +0 -38
  108. package/esm/svelte/tryCatch.d.ts +0 -12
  109. package/esm/svelte/tryCatch.js +0 -18
  110. package/esm/sveltekit/server/index.d.ts +0 -5
  111. package/esm/sveltekit/server/index.js +0 -24
  112. package/esm/ui/Button.svelte +0 -90
  113. package/esm/ui/Button.svelte.d.ts +0 -11
  114. package/esm/ui/Clipboardable.svelte +0 -25
  115. package/esm/ui/Clipboardable.svelte.d.ts +0 -12
  116. package/esm/ui/Field.svelte +0 -391
  117. package/esm/ui/Field.svelte.d.ts +0 -40
  118. package/esm/ui/FieldGroup.svelte +0 -117
  119. package/esm/ui/FieldGroup.svelte.d.ts +0 -44
  120. package/esm/ui/Grid.svelte +0 -262
  121. package/esm/ui/Grid.svelte.d.ts +0 -57
  122. package/esm/ui/Grid2.svelte +0 -290
  123. package/esm/ui/Grid2.svelte.d.ts +0 -57
  124. package/esm/ui/GridLoading.svelte +0 -58
  125. package/esm/ui/GridLoading.svelte.d.ts +0 -23
  126. package/esm/ui/GridPaginate.svelte +0 -69
  127. package/esm/ui/GridPaginate.svelte.d.ts +0 -23
  128. package/esm/ui/GridPaginate2.svelte +0 -25
  129. package/esm/ui/GridPaginate2.svelte.d.ts +0 -7
  130. package/esm/ui/Loading.svelte +0 -16
  131. package/esm/ui/Loading.svelte.d.ts +0 -31
  132. package/esm/ui/Tooltip.svelte +0 -45
  133. package/esm/ui/Tooltip.svelte.d.ts +0 -32
  134. package/esm/ui/dialog/DialogForm.svelte +0 -76
  135. package/esm/ui/dialog/DialogForm.svelte.d.ts +0 -21
  136. package/esm/ui/dialog/DialogManagement.svelte +0 -96
  137. package/esm/ui/dialog/DialogManagement.svelte.d.ts +0 -26
  138. package/esm/ui/dialog/DialogPrimitive.svelte +0 -90
  139. package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +0 -38
  140. package/esm/ui/dialog/FormEditAction.svelte +0 -62
  141. package/esm/ui/dialog/FormEditAction.svelte.d.ts +0 -31
  142. package/esm/ui/dialog/dialog.d.ts +0 -60
  143. package/esm/ui/dialog/dialog.js +0 -100
  144. package/esm/ui/index.d.ts +0 -6
  145. package/esm/ui/index.js +0 -20
  146. package/esm/ui/internals/FieldContainer.svelte +0 -39
  147. package/esm/ui/internals/FieldContainer.svelte.d.ts +0 -18
  148. package/esm/ui/internals/Input.svelte +0 -143
  149. package/esm/ui/internals/Input.svelte.d.ts +0 -37
  150. package/esm/ui/internals/Textarea.svelte +0 -66
  151. package/esm/ui/internals/Textarea.svelte.d.ts +0 -33
  152. package/esm/ui/internals/select/MultiSelectMelt.svelte +0 -260
  153. package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +0 -32
  154. package/esm/ui/internals/select/Select2.svelte +0 -88
  155. package/esm/ui/internals/select/Select2.svelte.d.ts +0 -12
  156. package/esm/ui/internals/select/SelectMelt.svelte +0 -289
  157. package/esm/ui/internals/select/SelectMelt.svelte.d.ts +0 -40
  158. package/esm/ui/internals/select/SelectRadio.svelte +0 -43
  159. package/esm/ui/internals/select/SelectRadio.svelte.d.ts +0 -27
  160. package/esm/ui/link/Link.svelte +0 -33
  161. package/esm/ui/link/Link.svelte.d.ts +0 -33
  162. package/esm/ui/link/LinkPlus.svelte +0 -63
  163. package/esm/ui/link/LinkPlus.svelte.d.ts +0 -9
  164. package/esm/utils/tailwind.d.ts +0 -2
  165. package/esm/utils/tailwind.js +0 -3
  166. package/esm/utils/transition.d.ts +0 -9
  167. package/esm/utils/transition.js +0 -33
  168. /package/esm/{internals → core}/BaseEnum.d.ts +0 -0
  169. /package/esm/{internals → core}/BaseEnum.js +0 -0
  170. /package/esm/{internals → core}/FF_Entity.js +0 -0
  171. /package/esm/{internals → core}/common.d.ts +0 -0
  172. /package/esm/{internals → core}/common.js +0 -0
  173. /package/esm/{utils → core}/types.d.ts +0 -0
  174. /package/esm/{utils → core}/types.js +0 -0
  175. /package/esm/{ui → svelte/ui}/Icon.svelte.d.ts +0 -0
  176. /package/esm/{ui → svelte/ui}/LibIcon.d.ts +0 -0
  177. /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`)));