accio-orm 0.1.0

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 (35) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +482 -0
  3. package/dist/connection/Connection.d.ts +29 -0
  4. package/dist/connection/Connection.js +63 -0
  5. package/dist/connection/types.d.ts +7 -0
  6. package/dist/connection/types.js +2 -0
  7. package/dist/decorators/Column.d.ts +23 -0
  8. package/dist/decorators/Column.js +34 -0
  9. package/dist/decorators/PrimaryColumn.d.ts +9 -0
  10. package/dist/decorators/PrimaryColumn.js +26 -0
  11. package/dist/decorators/Table.d.ts +10 -0
  12. package/dist/decorators/Table.js +21 -0
  13. package/dist/examples/test-connection.d.ts +1 -0
  14. package/dist/examples/test-connection.js +36 -0
  15. package/dist/examples/test-decorators.d.ts +1 -0
  16. package/dist/examples/test-decorators.js +40 -0
  17. package/dist/examples/test-metadata.d.ts +1 -0
  18. package/dist/examples/test-metadata.js +110 -0
  19. package/dist/examples/test-querybuilder.d.ts +1 -0
  20. package/dist/examples/test-querybuilder.js +142 -0
  21. package/dist/examples/test-repository.d.ts +1 -0
  22. package/dist/examples/test-repository.js +111 -0
  23. package/dist/index.d.ts +9 -0
  24. package/dist/index.js +23 -0
  25. package/dist/metadata/MetadataStorage.d.ts +30 -0
  26. package/dist/metadata/MetadataStorage.js +82 -0
  27. package/dist/metadata/types.d.ts +7 -0
  28. package/dist/metadata/types.js +2 -0
  29. package/dist/query/QueryBuilder.d.ts +64 -0
  30. package/dist/query/QueryBuilder.js +180 -0
  31. package/dist/repository/Repository.d.ts +43 -0
  32. package/dist/repository/Repository.js +156 -0
  33. package/dist/utils/entityMapper.d.ts +9 -0
  34. package/dist/utils/entityMapper.js +22 -0
  35. package/package.json +72 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Adubiagbe Mustapha
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,482 @@
1
+ # Accio 🪄
2
+
3
+ > The summoning charm for Postgres
4
+
5
+ Accio is a lightweight, type-safe TypeScript ORM for PostgreSQL, built from first principles with a focus on simplicity and developer experience.
6
+
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ ## Features
11
+
12
+ - ✨ **Decorator-based** entity definitions
13
+ - 🔒 **Type-safe** queries with TypeScript
14
+ - 🎯 **Simple and intuitive** API
15
+ - 🔗 **Fluent query builder** with method chaining
16
+ - 📦 **Zero dependencies** (except pg and reflect-metadata)
17
+ - 🎨 **Data Mapper pattern** for clean architecture
18
+ - 🚀 **Connection pooling** built-in
19
+ - 💪 **Full CRUD operations** out of the box
20
+
21
+ ## Installation
22
+
23
+ 1. Install the package
24
+
25
+ ```bash
26
+ npm install accio-orm
27
+ ```
28
+
29
+ 2. Install `pg` (postgres driver)
30
+
31
+ ```bash
32
+ npm install pg
33
+ ```
34
+
35
+ 3. Install `reflect-metadata`
36
+
37
+ ```bash
38
+ npm install reflect-metadata
39
+ ```
40
+
41
+ ### Important: Import reflect-metadata
42
+
43
+ You **must** import `reflect-metadata` once at your application's entry point (before any Accio code runs):
44
+
45
+ ```typescript
46
+ // src/index.ts or src/main.ts
47
+ import 'reflect-metadata';
48
+
49
+ // Now you can use Accio
50
+ import { connect, Table, Column, PrimaryColumn } from 'accio-orm';
51
+ ```
52
+
53
+ **Why?** TypeScript decorators require `reflect-metadata` to be loaded globally before any decorator-decorated classes are loaded. This enables Accio to read metadata from your `@Table` and `@Column` decorators.
54
+
55
+ **Note:** `pg` (^8.0.0) and `reflect-metadata` (^0.2.2) are peer dependencies and must be installed separately.
56
+
57
+ ### Prerequisites
58
+
59
+ - Node.js 16+
60
+ - PostgreSQL 12+
61
+ - TypeScript 5+
62
+
63
+ ## Quick Start
64
+
65
+ ### 1. Configure TypeScript
66
+
67
+ Add these to your `tsconfig.json`:
68
+
69
+ ```json
70
+ {
71
+ "compilerOptions": {
72
+ "experimentalDecorators": true,
73
+ "emitDecoratorMetadata": true
74
+ }
75
+ }
76
+ ```
77
+
78
+ ### 2. Define Your Entity
79
+
80
+ ```typescript
81
+ import 'reflect-metadata';
82
+ import { Table, Column, PrimaryColumn } from 'accio-orm';
83
+
84
+ @Table('users')
85
+ class User {
86
+ @PrimaryColumn()
87
+ id!: number;
88
+
89
+ @Column()
90
+ name!: string;
91
+
92
+ @Column()
93
+ age!: number;
94
+
95
+ @Column()
96
+ email!: string;
97
+ }
98
+ ```
99
+
100
+ ### 3. Connect to Database
101
+
102
+ ```typescript
103
+ import { connect } from 'accio-orm';
104
+
105
+ const db = connect({
106
+ host: 'localhost',
107
+ port: 5432,
108
+ database: 'mydb',
109
+ user: 'postgres',
110
+ password: 'password'
111
+ });
112
+ ```
113
+
114
+ ### 4. Use the Repository
115
+
116
+ ```typescript
117
+ const userRepo = db.getRepository(User);
118
+
119
+ // Create
120
+ const user = new User();
121
+ user.name = 'Alice';
122
+ user.age = 25;
123
+ user.email = 'alice@example.com';
124
+ await userRepo.save(user);
125
+
126
+ // Read
127
+ const foundUser = await userRepo.findById(1);
128
+ const allUsers = await userRepo.findAll();
129
+
130
+ // Update
131
+ foundUser.age = 26;
132
+ await userRepo.save(foundUser);
133
+
134
+ // Delete
135
+ await userRepo.delete(foundUser);
136
+ ```
137
+
138
+ ## API Documentation
139
+
140
+ ### Decorators
141
+
142
+ #### `@Table(tableName: string)`
143
+
144
+ Marks a class as a database entity.
145
+
146
+ ```typescript
147
+ @Table('users')
148
+ class User {
149
+ // ...
150
+ }
151
+ ```
152
+
153
+ #### `@PrimaryColumn()`
154
+
155
+ Marks a property as the primary key column.
156
+
157
+ ```typescript
158
+ @PrimaryColumn()
159
+ id!: number;
160
+ ```
161
+
162
+ #### `@Column(options?)`
163
+
164
+ Marks a property as a database column.
165
+
166
+ **Options:**
167
+
168
+ - `name?: string` - Custom column name (default: property name)
169
+ - `nullable?: boolean` - Whether the column can be null (default: true)
170
+ - `type?: string` - Database type hint (optional)
171
+
172
+ ```typescript
173
+ @Column()
174
+ name!: string;
175
+
176
+ @Column({ name: 'user_email', nullable: false })
177
+ email!: string;
178
+ ```
179
+
180
+ ### Connection
181
+
182
+ #### `connect(config: ConnectionConfig): Connection`
183
+
184
+ Creates a connection to the database.
185
+
186
+ ```typescript
187
+ const db = connect({
188
+ host: 'localhost',
189
+ port: 5432,
190
+ database: 'mydb',
191
+ user: 'postgres',
192
+ password: 'password',
193
+ max: 10 // optional: max connections in pool
194
+ });
195
+ ```
196
+
197
+ #### `connection.getRepository<T>(entityClass): Repository<T>`
198
+
199
+ Gets a repository for an entity.
200
+
201
+ ```typescript
202
+ const userRepo = db.getRepository(User);
203
+ ```
204
+
205
+ #### `connection.close(): Promise<void>`
206
+
207
+ Closes all database connections.
208
+
209
+ ```typescript
210
+ await db.close();
211
+ ```
212
+
213
+ ### Repository
214
+
215
+ #### Basic Operations
216
+
217
+ **`findById(id): Promise<T | null>`**
218
+
219
+ Find an entity by its primary key.
220
+
221
+ ```typescript
222
+ const user = await userRepo.findById(1);
223
+ ```
224
+
225
+ **`findAll(): Promise<T[]>`**
226
+
227
+ Find all entities.
228
+
229
+ ```typescript
230
+ const users = await userRepo.findAll();
231
+ ```
232
+
233
+ **`save(entity): Promise<T>`**
234
+
235
+ Insert or update an entity (smart save).
236
+
237
+ ```typescript
238
+ const user = new User();
239
+ user.name = 'Bob';
240
+ await userRepo.save(user); // Insert
241
+
242
+ user.age = 30;
243
+ await userRepo.save(user); // Update
244
+ ```
245
+
246
+ **`insert(entity): Promise<T>`**
247
+
248
+ Explicitly insert a new entity.
249
+
250
+ ```typescript
251
+ await userRepo.insert(user);
252
+ ```
253
+
254
+ **`update(entity): Promise<T>`**
255
+
256
+ Explicitly update an existing entity.
257
+
258
+ ```typescript
259
+ await userRepo.update(user);
260
+ ```
261
+
262
+ **`delete(entity): Promise<void>`**
263
+
264
+ Delete an entity.
265
+
266
+ ```typescript
267
+ await userRepo.delete(user);
268
+ ```
269
+
270
+ **`deleteById(id): Promise<void>`**
271
+
272
+ Delete by primary key.
273
+
274
+ ```typescript
275
+ await userRepo.deleteById(1);
276
+ ```
277
+
278
+ **`count(): Promise<number>`**
279
+
280
+ Count all entities.
281
+
282
+ ```typescript
283
+ const total = await userRepo.count();
284
+ ```
285
+
286
+ **`exists(id): Promise<boolean>`**
287
+
288
+ Check if an entity exists by ID.
289
+
290
+ ```typescript
291
+ const exists = await userRepo.exists(1);
292
+ ```
293
+
294
+ ### Query Builder
295
+
296
+ #### `where(conditions): QueryBuilder<T>`
297
+
298
+ Add WHERE conditions (can be chained, combined with AND).
299
+
300
+ ```typescript
301
+ // Single condition
302
+ const users = await userRepo.where({ age: 25 }).find();
303
+
304
+ // Multiple properties (AND)
305
+ const users = await userRepo.where({ age: 25, city: 'NYC' }).find();
306
+
307
+ // Chain multiple where() calls (AND)
308
+ const users = await userRepo.where({ age: 25 }).where({ city: 'NYC' }).find();
309
+
310
+ // Array values (IN clause)
311
+ const users = await userRepo.where({ age: [25, 30, 35] }).find();
312
+
313
+ // NULL values
314
+ const users = await userRepo.where({ middleName: null }).find();
315
+ ```
316
+
317
+ #### `orderBy(column, direction?): QueryBuilder<T>`
318
+
319
+ Order results by a column.
320
+
321
+ ```typescript
322
+ const users = await userRepo.where({ age: 25 }).orderBy('name', 'ASC').find();
323
+
324
+ // DESC order
325
+ const users = await userRepo.orderBy('age', 'DESC').find();
326
+ ```
327
+
328
+ #### `limit(n): QueryBuilder<T>`
329
+
330
+ Limit the number of results.
331
+
332
+ ```typescript
333
+ const users = await userRepo.where({ age: 25 }).limit(10).find();
334
+ ```
335
+
336
+ #### `offset(n): QueryBuilder<T>`
337
+
338
+ Skip the first N results (for pagination).
339
+
340
+ ```typescript
341
+ const users = await userRepo.where({ age: 25 }).offset(20).limit(10).find();
342
+ ```
343
+
344
+ #### Terminal Operations
345
+
346
+ **`find(): Promise<T[]>`**
347
+
348
+ Execute the query and return all results.
349
+
350
+ ```typescript
351
+ const users = await userRepo.where({ age: 25 }).find();
352
+ ```
353
+
354
+ **`findOne(): Promise<T | null>`**
355
+
356
+ Execute the query and return the first result.
357
+
358
+ ```typescript
359
+ const user = await userRepo.where({ email: 'alice@example.com' }).findOne();
360
+ ```
361
+
362
+ **`count(): Promise<number>`**
363
+
364
+ Count matching results.
365
+
366
+ ```typescript
367
+ const count = await userRepo.where({ age: 25 }).count();
368
+ ```
369
+
370
+ **`exists(): Promise<boolean>`**
371
+
372
+ Check if any results exist.
373
+
374
+ ```typescript
375
+ const exists = await userRepo.where({ email: 'alice@example.com' }).exists();
376
+ ```
377
+
378
+ **`toSQL(): { sql: string; params: unknown[] }`**
379
+
380
+ Get the SQL that would be executed (for debugging).
381
+
382
+ ```typescript
383
+ const { sql, params } = userRepo.where({ age: 25 }).toSQL();
384
+ console.log(sql); // SELECT * FROM users WHERE age = $1
385
+ console.log(params); // [25]
386
+ ```
387
+
388
+ ## Examples
389
+
390
+ ### Pagination
391
+
392
+ ```typescript
393
+ const page = 1;
394
+ const pageSize = 10;
395
+
396
+ const users = await userRepo
397
+ .orderBy('name', 'ASC')
398
+ .offset((page - 1) * pageSize)
399
+ .limit(pageSize)
400
+ .find();
401
+
402
+ const total = await userRepo.count();
403
+ const totalPages = Math.ceil(total / pageSize);
404
+ ```
405
+
406
+ ### Search
407
+
408
+ ```typescript
409
+ const results = await userRepo
410
+ .where({ city: 'NYC' })
411
+ .orderBy('age', 'DESC')
412
+ .limit(20)
413
+ .find();
414
+ ```
415
+
416
+ ### Complex Queries
417
+
418
+ ```typescript
419
+ const users = await userRepo
420
+ .where({ age: [25, 30, 35] })
421
+ .where({ city: 'NYC' })
422
+ .orderBy('name', 'ASC')
423
+ .limit(10)
424
+ .find();
425
+ ```
426
+
427
+ ## Database Setup
428
+
429
+ Create your tables manually (Accio is schema-agnostic):
430
+
431
+ ```sql
432
+ CREATE TABLE users (
433
+ id SERIAL PRIMARY KEY,
434
+ name TEXT NOT NULL,
435
+ age INTEGER NOT NULL,
436
+ email TEXT NOT NULL UNIQUE
437
+ );
438
+ ```
439
+
440
+ ## Design Philosophy
441
+
442
+ Accio follows the **Data Mapper pattern**, keeping your domain models clean and separate from persistence logic. This means:
443
+
444
+ - 📦 **Entities are just classes** - no methods for database operations
445
+ - 🔧 **Repositories handle persistence** - clear separation of concerns
446
+ - 🎯 **Type-safe queries** - TypeScript catches errors at compile time
447
+ - 🪶 **Lightweight** - minimal abstractions, close to SQL
448
+
449
+ ## Roadmap
450
+
451
+ - [ ] Relationships (one-to-many, many-to-many)
452
+ - [ ] Transactions support
453
+ - [ ] Advanced query operators (LIKE, >, <, !=, OR)
454
+ - [ ] Schema migrations
455
+ - [ ] Lifecycle hooks (beforeInsert, afterUpdate)
456
+ - [ ] Validation decorators
457
+ - [ ] Query result caching
458
+ - [ ] Soft deletes
459
+ - [ ] Automatic timestamps (createdAt, updatedAt)
460
+
461
+ ## Contributing
462
+
463
+ Contributions are welcome! This is a learning project, so feel free to:
464
+
465
+ - Report bugs
466
+ - Suggest features
467
+ - Submit pull requests
468
+ - Improve documentation
469
+
470
+ ## License
471
+
472
+ MIT
473
+
474
+ ## Acknowledgments
475
+
476
+ Built as a learning project to understand ORM internals, design patterns, and TypeScript decorators.
477
+
478
+ Inspired by TypeORM, Prisma, and other great ORMs in the ecosystem.
479
+
480
+ ---
481
+
482
+ **Accio!** âš¡ Summon your data with ease.
@@ -0,0 +1,29 @@
1
+ import { type QueryResult } from 'pg';
2
+ import { Repository } from '../repository/Repository';
3
+ import type { ConnectionConfig } from './types';
4
+ export declare class Connection {
5
+ private pool;
6
+ constructor(config: ConnectionConfig);
7
+ /**
8
+ * Get a repository for an entity class
9
+ * @param entityClass
10
+ * @returns
11
+ */
12
+ getRepository<T>(entityClass: new () => T): Repository<T>;
13
+ /**
14
+ * Execute a raw SQL query
15
+ */
16
+ query(sql: string, params?: any[]): Promise<QueryResult>;
17
+ /**
18
+ * Close all connections in the pool
19
+ */
20
+ close(): Promise<void>;
21
+ /**
22
+ * Test the connection
23
+ */
24
+ testConnection(): Promise<boolean>;
25
+ }
26
+ /**
27
+ * Factory function to create a connection
28
+ */
29
+ export declare function connect(config: ConnectionConfig): Connection;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Connection = void 0;
4
+ exports.connect = connect;
5
+ const pg_1 = require("pg");
6
+ const Repository_1 = require("../repository/Repository");
7
+ class Connection {
8
+ constructor(config) {
9
+ this.pool = new pg_1.Pool({
10
+ host: config.host,
11
+ port: config.port ?? 5432,
12
+ database: config.database,
13
+ user: config.user,
14
+ password: config.password
15
+ });
16
+ }
17
+ /**
18
+ * Get a repository for an entity class
19
+ * @param entityClass
20
+ * @returns
21
+ */
22
+ getRepository(entityClass) {
23
+ return new Repository_1.Repository(entityClass, this);
24
+ }
25
+ /**
26
+ * Execute a raw SQL query
27
+ */
28
+ async query(sql, params) {
29
+ try {
30
+ return await this.pool.query(sql, params);
31
+ }
32
+ catch (error) {
33
+ // re-throw with context
34
+ throw new Error(`Query failed: ${sql}\nError: ${error instanceof Error ? error.message : String(error)}`);
35
+ }
36
+ }
37
+ /**
38
+ * Close all connections in the pool
39
+ */
40
+ async close() {
41
+ await this.pool.end();
42
+ }
43
+ /**
44
+ * Test the connection
45
+ */
46
+ async testConnection() {
47
+ try {
48
+ await this.pool.query('SELECT 1');
49
+ return true;
50
+ }
51
+ catch (error) {
52
+ console.log('Connection test failed:', error);
53
+ return false;
54
+ }
55
+ }
56
+ }
57
+ exports.Connection = Connection;
58
+ /**
59
+ * Factory function to create a connection
60
+ */
61
+ function connect(config) {
62
+ return new Connection(config);
63
+ }
@@ -0,0 +1,7 @@
1
+ export interface ConnectionConfig {
2
+ host: string;
3
+ port?: number;
4
+ database: string;
5
+ user: string;
6
+ password: string;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,23 @@
1
+ import 'reflect-metadata';
2
+ export declare const COLUMNS_KEY: unique symbol;
3
+ export interface ColumnOptions {
4
+ name?: string;
5
+ type?: string;
6
+ nullable?: boolean;
7
+ }
8
+ export interface ColumnMetadata {
9
+ propertyKey: string;
10
+ columnName: string;
11
+ type?: string;
12
+ isNullable?: boolean;
13
+ isPrimary: boolean;
14
+ }
15
+ /**
16
+ * Decorator to mark a property as a database column
17
+ */
18
+ export declare function Column(options?: ColumnOptions): (target: object, // The prototype
19
+ propertyKey: string | symbol) => void;
20
+ /**
21
+ * helper to retrieve all columns from a class
22
+ */
23
+ export declare function getColumns(target: new (...args: unknown[]) => object): ColumnMetadata[];
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.COLUMNS_KEY = void 0;
4
+ exports.Column = Column;
5
+ exports.getColumns = getColumns;
6
+ require("reflect-metadata");
7
+ exports.COLUMNS_KEY = Symbol('table:columns');
8
+ /**
9
+ * Decorator to mark a property as a database column
10
+ */
11
+ function Column(options = {}) {
12
+ return function (target, // The prototype
13
+ propertyKey // The property name
14
+ ) {
15
+ // target is the prototype, target.constructor is the class
16
+ const constructor = target.constructor;
17
+ const columns = Reflect.getMetadata(exports.COLUMNS_KEY, constructor) ?? [];
18
+ const key = typeof propertyKey === 'symbol' ? propertyKey.toString() : propertyKey;
19
+ columns.push({
20
+ propertyKey: key,
21
+ columnName: options.name ?? key,
22
+ type: options.type,
23
+ isNullable: options.nullable ?? true,
24
+ isPrimary: false
25
+ });
26
+ Reflect.defineMetadata(exports.COLUMNS_KEY, columns, constructor);
27
+ };
28
+ }
29
+ /**
30
+ * helper to retrieve all columns from a class
31
+ */
32
+ function getColumns(target) {
33
+ return (Reflect.getMetadata(exports.COLUMNS_KEY, target) ?? []);
34
+ }
@@ -0,0 +1,9 @@
1
+ import 'reflect-metadata';
2
+ /**
3
+ * Decorator to mark a property as the primary key column
4
+ *
5
+ * Example:
6
+ * @PrimaryColumn
7
+ * id: number
8
+ */
9
+ export declare function PrimaryColumn(): (target: object, propertyKey: string | symbol) => void;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PrimaryColumn = PrimaryColumn;
4
+ require("reflect-metadata");
5
+ const Column_1 = require("./Column");
6
+ /**
7
+ * Decorator to mark a property as the primary key column
8
+ *
9
+ * Example:
10
+ * @PrimaryColumn
11
+ * id: number
12
+ */
13
+ function PrimaryColumn() {
14
+ return function (target, propertyKey) {
15
+ const constructor = target.constructor;
16
+ const columns = Reflect.getMetadata(Column_1.COLUMNS_KEY, constructor) ?? [];
17
+ const key = typeof propertyKey === 'symbol' ? propertyKey.toString() : propertyKey;
18
+ columns.push({
19
+ propertyKey: key,
20
+ columnName: key,
21
+ isPrimary: true,
22
+ isNullable: false
23
+ });
24
+ Reflect.defineMetadata(Column_1.COLUMNS_KEY, columns, constructor);
25
+ };
26
+ }
@@ -0,0 +1,10 @@
1
+ import 'reflect-metadata';
2
+ /**
3
+ * Decorator to mark a class as a database table
4
+ * @param tableName - The name of the database table
5
+ */
6
+ export declare function Table(tableName: string): <T extends new (...args: unknown[]) => object>(target: T) => void;
7
+ /**
8
+ * helper to retrieve the table name from a class
9
+ */
10
+ export declare function getTableName(target: new (...args: unknown[]) => object): string | undefined;