create-vitnode-app 0.0.10-canary.9 → 0.1.0-rc.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 (26) hide show
  1. package/dist/index.cjs +33 -33
  2. package/package.json +4 -4
  3. package/templates/basic/.gitignore_template +2 -1
  4. package/templates/basic/apps/backend/src/app.module.ts +4 -0
  5. package/templates/basic/apps/backend/tsconfig.json +1 -1
  6. package/templates/basic/apps/backend/uploads/public/assets/favicon.ico +0 -0
  7. package/templates/basic/apps/frontend/global.d.ts +4 -2
  8. package/templates/basic/apps/frontend/public/sw.js +3 -0
  9. package/templates/basic/apps/frontend/src/app/[locale]/(main)/(layout)/footer.tsx +18 -0
  10. package/templates/basic/apps/frontend/src/app/[locale]/(main)/(layout)/layout.tsx +8 -1
  11. package/templates/basic/apps/frontend/src/app/global.css +11 -7
  12. package/templates/basic/apps/frontend/src/app/robots.ts +9 -0
  13. package/templates/basic/apps/frontend/src/app/sitemap.ts +9 -0
  14. package/templates/basic/apps/frontend/src/middleware.ts +1 -1
  15. package/templates/basic/apps/frontend/src/plugins/admin/langs/en.json +136 -113
  16. package/templates/basic/apps/frontend/src/plugins/core/langs/en.json +58 -32
  17. package/templates/basic/apps/frontend/src/plugins/welcome/langs/en.json +2 -4
  18. package/templates/basic/apps/frontend/src/plugins/welcome/templates/default-page.tsx +1 -1
  19. package/templates/basic/apps/frontend/tailwind.config.ts +1 -0
  20. package/templates/basic/apps/frontend/tsconfig.json +7 -1
  21. package/templates/basic/apps/shared/plugins/welcome/example.dto.ts +0 -3
  22. package/templates/basic/apps/shared/tsconfig.json +2 -2
  23. package/templates/docker/apps/backend/DockerFile +1 -0
  24. package/templates/docker/apps/frontend/DockerFile +2 -1
  25. package/templates/docker/deploy.sh +1 -3
  26. package/templates/docker/docker-compose.yml +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-vitnode-app",
3
- "version": "0.0.10-canary.9",
3
+ "version": "0.1.0-rc.1",
4
4
  "description": "Create a new VitNode app in seconds.",
5
5
  "author": "VitNode Team",
6
6
  "license": "MIT",
@@ -34,15 +34,15 @@
34
34
  "devDependencies": {
35
35
  "@types/cross-spawn": "^6.0.6",
36
36
  "@types/figlet": "^1.7.0",
37
- "@types/node": "^22.9.1",
37
+ "@types/node": "^22.10.2",
38
38
  "@types/prompts": "^2.4.9",
39
39
  "@types/validate-npm-package-name": "^4.0.2",
40
40
  "commander": "^12.1.0",
41
41
  "cross-spawn": "^7.0.6",
42
42
  "ora": "^8.1.1",
43
43
  "tsup": "^8.3.5",
44
- "typescript": "^5.6.3",
45
- "eslint-config-typescript-vitnode": "0.0.10-canary.9"
44
+ "typescript": "^5.7.2",
45
+ "eslint-config-typescript-vitnode": "0.1.0-rc.1"
46
46
  },
