tina4-nodejs 3.13.94 → 3.13.95
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 +157 -28
- package/README.md +1 -1
- package/package.json +2 -1
- package/packages/cli/dist/bin.js +32418 -29638
- package/packages/cli/src/commands/metrics.ts +17 -11
- package/packages/cli/src/commands/serve.ts +10 -9
- package/packages/core/dist/index.js +32364 -29501
- package/packages/core/src/ai.ts +7 -1
- package/packages/core/src/auth.ts +191 -39
- package/packages/core/src/background.ts +19 -19
- package/packages/core/src/cache.ts +492 -49
- package/packages/core/src/devAdmin.ts +79 -32
- package/packages/core/src/dispatchPipeline.ts +285 -0
- package/packages/core/src/dotenv.ts +185 -40
- package/packages/core/src/index.ts +5 -4
- package/packages/core/src/logger.ts +257 -36
- package/packages/core/src/mcp.ts +1 -1
- package/packages/core/src/messenger.ts +9 -13
- package/packages/core/src/metrics.ts +199 -961
- package/packages/core/src/middleware.ts +390 -123
- package/packages/core/src/queue.ts +188 -32
- package/packages/core/src/queueBackends/kafkaBackend.ts +1 -1
- package/packages/core/src/queueBackends/liteBackend.ts +13 -0
- package/packages/core/src/queueBackends/mongoBackend.ts +101 -9
- package/packages/core/src/queueBackends/rabbitmqBackend.ts +22 -4
- package/packages/core/src/rateLimiter.ts +10 -5
- package/packages/core/src/request.ts +6 -9
- package/packages/core/src/response.ts +46 -1
- package/packages/core/src/router.ts +29 -4
- package/packages/core/src/server.ts +751 -414
- package/packages/core/src/session.ts +244 -27
- package/packages/core/src/sessionHandlers/databaseHandler.ts +338 -48
- package/packages/core/src/sessionHandlers/memcachedHandler.ts +181 -0
- package/packages/core/src/sessionHandlers/mongoClient.ts +293 -208
- package/packages/core/src/sessionHandlers/mongoHandler.ts +88 -8
- package/packages/core/src/sessionHandlers/respClient.ts +16 -147
- package/packages/core/src/sessionHandlers/sqlClient.ts +290 -0
- package/packages/core/src/sessionHandlers/syncBridge.ts +190 -0
- package/packages/core/src/sessionHandlers/syncSocket.ts +236 -0
- package/packages/core/src/testClient.ts +18 -5
- package/packages/core/src/trustedProxy.ts +249 -0
- package/packages/core/src/types.ts +29 -5
- package/packages/core/src/websocket.ts +66 -0
- package/packages/orm/dist/index.js +22367 -19504
- package/packages/orm/src/adapters/firebird.ts +183 -56
- package/packages/orm/src/adapters/mongodb.ts +25 -4
- package/packages/orm/src/adapters/mssql.ts +114 -29
- package/packages/orm/src/adapters/mysql.ts +103 -40
- package/packages/orm/src/adapters/odbc.ts +44 -21
- package/packages/orm/src/adapters/postgres.ts +118 -26
- package/packages/orm/src/adapters/sqlDialect.ts +120 -0
- package/packages/orm/src/adapters/sqlite.ts +60 -24
- package/packages/orm/src/baseModel.ts +135 -40
- package/packages/orm/src/cachedDatabase.ts +43 -19
- package/packages/orm/src/connectTimeout.ts +265 -0
- package/packages/orm/src/database.ts +237 -197
- package/packages/orm/src/databaseResult.ts +65 -13
- package/packages/orm/src/databaseUrl.ts +484 -0
- package/packages/orm/src/docstore.ts +386 -145
- package/packages/orm/src/index.ts +13 -3
- package/packages/orm/src/migration.ts +18 -3
- package/packages/orm/src/queryBuilder.ts +38 -4
- package/packages/orm/src/sqlTranslator.ts +310 -4
- package/packages/orm/src/types.ts +15 -4
- package/types/core/src/ai.d.ts +1 -1
- package/types/core/src/auth.d.ts +28 -5
- package/types/core/src/background.d.ts +3 -3
- package/types/core/src/cache.d.ts +15 -12
- package/types/core/src/dispatchPipeline.d.ts +117 -0
- package/types/core/src/dotenv.d.ts +38 -16
- package/types/core/src/index.d.ts +5 -6
- package/types/core/src/logger.d.ts +93 -16
- package/types/core/src/messenger.d.ts +2 -2
- package/types/core/src/metrics.d.ts +25 -61
- package/types/core/src/middleware.d.ts +134 -11
- package/types/core/src/queue.d.ts +54 -5
- package/types/core/src/queueBackends/kafkaBackend.d.ts +1 -1
- package/types/core/src/queueBackends/liteBackend.d.ts +9 -0
- package/types/core/src/queueBackends/mongoBackend.d.ts +24 -2
- package/types/core/src/queueBackends/rabbitmqBackend.d.ts +3 -3
- package/types/core/src/router.d.ts +14 -3
- package/types/core/src/server.d.ts +15 -0
- package/types/core/src/session.d.ts +87 -2
- package/types/core/src/sessionHandlers/databaseHandler.d.ts +60 -5
- package/types/core/src/sessionHandlers/memcachedHandler.d.ts +60 -0
- package/types/core/src/sessionHandlers/mongoClient.d.ts +16 -5
- package/types/core/src/sessionHandlers/mongoHandler.d.ts +51 -3
- package/types/core/src/sessionHandlers/respClient.d.ts +2 -2
- package/types/core/src/sessionHandlers/sqlClient.d.ts +39 -0
- package/types/core/src/sessionHandlers/syncBridge.d.ts +91 -0
- package/types/core/src/sessionHandlers/syncSocket.d.ts +49 -0
- package/types/core/src/trustedProxy.d.ts +44 -0
- package/types/core/src/types.d.ts +28 -5
- package/types/core/src/websocket.d.ts +26 -0
- package/types/orm/src/adapters/firebird.d.ts +55 -10
- package/types/orm/src/adapters/mongodb.d.ts +2 -2
- package/types/orm/src/adapters/mssql.d.ts +18 -11
- package/types/orm/src/adapters/mysql.d.ts +11 -10
- package/types/orm/src/adapters/odbc.d.ts +9 -12
- package/types/orm/src/adapters/postgres.d.ts +11 -10
- package/types/orm/src/adapters/sqlDialect.d.ts +71 -0
- package/types/orm/src/adapters/sqlite.d.ts +15 -3
- package/types/orm/src/baseModel.d.ts +45 -9
- package/types/orm/src/cachedDatabase.d.ts +18 -5
- package/types/orm/src/connectTimeout.d.ts +100 -0
- package/types/orm/src/database.d.ts +72 -26
- package/types/orm/src/databaseResult.d.ts +24 -0
- package/types/orm/src/databaseUrl.d.ts +125 -0
- package/types/orm/src/docstore.d.ts +102 -43
- package/types/orm/src/index.d.ts +5 -2
- package/types/orm/src/queryBuilder.d.ts +23 -3
- package/types/orm/src/sqlTranslator.d.ts +126 -2
- package/types/orm/src/types.d.ts +14 -4
- package/packages/core/src/sessionHandlers/redisHandler.ts +0 -219
- package/types/core/src/sessionHandlers/redisHandler.d.ts +0 -60
|
@@ -293,11 +293,56 @@ export function createResponse(res: ServerResponse): Tina4Response {
|
|
|
293
293
|
return response.json({ error: true, code, message, status: statusCode }, statusCode);
|
|
294
294
|
};
|
|
295
295
|
|
|
296
|
-
response.file = function (
|
|
296
|
+
response.file = function (
|
|
297
|
+
filePath: string,
|
|
298
|
+
options?: { download?: boolean; contentType?: string; root?: string },
|
|
299
|
+
): Tina4Response {
|
|
297
300
|
if (res.headersSent) return response;
|
|
298
301
|
|
|
302
|
+
// SECURITY: confine the read. The natural spelling of a download route,
|
|
303
|
+
//
|
|
304
|
+
// response.file("downloads/" + name) // name = "../secret.env"
|
|
305
|
+
//
|
|
306
|
+
// served any file the process could read - measured over real HTTP at 200
|
|
307
|
+
// with the contents of a .env one directory above the intended one.
|
|
308
|
+
//
|
|
309
|
+
// TWO checks. Containment ALONE does not close it: that payload resolves to
|
|
310
|
+
// <project>/secret.env, which IS inside the project root, and the project
|
|
311
|
+
// root is exactly where .env lives. Rejecting ".." on the way in is the
|
|
312
|
+
// check that closes it; containment then catches absolute paths and
|
|
313
|
+
// symlinks, neither of which carries a ".." segment. Same shape as
|
|
314
|
+
// static.ts's startsWith guard, which this function never had.
|
|
315
|
+
// Containment ONLY when a root is declared. Defaulting to cwd broke every
|
|
316
|
+
// legitimate absolute path.
|
|
317
|
+
const base = options?.root ? nodePath.resolve(options.root) : null;
|
|
318
|
+
let forbidden = filePath.split(/[\\/]/).includes("..");
|
|
319
|
+
|
|
320
|
+
if (!forbidden) {
|
|
321
|
+
const candidate = (base === null || nodePath.isAbsolute(filePath)) ? filePath : nodePath.join(base, filePath);
|
|
322
|
+
let resolved = candidate;
|
|
323
|
+
try {
|
|
324
|
+
resolved = fs.realpathSync(candidate);
|
|
325
|
+
} catch {
|
|
326
|
+
/* missing file: fall through to the 404 below with the joined path */
|
|
327
|
+
}
|
|
328
|
+
if (base !== null && base !== nodePath.sep && resolved !== base && !resolved.startsWith(base + nodePath.sep)) {
|
|
329
|
+
forbidden = true;
|
|
330
|
+
} else {
|
|
331
|
+
filePath = resolved;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (forbidden) {
|
|
336
|
+
// Refuse BEFORE reading: never load bytes we will not send.
|
|
337
|
+
res.statusCode = 403;
|
|
338
|
+
safeSetHeader("Content-Type", "text/plain");
|
|
339
|
+
safeEnd("Forbidden");
|
|
340
|
+
return response;
|
|
341
|
+
}
|
|
342
|
+
|
|
299
343
|
if (!fs.existsSync(filePath)) {
|
|
300
344
|
res.statusCode = 404;
|
|
345
|
+
safeSetHeader("Content-Type", "text/plain");
|
|
301
346
|
safeEnd("File not found");
|
|
302
347
|
return response;
|
|
303
348
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RouteHandler, RouteDefinition, RouteMeta, Middleware, MiddlewareSpec, Tina4Request, Tina4Response, WebSocketRouteHandler, WebSocketRouteDefinition } from "./types.js";
|
|
2
2
|
import { isTruthy } from "./dotenv.js";
|
|
3
|
+
import { MiddlewareRunner, isMiddlewareClass } from "./middleware.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Whether `TINA4_TRAILING_SLASH_REDIRECT` is enabled.
|
|
@@ -821,16 +822,29 @@ export async function resolveStringMiddleware(spec: string): Promise<Middleware>
|
|
|
821
822
|
/**
|
|
822
823
|
* Resolve a single route-middleware spec to a middleware function. Functions
|
|
823
824
|
* pass through unchanged; strings are resolved via resolveStringMiddleware.
|
|
825
|
+
* A middleware CLASS never reaches here — runRouteMiddlewares runs it through
|
|
826
|
+
* the MiddlewareRunner instead.
|
|
824
827
|
*/
|
|
825
828
|
async function resolveMiddlewareSpec(spec: MiddlewareSpec): Promise<Middleware> {
|
|
826
|
-
return typeof spec === "string" ? resolveStringMiddleware(spec) : spec;
|
|
829
|
+
return typeof spec === "string" ? resolveStringMiddleware(spec) : spec as Middleware;
|
|
827
830
|
}
|
|
828
831
|
|
|
829
832
|
/**
|
|
830
|
-
* Run per-route middleware chain
|
|
833
|
+
* Run the per-route middleware chain. Returns false when it short-circuited
|
|
834
|
+
* and the handler must be skipped.
|
|
831
835
|
*
|
|
832
|
-
* Accepts middleware functions and
|
|
833
|
-
*
|
|
836
|
+
* Accepts middleware functions, middleware CLASSES, and string specs
|
|
837
|
+
* (e.g. "ResponseCache:300"). A function or string spec is resolved and
|
|
838
|
+
* invoked as `mw(req, res, next)` exactly as before.
|
|
839
|
+
*
|
|
840
|
+
* A CLASS runs its beforeX hooks through the SAME `MiddlewareRunner.runBefore`
|
|
841
|
+
* and the SAME return-value table as global middleware — no parallel runner.
|
|
842
|
+
* Its afterX hooks run with the global after pass once the handler is done
|
|
843
|
+
* (server.ts / testClient.ts append the route's classes to that list), because
|
|
844
|
+
* "after" means after the handler, not after this function. Every spec used to
|
|
845
|
+
* be invoked as `mw(req, res, next)`, which for a class throws "Class
|
|
846
|
+
* constructor cannot be invoked without 'new'", so a class attached per-route
|
|
847
|
+
* was inert. Python and PHP both ran per-route class hooks already.
|
|
834
848
|
*/
|
|
835
849
|
export async function runRouteMiddlewares(
|
|
836
850
|
middlewares: MiddlewareSpec[],
|
|
@@ -838,6 +852,17 @@ export async function runRouteMiddlewares(
|
|
|
838
852
|
res: Tina4Response,
|
|
839
853
|
): Promise<boolean> {
|
|
840
854
|
for (const spec of middlewares) {
|
|
855
|
+
if (isMiddlewareClass(spec)) {
|
|
856
|
+
// tina4: a class hook that returns a DIFFERENT [req, res] pair cannot be
|
|
857
|
+
// rebound here — this returns a bool and is public API (four of this
|
|
858
|
+
// repo's own test files import it). Node's req/res are per-request
|
|
859
|
+
// singletons, so every built-in returns the same pair back; widen the
|
|
860
|
+
// return type if that ever stops being true.
|
|
861
|
+
const [, , proceed] = await MiddlewareRunner.runBefore([spec], req, res);
|
|
862
|
+
if (!proceed || res.raw.writableEnded) return false;
|
|
863
|
+
continue;
|
|
864
|
+
}
|
|
865
|
+
|
|
841
866
|
const mw = await resolveMiddlewareSpec(spec);
|
|
842
867
|
let nextCalled = false;
|
|
843
868
|
await mw(req, res, () => {
|