@stingerloom/orm 0.1.2 → 0.2.1

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.
Files changed (56) hide show
  1. package/README.md +139 -30
  2. package/dist/core/EntityManager.d.ts +2 -0
  3. package/dist/core/EntityManager.d.ts.map +1 -1
  4. package/dist/core/EntityManager.js +35 -0
  5. package/dist/core/EntityManager.js.map +1 -1
  6. package/dist/core/generators/SchemaGenerator.d.ts.map +1 -1
  7. package/dist/core/generators/SchemaGenerator.js +4 -0
  8. package/dist/core/generators/SchemaGenerator.js.map +1 -1
  9. package/dist/decorators/Column.d.ts +1 -1
  10. package/dist/decorators/Column.d.ts.map +1 -1
  11. package/dist/decorators/Column.js.map +1 -1
  12. package/dist/decorators/CreateTimestamp.d.ts +3 -0
  13. package/dist/decorators/CreateTimestamp.d.ts.map +1 -0
  14. package/dist/decorators/CreateTimestamp.js +16 -0
  15. package/dist/decorators/CreateTimestamp.js.map +1 -0
  16. package/dist/decorators/UpdateTimestamp.d.ts +3 -0
  17. package/dist/decorators/UpdateTimestamp.d.ts.map +1 -0
  18. package/dist/decorators/UpdateTimestamp.js +16 -0
  19. package/dist/decorators/UpdateTimestamp.js.map +1 -0
  20. package/dist/decorators/index.d.ts +2 -0
  21. package/dist/decorators/index.d.ts.map +1 -1
  22. package/dist/decorators/index.js +2 -0
  23. package/dist/decorators/index.js.map +1 -1
  24. package/dist/dialects/mysql/MySqlDriver.d.ts.map +1 -1
  25. package/dist/dialects/mysql/MySqlDriver.js +2 -0
  26. package/dist/dialects/mysql/MySqlDriver.js.map +1 -1
  27. package/dist/dialects/postgres/PostgresDriver.d.ts.map +1 -1
  28. package/dist/dialects/postgres/PostgresDriver.js +2 -0
  29. package/dist/dialects/postgres/PostgresDriver.js.map +1 -1
  30. package/dist/dialects/sqlite/SqliteDriver.d.ts.map +1 -1
  31. package/dist/dialects/sqlite/SqliteDriver.js +1 -0
  32. package/dist/dialects/sqlite/SqliteDriver.js.map +1 -1
  33. package/dist/integration/nestjs/index.d.ts +5 -0
  34. package/dist/integration/nestjs/index.d.ts.map +1 -0
  35. package/dist/integration/nestjs/index.js +16 -0
  36. package/dist/integration/nestjs/index.js.map +1 -0
  37. package/dist/integration/nestjs/inject-repository.decorator.d.ts +3 -0
  38. package/dist/integration/nestjs/inject-repository.decorator.d.ts.map +1 -0
  39. package/dist/integration/nestjs/inject-repository.decorator.js +10 -0
  40. package/dist/integration/nestjs/inject-repository.decorator.js.map +1 -0
  41. package/dist/integration/nestjs/stingerloom-orm-core.module.d.ts +6 -0
  42. package/dist/integration/nestjs/stingerloom-orm-core.module.d.ts.map +1 -0
  43. package/dist/integration/nestjs/stingerloom-orm-core.module.js +35 -0
  44. package/dist/integration/nestjs/stingerloom-orm-core.module.js.map +1 -0
  45. package/dist/integration/nestjs/stingerloom-orm.module.d.ts +11 -0
  46. package/dist/integration/nestjs/stingerloom-orm.module.d.ts.map +1 -0
  47. package/dist/integration/nestjs/stingerloom-orm.module.js +58 -0
  48. package/dist/integration/nestjs/stingerloom-orm.module.js.map +1 -0
  49. package/dist/integration/nestjs/stingerloom-orm.service.d.ts +18 -0
  50. package/dist/integration/nestjs/stingerloom-orm.service.d.ts.map +1 -0
  51. package/dist/integration/nestjs/stingerloom-orm.service.js +70 -0
  52. package/dist/integration/nestjs/stingerloom-orm.service.js.map +1 -0
  53. package/dist/metadata/MetadataContext.d.ts.map +1 -1
  54. package/dist/metadata/MetadataContext.js +3 -1
  55. package/dist/metadata/MetadataContext.js.map +1 -1
  56. package/package.json +29 -13