47
47
  "scripts": {
48
48
  "lint": "eslint .",
@@ -51,7 +51,8 @@ yarn-error.log*
51
51
  !/apps/backend/uploads/temp/index.html
52
52
 
53
53
  ## Configuration
54
- /apps/backend/src/plugins/core/
54
+ /apps/backend/src/plugins/core/utils/*
55
55
 
56
56
  ## Frontend
57
57
  /apps/frontend/next-env.d.ts
58
+ /apps/frontend/.source/
@@ -1,3 +1,4 @@
1
+ import { CacheModule } from '@nestjs/cache-manager';
1
2
  import { Module } from '@nestjs/common';
2
3
  import { VitNodeCoreModule } from 'vitnode-backend/app.module';
3
4
 
@@ -15,6 +16,9 @@ import { PluginsModule } from './plugins/plugins.module';
15
16
  }),
16
17
  DatabaseModule,
17
18
  PluginsModule,
19
+ CacheModule.register({
20
+ isGlobal: true,
21
+ }),
18
22
  ],
19
23
  })
20
24
  export class AppModule {}
@@ -8,7 +8,7 @@
8
8
  "baseUrl": "./",
9
9
  "outDir": "./dist",
10
10
  "paths": {
11
- "@/*": ["./src/*", "./node_modules/vitnode-backend/dist/*"]
11
+ "@/*": ["./src/*"]
12
12
  }
13
13
  },
14
14
  "exclude": ["uploads"]
@@ -4,6 +4,8 @@ import type welcome from '@/plugins/welcome/langs/en.json';
4
4
 
5
5
  type Messages = typeof core & typeof admin & typeof welcome;
6
6
 
7
- declare global {
8
- interface IntlMessages extends Messages {}
7
+ declare module 'next-intl' {
8
+ interface AppConfig {
9
+ Messages: Messages;
10
+ }
9
11
  }
@@ -0,0 +1,3 @@
1
+ 'use strict';
2
+
3
+ self.addEventListener('install', () => {});
@@ -0,0 +1,18 @@
1
+ import { getTranslations } from 'next-intl/server';
2
+ import { Link } from 'vitnode-frontend/navigation';
3
+
4
+ export const Footer = async () => {
5
+ const t = await getTranslations('core.legal');
6
+
7
+ return (
8
+ <footer className="container mb-14 mt-6 flex flex-col items-center justify-between gap-4 border-t py-6 text-sm sm:mb-0 sm:flex-row">
9
+ <Link className="text-muted-foreground" href="https://vitnode.com/">
10
+ Powered by <span className="text-primary font-medium">VitNode</span>
11
+ </Link>
12
+
13
+ <div>
14
+ <Link href="/legal">{t('title')}</Link>
15
+ </div>
16
+ </footer>
17
+ );
18
+ };
@@ -1,5 +1,12 @@
1
1
  import { ThemeLayout } from 'vitnode-frontend/views/theme/layout/theme-layout';
2
2
 
3
+ import { Footer } from './footer';
4
+
3
5
  export default function Layout({ children }: { children: React.ReactNode }) {
4
- return <ThemeLayout>{children}</ThemeLayout>;
6
+ return (
7
+ <>
8
+ <ThemeLayout>{children}</ThemeLayout>
9
+ <Footer />
10
+ </>
11
+ );
5
12
  }
@@ -11,9 +11,13 @@
11
11
  @apply bg-background text-foreground;
12
12
  }
13
13
 
14
+ a {
15
+ @apply text-primary;
16
+ }
17
+
14
18
  :root {
15
- --background: 220 40% 98%;
16
- --foreground: 213deg 5% 8%;
19
+ --background: 217 20% 96%;
20
+ --foreground: 213 5% 8%;
17
21
  --card: 220 40% 100%;
18
22
  --card-foreground: 213deg 26% 7%;
19
23
  --popover: var(--card);
@@ -24,11 +28,11 @@
24
28
  --secondary-foreground: 210 40% 2%;
25
29
  --muted: 220 40% 96%;
26
30
  --muted-foreground: 220 8% 44%;
27
- --accent: 220 40% 92%;
31
+ --accent: 220 40% 94%;
28
32
  --accent-foreground: 222 47% 11%;
29
33
  --destructive: 0 57% 43%;
30
34
  --destructive-foreground: 210 40% 98%;
31
- --border: 220 20% 90%;
35
+ --border: 220 40% 90%;
32
36
  --input: var(--border);
33
37
  --ring: var(--primary);
34
38
  --radius: 0.5rem;
@@ -45,7 +49,7 @@
45
49
  .dark {
46
50
  --background: 220 11% 6%;
47
51
  --foreground: 0 0% 98%;
48
- --card: 225 11% 8%;
52
+ --card: 225 15% 9%;
49
53
  --card-foreground: 0 0% 98%;
50
54
  /* --popover: var(--card); */
51
55
  /* --popover-foreground: var(--card-foreground); */
@@ -53,9 +57,9 @@
53
57
  --primary-foreground: 220 40% 98%;
54
58
  --secondary: 216 10% 18%;
55
59
  --secondary-foreground: 0 0% 98%;
56
- --muted: 228 11% 12%;
60
+ --muted: 225 15% 12%;
57
61
  --muted-foreground: 216 0% 68%;
58
- --accent: 225 10% 10%;
62
+ --accent: 225 15% 14%;
59
63
  --accent-foreground: 0 0% 98%;
60
64
  --destructive: 359 78% 55%;
61
65
  --destructive-foreground: 210 40% 98%;
@@ -0,0 +1,9 @@
1
+ import type { MetadataRoute } from 'next';
2
+
3
+ import { rootRobots } from 'vitnode-frontend/robots';
4
+
5
+ export default async function robots(): Promise<MetadataRoute.Robots> {
6
+ const robots = await rootRobots();
7
+
8
+ return robots;
9
+ }
@@ -0,0 +1,9 @@
1
+ import type { MetadataRoute } from 'next';
2
+
3
+ import { rootSitemap } from 'vitnode-frontend/sitemap';
4
+
5
+ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
6
+ const sitemap = await rootSitemap();
7
+
8
+ return sitemap;
9
+ }
@@ -3,5 +3,5 @@ import { createMiddleware } from 'vitnode-frontend/middleware';
3
3
  export default createMiddleware();
