@nitronjs/framework 0.2.2 → 0.2.4

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 (71) hide show
  1. package/README.md +3 -1
  2. package/cli/create.js +88 -72
  3. package/cli/njs.js +17 -19
  4. package/lib/Auth/Auth.js +167 -0
  5. package/lib/Build/CssBuilder.js +9 -0
  6. package/lib/Build/FileAnalyzer.js +16 -0
  7. package/lib/Build/HydrationBuilder.js +17 -0
  8. package/lib/Build/Manager.js +15 -0
  9. package/lib/Build/colors.js +4 -0
  10. package/lib/Build/plugins.js +84 -20
  11. package/lib/Console/Commands/DevCommand.js +13 -9
  12. package/lib/Console/Commands/MakeCommand.js +24 -10
  13. package/lib/Console/Commands/MigrateCommand.js +4 -3
  14. package/lib/Console/Commands/MigrateFreshCommand.js +22 -27
  15. package/lib/Console/Commands/MigrateRollbackCommand.js +8 -4
  16. package/lib/Console/Commands/MigrateStatusCommand.js +8 -4
  17. package/lib/Console/Commands/SeedCommand.js +8 -28
  18. package/lib/Console/Commands/StorageLinkCommand.js +20 -5
  19. package/lib/Console/Output.js +143 -0
  20. package/lib/Core/Config.js +2 -1
  21. package/lib/Core/Paths.js +8 -8
  22. package/lib/Database/DB.js +141 -51
  23. package/lib/Database/Drivers/MySQLDriver.js +102 -157
  24. package/lib/Database/Migration/Checksum.js +3 -8
  25. package/lib/Database/Migration/MigrationRepository.js +25 -35
  26. package/lib/Database/Migration/MigrationRunner.js +59 -67
  27. package/lib/Database/Model.js +165 -75
  28. package/lib/Database/QueryBuilder.js +43 -0
  29. package/lib/Database/QueryValidation.js +51 -30
  30. package/lib/Database/Schema/Blueprint.js +25 -36
  31. package/lib/Database/Schema/Manager.js +31 -68
  32. package/lib/Database/Seeder/SeederRunner.js +24 -145
  33. package/lib/Date/DateTime.js +9 -0
  34. package/lib/Encryption/Encryption.js +52 -0
  35. package/lib/Faker/Faker.js +11 -0
  36. package/lib/Filesystem/Storage.js +120 -0
  37. package/lib/HMR/Server.js +79 -9
  38. package/lib/Hashing/Hash.js +41 -0
  39. package/lib/Http/Server.js +179 -151
  40. package/lib/Logging/{Manager.js → Log.js} +68 -80
  41. package/lib/Mail/Mail.js +187 -0
  42. package/lib/Route/Router.js +416 -0
  43. package/lib/Session/File.js +135 -233
  44. package/lib/Session/Manager.js +117 -171
  45. package/lib/Session/Memory.js +28 -38
  46. package/lib/Session/Session.js +71 -107
  47. package/lib/Support/Str.js +103 -0
  48. package/lib/Translation/Lang.js +54 -0
  49. package/lib/View/Client/hmr-client.js +87 -51
  50. package/lib/View/Client/nitronjs-icon.png +0 -0
  51. package/lib/View/{Manager.js → View.js} +44 -29
  52. package/lib/index.d.ts +49 -27
  53. package/lib/index.js +19 -13
  54. package/package.json +1 -1
  55. package/skeleton/app/Controllers/HomeController.js +7 -1
  56. package/skeleton/package.json +2 -0
  57. package/skeleton/resources/css/global.css +1 -0
  58. package/skeleton/resources/views/Site/Home.tsx +456 -79
  59. package/skeleton/tsconfig.json +6 -1
  60. package/lib/Auth/Manager.js +0 -111
  61. package/lib/Database/Connection.js +0 -61
  62. package/lib/Database/Manager.js +0 -162
  63. package/lib/Database/Migration/migrations/0000_00_00_00_01_create_seeders_table.js +0 -20
  64. package/lib/Database/Seeder/SeederRepository.js +0 -45
  65. package/lib/Encryption/Manager.js +0 -47
  66. package/lib/Filesystem/Manager.js +0 -74
  67. package/lib/Hashing/Manager.js +0 -25
  68. package/lib/Mail/Manager.js +0 -120
  69. package/lib/Route/Loader.js +0 -80
  70. package/lib/Route/Manager.js +0 -286
  71. package/lib/Translation/Manager.js +0 -49
