tina4-nodejs 3.8.2 → 3.8.4

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/README.md CHANGED
@@ -9,6 +9,14 @@
9
9
  Laravel joy. TypeScript speed. 10x less code. Zero third-party dependencies.
10
10
  </p>
11
11
 
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/tina4-nodejs"><img src="https://img.shields.io/npm/v/tina4-nodejs?color=7b1fa2&label=npm" alt="npm"></a>
14
+ <img src="https://img.shields.io/badge/tests-1%2C812%20passing-brightgreen" alt="Tests">
15
+ <img src="https://img.shields.io/badge/features-38-blue" alt="Features">
16
+ <img src="https://img.shields.io/badge/dependencies-0-brightgreen" alt="Zero Deps">
17
+ <a href="https://tina4.com"><img src="https://img.shields.io/badge/docs-tina4.com-7b1fa2" alt="Docs"></a>
18
+ </p>
19
+
12
20
  <p align="center">
13
21
  <a href="https://tina4.com">Documentation</a> &bull;
14
22
  <a href="#getting-started">Getting Started</a> &bull;
@@ -17,14 +25,6 @@
17
25
  <a href="https://tina4.com">tina4.com</a>
18
26
  </p>
19
27
 
20
- <p align="center">
21
- <img src="https://img.shields.io/badge/tests-1669%20passing-brightgreen" alt="Tests">
22
- <img src="https://img.shields.io/badge/carbonah-A%2B%20rated-00cc44" alt="Carbonah A+">
23
- <img src="https://img.shields.io/badge/zero--dep-core-blue" alt="Zero Dependencies">
24
- <img src="https://img.shields.io/badge/node-20%2B-blue" alt="Node 20+">
25
- <img src="https://img.shields.io/badge/license-MIT-lightgrey" alt="MIT License">
26
- </p>
27
-
28
28
  ---
29
29
 
30
30
  ## Quick Start
@@ -84,8 +84,8 @@ Every feature is built from scratch -- no npm install, no node_modules bloat, no
84
84
  | **Templates** | Frond engine (Twig-compatible), inheritance, partials, 53+ filters, macros, fragment caching, sandboxing |
85
85
  | **ORM** | Active Record, typed fields with validation, soft delete, relationships (`hasOne`/`hasMany`/`belongsTo`), scopes, result caching, auto-CRUD |
86
86
  | **Database** | SQLite, PostgreSQL, MySQL, MSSQL/SQL Server, Firebird -- unified adapter interface, query caching (TINA4_DB_CACHE=true for 4x speedup) |
87
- | **Auth** | Zero-dep JWT (HS256 + RS256), sessions (file backend), PBKDF2 password hashing, form tokens |
88
- | **API** | Swagger/OpenAPI auto-generation, GraphQL with schema builder and GraphiQL IDE |
87
+ | **Auth** | Zero-dep JWT (HS256/RS256), sessions (file/Redis/Valkey/MongoDB/database), password hashing, form tokens |
88
+ | **API** | Swagger/OpenAPI auto-generation, GraphQL with ORM auto-schema and GraphiQL IDE, WSDL/SOAP with auto WSDL |
89
89
  | **Background** | Queue (SQLite/RabbitMQ/Kafka/MongoDB) with priority, delayed jobs, retry, batch processing |
90
90
  | **Real-time** | Native WebSocket (RFC 6455), per-path routing, connection manager, broadcast |
91
91
  | **Frontend** | tina4-css (~24 KB), frond.js helper, SCSS compiler, live reload, CSS hot-reload |
@@ -93,7 +93,7 @@ Every feature is built from scratch -- no npm install, no node_modules bloat, no
93
93
  | **Data** | Migrations with rollback, 26+ fake data generators, ORM and table seeders |
94
94
  | **Other** | Service runner, localization (i18n), cache (memory/Redis/file), messenger (.env driven), HTTP constants, health check, configurable error pages |
95
95
 
96
- **1,669 tests across 38 built-in features. Zero dependencies. All Carbonah benchmarks rated A+.**
96
+ **1,812 tests across 38 built-in features. Zero dependencies. All Carbonah benchmarks rated A+.**
97
97
 