4
4
 
5
5
  export const config = {
6
- matcher: '/((?!_next|robots.txt|sitemap.xml|sitemap).*)',
6
+ matcher: '/((?!_next|robots.txt|api|sw.js|sitemap.xml|robots.txt).*)',
7
7
  };
@@ -8,6 +8,7 @@
8
8
  "diagnostic_tools": "Diagnostic Tools",
9
9
  "home_page": "Home Page",
10
10
  "mobile_not_supported": "Mobile devices are not supported.",
11
+ "require_email_service": "The email service is disabled.",
11
12
  "search": {
12
13
  "placeholder": "Search...",
13
14
  "no_results": "No results found.",
@@ -15,6 +16,17 @@
15
16
  "pages": "Pages"
16
17
  }
17
18
  },
19
+ "dashboard": {
20
+ "new_users": {
21
+ "title": "New Users",
22
+ "users": "Users"
23
+ },
24
+ "note": {
25
+ "title": "Note for Administrators",
26
+ "last_updated": "Last Updated: <date></date>",
27
+ "submit": "Save Note"
28
+ }
29
+ },
18
30
  "theme_editor": {
19
31
  "title": "Theme Editor",
20
32
  "desktop": "Desktop",
@@ -50,33 +62,54 @@
50
62
  "diagnostic": {
51
63
  "title": "Diagnostic Tools",
52
64
  "desc": "Use these tools to diagnose and fix common issues with your website.",
65
+ "get_support": "Get Support",
53
66
  "clear_cache": {
54
67
  "title": "Clear Cache",
55
68
  "desc": "This action clean up the cache of your website. This can help fix issues with your website but may slow down your website temporarily.",
56
69
  "confirm": "Yes, clear cache",
57
70
  "success": "Cache has been cleared."
58
- }
71
+ },
72
+ "captcha": {
73
+ "title": "Captcha",
74
+ "desc": "Protect your website from spam."
75
+ },
76
+ "email": {
77
+ "title": "Email",
78
+ "desc": "Access to send emails."
79
+ },
80
+ "ai": {
81
+ "title": "Artificial Intelligence (AI)",
82
+ "desc": "Use AI to improve your website."
83
+ },
84
+ "enable": "Enable",
85
+ "disable": "Disable",
86
+ "how_to_enable": "How to enable?"
59
87
  },
60
88
  "email": {
61
- "hello": "Hello",
62
- "footer": "You're receiving this email because your account activity triggered this email. Please do not reply to this email. If you have any questions, please contact us at:"
89
+ "hello": "Hello"
63
90
  },
