tina4-nodejs 3.13.68 → 3.13.70

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.68)
1
+ # CLAUDE.md - AI Developer Guide for tina4-nodejs (v3.13.70)
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.68 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.70 - 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
 
@@ -877,7 +877,7 @@ frond.unsandbox();
877
877
 
878
878
  Zero-dep HTTP client over `node:http` / `node:https`. Used by integrations, queue producers, health checks, and tests.
879
879
 
880
- **Retry/backoff (opt-in, default off):** pass `maxRetries` (default `0`) and `retryBackoff` (default `0.5`s base, exponential) in the options bag — `new Api(url, { bearerToken, maxRetries: 3, retryBackoff: 0.5 })`. Retries a transport error (`http_code` null) or a retryable status (429/500/502/503/504); 4xx is never retried (a retried non-idempotent request may be re-sent, so retries are opt-in). Node's `node:http`/`node:https` doesn't auto-follow redirects, so there's no cross-host Authorization-leak surface (the redirect auth-strip is Python-only).
880
+ **Retry/backoff (opt-in, default off):** pass `maxRetries` (default `0`) and `retryBackoff` (default `0.5`s base, exponential) in the options bag — `new Api(url, { bearerToken, maxRetries: 3, retryBackoff: 0.5 })`. Retries a transport error (`http_code` null) or a retryable status (429/500/502/503/504); 4xx is never retried (a retried non-idempotent request may be re-sent, so retries are opt-in).
881
881
 