98
98
  For full documentation visit **[tina4.com](https://tina4.com)**.
99
99
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tina4-nodejs",
3
- "version": "3.8.2",
3
+ "version": "3.8.4",
4
4
  "type": "module",
5
5
  "description": "This is not a framework. Tina4 for Node.js/TypeScript — zero deps, 38 built-in features.",
6
6
  "keywords": ["tina4", "framework", "web", "api", "orm", "graphql", "websocket", "typescript"],
@@ -170,7 +170,7 @@ test/ — Test files
170
170
  | Routing | router | \`import { get, post, put, del } from "@tina4/core"\` |
171
171
  | ORM | orm | \`import { BaseModel } from "@tina4/orm"\` |
172
172
  | Database | database | \`import { initDatabase } from "@tina4/orm"\` |
173
- | Templates | twig | \`import { renderTemplate } from "@tina4/twig"\` |
173
+ | Templates | twig | \`import { renderTemplate } from "@tina4/frond"\` |
174
174
  | JWT Auth | auth | \`import { createToken, validateToken } from "@tina4/core"\` |
175
175
  | REST API Client | api | \`import { Api } from "@tina4/core"\` |
176
176
  | GraphQL | graphql | \`import { GraphQL } from "@tina4/core"\` |
@@ -161,36 +161,19 @@ export function createResponse(res: ServerResponse): Tina4Response {
161
161
  return response;
162
162
  };
163
163
 
164
- response.render = async function (templateName: string, data?: Record<string, unknown>): Promise<Tina4Response> {
165
- try {
166
- const twig = await import("@tina4/twig");
167
- const html = await twig.renderTemplate(templateName, data);
168
- response.html(html);
169
- } catch (err) {
170
- res.statusCode = 500;
171
- response.json({
172
- error: "Template rendering failed",
173
- statusCode: 500,
174
- message: String(err),
175
- });
176
- }
164
+ // Default render/template stubs overwritten by server.ts when Frond is available
165
+ response.render = async function (templateName: string, _data?: Record<string, unknown>): Promise<Tina4Response> {
166
+ res.statusCode = 500;
167
+ response.json({
168
+ error: "Template engine not available",
169
+ statusCode: 500,
170
+ message: "Frond template engine is not initialized. Ensure @tina4/frond is installed.",
171
+ });
177
172
  return response;
178
173
  };
179
174
 
180
175
  response.template = async function (name: string, data?: Record<string, unknown>): Promise<Tina4Response> {
181
- try {
182
- const twig = await import("@tina4/twig");
183
- const html = await twig.renderTemplate(name, data);
184
- response.html(html);
185
- } catch (err) {
186
- res.statusCode = 500;
187
- response.json({
188
- error: "Template rendering failed",
189
- statusCode: 500,
190
- message: String(err),
191
- });
192
- }
193
- return response;
176
+ return response.render(name, data);
194
177
  };
195
178
 
196
179
  return response;
@@ -446,14 +446,13 @@ ${reset}
446
446
  const healthRoute = createHealthRoute(TINA4_VERSION);
447
447
  router.addRoute(healthRoute);
448
448
 
449
- // Initialize Twig if available
450
- let twigAvailable = false;
449
+ // Initialize Frond template engine
450
+ let frondEngine: any = null;
451
451
  try {
452
- const twig = await import("@tina4/twig");
453
- twig.setTemplatesDir(templatesDir);
454
- twigAvailable = true;
452
+ const { Frond } = await import("@tina4/frond");
453
+ frondEngine = new Frond(templatesDir);
455
454
  } catch {
456
- // Twig not installed, res.render() won't be available
455
+ // Frond not available
457
456
  }
458
457
 
459
458
  // Built-in middleware
@@ -569,12 +568,12 @@ ${reset}
569
568
  const req = createRequest(rawReq);
570
569
  const res = createResponse(rawRes);
571
570
 
572
- // Add res.render() if Twig is available
573
- if (twigAvailable) {
574
- try {
575
- const twig = await import("@tina4/twig");
576
- twig.addRenderMethod(res);
577
- } catch { /* ignore */ }
571
+ // Add res.render() if Frond is available
572
+ if (frondEngine) {
573
+ res.render = (template: string, data?: Record<string, unknown>, statusCode?: number) => {
574
+ const html = frondEngine.render(template, data);
575
+ return res.html(html, statusCode ?? 200);
576
+ };
578
577
  }
579
578
 
580
579
  try {
@@ -848,6 +848,8 @@ export class Frond {
848
848
  /** Token pre-compilation cache for string templates */
849
849
  private compiledStrings = new Map<string, Token[]>();
850
850
 
851
+ getTemplateDir(): string { return this.templateDir; }
852
+
851
853
  constructor(templateDir: string = "src/templates") {
852
854
  this.templateDir = resolve(templateDir);
853
855
  this.filters = { ...BUILTIN_FILTERS };