tina4-nodejs 3.13.19 → 3.13.21

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 CHANGED
@@ -1,10 +1,10 @@
1
- # CLAUDE.md — AI Developer Guide for tina4-nodejs (v3.13.19)
1
+ # CLAUDE.md — AI Developer Guide for tina4-nodejs (v3.13.21)
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.19 — The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
7
+ Tina4 for Node.js/TypeScript v3.13.21 — 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
 
@@ -1098,7 +1098,7 @@ When adding new features, add a corresponding `test/<feature>.test.ts` file.
1098
1098
  ## v3 Features Summary
1099
1099
 
1100
1100
  - **45 built-in features**, zero third-party dependencies
1101
- - **3,679 tests** passing across all modules
1101
+ - **3,684 tests** passing across all modules
1102
1102
  - **Race-safe `getNextId()`** with atomic sequence table (`tina4_sequences`) for SQLite/MySQL/MSSQL; PostgreSQL auto-creates sequences
1103
1103
  - **Frond template engine optimizations**: pre-compiled regexes, lazy loop context (copy-on-write), filter chain caching, path split caching, inline common filters (11-15% speedup)
1104
1104
  - **Production server auto-detect**: `npx tina4nodejs serve --production` auto-uses cluster mode
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
 
5
5
 
6
- "version": "3.13.19",
6
+ "version": "3.13.21",
7
7
 
8
8
  "type": "module",
9
9
  "description": "Tina4 for Node.js/TypeScript \u2014 54 built-in features, zero dependencies",
@@ -12,7 +12,7 @@ import { validToken, getPayload, refreshToken } from "./auth.js";
12
12
  import { discoverRoutes } from "./routeDiscovery.js";
13
13
  import { createRequest } from "./request.js";
14
14
  import { createResponse, setDefaultTemplatesDir } from "./response.js";
15
- import { MiddlewareChain, cors, requestLogger } from "./middleware.js";
15
+ import { MiddlewareChain, MiddlewareRunner, cors, requestLogger } from "./middleware.js";
16
16
  import { tryServeStatic } from "./static.js";
17
17
  import { loadEnv, isTruthy } from "./dotenv.js";
18
18
  import { createHealthRoutes } from "./health.js";
@@ -975,7 +975,7 @@ ${reset}
975
975
  } as typeof rawRes.end;
976
976
  }
977
977
 
978
- // res.render() / res.template() are handled natively by response.ts via Frond
978
+ // res.render() is handled natively by response.ts via Frond
979
979
 
980
980
  try {
981
981
  // Run middleware chain
@@ -1108,6 +1108,19 @@ ${reset}
1108
1108
  req.params = match.params;
1109
1109
  matchedPattern = match.pattern;
1110
1110
 
1111
+ // Global class-based middleware registered via Router.use(...) /
1112
+ // MiddlewareRunner.use(...) — run the beforeX hooks before the handler.
1113
+ // beforeX may set response headers (they persist through the handler's
1114
+ // write), mutate the request, or short-circuit on a >= 400 status.
1115
+ // (Parity with Python/PHP/Ruby, whose Router.use class middleware runs.)
1116
+ const globalMiddleware = [
1117
+ ...new Set([...Router.getClassMiddlewares(), ...MiddlewareRunner.getGlobal()]),
1118
+ ];
1119
+ if (globalMiddleware.length > 0) {
1120
+ const [, , proceed] = MiddlewareRunner.runBefore(globalMiddleware, req, res);
1121
+ if (!proceed || res.raw.writableEnded) return;
1122
+ }
1123
+
1111
1124
  // Run per-route middlewares if any
1112
1125
  if (match.middlewares && match.middlewares.length > 0) {
1113
1126
  const proceed = await runRouteMiddlewares(match.middlewares, req, res);
@@ -1198,6 +1211,13 @@ ${reset}
1198
1211
  await res.render(match.template, result as Record<string, unknown>);
1199
1212
  }
1200
1213
 
1214
+ // Global class-based middleware afterX hooks (logging / post-processing).
1215
+ // Header mutations here are no-ops once the response is flushed (Node
1216
+ // sends headers with the body) — set response headers in beforeX.
1217
+ if (globalMiddleware.length > 0) {
1218
+ MiddlewareRunner.runAfter(globalMiddleware, req, res);
1219
+ }
1220
+
1201
1221
  if (!res.raw.writableEnded) {
1202
1222
  res.raw.end();
1203
1223
  }