nitronjs 0.1.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 (87) hide show
  1. package/README.md +429 -0
  2. package/cli/create.js +260 -0
  3. package/cli/njs.js +164 -0
  4. package/lib/Auth/Manager.js +111 -0
  5. package/lib/Build/Manager.js +1232 -0
  6. package/lib/Console/Commands/BuildCommand.js +25 -0
  7. package/lib/Console/Commands/DevCommand.js +385 -0
  8. package/lib/Console/Commands/MakeCommand.js +110 -0
  9. package/lib/Console/Commands/MigrateCommand.js +98 -0
  10. package/lib/Console/Commands/MigrateFreshCommand.js +97 -0
  11. package/lib/Console/Commands/SeedCommand.js +92 -0
  12. package/lib/Console/Commands/StorageLinkCommand.js +31 -0
  13. package/lib/Console/Stubs/controller.js +19 -0
  14. package/lib/Console/Stubs/middleware.js +9 -0
  15. package/lib/Console/Stubs/migration.js +23 -0
  16. package/lib/Console/Stubs/model.js +7 -0
  17. package/lib/Console/Stubs/page-hydration.tsx +54 -0
  18. package/lib/Console/Stubs/seeder.js +9 -0
  19. package/lib/Console/Stubs/vendor.tsx +11 -0
  20. package/lib/Core/Config.js +86 -0
  21. package/lib/Core/Environment.js +21 -0
  22. package/lib/Core/Paths.js +188 -0
  23. package/lib/Database/Connection.js +61 -0
  24. package/lib/Database/DB.js +84 -0
  25. package/lib/Database/Drivers/MySQLDriver.js +234 -0
  26. package/lib/Database/Manager.js +162 -0
  27. package/lib/Database/Model.js +161 -0
  28. package/lib/Database/QueryBuilder.js +714 -0
  29. package/lib/Database/QueryValidation.js +62 -0
  30. package/lib/Database/Schema/Blueprint.js +126 -0
  31. package/lib/Database/Schema/Manager.js +116 -0
  32. package/lib/Date/DateTime.js +108 -0
  33. package/lib/Date/Locale.js +68 -0
  34. package/lib/Encryption/Manager.js +47 -0
  35. package/lib/Filesystem/Manager.js +49 -0
  36. package/lib/Hashing/Manager.js +25 -0
  37. package/lib/Http/Server.js +317 -0
  38. package/lib/Logging/Manager.js +153 -0
  39. package/lib/Mail/Manager.js +120 -0
  40. package/lib/Route/Loader.js +81 -0
  41. package/lib/Route/Manager.js +265 -0
  42. package/lib/Runtime/Entry.js +11 -0
  43. package/lib/Session/File.js +299 -0
  44. package/lib/Session/Manager.js +259 -0
  45. package/lib/Session/Memory.js +67 -0
  46. package/lib/Session/Session.js +196 -0
  47. package/lib/Support/Str.js +100 -0
  48. package/lib/Translation/Manager.js +49 -0
  49. package/lib/Validation/MimeTypes.js +39 -0
  50. package/lib/Validation/Validator.js +691 -0
  51. package/lib/View/Manager.js +544 -0
  52. package/lib/View/Templates/default/Home.tsx +262 -0
  53. package/lib/View/Templates/default/MainLayout.tsx +44 -0
  54. package/lib/View/Templates/errors/404.tsx +13 -0
  55. package/lib/View/Templates/errors/500.tsx +13 -0
  56. package/lib/View/Templates/errors/ErrorLayout.tsx +112 -0
  57. package/lib/View/Templates/messages/Maintenance.tsx +17 -0
  58. package/lib/View/Templates/messages/MessageLayout.tsx +136 -0
  59. package/lib/index.js +57 -0
  60. package/package.json +48 -0
  61. package/skeleton/.env.example +26 -0
  62. package/skeleton/app/Controllers/HomeController.js +9 -0
  63. package/skeleton/app/Kernel.js +11 -0
  64. package/skeleton/app/Middlewares/Authentication.js +9 -0
  65. package/skeleton/app/Middlewares/Guest.js +9 -0
  66. package/skeleton/app/Middlewares/VerifyCsrf.js +24 -0
  67. package/skeleton/app/Models/User.js +7 -0
  68. package/skeleton/config/app.js +4 -0
  69. package/skeleton/config/auth.js +16 -0
  70. package/skeleton/config/database.js +27 -0
  71. package/skeleton/config/hash.js +3 -0
  72. package/skeleton/config/server.js +28 -0
  73. package/skeleton/config/session.js +21 -0
  74. package/skeleton/database/migrations/2025_01_01_00_00_users.js +20 -0
  75. package/skeleton/database/seeders/UserSeeder.js +15 -0
  76. package/skeleton/globals.d.ts +1 -0
  77. package/skeleton/package.json +24 -0
  78. package/skeleton/public/.gitkeep +0 -0
  79. package/skeleton/resources/css/.gitkeep +0 -0
  80. package/skeleton/resources/langs/.gitkeep +0 -0
  81. package/skeleton/resources/views/Site/Home.tsx +66 -0
  82. package/skeleton/routes/web.js +4 -0
  83. package/skeleton/storage/app/private/.gitkeep +0 -0
  84. package/skeleton/storage/app/public/.gitkeep +0 -0
  85. package/skeleton/storage/framework/sessions/.gitkeep +0 -0
  86. package/skeleton/storage/logs/.gitkeep +0 -0
  87. package/skeleton/tsconfig.json +33 -0
