tina4-nodejs 3.13.131 → 3.13.133

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
@@ -13,13 +13,13 @@ Even if the skill text is not currently loaded, these are non-negotiable:
13
13
 
14
14
  The full discipline lives in `.claude/skills/tina4-maintainer/SKILL.md`; this block is the always-on floor.
15
15
 
16
- # CLAUDE.md - AI Developer Guide for tina4-nodejs (v3.13.131)
16
+ # CLAUDE.md - AI Developer Guide for tina4-nodejs (v3.13.133)
17
17
 
18
18
  > This file helps AI assistants (Claude, Copilot, Cursor, etc.) understand and work on this codebase effectively.
19
19
 
20
20
  ## What This Project Is
21
21
 
22
- Tina4 for Node.js/TypeScript v3.13.131 - The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
22
+ Tina4 for Node.js/TypeScript v3.13.133 - The Intelligent Native Application 4ramework. A convention-over-configuration structural paradigm. The developer writes TypeScript; Tina4 is invisible infrastructure.
23
23
 
24
24
  The philosophy: zero ceremony, batteries included, file system as source of truth.
25
25
 
@@ -172,6 +172,7 @@ Database layer with auto-CRUD generation, seeding, fake data, and SQL translatio
172
172
  - `sqlTranslator.ts` — Cross-engine SQL translator (`SQLTranslator`) and TTL query cache (`QueryCache`)
173
173
  - **Instance methods:** `save(): this|false` (fluent, false on failure), `delete()`, `forceDelete()`, `restore()`, `load(sql, params?, include?): boolean`, `validate(): string[]`, `toDict(include?)`, `toAssoc(include?)`, `toObject()`, `toArray(): unknown[]`, `toList()`, `toJson(include?)`, `hasOne(class, fk)`, `hasMany(class, fk, limit?, offset?)`, `belongsTo(class, fk)`
174
174
  - **Static methods:** `find(id, include?)`, `findById(id, include?)`, `findOrFail(id)`, `create(data)`, `all(limit=100, offset=0, include?, orderBy?)`, `select(sql, params?, limit=100, offset=0)`, `selectOne(sql, params?, include?)`, `where(conditions, params?, limit=100, offset=0, include?, orderBy?)`, `count(conditions?, params?)`, `withTrashed(conditions?, params?, limit=100, offset=0)`, `scope(name, filterSql, params?)` (registers reusable method), `createTable()`, `query()`, `_processForeignKeys()`, `_applyFkRegistry()`
175
+ - **ModelCollection (ADR-0064):** `where`, `select`, `find` (filter form), `all`, and `withTrashed` return a `ModelCollection<T>` (extends `Array<T>`, so `Array.isArray` stays true and iterate/index/`.length`/`JSON.stringify` are unchanged) that ALSO carries the filter total, independent of limit/offset: `rows.getTotalRecords()` (e.g. 250, reuses the query COUNT -- zero extra queries) and `rows.toPaginate()` (`{ records, total, page, per_page, total_pages, limit, offset }`). A method, not a `.count` property. Single-record finders (`findById`, `selectOne`) are unchanged.
175
176
  - **Foreign key auto-wire (declarative, read-side-only):** Declare a field with `type: "foreignKey"` and `references: "ModelName"` to auto-wire both `belongsTo` on the declaring model and `hasMany` on the referenced model. Optional `relatedName` overrides the has-many key. Models must be registered via `BaseModel.registerModel(name, class)` for name-based resolution. Example: `author_id: { type: "foreignKey", references: "Author", relatedName: "posts" }` attaches LAZY accessors on both sides — `await post.author` (belongsTo) and `await author.posts` (hasMany) resolve on attribute access (async, cached), and `include: ["posts"]` on `find`/`all`/`where` eager-loads them in ONE query per relation. A soft-deleted child is excluded from traversal, and the has-many read is uncapped. The auto-wire emits NO DB-level FK / ON DELETE clause (REL-DEC-01, read-side-only): referential integrity is the migration/DDL's job, so deleting a parent does not cascade to children at the engine level. (Before 3.13.99 the declarative accessors did not attach and lazy load did not exist — only the imperative `post.belongsTo(Author, "author_id")` / `author.hasMany(Post, "author_id")` worked.)
176
177
  - QueryBuilder supports `toMongo()` for generating MongoDB query documents from the same fluent API
177
178
  - `getNextId(table: string, pkColumn?: string, generatorName?: string): Promise<number>` — Race-safe ID generation using atomic sequence table (`tina4_sequences`). SQLite/MySQL/MSSQL use `tina4_sequences` with atomic UPDATE+SELECT. PostgreSQL auto-creates sequences if missing. Firebird uses existing generators (unchanged).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tina4-nodejs",
3
- "version": "3.13.131",
3
+ "version": "3.13.133",
4
4
  "type": "module",
5
5
  "description": "Tina4 for Node.js/TypeScript - native TypeScript conventions and shared Tina4 contracts",
6
6
  "keywords": [