@@ -1,18 +1,29 @@
1
+ /**
2
+ * HMR Client - Browser-side hot module replacement handler.
3
+ * Connects to the HMR WebSocket server and handles live updates.
4
+ */
1
5
  (function() {
2
6
  "use strict";
3
7
 
4
8
  var socket = null;
5
- var overlay = null;
9
+ var errorOverlay = null;
6
10
 
11
+ // Connection
7
12
  function connect() {
8
13
  if (socket) return;
14
+
9
15
  if (typeof io === "undefined") {
10
16
  setTimeout(connect, 100);
17
+
11
18
  return;
12
19
  }
13
20
 
14
21
  try {
15
- socket = io({ path: "/__nitron_hmr", transports: ["websocket", "polling"], reconnection: true });
22
+ socket = io({
23
+ path: "/__nitron_hmr",
24
+ transports: ["websocket", "polling"],
25
+ reconnection: true
26
+ });
16
27
  }
17
28
  catch (e) {
18
29
  return;
@@ -20,147 +31,172 @@
20
31
 
21
32
  socket.on("connect", function() {
22
33
  window.__nitron_hmr_connected__ = true;
23
- hideOverlay();
34
+ hideErrorOverlay();
24
35
  });
25
36
 
26
37
  socket.on("disconnect", function() {
27
38
  window.__nitron_hmr_connected__ = false;
28
39
  });
29
40
 
30
- socket.on("hmr:update", function(data) {
41
+ socket.on("hmr:update", function() {
31
42
  refetchPage();
32
43
  });
33
44
 
34
- socket.on("hmr:reload", function(data) {
45
+ socket.on("hmr:reload", function() {
35
46
  location.reload();
36
47
  });
37
48
 
38
49
  socket.on("hmr:css", function(data) {
39
- updateCss(data.file);
50
+ refreshCss(data.file);
40
51
  });
41
52
 
42
53
  socket.on("hmr:error", function(data) {
43
- showOverlay(data.message || "Unknown error", data.file);
54
+ showErrorOverlay(data.message || "Unknown error", data.file);
44
55
  });
45
56
  }
46
57
 
58
+ // Page Updates
47
59
  function refetchPage() {
48
60
  var url = location.pathname + location.search;
49
-
61
+
50
62
  fetch("/__nitron/navigate?url=" + encodeURIComponent(url), {
51
63
  headers: { "X-Nitron-SPA": "1" },
52
64
  credentials: "same-origin"
53
65
  })
54
- .then(function(r) {
55
- if (!r.ok) throw new Error("HTTP " + r.status);
56
- return r.json();
66
+ .then(function(response) {
67
+ if (!response.ok) throw new Error("HTTP " + response.status);
68
+
69
+ return response.json();
57
70
  })
58
- .then(function(d) {
59
- if (d.error || d.redirect) {
71
+ .then(function(data) {
72
+ if (data.error || data.redirect) {
60
73
  location.reload();
74
+
61
75
  return;
62
76
  }
63
77
 
64
- // Find current slot
65
78
  var slot = document.querySelector("[data-nitron-slot='page']");
66
- if (!slot || !d.html) {
79
+
80
+ if (!slot || !data.html) {
67
81
  location.reload();
82
+
68
83
  return;
69
84
  }
70
85
 
71
- // Parse response HTML and extract slot content
72
- var tmp = document.createElement("div");
73
- tmp.innerHTML = d.html;
74
- var newSlot = tmp.querySelector("[data-nitron-slot='page']");
75
- var newContent = newSlot ? newSlot.innerHTML : d.html;
86
+ var container = document.createElement("div");
87
+ container.innerHTML = data.html;
76
88
 
77
- // Update slot content
78
- slot.innerHTML = newContent;
89
+ var newSlot = container.querySelector("[data-nitron-slot='page']");
90
+ slot.innerHTML = newSlot ? newSlot.innerHTML : data.html;
79
91
 
80
- // Update hydration
81
- if (d.hydrationScript) {
82
- if (d.runtime && window.__NITRON_RUNTIME__) {
83
- Object.assign(window.__NITRON_RUNTIME__, d.runtime);
92
+ if (data.hydrationScript) {
93
+ if (data.runtime && window.__NITRON_RUNTIME__) {
94
+ Object.assign(window.__NITRON_RUNTIME__, data.runtime);
84
95
  }
85
- if (d.props) {
86
- window.__NITRON_PROPS__ = d.props;
96
+
97
+ if (data.props) {
98
+ window.__NITRON_PROPS__ = data.props;
87
99
  }
88
- loadHydration(d.hydrationScript);
100
+
101
+ loadHydrationScript(data.hydrationScript);
89
102
  }
90
103
  })
91
- .catch(function(e) {
104
+ .catch(function() {
92
105
  location.reload();
93
106
  });
94
107
  }
95
108
 
96
- function loadHydration(scriptPath) {
109
+ function loadHydrationScript(scriptPath) {
97
110
  var script = document.createElement("script");
98
111
  script.type = "module";
99
112
  script.src = "/storage" + scriptPath + "?t=" + Date.now();
113
+
100
114
  script.onload = function() {
101
115
  if (window.__NITRON_REFRESH__) {
102
116
  try {
103
117
  window.__NITRON_REFRESH__.performReactRefresh();
104
- } catch(e) {}
118
+ }
119
+ catch (e) {}
105
120
  }
121
+
106
122
  script.remove();
107
123
  };
124
+
108
125
  document.head.appendChild(script);
109
126
  }
110
127
 
111
- function updateCss(file) {
128
+ // CSS Updates
129
+ function refreshCss(filename) {
112
130
  var links = document.querySelectorAll('link[rel="stylesheet"]');
113
131
  var timestamp = Date.now();
114
132
 
115
- if (!file) {
133
+ if (!filename) {
116
134
  for (var i = 0; i < links.length; i++) {
117
135
  var href = (links[i].href || "").split("?")[0];
118
136
  links[i].href = href + "?t=" + timestamp;
119
137
  }
138
+
120
139
  return;
121
140
  }
122
141
 
123
142
  var found = false;
124
- var target = file.split(/[\\/]/).pop();
143
+ var target = filename.split(/[\\/]/).pop();
125
144
 
126
145
  for (var i = 0; i < links.length; i++) {
127
146
  var href = (links[i].href || "").split("?")[0];
147
+
128
148
  if (href.endsWith("/" + target)) {
129
149
  links[i].href = href + "?t=" + timestamp;
130
150
  found = true;
131
151
  }
132
152
  }
133
153
 
134
- if (!found) location.reload();
154
+ if (!found) {
155
+ location.reload();
156
+ }
135
157
  }
136
158
 
137
- function showOverlay(msg, file) {
138
- hideOverlay();
139
- overlay = document.createElement("div");
140
- overlay.id = "__nitron_error__";
141
- overlay.innerHTML =
159
+ // Error Overlay
160
+ function showErrorOverlay(message, file) {
161
+ hideErrorOverlay();
162
+
163
+ errorOverlay = document.createElement("div");
164
+ errorOverlay.id = "__nitron_error__";
165
+ errorOverlay.innerHTML =
142
166
  '<div style="position:fixed;inset:0;background:rgba(0,0,0,.95);color:#ff4444;padding:32px;font-family:monospace;z-index:999999;overflow:auto">' +
143
- '<div style="font-size:24px;font-weight:bold;margin-bottom:16px">Build Error</div>' +
144
- '<div style="color:#888;margin-bottom:16px">' + escapeHtml(file || "") + '</div>' +
145
- '<pre style="white-space:pre-wrap;background:#1a1a2e;padding:16px;border-radius:8px">' + escapeHtml(msg) + '</pre>' +
146
- '<button onclick="this.parentNode.parentNode.remove()" style="position:absolute;top:16px;right:16px;background:#333;color:#fff;border:none;padding:8px 16px;cursor:pointer;border-radius:4px">Close</button>' +
167
+ '<div style="font-size:24px;font-weight:bold;margin-bottom:16px">Build Error</div>' +
168
+ '<div style="color:#888;margin-bottom:16px">' + escapeHtml(file || "") + '</div>' +
169
+ '<pre style="white-space:pre-wrap;background:#1a1a2e;padding:16px;border-radius:8px">' + escapeHtml(message) + '</pre>' +
170
+ '<button onclick="this.parentNode.parentNode.remove()" style="position:absolute;top:16px;right:16px;background:#333;color:#fff;border:none;padding:8px 16px;cursor:pointer;border-radius:4px">Close</button>' +
147
171
  '</div>';
148
- document.body.appendChild(overlay);
172
+
173
+ document.body.appendChild(errorOverlay);
149
174
  }
150
175
 
151
- function hideOverlay() {
176
+ function hideErrorOverlay() {
152
177
  var el = document.getElementById("__nitron_error__");
153
- if (el) el.remove();
154
- overlay = null;
178
+
179
+ if (el) {
180
+ el.remove();
181
+ }
182
+
183
+ errorOverlay = null;
155
184
  }
156
185
 
186
+ // Utilities
157
187
  function escapeHtml(str) {
158
- return String(str || "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
188
+ return String(str || "")
189
+ .replace(/&/g, "&amp;")
190
+ .replace(/</g, "&lt;")
191
+ .replace(/>/g, "&gt;");
159
192
  }
160
193
 
194
+ // Initialize
161
195
  if (document.readyState === "loading") {
162
196
  document.addEventListener("DOMContentLoaded", connect);
163
- } else {
197
+ }
198
+ else {
164
199
  connect();
165
200
  }
201
+
166
202
  })();
@@ -6,8 +6,8 @@ import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { PassThrough } from "stream";
7
7
  import React from "react";
8
8
  import { renderToPipeableStream } from "react-dom/server";
9
- import Log from "../Logging/Manager.js";
10
- import Route from "../Route/Manager.js";
9
+ import Log from "../Logging/Log.js";
10
+ import Router from "../Route/Router.js";
11
11
  import Paths from "../Core/Paths.js";
12
12
  import Config from "../Core/Config.js";
13
13
  import Environment from "../Core/Environment.js";
@@ -38,6 +38,13 @@ function escapeHtml(str) {
38
38
  return String(str).replace(/[&<>"'`]/g, char => ESC_MAP[char]);
39
39
  }
40
40
 
41
+ /**
42
+ * React SSR view renderer with streaming support.
43
+ * Handles component rendering, asset injection, and client hydration.
44
+ *
45
+ * @example
46
+ * return View.render(res, "Dashboard", { user: currentUser });
47
+ */
41
48
  class View {
42
49
  static #root = Paths.project;
43
50
  static #userViews = Paths.buildViews;
@@ -110,27 +117,38 @@ class View {
110
117
  });
111
118
  });
112
119
 
113
- server.get("/__nitron/navigate", async (req, res) => {
114
- const url = req.query.url;
115
- if (!url) {
116
- return res.code(400).send({ error: "Missing url" });
117
- }
120
+ if (View.#isDev) {
121
+ server.get("/__nitron/navigate", async (req, res) => {
122
+ const url = req.query.url;
123
+ if (!url) {
124
+ return res.code(400).send({ error: "Missing url" });
125
+ }
118
126
 
119
- const result = await View.#renderPartial(url, req, res);
120
-
121
- if (result.handled) return;
122
-
123
- return res
124
- .code(result.status || 200)
125
- .header("X-Content-Type-Options", "nosniff")
126
- .send(result);
127
- });
127
+ const result = await View.#renderPartial(url, req, res);
128
+
129
+ if (result.handled) return;
130
+
131
+ return res
132
+ .code(result.status || 200)
133
+ .header("X-Content-Type-Options", "nosniff")
134
+ .send(result);
135
+ });
136
+
137
+ server.get("/__nitron/icon.png", async (req, res) => {
138
+ const iconPath = path.join(__dirname, "Client", "nitronjs-icon.png");
139
+ const iconBuffer = readFileSync(iconPath);
140
+ return res
141
+ .header("Content-Type", "image/png")
142
+ .header("Cache-Control", "public, max-age=31536000")
143
+ .send(iconBuffer);
144
+ });
145
+ }
128
146
  }
129
147
 
130
148
  static async #renderPartial(url, originalReq, originalRes) {
131
149
  try {
132
150
  const parsedUrl = new URL(url, `http://${originalReq.headers.host}`);
133
- const routeMatch = Route.match(parsedUrl.pathname, "GET");
151
+ const routeMatch = Router.match(parsedUrl.pathname, "GET");
134
152
 
135
153
  if (!routeMatch) {
136
154
  return { status: 404, error: "Route not found" };
@@ -220,7 +238,7 @@ class View {
220
238
  }
221
239
 
222
240
  static #getRoutesForScript(script) {
223
- const allRoutes = Route.getClientManifest();
241
+ const allRoutes = Router.getClientManifest();
224
242
  const usedNames = this.#getUsedRoutes(script);
225
243
  const routes = {};
226
244
  for (const name of usedNames) {
@@ -645,7 +663,7 @@ class View {
645
663
  const nonceAttr = nonce ? ` nonce="${escapeHtml(nonce)}"` : "";
646
664
  const hasHydration = !!hydrationScript;
647
665
 
648
- const allRoutes = Route.getClientManifest();
666
+ const allRoutes = Router.getClientManifest();
649
667
  const usedRouteNames = hasHydration ? this.#getUsedRoutes(hydrationScript) : [];
650
668
  const routes = {};
651
669
  for (const name of usedRouteNames) {
@@ -733,10 +751,10 @@ ${vendorScript}${hmrScript}${hydrateScript}${spaScript}${devIndicator}
733
751
  box-shadow:0 6px 24px rgba(0,0,0,0.6);
734
752
  }
735
753
  #__nitron_dev_btn__ .logo {
736
- width:20px;height:20px;background:#fff;
737
- border-radius:5px;display:flex;align-items:center;justify-content:center;
754
+ width:20px;height:20px;
755
+ display:flex;align-items:center;justify-content:center;
738
756
  }
739
- #__nitron_dev_btn__ .logo svg { width:12px;height:12px; }
757
+ #__nitron_dev_btn__ .logo svg { width:20px;height:20px; }
740
758
  #__nitron_dev_btn__ .dot { width:6px;height:6px;border-radius:50%;animation:pulse 2s infinite; }
741
759
  @keyframes pulse { 0%,100%{opacity:1;} 50%{opacity:0.4;} }
742
760
  #__nitron_dev_panel__ {
@@ -752,10 +770,9 @@ ${vendorScript}${hmrScript}${hydrateScript}${spaScript}${devIndicator}
752
770
  border-bottom:1px solid #1f1f1f;display:flex;align-items:center;gap:10px;
753
771
  }
754
772
  #__nitron_dev_panel__ .header .icon {
755
- width:28px;height:28px;background:#fff;
773
+ width:28px;height:28px;
756
774
  border-radius:6px;display:flex;align-items:center;justify-content:center;
757
775
  }
758
- #__nitron_dev_panel__ .header .icon svg { width:16px;height:16px; }
759
776
  #__nitron_dev_panel__ .header .info { display:flex;flex-direction:column; }
760
777
  #__nitron_dev_panel__ .header .title { font-size:14px;font-weight:600;color:#fff;line-height:1.2; }
761
778
  #__nitron_dev_panel__ .header .version { font-size:11px;color:#666;line-height:1.2; }
@@ -788,13 +805,13 @@ ${vendorScript}${hmrScript}${hydrateScript}${spaScript}${devIndicator}
788
805
  #__nitron_dev_panel__ .footer a:hover { background:#1a1a1a;color:#999;border-color:#2a2a2a; }
789
806
  </style>
790
807
  <button id="__nitron_dev_btn__">
791
- <span class="logo"><svg viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2.5"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg></span>
808
+ <span class="logo"><img src="/__nitron/icon.png" alt="N" style="width:20px;height:20px;"></span>
792
809
  <span style="color:#888;">NitronJS</span>
793
810
  <span class="dot" id="__nitron_status_dot__" style="background:#4ade80;"></span>
794
811
  </button>
795
- <div id="__nitron_dev_panel__">
812
+ <div id="__nitron_dev_panel__" style="display:none;">
796
813
  <div class="header">
797
- <div class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg></div>
814
+ <div class="icon"><img src="/__nitron/icon.png" alt="N" style="width:28px;height:28px;"></div>
798
815
  <div class="info">
799
816
  <span class="title">NitronJS</span>
800
817
  <span class="version">v${FRAMEWORK_VERSION}</span>
@@ -802,11 +819,9 @@ ${vendorScript}${hmrScript}${hydrateScript}${spaScript}${devIndicator}
802
819
  <span class="badge">dev</span>
803
820
  </div>
804
821
  <div class="body">
805
- <div class="row"><span class="label">Environment</span><span class="value"><span class="status ok"></span>Development</span></div>
806
822
  <div class="row"><span class="label">HMR</span><span class="value"><span class="status" id="__nitron_hmr_ind__"></span><span id="__nitron_hmr_txt__">Checking...</span></span></div>
807
823
  <div class="row"><span class="label">Server</span><span class="value">localhost:${port}</span></div>
808
824
  <div class="row"><span class="label">Node.js</span><span class="value">${nodeVersion}</span></div>
809
- <div class="row"><span class="label">React</span><span class="value"><span class="status ok"></span>Ready</span></div>
810
825
  </div>
811
826
  <div class="footer">
812
827
  <a href="/__nitron/routes" target="_blank">Routes</a>
package/lib/index.d.ts CHANGED
@@ -187,24 +187,13 @@ export class Lang {
187
187
  }
188
188
 
189
189
  export class DateTime {
190
- static now(): DateTime;
191
- static parse(date: string | Date): DateTime;
192
- static create(year: number, month: number, day: number, hour?: number, minute?: number, second?: number): DateTime;
193
- format(format: string): string;
194
- toDate(): Date;
195
- toISO(): string;
196
- addDays(days: number): DateTime;
197
- addMonths(months: number): DateTime;
198
- addYears(years: number): DateTime;
199
- subDays(days: number): DateTime;
200
- subMonths(months: number): DateTime;
201
- subYears(years: number): DateTime;
202
- diffInDays(other: DateTime): number;
203
- diffInMonths(other: DateTime): number;
204
- diffInYears(other: DateTime): number;
205
- isBefore(other: DateTime): boolean;
206
- isAfter(other: DateTime): boolean;
207
- isSame(other: DateTime): boolean;
190
+ static toSQL(timestamp?: number | null): string;
191
+ static getTime(sqlDateTime?: string | null): number;
192
+ static getDate(timestamp?: number | null, format?: string): string;
193
+ static addDays(days: number): string;
194
+ static addHours(hours: number): string;
195
+ static subDays(days: number): string;
196
+ static subHours(hours: number): string;
208
197
  }
209
198
 
210
199
  export class Str {
@@ -362,18 +351,23 @@ export class Config {
362
351
  static has(key: string): boolean;
363
352
  }
364
353
 
365
- export class Route {
366
- static get(path: string, handler: any): Route;
367
- static post(path: string, handler: any): Route;
368
- static put(path: string, handler: any): Route;
369
- static patch(path: string, handler: any): Route;
370
- static delete(path: string, handler: any): Route;
354
+ export class Router {
355
+ static get(path: string, handler: any): Router;
356
+ static post(path: string, handler: any): Router;
357
+ static put(path: string, handler: any): Router;
358
+ static patch(path: string, handler: any): Router;
359
+ static delete(path: string, handler: any): Router;
371
360
  static group(options: Record<string, any>, callback: () => void): void;
372
361
  static resource(name: string, controller: any): void;
373
- name(name: string): Route;
374
- middleware(...middleware: any[]): Route;
362
+ static prefix(prefix: string): Router;
363
+ static middleware(...middleware: any[]): Router;
364
+ name(name: string): Router;
365
+ middleware(...middleware: any[]): Router;
375
366
  }
376
367
 
368
+ // Alias for backwards compatibility
369
+ export { Router as Route };
370
+
377
371
  export class Mail {
378
372
  static to(address: string): Mail;
379
373
  static from(address: string): Mail;
@@ -396,7 +390,6 @@ export class View {
396
390
  export const MigrationRunner: any;
397
391
  export const MigrationRepository: any;
398
392
  export const SeederRunner: any;
399
- export const SeederRepository: any;
400
393
  export const Checksum: any;
401
394
  export const DatabaseManager: any;
402
395
  export const SessionManager: any;
@@ -406,6 +399,35 @@ export const Environment: any;
406
399
 
407
400
  export function start(): Promise<void>;
408
401
 
402
+ // ─────────────────────────────────────────────────────────────────────────────
403
+ // Path Aliases (for import convenience)
404
+ // ─────────────────────────────────────────────────────────────────────────────
405
+
406
+ declare module "@css/*" {
407
+ const content: string;
408
+ export default content;
409
+ }
410
+
411
+ declare module "@views/*" {
412
+ const component: React.ComponentType<any>;
413
+ export default component;
414
+ }
415
+
416
+ declare module "@models/*" {
417
+ const model: any;
418
+ export default model;
419
+ }
420
+
421
+ declare module "@controllers/*" {
422
+ const controller: any;
423
+ export default controller;
424
+ }
425
+
426
+ declare module "@middlewares/*" {
427
+ const middleware: any;
428
+ export default middleware;
429
+ }
430
+
409
431
  // ─────────────────────────────────────────────────────────────────────────────
410
432
  // Global Functions (available in all views without import)
411
433
  // ─────────────────────────────────────────────────────────────────────────────
package/lib/index.js CHANGED
@@ -3,18 +3,27 @@ export { default as Config } from "./Core/Config.js";
3
3
  export { default as Paths } from "./Core/Paths.js";
4
4
  export { default as Environment } from "./Core/Environment.js";
5
5
 
6
+ // Version
7
+ import { readFileSync } from "fs";
8
+ import path from "path";
9
+ import { fileURLToPath } from "url";
10
+
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+ const packageJsonPath = path.join(__dirname, "../package.json");
13
+ export const VERSION = JSON.parse(readFileSync(packageJsonPath, "utf-8")).version;
14
+
6
15
  // Http
7
16
  export { default as Server } from "./Http/Server.js";
8
17
  export { start } from "./Runtime/Entry.js";
9
18
 
10
19
  // Routing
11
- export { default as Route } from "./Route/Manager.js";
20
+ export { default as Router } from "./Route/Router.js";
21
+ export { default as Route } from "./Route/Router.js";
12
22
 
13
23
  // Database
14
24
  export { default as DB } from "./Database/DB.js";
15
25
  export { default as Model } from "./Database/Model.js";
16
26
  export { default as Schema } from "./Database/Schema/Manager.js";
17
- export { default as DatabaseManager } from "./Database/Manager.js";
18
27
 
19
28
  // Migration
20
29
  export { default as MigrationRunner } from "./Database/Migration/MigrationRunner.js";
@@ -23,38 +32,37 @@ export { default as Checksum } from "./Database/Migration/Checksum.js";
23
32
 
24
33
  // Seeder
25
34
  export { default as SeederRunner } from "./Database/Seeder/SeederRunner.js";
26
- export { default as SeederRepository } from "./Database/Seeder/SeederRepository.js";
27
35
 
28
36
  // Authentication
29
- export { default as Auth } from "./Auth/Manager.js";
37
+ export { default as Auth } from "./Auth/Auth.js";
30
38
 
31
39
  // Session
32
40
  export { default as Session } from "./Session/Session.js";
33
41
  export { default as SessionManager } from "./Session/Manager.js";
34
42
 
35
43
  // View
36
- export { default as View } from "./View/Manager.js";
44
+ export { default as View } from "./View/View.js";
37
45
 
38
46
  // Hashing
39
- export { default as Hash } from "./Hashing/Manager.js";
47
+ export { default as Hash } from "./Hashing/Hash.js";
40
48
 
41
49
  // Logging
42
- export { default as Log } from "./Logging/Manager.js";
50
+ export { default as Log } from "./Logging/Log.js";
43
51
 
44
52
  // Filesystem
45
- export { default as Storage } from "./Filesystem/Manager.js";
53
+ export { default as Storage } from "./Filesystem/Storage.js";
46
54
 
47
55
  // Mail
48
- export { default as Mail } from "./Mail/Manager.js";
56
+ export { default as Mail } from "./Mail/Mail.js";
49
57
 
50
58
  // Encryption
51
- export { default as AES } from "./Encryption/Manager.js";
59
+ export { default as AES } from "./Encryption/Encryption.js";
52
60
 
53
61
  // Validation
54
62
  export { default as Validator } from "./Validation/Validator.js";
55
63
 
56
64
  // Translation
57
- export { default as Lang } from "./Translation/Manager.js";
65
+ export { default as Lang } from "./Translation/Lang.js";
58
66
 
59
67
  // Date
60
68
  export { default as DateTime } from "./Date/DateTime.js";
@@ -65,5 +73,3 @@ export { default as Str } from "./Support/Str.js";
65
73
  // Faker
66
74
  export { default as Faker } from "./Faker/Faker.js";
67
75
 
68
- // Backward Compatibility Aliases
69
- export { default as Enviroment } from "./Core/Environment.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitronjs/framework",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "NitronJS is a modern and extensible Node.js MVC framework built on Fastify. It focuses on clean architecture, modular structure, and developer productivity, offering built-in routing, middleware, configuration management, CLI tooling, and native React integration for scalable full-stack applications.",
5
5
  "bin": {
6
6
  "njs": "./cli/njs.js"
@@ -1,7 +1,13 @@
1
+ import { VERSION } from "@nitronjs/framework";
2
+
1
3
  class HomeController {
2
4
 
3
5
  static async index(req, res) {
4
- return res.view("Site/Home");
6
+ const version = VERSION;
7
+
8
+ return res.view("Site/Home", {
9
+ version
10
+ });
5
11
  }
6
12
 
7
13
  }
@@ -10,6 +10,8 @@
10
10
  "migrate:seed": "njs migrate --seed",
11
11
  "migrate:fresh": "njs migrate:fresh",
12
12
  "migrate:fresh:seed": "njs migrate:fresh --seed",
13
+ "migrate:status": "njs migrate:status",
14
+ "migrate:rollback": "njs migrate:rollback",
13
15
  "seed": "njs seed",
14
16
  "storage:link": "njs storage:link",
15
17
  "make:controller": "njs make:controller",
@@ -0,0 +1 @@
1
+ @import "tailwindcss";