64
91
  "settings": {
65
92
  "main": {
66
93
  "title": "Main Settings",
67
94
  "desc": "These settings are used to configure the main features of your website.",
68
95
  "name": {
69
- "label": "Name Site"
96
+ "label": "Name Site",
97
+ "seo": "Recommended between 50-60 characters."
70
98
  },
71
99
  "short_name": {
72
- "label": "Short Name Site"
100
+ "label": "Short Name Site",
101
+ "seo": "Recommended max 20 characters."
73
102
  },
74
103
  "description": {
75
- "label": "Description Site"
104
+ "label": "Description Site",
105
+ "seo": "Recommended between 120-160 characters."
76
106
  },
77
107
  "contact_email": {
78
108
  "label": "Contact Email",
79
109
  "desc": "This email address will be applied to the contact form and other contact points on your website."
110
+ },
111
+ "app_type": {
112
+ "label": "App Type"
80
113
  }
81
114
  },
82
115
  "email": {
@@ -124,44 +157,51 @@
124
157
  "send_testing_email": "Send Testing Email"
125
158
  }
126
159
  },
127
- "security": {
128
- "captcha": {
129
- "title": "Captcha",
130
- "desc": "Captcha is a security feature that requires users to complete a challenge to prove they are human. This helps prevent spam and abuse.",
131
- "type": {
132
- "title": "Type",
133
- "none": {
134
- "title": "None"
135
- },
136
- "recaptcha_desc": "Read more on <link>Google reCAPTCHA</link>.",
137
- "recaptcha_v2_invisible": "reCAPTCHA v2 Invisible",
138
- "recaptcha_v2_checkbox": "reCAPTCHA v2 Checkbox",
139
- "recaptcha_v3": "reCAPTCHA v3",
140
- "cloudflare_turnstile": {
141
- "title": "Cloudflare Turnstile",
142
- "desc": "Read more on <link>Cloudflare Turnstile</link>."
143
- }
144
- },
145
- "site_key": "Site Key",
146
- "secret_key": "Secret Key"
147
- }
148
- },
149
160
  "authorization": {
150
- "force_login": {
151
- "title": "Force Login",
152
- "desc": "Force users to log in before they can access your website."
153
- },
154
- "lock_register": {
155
- "title": "Lock Register",
156
- "desc": "Don't allow users to register on your website."
161
+ "title": "Authorization",
162
+ "desc": "Manage authorization settings for your website.",
163
+ "settings": {
164
+ "title": "Settings",
165
+ "force_login": {
166
+ "title": "Force Login",
167
+ "desc": "Force users to log in before they can access your website."
168
+ },
169
+ "lock_register": {
170
+ "title": "Lock Register",
171
+ "desc": "Don't allow users to register on your website."
172
+ },
173
+ "require_confirm_email": {
174
+ "title": "Require Confirm Email",
175
+ "desc": "Require users to confirm their email address before they can access your site."
176
+ }
157
177
  },
158
- "require_confirm_email": {
159
- "title": "Require Confirm Email",
160
- "desc": "Require users to confirm their email address before they can access your site."
178
+ "methods": {
179
+ "title": "Login Methods",
180
+ "name": "Name",
181
+ "enabled": "Enabled",
182
+ "create": {
183
+ "title": "Create Method",
184
+ "desc": "New login method for your website.",
185
+ "provider": "Provider",
186
+ "client_id": "Client ID",
187
+ "client_secret": "Client Secret",
188
+ "success": "Login method has been created.",
189
+ "your_callback_url": "Your callback URL"
190
+ },
191
+ "edit": {
192
+ "title": "Edit Method",
193
+ "success": "Login method has been updated."
194
+ },
195
+ "delete": {
196
+ "desc": "This action will delete the login method <name></name>.",
197
+ "warn": "If you delete this login method, users who use this method to log in will not be able to log in.",
198
+ "success": "Login method has been deleted.",
199
+ "submit": "Yes, delete login method"
200
+ }
161
201
  }
162
202
  },
163
203
  "legal": {
164
- "title": "Legal & Policies",
204
+ "title": "Legal",
165
205
  "desc": "These settings are used to generate the legal pages on your website.",
166
206
  "legal_public": "Public Legal",
167
207
  "created": "Created",
@@ -213,12 +253,24 @@
213
253
  "prompt_placeholder": "Ask a question...",
214
254
  "submit": "Ask"
215
255
  }
216
- }
217
- },
218
- "metadata": {
219
- "manifest": {
220
- "title": "Manifest",
221
- "desc": "The web app manifest provides information about an application (such as name, author, icon, and description) in a JSON text file. The manifest is used to install the web application (PWA) to the home screen of a device.",
256
+ },
257
+ "metadata": {
258
+ "title": "Metadata",
259
+ "desc": "Share your website with the world by adding metadata to your website.",
260
+ "theme_color": "Theme Color",
261
+ "background_color": "Background Color",
262
+ "start_url": {
263
+ "label": "Start URL",
264
+ "desc": "When user launches the app, this is the page that will be loaded."
265
+ },
266
+ "icon": {
267
+ "label": "Icon",
268
+ "desc": "Represent your website on devices (PWA). Recommended size: 512x512px."
269
+ },
270
+ "favicon": {
271
+ "label": "Favicon",
272
+ "desc": "Icon in browser tab. Recommended size: 32x32px."
273
+ },
222
274
  "display": {
223
275
  "label": "Display",
224
276
  "desc": "The display property controls how the app is displayed.",
@@ -230,7 +282,7 @@
230
282
  "title": "Standalone",
231
283
  "desc": "Without any browser UI."
232
284
  },
233
- "minimal-ui": {
285
+ "minimal": {
234
286
  "title": "Minimal UI",
235
287
  "desc": "Minimal browser UI."
236
288
  },
@@ -238,16 +290,6 @@
238
290
  "title": "Browser",
239
291
  "desc": "With browser UI."
240
292
  }
241
- },
242
- "start_url": {
243
- "label": "Start URL",
244
- "desc": "When user launches the app, this is the page that will be loaded."
245
- },
246
- "theme_color": {
247
- "label": "Theme Color"
248
- },
249
- "background_color": {
250
- "label": "Background Color"
251
293
  }
252
294
  }
