@nitronjs/framework 0.2.6 → 0.2.8

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.
@@ -59,6 +59,20 @@ class QueryBuilder {
59
59
  return validateIdentifier(identifier);
60
60
  }
61
61
 
62
+ /**
63
+ * Quotes an identifier (table/column name) to handle reserved keywords.
64
+ * Uses backticks for MySQL compatibility.
65
+ * @param {string} identifier
66
+ * @returns {string}
67
+ */
68
+ #quoteIdentifier(identifier) {
69
+ // Handle table.column format
70
+ if (identifier.includes('.')) {
71
+ return identifier.split('.').map(part => `\`${part}\``).join('.');
72
+ }
73
+ return `\`${identifier}\``;
74
+ }
75
+
62
76
  #validateWhereOperator(operator) {
63
77
  return validateWhereOperator(operator);
64
78
  }
@@ -543,12 +557,12 @@ class QueryBuilder {
543
557
  }
544
558
 
545
559
  const columns = Object.keys(rows[0]);
546
- columns.forEach(col => this.#validateIdentifier(col));
560
+ const validatedColumns = columns.map(col => this.#validateIdentifier(col));
547
561
 
548
562
  const placeholders = rows.map(() => `(${columns.map(() => '?').join(', ')})`).join(', ');
549
563
  const values = rows.flatMap(row => columns.map(col => row[col]));
550
564
 
551
- const sql = `INSERT INTO ${this.#table} (${columns.join(', ')}) VALUES ${placeholders}`;
565
+ const sql = `INSERT INTO ${this.#quoteIdentifier(this.#table)} (${validatedColumns.join(', ')}) VALUES ${placeholders}`;
552
566
  const [result] = await connection.query(sql, values);
553
567
 
554
568
 
@@ -584,7 +598,7 @@ class QueryBuilder {
584
598
  }
585
599
  }
586
600
 
587
- const sql = `UPDATE ${this.#table} SET ${sets.join(', ')}${this.#compileWheres()}`;
601
+ const sql = `UPDATE ${this.#quoteIdentifier(this.#table)} SET ${sets.join(', ')}${this.#compileWheres()}`;
588
602
  const [result] = await connection.query(sql, [...values, ...this.#bindings]);
589
603
 
590
604
  return result.affectedRows;
@@ -602,7 +616,7 @@ class QueryBuilder {
602
616
  async delete() {
603
617
  const connection = await this.#getConnection();
604
618
  try {
605
- const sql = `DELETE FROM ${this.#table}${this.#compileWheres()}`;
619
+ const sql = `DELETE FROM ${this.#quoteIdentifier(this.#table)}${this.#compileWheres()}`;
606
620
  const [result] = await connection.query(sql, this.#bindings);
607
621
 
608
622
  return result.affectedRows;
@@ -630,7 +644,7 @@ class QueryBuilder {
630
644
  const orders = this.#compileOrders();
631
645
  const limit = this.#compileLimit();
632
646
 
633
- return `SELECT ${distinct}${columns} FROM ${this.#table}${joins}${wheres}${groups}${havings}${orders}${limit}`;
647
+ return `SELECT ${distinct}${columns} FROM ${this.#quoteIdentifier(this.#table)}${joins}${wheres}${groups}${havings}${orders}${limit}`;
634
648
  }
635
649
 
636
650
  #compileJoins() {
package/lib/HMR/Server.js CHANGED
@@ -34,7 +34,7 @@ class HMRServer {
34
34
  registerRoutes(fastify) {
35
35
  this.#clientScript = this.#findSocketIoClient();
36
36
 
37
- fastify.get("/__nitron_hmr/socket.io.js", (req, reply) => {
37
+ fastify.get("/__nitron_client/socket.io.js", (req, reply) => {
38
38
  if (!this.#clientScript) {
39
39
  return reply.code(503).send("// HMR disabled: socket.io client not found");
40
40
  }
@@ -157,57 +157,33 @@ class HMRServer {
157
157
  // Private Methods
158
158
 
159
159
  /**
160
- * Finds socket.io client script from multiple possible locations.
161
- * Searches in order: createRequire resolution, cwd node_modules,
162
- * parent directories, and monorepo root.
160
+ * Finds socket.io client script.
161
+ * Searches framework node_modules and walks up directory tree for monorepo support.
163
162
  * @returns {string|null} Path to socket.io.min.js or null if not found
164
163
  */
165
164
  #findSocketIoClient() {
166
165
  const clientFile = "client-dist/socket.io.min.js";
167
- const possiblePaths = [];
168
166
 
169
- // 1. Try resolving from framework package location
167
+ // 1. Try resolving from framework package location (most common case)
170
168
  try {
171
169
  const frameworkRequire = createRequire(import.meta.url);
172
170
  const socketIoDir = path.dirname(frameworkRequire.resolve("socket.io/package.json"));
173
- possiblePaths.push(path.join(socketIoDir, clientFile));
171
+ const clientPath = path.join(socketIoDir, clientFile);
172
+ if (fs.existsSync(clientPath)) return clientPath;
174
173
  }
175
174
  catch {}
176
175
 
177
- // 2. Try resolving from project's node_modules
178
- try {
179
- const projectRequire = createRequire(path.join(process.cwd(), "package.json"));
180
- const socketIoDir = path.dirname(projectRequire.resolve("socket.io/package.json"));
181
- possiblePaths.push(path.join(socketIoDir, clientFile));
182
- }
183
- catch {}
184
-
185
- // 3. Walk up from cwd looking for node_modules/socket.io
186
- let currentDir = process.cwd();
176
+ // 2. Walk up from framework location for monorepo setups
177
+ let currentDir = __dirname;
187
178
  for (let i = 0; i < 5; i++) {
188
- possiblePaths.push(path.join(currentDir, "node_modules", "socket.io", clientFile));
179
+ const clientPath = path.join(currentDir, "node_modules", "socket.io", clientFile);
180
+ if (fs.existsSync(clientPath)) return clientPath;
181
+
189
182
  const parentDir = path.dirname(currentDir);
190
183
  if (parentDir === currentDir) break;
191
184
  currentDir = parentDir;
192
185
  }
193
186
 
194
- // 4. Walk up from framework package location
195
- currentDir = __dirname;
196
- for (let i = 0; i < 5; i++) {
197
- possiblePaths.push(path.join(currentDir, "node_modules", "socket.io", clientFile));
198
- const parentDir = path.dirname(currentDir);
199
- if (parentDir === currentDir) break;
200
- currentDir = parentDir;
201
- }
202
-
203
- // Find first existing path
204
- for (const p of possiblePaths) {
205
- if (fs.existsSync(p)) {
206
- return p;
207
- }
208
- }
209
-
210
- console.warn("[HMR] socket.io client not found. Searched paths:", possiblePaths);
211
187
  return null;
212
188
  }
213
189
  }
package/lib/View/View.js CHANGED
@@ -689,7 +689,7 @@ class View {
689
689
  : "";
690
690
 
691
691
  const hmrScript = this.#isDev
692
- ? `<script src="/__nitron_hmr/socket.io.js"${nonceAttr}></script><script src="/storage/js/hmr.js"${nonceAttr}></script>`
692
+ ? `<script src="/__nitron_client/socket.io.js"${nonceAttr}></script><script src="/storage/js/hmr.js"${nonceAttr}></script>`
693
693
  : "";
694
694
 
695
695
  const hydrateScript = hasHydration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nitronjs/framework",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
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"