882
882
  ```typescript
883
883
  import { Api } from "@tina4/core";
@@ -902,6 +902,34 @@ await api.sendRequest("OPTIONS", "/users");
902
902
 
903
903
  `error` is non-null on transport failure or timeout; `http_code` is `null` if the request never reached the server.
904
904
 
905
+ **Multipart upload, streaming download, transport seam, cookie jar, redirects (v3.13.69, Python master parity).** All zero-dep, all opt-in and non-breaking:
906
+
907
+ ```typescript
908
+ // Multipart upload — from disk OR in-memory bytes (no temp file needed).
909
+ // Boundary is "----Tina4Boundary" + 32 hex; part Content-Type is guessed from
910
+ // the filename (fallback application/octet-stream). A missing file / no source
911
+ // returns a clean error result ({ http_code: null, error: ... }) — never throws.
912
+ await api.upload("/avatars", { filePath: "/tmp/me.png", extraFields: { user_id: "42" } });
913
+ await api.upload("/avatars", { fileBytes: buf, filename: "me.png", fieldName: "file" });
914
+
915
+ // Streaming download — writes the body to disk in 64KB chunks (never buffered
916
+ // whole). Returns { http_code, headers, error, path } (NO body field); path is
917
+ // null and no file is written on any error.
918
+ const dl = await api.download("/report.pdf", "/tmp/report.pdf", { q: "2026" });
919
+
920
+ // Transport seam — an injectable async/sync callable
921
+ // (method, url, headers, body, timeout) => { http_code, body, headers, error }
922
+ // that REPLACES the node:http/https call. For APPLICATION-developer unit tests
923
+ // only — Tina4's own suite never injects a fake (no-mock rule).
924
+ new Api(url, { transport: async (method, u, headers, body, timeout) => ({ http_code: 200, body: {}, headers: {}, error: null }) });
925
+
926
+ // Cookie jar — opt-in, in-memory, per-client. Parses Set-Cookie (leading
927
+ // name=value, last write wins) and replays the accumulated Cookie header.
928
+ new Api(url, { cookies: true });
929
+ ```
930
+
931
+ **Redirect following (all verbs + download):** unlike bare `node:http`/`node:https`, the client now follows 3xx redirects (bounded to 10 hops). 301/302/303 on a body-bearing method become GET (body dropped, matching urllib); 307/308 preserve method + body. **Security:** the `Authorization` AND `Cookie` headers are STRIPPED when the redirect target is a different origin (scheme/host/port), so a bearer token or session cookie never leaks to a host you didn't authenticate to; same-origin redirects keep them. Full parity with Python master.
932
+
905
933
  ## Module: Queue (`packages/core/src/queue.ts`)
906
934
 
907
935
  Pluggable job queue (file/RabbitMQ/Kafka/MongoDB backends). The same fluent API works against any backend — pick via env vars.
@@ -1210,7 +1238,7 @@ When adding new features, add a corresponding `test/<feature>.test.ts` file.
1210
1238
  ## v3 Features Summary
1211
1239
 
1212
1240
  - **45 built-in features**, zero third-party dependencies
1213
- - **3,752 tests** passing across all modules
1241
+ - **5,379 tests** passing across 154 files (build + typecheck green; 9 PostgreSQL/Valkey service-gated failures)
1214
1242
  - **Race-safe `getNextId()`** with atomic sequence table (`tina4_sequences`) for SQLite/MySQL/MSSQL; PostgreSQL auto-creates sequences
1215
1243
  - **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)
1216
1244
  - **Production server auto-detect**: `npx tina4nodejs serve --production` auto-uses cluster mode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tina4-nodejs",
3
- "version": "3.13.68",
3
+ "version": "3.13.70",
4
4
  "type": "module",
5
5
  "description": "Tina4 for Node.js/TypeScript - 54 built-in features, zero dependencies",
6
6
  "keywords": [
@@ -60,6 +60,13 @@
60
60
  "engines": {
61
61
  "node": ">=22.0.0"
62
62
  },
63
+ "optionalDependencies": {
64
+ "@aws-sdk/client-s3": "^3.600.0",
65
+ "@aws-sdk/s3-request-presigner": "^3.600.0",
66
+ "mongodb": "^6.0.0",
67
+ "pg": "^8.20.0",
68
+ "redis": "^4.7.0"
69
+ },
63
70
  "devDependencies": {
64
71
  "@types/node": "^22.10.0",
65
72
  "esbuild": "^0.24.0",
@@ -4,7 +4,7 @@
4
4
  * Simple menu-driven installer for AI tool context files.
5
5
  * The user picks which tools they use, we install the appropriate files.
6
6
  *
7
- * import { showMenu, installSelected } from "@tina4/core";
7
+ * import { showMenu, installSelected } from "tina4-nodejs";
8
8
  */
9
9
  import { existsSync, mkdirSync, writeFileSync, readFileSync } from "node:fs";
10
10
  import { homedir } from "node:os";
@@ -693,7 +693,7 @@ Set \`TINA4_DATABASE_URL\` in \`.env\` (e.g. \`postgres://localhost:5432/mydb\`)
693
693
 
694
694
  ## Auth
695
695
 
696
- JWT auth built in. \`import { createToken, validateToken, hashPassword, checkPassword } from "@tina4/core"\`.
696
+ JWT auth built in. \`import { createToken, validateToken, hashPassword, checkPassword } from "tina4-nodejs"\`.
697
697
  GET routes are public. POST/PUT/PATCH/DELETE require auth by default.
698
698
  `;
699
699
  }
@@ -862,7 +862,7 @@ Set \`TINA4_DATABASE_URL\` in \`.env\` (e.g. \`sqlite:///path/to/db.sqlite\`, \`
862
862
 
863
863
  ## Auth
864
864
 
865
- JWT auth built in. \`import { createToken, validateToken, hashPassword, checkPassword } from "@tina4/core"\`.
865
+ JWT auth built in. \`import { createToken, validateToken, hashPassword, checkPassword } from "tina4-nodejs"\`.
866
866
  GET routes are public. POST/PUT/PATCH/DELETE require auth by default.
867
867
 
868
868
  ## Testing
@@ -873,7 +873,7 @@ npx tina4nodejs test # Run all tests
873
873
 
874
874
  Add test files in \`test/\` directory. Use built-in inline testing:
875
875
  \`\`\`typescript
876
- import { tests, assertEqual, runAll } from "@tina4/core";
876
+ import { tests, assertEqual, runAll } from "tina4-nodejs";
877
877
  \`\`\`
878
878
 
879
879
  ## Important