253
295
  },
@@ -268,9 +310,7 @@
268
310
  "desc": "We're detected changes in <bold>the plugin system</bold>. To apply these changes, you need to <bold>restart the server</bold>."
269
311
  },
270
312
  "dev": {
271
- "overview": {
272
- "title": "Overview"
273
- },
313
+ "overview": "Overview",
274
314
  "nav": {
275
315
  "title": "Navigation in AdminCP",
276
316
  "lang_key": "Lang Key: <key></key>",
@@ -332,6 +372,18 @@
332
372
  "desc": "If you delete this permission, all children will be deleted too."
333
373
  }
334
374
  }
375
+ },
376
+ "export": {
377
+ "title": "Export Plugin",
378
+ "desc": "Choose version to export.",
379
+ "type": {
380
+ "rebuild": "Rebuild current version - {version}",
381
+ "new_version": "Create new version"
382
+ },
383
+ "version": "Version",
384
+ "version_code": "Version Code",
385
+ "success": "Plugin has been exported.",
386
+ "submit": "Export"
335
387
  }
336
388
  },
337
389
  "create": {
@@ -368,32 +420,24 @@
368
420
  },
369
421
  "upload": {
370
422
  "title": "Upload Plugin",
423
+ "desc": "Upload a new plugin to your website.",
371
424
  "title_new_version": "Upload New Version Plugin",
372
- "info": "After uploading the plugin, you need to restart the server to apply the changes.",
425
+ "info": "After the process will be complete, you need to restart the server to apply the changes.",
373
426
  "errors": {
374
427
  "PLUGIN_ALREADY_EXISTS": "Plugin with this code already exists. If you want to update the plugin, use the upload new version form from the plugin dropdown menu.",
375
- "PLUGIN_VERSION_IS_LOWER": "The version of the uploaded plugin is lower than the current version."
428
+ "PLUGIN_VERSION_IS_LOWER": "The version of the uploaded plugin is lower than the current version.",
429
+ "CONFLICT_PLUGIN_CODE": "Files with the same name already exist your project. Please remove them and try again."
430
+ },
431
+ "success": {
432
+ "upload": "Plugin has been uploaded.",
433
+ "new_version": "New version of the plugin has been uploaded."
376
434
  },
377
435
  "submit": "Upload"
378
436
  },
