tina4-nodejs 3.13.5 → 3.13.7
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.
- package/CLAUDE.md +2 -2
- package/package.json +1 -1
- package/packages/core/src/server.ts +31 -4
- package/packages/core/templates/errors/500.twig +1 -1
- package/packages/orm/src/adapters/firebird.ts +5 -1
- package/packages/orm/src/adapters/mongodb.ts +5 -2
- package/packages/orm/src/adapters/mssql.ts +5 -1
- package/packages/orm/src/adapters/mysql.ts +5 -1
- package/packages/orm/src/adapters/odbc.ts +5 -1
- package/packages/orm/src/adapters/postgres.ts +5 -1
package/CLAUDE.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
# CLAUDE.md — AI Developer Guide for tina4-nodejs (v3.13.
|
|
1
|
+
# CLAUDE.md — AI Developer Guide for tina4-nodejs (v3.13.7)
|
|
2
2
|
|
|
3
3
|
> This file helps AI assistants (Claude, Copilot, Cursor, etc.) understand and work on this codebase effectively.
|
|
4
4
|
|
|
5
5
|
## What This Project Is
|
|
6
6
|
|
|
7
|
-
Tina4 for Node.js/TypeScript v3.13.
|
|
7
|
+
Tina4 for Node.js/TypeScript v3.13.7 — The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
|
|
8
8
|
|
|
9
9
|
The philosophy: zero ceremony, batteries included, file system as source of truth.
|
|
10
10
|
|
package/package.json
CHANGED
|
@@ -1278,7 +1278,31 @@ ${reset}
|
|
|
1278
1278
|
res({ error: "Not Found", statusCode: 404, message: `No route found for ${req.method} ${pathname}` }, 404);
|
|
1279
1279
|
}
|
|
1280
1280
|
} catch (err) {
|
|
1281
|
-
|
|
1281
|
+
// v3.13.7: log structured + surface to observability BEFORE rendering.
|
|
1282
|
+
// Listeners get the canonical {exception, request} payload mirrored
|
|
1283
|
+
// by Python / PHP / Ruby. Listener errors are swallowed + warning-
|
|
1284
|
+
// logged so a broken listener can't break the 500 page.
|
|
1285
|
+
Log.error(`Route error: ${err instanceof Error ? `${err.name}: ${err.message}` : String(err)}`, {
|
|
1286
|
+
method: req?.method,
|
|
1287
|
+
path: req?.path,
|
|
1288
|
+
});
|
|
1289
|
+
try {
|
|
1290
|
+
const { Events } = await import("./events.js");
|
|
1291
|
+
Events.emit("tina4.request.error", { exception: err, request: req });
|
|
1292
|
+
} catch (listenerErr) {
|
|
1293
|
+
try {
|
|
1294
|
+
Log.warn(
|
|
1295
|
+
`Listener for tina4.request.error raised: ${
|
|
1296
|
+
listenerErr instanceof Error
|
|
1297
|
+
? `${listenerErr.name}: ${listenerErr.message}`
|
|
1298
|
+
: String(listenerErr)
|
|
1299
|
+
}`
|
|
1300
|
+
);
|
|
1301
|
+
} catch {
|
|
1302
|
+
// Log failures must never block the 500 render.
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1282
1306
|
if (!res.raw.writableEnded) {
|
|
1283
1307
|
if (isDevMode() && err instanceof Error) {
|
|
1284
1308
|
// Rich error overlay with stack trace, source context, and line numbers
|
|
@@ -1287,9 +1311,12 @@ ${reset}
|
|
|
1287
1311
|
res.raw.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
1288
1312
|
res.raw.end(overlayHtml);
|
|
1289
1313
|
} else {
|
|
1290
|
-
|
|
1314
|
+
// v3.13.7 SECURITY (CWE-209): production response body must NOT
|
|
1315
|
+
// contain the stack trace or exception message. Pass an empty
|
|
1316
|
+
// error_message — the 500.twig template only renders the trace
|
|
1317
|
+
// block when error_message is truthy.
|
|
1291
1318
|
const html500 = await renderErrorPage(500, {
|
|
1292
|
-
error_message:
|
|
1319
|
+
error_message: "",
|
|
1293
1320
|
request_id: `${Date.now().toString(36)}`,
|
|
1294
1321
|
path: req.path,
|
|
1295
1322
|
}, templatesDir);
|
|
@@ -1297,7 +1324,7 @@ ${reset}
|
|
|
1297
1324
|
res.raw.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
1298
1325
|
res.raw.end(html500);
|
|
1299
1326
|
} else {
|
|
1300
|
-
res({ error: "Internal Server Error", statusCode: 500
|
|
1327
|
+
res({ error: "Internal Server Error", statusCode: 500 }, 500);
|
|
1301
1328
|
}
|
|
1302
1329
|
}
|
|
1303
1330
|
}
|
|
@@ -27,7 +27,7 @@ body { font-family: system-ui, -apple-system, sans-serif; background: #0f172a; c
|
|
|
27
27
|
<div class="error-title">Server Error</div>
|
|
28
28
|
</div>
|
|
29
29
|
<div class="error-msg">Something went wrong while processing your request.</div>
|
|
30
|
-
<pre class="error-trace">{{ error_message }}</pre>
|
|
30
|
+
{% if error_message %}<pre class="error-trace">{{ error_message }}</pre>{% endif %}
|
|
31
31
|
<div class="error-footer">
|
|
32
32
|
<span class="error-hint">Fix the error and save to auto-reload</span>
|
|
33
33
|
<span class="error-id">{{ request_id }}</span>
|
|
@@ -18,7 +18,11 @@ function requireFirebird(): any {
|
|
|
18
18
|
return firebird;
|
|
19
19
|
} catch {
|
|
20
20
|
throw new Error(
|
|
21
|
-
'Firebird adapter requires the "node-firebird" package. Install
|
|
21
|
+
'Firebird adapter requires the "node-firebird" package. Install one of:\n' +
|
|
22
|
+
" npm install node-firebird\n" +
|
|
23
|
+
" yarn add node-firebird\n" +
|
|
24
|
+
" pnpm add node-firebird\n" +
|
|
25
|
+
" bun add node-firebird",
|
|
22
26
|
);
|
|
23
27
|
}
|
|
24
28
|
}
|
|
@@ -301,8 +301,11 @@ export class MongodbAdapter implements DatabaseAdapter {
|
|
|
301
301
|
MongoClient = (await import("mongodb")).MongoClient;
|
|
302
302
|
} catch {
|
|
303
303
|
throw new Error(
|
|
304
|
-
"The 'mongodb' package is required for MongoDB connections. " +
|
|
305
|
-
|
|
304
|
+
"The 'mongodb' package is required for MongoDB connections. Install one of:\n" +
|
|
305
|
+
" npm install mongodb\n" +
|
|
306
|
+
" yarn add mongodb\n" +
|
|
307
|
+
" pnpm add mongodb\n" +
|
|
308
|
+
" bun add mongodb",
|
|
306
309
|
);
|
|
307
310
|
}
|
|
308
311
|
|
|
@@ -18,7 +18,11 @@ function requireTedious(): any {
|
|
|
18
18
|
return tedious;
|
|
19
19
|
} catch {
|
|
20
20
|
throw new Error(
|
|
21
|
-
'MSSQL adapter requires the "tedious" package. Install
|
|
21
|
+
'MSSQL adapter requires the "tedious" package. Install one of:\n' +
|
|
22
|
+
" npm install tedious\n" +
|
|
23
|
+
" yarn add tedious\n" +
|
|
24
|
+
" pnpm add tedious\n" +
|
|
25
|
+
" bun add tedious",
|
|
22
26
|
);
|
|
23
27
|
}
|
|
24
28
|
}
|
|
@@ -18,7 +18,11 @@ function requireMysql2(): any {
|
|
|
18
18
|
return mysql2;
|
|
19
19
|
} catch {
|
|
20
20
|
throw new Error(
|
|
21
|
-
'MySQL adapter requires the "mysql2" package. Install
|
|
21
|
+
'MySQL adapter requires the "mysql2" package. Install one of:\n' +
|
|
22
|
+
" npm install mysql2\n" +
|
|
23
|
+
" yarn add mysql2\n" +
|
|
24
|
+
" pnpm add mysql2\n" +
|
|
25
|
+
" bun add mysql2",
|
|
22
26
|
);
|
|
23
27
|
}
|
|
24
28
|
}
|
|
@@ -21,7 +21,11 @@ function requireOdbc(): any {
|
|
|
21
21
|
return odbcModule;
|
|
22
22
|
} catch {
|
|
23
23
|
throw new Error(
|
|
24
|
-
"The 'odbc' package is required for ODBC connections. Install
|
|
24
|
+
"The 'odbc' package is required for ODBC connections. Install one of:\n" +
|
|
25
|
+
" npm install odbc\n" +
|
|
26
|
+
" yarn add odbc\n" +
|
|
27
|
+
" pnpm add odbc\n" +
|
|
28
|
+
" bun add odbc",
|
|
25
29
|
);
|
|
26
30
|
}
|
|
27
31
|
}
|
|
@@ -19,7 +19,11 @@ function requirePg(): typeof import("pg") {
|
|
|
19
19
|
return pg!;
|
|
20
20
|
} catch {
|
|
21
21
|
throw new Error(
|
|
22
|
-
'PostgreSQL adapter requires the "pg" package. Install
|
|
22
|
+
'PostgreSQL adapter requires the "pg" package. Install one of:\n' +
|
|
23
|
+
" npm install pg\n" +
|
|
24
|
+
" yarn add pg\n" +
|
|
25
|
+
" pnpm add pg\n" +
|
|
26
|
+
" bun add pg",
|
|
23
27
|
);
|
|
24
28
|
}
|
|
25
29
|
}
|