litedbmodel 1.2.7 → 1.2.8
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 +68 -2
- package/dist/SqlFragment.d.ts.map +1 -1
- package/dist/SqlFragment.js +8 -0
- package/dist/SqlFragment.js.map +1 -1
- package/docs/README_REVIEW.md +23 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
**[📖 API Documentation](https://github.com/foo-ogawa/litedbmodel.ts/blob/main/docs/api/README.md)**
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
**Production-safe SQL-first Database Access Layer for AI-assisted development.**
|
|
9
|
+
|
|
10
|
+
litedbmodel keeps SQL predictable, behavior reviewable, and operations safe — priorities that matter most when AI agents and humans co-develop production systems. Supports PostgreSQL, MySQL, and SQLite.
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
## Philosophy
|
|
@@ -31,6 +32,38 @@ litedbmodel keeps SQL visible and controllable: generated queries are intentiona
|
|
|
31
32
|
|
|
32
33
|
> See [Design Philosophy](./docs/BENCHMARK.md#litedbmodels-design-philosophy) for detailed comparison with query-centric ORMs.
|
|
33
34
|
|
|
35
|
+
### DX redefined for AI-assisted development
|
|
36
|
+
|
|
37
|
+
litedbmodel is not optimized for traditional ORM convenience.
|
|
38
|
+
It is optimized for AI-assisted development where predictable SQL, reviewable behavior, transaction safety, and operational stability matter more than hiding SQL behind abstractions.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Why AI-friendly?
|
|
43
|
+
|
|
44
|
+
AI agents generate and modify database code at scale. When that code reaches production, you need guarantees — not hope.
|
|
45
|
+
|
|
46
|
+
- **SQL is predictable** — generated queries are simple and reviewable; no hidden query plan changes from abstraction layers
|
|
47
|
+
- **No hidden queries** — what you write is what runs; there are no implicit loads or lazy surprises
|
|
48
|
+
- **Transaction boundaries are explicit** — no implicit writes; every mutation requires a declared transaction
|
|
49
|
+
- **Hard limits prevent accidental over-fetching** — configurable guards catch runaway queries before they hit production
|
|
50
|
+
- **Reader/writer separation enforces safe defaults** — reads go to replicas, writes require transactions on the writer
|
|
51
|
+
- **Every DB access is reviewable and auditable** — the SQL you see in code is the SQL that executes
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Production Safety Features
|
|
56
|
+
|
|
57
|
+
| Feature | What it does |
|
|
58
|
+
|---------|-------------|
|
|
59
|
+
| **Transaction-required writes** | `create`, `update`, `delete` throw outside a transaction — no accidental writes |
|
|
60
|
+
| **Hard query limits** | `findHardLimit` / `hasManyHardLimit` cap result sets and throw `LimitExceededError` |
|
|
61
|
+
| **N+1 prevention** | Automatic batch loading for lazy relations — no manual eager-loading needed |
|
|
62
|
+
| **Reader/writer separation** | Reads route to replicas; sticky-writer after transactions handles replication lag |
|
|
63
|
+
| **SQL visibility** | Generated SQL is intentionally simple; complex queries use real SQL via `query()` / `execute()` |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
34
67
|
## Key Features
|
|
35
68
|
|
|
36
69
|
### SQL Control & Modeling
|
|
@@ -1350,6 +1383,14 @@ const article = await CmsDB.withWriter(async () => {
|
|
|
1350
1383
|
|
|
1351
1384
|
## Comparison
|
|
1352
1385
|
|
|
1386
|
+
| Approach | Philosophy |
|
|
1387
|
+
|----------|------------|
|
|
1388
|
+
| Prisma | Abstraction-first |
|
|
1389
|
+
| Drizzle / Kysely | SQL-first |
|
|
1390
|
+
| litedbmodel | SQL-first + production safety |
|
|
1391
|
+
|
|
1392
|
+
### Feature Comparison
|
|
1393
|
+
|
|
1353
1394
|
| Feature | litedbmodel | Kysely | Drizzle | TypeORM | Prisma |
|
|
1354
1395
|
|---------|-------------|--------|---------|---------|--------|
|
|
1355
1396
|
| **Relation Loading** | On-demand | Manual | Eager/upfront | Eager/upfront | Include |
|
|
@@ -1366,6 +1407,31 @@ const article = await CmsDB.withWriter(async () => {
|
|
|
1366
1407
|
|
|
1367
1408
|
---
|
|
1368
1409
|
|
|
1410
|
+
## Security
|
|
1411
|
+
|
|
1412
|
+
litedbmodel parameterizes values by default via the `sql` tagged template. However, several escape hatches bypass parameterization and embed raw strings directly into SQL:
|
|
1413
|
+
|
|
1414
|
+
| API | Risk |
|
|
1415
|
+
|-----|------|
|
|
1416
|
+
| `sql.raw()` | Embeds string directly — **never pass user input** |
|
|
1417
|
+
| `dbRaw()` | Raw SQL expression — trusted code only |
|
|
1418
|
+
| `dbImmediate()` | Inline value without parameterization — trusted code only |
|
|
1419
|
+
| `dbDynamic()` | Dynamic SQL fragment — trusted code only |
|
|
1420
|
+
|
|
1421
|
+
**Safe pattern:** Use the `sql` tagged template for all dynamic values. Values interpolated via `${}` are automatically parameterized.
|
|
1422
|
+
|
|
1423
|
+
```typescript
|
|
1424
|
+
// Safe — parameterized
|
|
1425
|
+
sql`SELECT * FROM users WHERE id = ${userId}`
|
|
1426
|
+
|
|
1427
|
+
// UNSAFE — raw string injection
|
|
1428
|
+
sql.raw(userInput) // NEVER do this
|
|
1429
|
+
```
|
|
1430
|
+
|
|
1431
|
+
For vulnerability reporting, see [SECURITY.md](./SECURITY.md).
|
|
1432
|
+
|
|
1433
|
+
---
|
|
1434
|
+
|
|
1369
1435
|
## License
|
|
1370
1436
|
|
|
1371
1437
|
MIT
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlFragment.d.ts","sourceRoot":"","sources":["../src/SqlFragment.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SqlFragment.d.ts","sourceRoot":"","sources":["../src/SqlFragment.ts"],"names":[],"mappings":"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"}
|
package/dist/SqlFragment.js
CHANGED
|
@@ -212,10 +212,18 @@ function sql(strings, ...values) {
|
|
|
212
212
|
* Create a raw SQL string that is embedded directly (not parameterized).
|
|
213
213
|
* Use for dynamic SQL keywords like ORDER direction, DISTINCT, etc.
|
|
214
214
|
*
|
|
215
|
+
* **SECURITY WARNING: Never pass user input to sql.raw().
|
|
216
|
+
* Values from request parameters, headers, query strings, body fields,
|
|
217
|
+
* or unvalidated LLM output must use parameterized queries instead.**
|
|
218
|
+
*
|
|
215
219
|
* @example
|
|
216
220
|
* ```typescript
|
|
221
|
+
* // ✅ Safe: hardcoded trusted values
|
|
217
222
|
* const direction = sql.raw(isAsc ? 'ASC' : 'DESC');
|
|
218
223
|
* sql`SELECT * FROM users ORDER BY name ${direction}`
|
|
224
|
+
*
|
|
225
|
+
* // ❌ UNSAFE: user input
|
|
226
|
+
* sql.raw(req.query.sort) // SQL INJECTION RISK
|
|
219
227
|
* ```
|
|
220
228
|
*/
|
|
221
229
|
sql.raw = function (value) {
|
package/dist/SqlFragment.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SqlFragment.js","sourceRoot":"","sources":["../src/SqlFragment.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SqlFragment.js","sourceRoot":"","sources":["../src/SqlFragment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# README Review Notes
|
|
2
|
+
|
|
3
|
+
## Date
|
|
4
|
+
|
|
5
|
+
2026-06-20
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
The README was reviewed and restructured based on external feedback. The library's positioning was changed from "lightweight TypeScript ORM" to "Production-safe SQL-first Database Access Layer for AI-assisted development."
|
|
10
|
+
|
|
11
|
+
## Changes Made
|
|
12
|
+
|
|
13
|
+
1. **Opening description**: Replaced generic ORM positioning with a value proposition centered on production safety and AI-assisted development.
|
|
14
|
+
2. **"Why AI-friendly?" section**: Added after Philosophy to explain why predictable SQL, explicit transactions, and hard limits matter when AI agents co-develop production code.
|
|
15
|
+
3. **"Production Safety Features" section**: Elevated safety features (transaction-required writes, hard limits, N+1 prevention, reader/writer separation, SQL visibility) into a standalone section.
|
|
16
|
+
4. **DX redefinition note**: Added to the Philosophy section to clarify that litedbmodel optimizes for reviewability and safety over traditional ORM convenience.
|
|
17
|
+
5. **Comparison table**: Changed framing from feature-by-feature speed comparison to philosophy-first positioning (Abstraction-first vs SQL-first vs SQL-first + production safety).
|
|
18
|
+
6. **Security section**: Added near the end of README with warnings about raw SQL escape hatches and a link to SECURITY.md.
|
|
19
|
+
7. **SECURITY.md**: Created as a standalone file documenting trust boundaries, unsafe/safe patterns, and vulnerability reporting instructions.
|
|
20
|
+
|
|
21
|
+
## Rationale
|
|
22
|
+
|
|
23
|
+
The previous README described litedbmodel accurately but positioned it as a generic ORM alternative. The restructured README highlights the properties that differentiate it in AI-assisted development workflows: predictable SQL output, explicit transaction boundaries, hard safety limits, and full SQL visibility.
|