package/cli/njs.js ADDED
@@ -0,0 +1,164 @@
1
+ #!/usr/bin/env node
2
+
3
+ const COLORS = {
4
+ reset: "\x1b[0m",
5
+ bold: "\x1b[1m",
6
+ dim: "\x1b[2m",
7
+ red: "\x1b[31m",
8
+ green: "\x1b[32m",
9
+ yellow: "\x1b[33m",
10
+ cyan: "\x1b[36m"
11
+ };
12
+
13
+ function printHelp() {
14
+ console.log(`
15
+ ${COLORS.cyan}╔══════════════════════════════════════════════════════════════╗${COLORS.reset}
16
+ ${COLORS.cyan}║${COLORS.reset} ${COLORS.bold}NitronJS CLI${COLORS.reset} ${COLORS.cyan}║${COLORS.reset}
17
+ ${COLORS.cyan}╚══════════════════════════════════════════════════════════════╝${COLORS.reset}
18
+
19
+ ${COLORS.bold}Usage:${COLORS.reset}
20
+ ${COLORS.cyan}npx nitronjs <project>${COLORS.reset} Create a new NitronJS project
21
+ ${COLORS.cyan}njs <command>${COLORS.reset} Run a command in your project
22
+
23
+ ${COLORS.bold}Development:${COLORS.reset}
24
+ ${COLORS.cyan}njs dev${COLORS.reset} Start development server with hot reload
25
+ ${COLORS.cyan}njs build${COLORS.reset} Build application for production
26
+ ${COLORS.cyan}njs start${COLORS.reset} Start production server
27
+
28
+ ${COLORS.bold}Database:${COLORS.reset}
29
+ ${COLORS.cyan}njs migrate${COLORS.reset} Run database migrations
30
+ ${COLORS.cyan}njs migrate --seed${COLORS.reset} Run migrations and seeders
31
+ ${COLORS.cyan}njs migrate:fresh${COLORS.reset} Drop all tables and re-migrate
32
+ ${COLORS.cyan}njs migrate:fresh --seed${COLORS.reset} Fresh migrate with seeders
33
+ ${COLORS.cyan}njs seed${COLORS.reset} Run database seeders
34
+
35
+ ${COLORS.bold}Generators:${COLORS.reset}
36
+ ${COLORS.cyan}njs make:controller${COLORS.reset} Create a new controller
37
+ ${COLORS.cyan}njs make:middleware${COLORS.reset} Create a new middleware
38
+ ${COLORS.cyan}njs make:model${COLORS.reset} Create a new model
39
+ ${COLORS.cyan}njs make:migration${COLORS.reset} Create a new migration
40
+ ${COLORS.cyan}njs make:seeder${COLORS.reset} Create a new seeder
41
+
42
+ ${COLORS.bold}Utilities:${COLORS.reset}
43
+ ${COLORS.cyan}njs storage:link${COLORS.reset} Create symbolic link for storage
44
+
45
+ ${COLORS.bold}Examples:${COLORS.reset}
46
+ ${COLORS.dim}# Create a new project${COLORS.reset}
47
+ npx nitronjs my-app
48
+
49
+ ${COLORS.dim}# Generate a controller with subdirectory${COLORS.reset}
50
+ njs make:controller Admin/DashboardController
51
+
52
+ ${COLORS.dim}# Fresh migrate with seeders${COLORS.reset}
53
+ njs migrate:fresh --seed
54
+ `);
55
+ }
56
+
57
+ const args = process.argv.slice(2);
58
+
59
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
60
+ printHelp();
61
+ process.exit(0);
62
+ }
63
+
64
+ const command = args[0];
65
+ const additionalArgs = args.slice(1);
66
+
67
+ const KNOWN_COMMANDS = [
68
+ "dev", "start", "build",
69
+ "migrate", "migrate:fresh", "seed",
70
+ "storage:link",
71
+ "make:controller", "make:middleware", "make:model", "make:migration", "make:seeder"
72
+ ];
73
+
74
+ const isProjectName = command &&
75
+ !command.startsWith("-") &&
76
+ !KNOWN_COMMANDS.includes(command) &&
77
+ !command.startsWith("make:");
78
+
79
+ async function run() {
80
+ try {
81
+ if (isProjectName) {
82
+ const { default: create } = await import("./create.js");
83
+ await create(command);
84
+ return;
85
+ }
86
+
87
+ switch (command) {
88
+ case "dev": {
89
+ const { default: Dev } = await import("../lib/Console/Commands/DevCommand.js");
90
+ await Dev();
91
+ break;
92
+ }
93
+
94
+ case "start": {
95
+ const { start } = await import("../lib/Runtime/Entry.js");
96
+ await start();
97
+ break;
98
+ }
99
+
100
+ case "build": {
101
+ const { default: Build } = await import("../lib/Console/Commands/BuildCommand.js");
102
+ await Build();
103
+ break;
104
+ }
105
+
106
+ case "migrate": {
107
+ const { default: Migrate } = await import("../lib/Console/Commands/MigrateCommand.js");
108
+ await Migrate(additionalArgs.includes("--seed"));
109
+ break;
110
+ }
111
+
112
+ case "migrate:fresh": {
113
+ const { default: MigrateFresh } = await import("../lib/Console/Commands/MigrateFreshCommand.js");
114
+ await MigrateFresh(additionalArgs.includes("--seed"));
115
+ break;
116
+ }
117
+
118
+ case "seed": {
119
+ const { default: Seed } = await import("../lib/Console/Commands/SeedCommand.js");
120
+ await Seed();
121
+ break;
122
+ }
123
+
124
+ case "storage:link": {
125
+ const { default: StorageLink } = await import("../lib/Console/Commands/StorageLinkCommand.js");
126
+ await StorageLink();
127
+ break;
128
+ }
129
+
130
+ case "make:controller":
131
+ case "make:middleware":
132
+ case "make:model":
133
+ case "make:migration":
134
+ case "make:seeder": {
135
+ const type = command.split(":")[1];
136
+ const name = additionalArgs[0];
137
+
138
+ if (!name) {
139
+ console.error(`${COLORS.red}Error: Name is required${COLORS.reset}`);
140
+ console.log(`${COLORS.dim}Usage: njs ${command} <Name>${COLORS.reset}`);
141
+ console.log(`${COLORS.dim}Example: njs ${command} ${type === "controller" ? "HomeController" : type === "middleware" ? "AuthMiddleware" : type === "model" ? "User" : type === "migration" ? "users" : "UserSeeder"}${COLORS.reset}`);
142
+ process.exit(1);
143
+ }
144
+
145
+ const { default: Make } = await import("../lib/Console/Commands/MakeCommand.js");
146
+ await Make(type, name);
147
+ break;
148
+ }
149
+
150
+ default:
151
+ console.error(`${COLORS.red}Error: Unknown command '${command}'${COLORS.reset}`);
152
+ console.log(`${COLORS.dim}Run 'njs --help' for available commands${COLORS.reset}`);
153
+ process.exit(1);
154
+ }
155
+ } catch (error) {
156
+ console.error(`${COLORS.red}Error: ${error.message}${COLORS.reset}`);
157
+ if (process.env.DEBUG) {
158
+ console.error(error.stack);
159
+ }
160
+ process.exit(1);
161
+ }
162
+ }
163
+
164
+ run();
@@ -0,0 +1,111 @@
1
+ import Hash from "../Hashing/Manager.js";
2
+ import Config from "../Core/Config.js";
3
+
4
+ class Auth {
5
+ static setup(server) {
6
+ server.decorateRequest('auth', null);
7
+
8
+ server.addHook('onRequest', async (req, res) => {
9
+ req.auth = {
10
+ guard: (guardName = null) => ({
11
+ attempt: (credentials) => Auth.attempt(req, credentials, guardName),
12
+ logout: () => Auth.logout(req, guardName),
13
+ user: () => Auth.user(req, guardName),
14
+ check: () => Auth.check(req, guardName),
15
+ home: () => Auth.home(res, guardName),
16
+ redirect: () => Auth.redirect(res, guardName)
17
+ }),
18
+ attempt: (credentials) => Auth.attempt(req, credentials, null),
19
+ logout: () => Auth.logout(req, null),
20
+ user: () => Auth.user(req, null),
21
+ check: () => Auth.check(req, null),
22
+ home: () => Auth.home(res, null),
23
+ redirect: () => Auth.redirect(res, null)
24
+ };
25
+ });
26
+ }
27
+
28
+ static #getAuthConfig() {
29
+ return Config.all("auth");
30
+ }
31
+
32
+ static async attempt(req, credentials, guardName = null) {
33
+ const authConfig = this.#getAuthConfig();
34
+ const guard = guardName || authConfig.defaults.guard;
35
+ const config = authConfig.guards[guard];
36
+
37
+ if (!config) throw new Error(`Guard '${guard}' not configured`);
38
+
39
+ const { provider, identifier } = config;
40
+
41
+ const user = await provider
42
+ .where(identifier, '=', credentials[identifier])
43
+ .first();
44
+
45
+ if (!user) return false;
46
+
47
+ const isValid = await Hash.check(credentials.password, user.password);
48
+ if (!isValid) return false;
49
+
50
+ req.session.regenerate();
51
+ req.session.set(`auth_${guard}`, user.id);
52
+
53
+ return true;
54
+ }
55
+
56
+ static logout(req, guardName = null) {
57
+ const authConfig = this.#getAuthConfig();
58
+ const guard = guardName || authConfig.defaults.guard;
59
+
60
+ req.session.set(`auth_${guard}`, null);
61
+ }
62
+
63
+ static async user(req, guardName = null) {
64
+ const authConfig = this.#getAuthConfig();
65
+ const guard = guardName || authConfig.defaults.guard;
66
+ const userId = req.session.get(`auth_${guard}`) || null;
67
+
68
+ if (!userId) return null;
69
+
70
+ const config = authConfig.guards[guard];
71
+
72
+ if (!config) return null;
73
+
74
+ return await config.provider.find(userId);
75
+ }
76
+
77
+ static check(req, guardName = null) {
78
+ const authConfig = this.#getAuthConfig();
79
+ const guard = guardName || authConfig.defaults.guard;
80
+
81
+ return req.session.get(`auth_${guard}`) !== null && req.session.get(`auth_${guard}`) !== undefined;
82
+ }
83
+
84
+ static home(res, guardName = null) {
85
+ const authConfig = this.#getAuthConfig();
86
+ const guard = guardName || authConfig.defaults.guard;
87
+ const config = authConfig.guards[guard];
88
+
89
+ return res.redirect(this.#resolveUrl(config?.home));
90
+ }
91
+
92
+ static redirect(res, guardName = null) {
93
+ const authConfig = this.#getAuthConfig();
94
+ const guard = guardName || authConfig.defaults.guard;
95
+ const config = authConfig.guards[guard];
96
+
97
+ return res.redirect(this.#resolveUrl(config?.redirect));
98
+ }
99
+
100
+ static #resolveUrl(path) {
101
+ if (!path) return '/';
102
+
103
+ if (path.startsWith('/') || path.startsWith('http://') || path.startsWith('https://')) {
104
+ return path;
105
+ }
106
+
107
+ return route(path);
108
+ }
109
+ }
110
+
111
+ export default Auth;