379
437
  "delete": {
380
438
  "submit": "Yes, delete plugin",
381
439
  "desc": "This action will delete <name></name> plugin created by <author></author> and all data associated with it.",
382
- "info": "After the process is complete, you need to restart the server to apply the changes."
383
- },
384
- "download": {
385
- "title": "Download Plugin",
386
- "type": {
387
- "rebuild": "Rebuild current version - {version}",
388
- "new_version": "Create new version"
389
- },
390
- "version": {
391
- "label": "Version"
392
- },
393
- "version_code": {
394
- "label": "Version Code"
395
- },
396
- "submit": "Download"
440
+ "info": "After the process will be complete, you need to restart the server to apply the changes."
397
441
  }
398
442
  },
399
443
  "styles": {
@@ -452,30 +496,36 @@
452
496
  "sticky": {
453
497
  "label": "Sticky Toolbar",
454
498
  "desc": "The toolbar will be fixed at the top of the screen."
455
- },
456
- "files": {
457
- "allow_type": {
458
- "title": "Allow File Type",
459
- "all": "All",
460
- "images_videos": "Images & Videos",
461
- "images": "Images",
462
- "none": "None"
463
- }
464
499
  }
465
500
  }
466
501
  },
467
502
  "langs": {
468
503
  "title": "Languages",
504
+ "desc": "Manage languages on your website.",
469
505
  "search_placeholder": "Search by name...",
470
506
  "table": {
471
507
  "key": "Key",
472
508
  "time_24": "24h Format",
473
- "locale": "Locale",
474
509
  "name": "Name",
475
510
  "updated": "Updated",
476
511
  "enabled": "Enabled"
477
512
  },
478
513
  "actions": {
514
+ "translate-ai": {
515
+ "title": "Translate with AI",
516
+ "desc": "Choose which plugins you want to translate for <lang></lang> language.",
517
+ "all_plugins": {
518
+ "label": "All Plugins",
519
+ "desc": "This process may take a little longer."
520
+ },
521
+ "admin": "Admin",
522
+ "plugins": {
523
+ "label": "Plugins",
524
+ "desc": "Select specific plugins to translate."
525
+ },
526
+ "submit": "Translate",
527
+ "success": "The language has been translated."
528
+ },
479
529
  "create": {
480
530
  "title": "Create Language",
481
531
  "name": {
@@ -495,9 +545,6 @@
495
545
  "label": "24h Time Format",
496
546
  "desc": "Shows 24h time format instead of 12h."
497
547
  },
498
- "locale": {
499
- "label": "Locale"
500
- },
501
548
  "allow_in_input": {
502
549
  "label": "Allow in Input",
503
550
  "desc": "Allow users to select this language in the input field."
@@ -532,30 +579,6 @@
532
579
  "submit": "Yes, delete file"
533
580
  }
534
581
  }
535
- },
536
- "security": {
537
- "spam": {
538
- "title": "Spam Protection",
539
- "captcha": {
540
- "title": "Captcha",
541
- "type": {
542
- "title": "Type",
543
- "none": {
544
- "title": "None"
545
- },
546
- "recaptcha_desc": "Read more on <link>Google reCAPTCHA</link>.",
547
- "recaptcha_v2_invisible": "reCAPTCHA v2 Invisible",
548
- "recaptcha_v2_checkbox": "reCAPTCHA v2 Checkbox",
549
- "recaptcha_v3": "reCAPTCHA v3",
550
- "cloudflare_turnstile": {
551
- "title": "Cloudflare Turnstile",
552
- "desc": "Read more on <link>Cloudflare Turnstile</link>."
553
- }
554
- },
555
- "site_key": "Site Key",
556
- "secret_key": "Secret Key"
557
- }
558
- }
559
582
  }
560
583
  },
561
584
  "members": {