package/README.md CHANGED
@@ -10,6 +10,8 @@
10
10
 
11
11
  ---
12
12
 
13
+ Stingerloom ORM is a decorator-driven TypeScript ORM designed for type-safe database access with first-class multi-tenancy support.
14
+
13
15
  ## Install
14
16
 
15
17
  ```bash
@@ -19,52 +21,159 @@ npm install @stingerloom/orm reflect-metadata
19
21
  Install only the driver you need:
20
22
 
21
23
  ```bash
22
- npm install mysql2 # MySQL
23
- npm install pg # PostgreSQL
24
+ npm install mysql2 # MySQL / MariaDB
25
+ npm install pg # PostgreSQL
24
26
  npm install better-sqlite3 # SQLite
25
27
  ```
26
28
 
27
- ## Quick Start
29
+ ## Defining Entities
30
+
31
+ Entities are defined with decorators. Column types are automatically inferred from TypeScript types — `string` maps to `VARCHAR`, `number` to `INT`, `boolean` to `TINYINT`/`BOOLEAN`.
28
32
 
29
33
  ```typescript
30
34
  @Entity()
31
- class User {
32
- @PrimaryGeneratedColumn() id!: number;
33
- @Column() name!: string;
34
- @Column() email!: string;
35
+ class Post {
36
+ @PrimaryGeneratedColumn()
37
+ id!: number;
38
+
39
+ @Column()
40
+ title!: string;
41
+
42
+ @Column({ type: "text" })
43
+ content!: string;
44
+
45
+ @DeletedAt()
46
+ deletedAt!: Date | null;
47
+
48
+ @ManyToOne(() => User, { joinColumn: "author_id", eager: true })
49
+ author!: User;
50
+
51
+ @BeforeInsert()
52
+ setDefaults() {
53
+ this.createdAt = new Date();
54
+ }
35
55
  }
56
+ ```
57
+
58
+ ## CRUD with EntityManager
36
59
 
60
+ ```typescript
37
61
  const em = new EntityManager();
38
- await em.register({ type: "postgres", entities: [User], synchronize: true });
62
+ await em.register({ type: "mysql", entities: [Post, User], synchronize: true });
63
+
64
+ // Create
65
+ const post = await em.save(Post, { title: "Hello", content: "World" });
66
+
67
+ // Read — eager relations are loaded automatically
68
+ const found = await em.findOne(Post, { where: { id: 1 } });
69
+
70
+ // Update
71
+ found.title = "Updated";
72
+ await em.save(Post, found);
73
+
74
+ // Soft Delete — find queries automatically exclude soft-deleted rows
75
+ await em.softDelete(Post, { id: 1 });
76
+ ```
77
+
78
+ ## Relationships
79
+
80
+ Four relationship types with eager, lazy, and explicit loading strategies:
81
+
82
+ ```typescript
83
+ @ManyToOne(() => User, { eager: true }) // N:1, auto-loads on find
84
+ @OneToMany(() => Comment, c => c.post) // 1:N, inverse side
85
+ @OneToOne(() => Profile, { joinColumn: "profile_id" })
86
+ @ManyToMany(() => Tag, { joinTable: "post_tags" }) // auto-generated join table DDL
87
+ ```
88
+
89
+ ## Query Builder
90
+
91
+ For complex queries beyond the `find` API:
39
92
 
40
- await em.save(User, { name: "Alice", email: "alice@example.com" });
41
- await em.find(User, { where: { name: "Alice" } });
93
+ ```typescript
94
+ const qb = RawQueryBuilderFactory.create()
95
+ .select(["p.id", "p.title", "COUNT(c.id) AS comment_count"])
96
+ .from("post", "p")
97
+ .leftJoin("comment", "c", sql`c.post_id = p.id`)
98
+ .where([sql`p.deleted_at IS NULL`])
99
+ .groupBy(["p.id"])
100
+ .having([sql`COUNT(c.id) > ${5}`])
101
+ .orderBy([{ column: "comment_count", direction: "DESC" }])
102
+ .limit(10)
103
+ .build();
104
+ ```
105
+
106
+ ## Multi-Tenancy
107
+
108
+ Layered metadata system inspired by Docker OverlayFS. Each tenant gets an isolated metadata layer with Copy-on-Write semantics, powered by `AsyncLocalStorage` for safe concurrent access:
109
+
110
+ ```typescript
111
+ // Requests are isolated per tenant — no cross-tenant data leakage
112
+ app.use((req, res, next) => {
113
+ MetadataContext.run(req.headers["x-tenant-id"], () => next());
114
+ });
115
+ ```
116
+
117
+ PostgreSQL schema-based isolation with automatic provisioning:
118
+
119
+ ```typescript
120
+ const runner = new PostgresTenantMigrationRunner(driver);
121
+ await runner.ensureSchema("tenant_42"); // CREATE SCHEMA IF NOT EXISTS
122
+ await runner.syncTenantSchemas(["t1", "t2"]); // batch provisioning
123
+ ```
124
+
125
+ ## Transactions
126
+
127
+ Method-level with `@Transactional()` or manual with savepoint support:
128
+
129
+ ```typescript
130
+ @Transactional("SERIALIZABLE")
131
+ async transfer(from: number, to: number, amount: number) {
132
+ // automatic BEGIN, COMMIT on success, ROLLBACK on error
133
+ }
42
134
  ```
43
135
 
44
- ## Features
45
-
46
- - CRUD
47
- - Relations (ManyToOne, OneToMany, ManyToMany, OneToOne)
48
- - Eager & Lazy Loading
49
- - Transactions
50
- - Migrations
51
- - Query Builder
52
- - Multi-tenancy
53
- - Soft Delete
54
- - Upsert
55
- - Cursor Pagination
56
- - N+1 Detection
57
- - EntitySubscriber
58
- - NestJS Integration
136
+ ## Migrations
137
+
138
+ Schema Diff compares entity metadata against the live database and auto-generates migration code:
139
+
140
+ ```typescript
141
+ const diff = await SchemaDiff.compare(em, [User, Post]);
142
+ const migration = new SchemaDiffMigrationGenerator().generate(diff, "mysql");
143
+ ```
144
+
145
+ ## Additional Features
146
+
147
+ - **Cursor Pagination** — `findWithCursor()` for consistent performance on large datasets
148
+ - **Upsert** — `INSERT ON CONFLICT` / `ON DUPLICATE KEY UPDATE` with native driver syntax
149
+ - **N+1 Detection** — QueryTracker warns on repeated single-row queries and slow queries
150
+ - **Aggregation** — `count`, `sum`, `avg`, `min`, `max` with optional WHERE
151
+ - **Lifecycle Hooks** — `@BeforeInsert`, `@AfterInsert`, `@BeforeUpdate`, `@AfterUpdate`, `@BeforeDelete`, `@AfterDelete`
152
+ - **EntitySubscriber** — event-driven observation pattern per entity class
153
+ - **Validation** — `@NotNull`, `@MinLength`, `@MaxLength`, `@Min`, `@Max`
154
+ - **Connection Pooling** — configurable pool size, acquire/idle timeouts
155
+ - **Retry & Timeout** — exponential backoff on connection failure, per-query timeout
156
+ - **EXPLAIN** — query execution plan analysis
157
+ - **NestJS Integration** — `@InjectRepository`, `@InjectEntityManager`, module system
59
158
 
60
159
  ## Databases
61
160
 
62
- PostgreSQL · MySQL · SQLite
161
+ | | MySQL | PostgreSQL | SQLite |
162
+ | ---------------- | ----- | ---------- | ------ |
163
+ | CRUD | ✓ | ✓ | ✓ |
164
+ | Transactions | ✓ | ✓ | ✓ |
165
+ | Schema Sync | ✓ | ✓ | ✓ |
166
+ | Migrations | ✓ | ✓ | ✓ |
167
+ | ENUM | ✓ | ✓ (native) | — |
168
+ | Schema Isolation | — | ✓ | — |
169
+ | Read Replica | ✓ | ✓ | — |
63
170
 
64
- ## Docs
171
+ ## Test Status
65
172
 
66
- See **[docs/](./docs/README.md)** for full documentation.
173
+ - **1,405** unit tests passed, 0 failures
174
+ - **4** example projects type-checked (nestjs-cats, nestjs-blog, nestjs-multitenant, nestjs-todo)
175
+ - **6** SQL injection vectors patched and audited across all drivers
67
176
 
68
- ## License
177
+ ## Documentation
69
178
 
70
- [MIT](./LICENSE)
179
+ Full documentation available at [docs/](https://github.com/biud436/stingerloom-orm/tree/main/docs).
@@ -56,6 +56,8 @@ export declare class EntityManager implements BaseEntityManager {
56
56
  getNameStrategy<T>(clazz: ClazzType<T>): string;
57
57
  private resolveEntityMetadata;
58
58
  private getDeletedAtColumn;
59
+ private getCreateTimestampColumn;
60
+ private getUpdateTimestampColumn;
59
61
  private runHooks;
60
62
  private createProxy;
61
63
  private registerEntities;
@@ -1 +1 @@
1
- {"version":3,"file":"EntityManager.d.ts","sourceRoot":"","sources":["../../src/core/EntityManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EntityManager.d.ts","sourceRoot":"","sources":["../../src/core/EntityManager.ts"],"names":[],"mappings":"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"}
@@ -275,6 +275,14 @@ class EntityManager {
275
275
  const column = Reflect.getMetadata(decorators_1.DELETED_AT_TOKEN, entity);
276
276
  return column ?? null;
277
277
  }
278
+ getCreateTimestampColumn(entity) {
279
+ const column = Reflect.getMetadata(decorators_1.CREATE_TIMESTAMP_TOKEN, entity);
280
+ return column ?? null;
281
+ }
282
+ getUpdateTimestampColumn(entity) {
283
+ const column = Reflect.getMetadata(decorators_1.UPDATE_TIMESTAMP_TOKEN, entity);
284
+ return column ?? null;
285
+ }
278
286
  async runHooks(entity, item, event) {
279
287
  const hooks = Reflect.getMetadata(decorators_1.HOOK_TOKEN, entity);
280
288
  if (!hooks || hooks.length === 0)
@@ -1486,6 +1494,21 @@ class EntityManager {
1486
1494
  const values = insertableColumns.map((column) => {
1487
1495
  return item[column.name];
1488
1496
  });
1497
+ const now = new Date().toISOString();
1498
+ const createTsCol = this.getCreateTimestampColumn(entity);
1499
+ if (createTsCol) {
1500
+ const idx = insertableColumns.findIndex((col) => col.name === createTsCol);
1501
+ if (idx >= 0) {
1502
+ values[idx] = item[createTsCol]?.toISOString?.() ?? now;
1503
+ }
1504
+ }
1505
+ const updateTsCol = this.getUpdateTimestampColumn(entity);
1506
+ if (updateTsCol) {
1507
+ const idx = insertableColumns.findIndex((col) => col.name === updateTsCol);
1508
+ if (idx >= 0) {
1509
+ values[idx] = item[updateTsCol]?.toISOString?.() ?? now;
1510
+ }
1511
+ }
1489
1512
  const manyToOneRelations = this.resolveManyToOneMetadata(entity);
1490
1513
  for (const rel of manyToOneRelations) {
1491
1514
  if (!rel.joinColumn)
@@ -1595,6 +1618,18 @@ class EntityManager {
1595
1618
  const updateMap = updatableColumns.map((column) => {
1596
1619
  return (0, sql_template_tag_1.default) `${(0, sql_template_tag_1.raw)(this.wrap(column.name))} = ${item[column.name]}`;
1597
1620
  });
1621
+ const updateTsColName = this.getUpdateTimestampColumn(entity);
1622
+ if (updateTsColName) {
1623
+ const existingIdx = updatableColumns.findIndex((col) => col.name === updateTsColName);
1624
+ const updateNow = new Date().toISOString();
1625
+ if (existingIdx >= 0) {
1626
+ updateMap[existingIdx] =
1627
+ (0, sql_template_tag_1.default) `${(0, sql_template_tag_1.raw)(this.wrap(updateTsColName))} = ${updateNow}`;
1628
+ }
1629
+ else {
1630
+ updateMap.push((0, sql_template_tag_1.default) `${(0, sql_template_tag_1.raw)(this.wrap(updateTsColName))} = ${updateNow}`);
1631
+ }
1632
+ }
1598
1633
  const updatedColumnNames = new Set(updatableColumns.map((col) => col.name));
1599
1634
  const updateManyToOneRelations = this.resolveManyToOneMetadata(entity);
1600
1635
  for (const rel of updateManyToOneRelations) {