ilana-orm 1.0.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.
- package/README.md +4763 -0
- package/cli/ilana.js +928 -0
- package/database/DB.js +85 -0
- package/database/connection.js +114 -0
- package/database/schema-builder.js +219 -0
- package/ilana.config.js +61 -0
- package/ilana.png +0 -0
- package/index.js +34 -0
- package/orm/Collection.js +283 -0
- package/orm/CustomCasts.js +75 -0
- package/orm/Factory.js +372 -0
- package/orm/MigrationRunner.js +458 -0
- package/orm/Model.js +607 -0
- package/orm/ModelRegistry.js +26 -0
- package/orm/QueryBuilder.js +680 -0
- package/orm/Relation.js +299 -0
- package/orm/Seeder.js +153 -0
- package/package.json +71 -0
- package/test-role.js +26 -0
package/database/DB.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
const Database = require('./connection');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Laravel-style DB facade for IlanaORM
|
|
5
|
+
*/
|
|
6
|
+
class DB {
|
|
7
|
+
/**
|
|
8
|
+
* Execute a database transaction with automatic retry for deadlocks
|
|
9
|
+
* @param {Function} callback - Transaction callback function
|
|
10
|
+
* @param {number} attempts - Number of retry attempts (default: 1)
|
|
11
|
+
* @param {string} connection - Connection name (optional)
|
|
12
|
+
* @returns {Promise<any>}
|
|
13
|
+
*/
|
|
14
|
+
static async transaction(callback, attempts = 1, connection = null) {
|
|
15
|
+
return Database.transaction(callback, attempts, connection);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Begin a database transaction manually
|
|
20
|
+
* @param {string} connection - Connection name (optional)
|
|
21
|
+
* @returns {Promise<Transaction>}
|
|
22
|
+
*/
|
|
23
|
+
static async beginTransaction(connection = null) {
|
|
24
|
+
return Database.beginTransaction(connection);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Commit a transaction
|
|
29
|
+
* @param {Transaction} trx - Transaction object
|
|
30
|
+
* @returns {Promise<void>}
|
|
31
|
+
*/
|
|
32
|
+
static async commit(trx) {
|
|
33
|
+
return Database.commit(trx);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Rollback a transaction
|
|
38
|
+
* @param {Transaction} trx - Transaction object
|
|
39
|
+
* @returns {Promise<void>}
|
|
40
|
+
*/
|
|
41
|
+
static async rollback(trx) {
|
|
42
|
+
return Database.rollback(trx);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get a query builder for a table
|
|
47
|
+
* @param {string} table - Table name
|
|
48
|
+
* @param {string} connection - Connection name (optional)
|
|
49
|
+
* @returns {QueryBuilder}
|
|
50
|
+
*/
|
|
51
|
+
static table(table, connection = null) {
|
|
52
|
+
return Database.table(table, connection);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Execute a raw SQL query
|
|
57
|
+
* @param {string} sql - SQL query
|
|
58
|
+
* @param {Array} bindings - Query bindings
|
|
59
|
+
* @param {string} connection - Connection name (optional)
|
|
60
|
+
* @returns {Promise<any>}
|
|
61
|
+
*/
|
|
62
|
+
static raw(sql, bindings = [], connection = null) {
|
|
63
|
+
const db = connection ? Database.connection(connection) : Database.getInstance();
|
|
64
|
+
return db.raw(sql, bindings);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get a database connection
|
|
69
|
+
* @param {string} name - Connection name (optional)
|
|
70
|
+
* @returns {Connection}
|
|
71
|
+
*/
|
|
72
|
+
static connection(name = null) {
|
|
73
|
+
return Database.connection(name);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Get the default connection name
|
|
78
|
+
* @returns {string}
|
|
79
|
+
*/
|
|
80
|
+
static getDefaultConnection() {
|
|
81
|
+
return Database.getDefaultConnection();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = DB;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const knex = require('knex');
|
|
2
|
+
|
|
3
|
+
class Database {
|
|
4
|
+
static connections = new Map();
|
|
5
|
+
static _currentTransaction = null;
|
|
6
|
+
|
|
7
|
+
static configure(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.defaultConnection = config.default;
|
|
10
|
+
|
|
11
|
+
// Initialize all configured connections
|
|
12
|
+
for (const [name, connConfig] of Object.entries(config.connections)) {
|
|
13
|
+
const connection = knex({
|
|
14
|
+
...connConfig,
|
|
15
|
+
migrations: config.migrations || {
|
|
16
|
+
directory: './migrations',
|
|
17
|
+
tableName: 'migrations'
|
|
18
|
+
},
|
|
19
|
+
seeds: config.seeds || {
|
|
20
|
+
directory: './seeds'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
this.connections.set(name, connection);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Set default instance after all connections are created
|
|
27
|
+
if (this.connections.has(this.defaultConnection)) {
|
|
28
|
+
this.instance = this.connections.get(this.defaultConnection);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!this.instance) {
|
|
32
|
+
throw new Error(`Default connection '${this.defaultConnection}' not found in connections config.`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static connection(name) {
|
|
37
|
+
if (!name) return this.getInstance();
|
|
38
|
+
const conn = this.connections.get(name);
|
|
39
|
+
if (!conn) {
|
|
40
|
+
throw new Error(`Database connection '${name}' not configured.`);
|
|
41
|
+
}
|
|
42
|
+
return conn;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static getDefaultConnection() {
|
|
46
|
+
return this.defaultConnection;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static hasConnection(name) {
|
|
50
|
+
return this.connections.has(name);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static getInstance() {
|
|
54
|
+
if (!this.instance) {
|
|
55
|
+
throw new Error('Database not configured. Call Database.configure() first.');
|
|
56
|
+
}
|
|
57
|
+
return this.instance;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static async transaction(callback, attempts = 1, connection) {
|
|
61
|
+
const db = this.connection(connection);
|
|
62
|
+
|
|
63
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
64
|
+
try {
|
|
65
|
+
return await db.transaction(async (trx) => {
|
|
66
|
+
// Set current transaction for models to use
|
|
67
|
+
this._currentTransaction = trx;
|
|
68
|
+
try {
|
|
69
|
+
const result = await callback(trx);
|
|
70
|
+
return result;
|
|
71
|
+
} finally {
|
|
72
|
+
this._currentTransaction = null;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (attempt === attempts) throw error;
|
|
77
|
+
// Wait before retry for deadlock scenarios
|
|
78
|
+
await new Promise(resolve => setTimeout(resolve, 100 * attempt));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static async beginTransaction(connection) {
|
|
84
|
+
const db = this.connection(connection);
|
|
85
|
+
const trx = await db.transaction();
|
|
86
|
+
return {
|
|
87
|
+
...trx,
|
|
88
|
+
commit: () => trx.commit(),
|
|
89
|
+
rollback: () => trx.rollback()
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static commit(trx) {
|
|
94
|
+
return trx.commit();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static rollback(trx) {
|
|
98
|
+
return trx.rollback();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
static getCurrentTransaction() {
|
|
102
|
+
return this._currentTransaction;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static table(tableName, connectionName) {
|
|
106
|
+
return this.connection(connectionName)(tableName);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static raw(sql, bindings) {
|
|
110
|
+
return this.getInstance().raw(sql, bindings);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = Database;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
const Database = require('./connection');
|
|
2
|
+
|
|
3
|
+
class SchemaBuilder {
|
|
4
|
+
constructor(connection) {
|
|
5
|
+
this.knex = Database.connection(connection);
|
|
6
|
+
this.currentTable = '';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
createTable(tableName, callback) {
|
|
10
|
+
return this.knex.schema.createTable(tableName, callback);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
dropTable(tableName) {
|
|
14
|
+
return this.knex.schema.dropTable(tableName);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
dropTableIfExists(tableName) {
|
|
18
|
+
return this.knex.schema.dropTableIfExists(tableName);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
renameTable(from, to) {
|
|
22
|
+
return this.knex.schema.renameTable(from, to);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
hasTable(tableName) {
|
|
26
|
+
return this.knex.schema.hasTable(tableName);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
hasColumn(tableName, columnName) {
|
|
30
|
+
return this.knex.schema.hasColumn(tableName, columnName);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
table(tableName, callback) {
|
|
34
|
+
return this.knex.schema.table(tableName, callback);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
alterTable(tableName, callback) {
|
|
38
|
+
return this.knex.schema.alterTable(tableName, callback);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
raw(statement) {
|
|
42
|
+
return this.knex.raw(statement);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// PostgreSQL specific
|
|
46
|
+
createSchema(schemaName) {
|
|
47
|
+
return this.knex.schema.createSchema(schemaName);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dropSchema(schemaName) {
|
|
51
|
+
return this.knex.schema.dropSchema(schemaName);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Advanced column types
|
|
55
|
+
jsonb(columnName) {
|
|
56
|
+
if (this.knex.client.config.client === 'pg') {
|
|
57
|
+
return this.knex.schema.jsonb ? this.knex.schema.jsonb(columnName) : this.knex.schema.json(columnName);
|
|
58
|
+
}
|
|
59
|
+
return this.knex.schema.json(columnName);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
geometry(columnName, geometryType) {
|
|
63
|
+
return this.knex.schema.specificType(columnName, geometryType || 'geometry');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
point(columnName) {
|
|
67
|
+
return this.knex.schema.specificType(columnName, 'point');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
lineString(columnName) {
|
|
71
|
+
return this.knex.schema.specificType(columnName, 'linestring');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
polygon(columnName) {
|
|
75
|
+
return this.knex.schema.specificType(columnName, 'polygon');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
inet(columnName) {
|
|
79
|
+
return this.knex.schema.specificType(columnName, 'inet');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
macaddr(columnName) {
|
|
83
|
+
return this.knex.schema.specificType(columnName, 'macaddr');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
specificType(columnName, type) {
|
|
87
|
+
return this.knex.schema.specificType(columnName, type);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Enhanced column modifiers with database-specific implementations
|
|
91
|
+
after(columnName) {
|
|
92
|
+
if (this.knex.client.config.client === 'mysql2') {
|
|
93
|
+
return this.knex.schema.raw(`AFTER ${columnName}`);
|
|
94
|
+
}
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
first() {
|
|
99
|
+
if (this.knex.client.config.client === 'mysql2') {
|
|
100
|
+
return this.knex.schema.raw('FIRST');
|
|
101
|
+
}
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
checkPositive(column) {
|
|
106
|
+
const client = this.knex.client.config.client;
|
|
107
|
+
if (client === 'pg') {
|
|
108
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD CONSTRAINT ${column}_positive CHECK (${column} > 0)`);
|
|
109
|
+
} else if (client === 'mysql2') {
|
|
110
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD CONSTRAINT ${column}_positive CHECK (${column} > 0)`);
|
|
111
|
+
}
|
|
112
|
+
return Promise.resolve();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
checkRegex(column, pattern) {
|
|
116
|
+
const client = this.knex.client.config.client;
|
|
117
|
+
if (client === 'pg') {
|
|
118
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD CONSTRAINT ${column}_regex CHECK (${column} ~ '${pattern}')`);
|
|
119
|
+
} else if (client === 'mysql2') {
|
|
120
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD CONSTRAINT ${column}_regex CHECK (${column} REGEXP '${pattern}')`);
|
|
121
|
+
}
|
|
122
|
+
return Promise.resolve();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
generatedAs(column, expression) {
|
|
126
|
+
const client = this.knex.client.config.client;
|
|
127
|
+
if (client === 'mysql2') {
|
|
128
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD ${column} VARCHAR(255) GENERATED ALWAYS AS (${expression}) STORED`);
|
|
129
|
+
} else if (client === 'pg') {
|
|
130
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD ${column} TEXT GENERATED ALWAYS AS (${expression}) STORED`);
|
|
131
|
+
}
|
|
132
|
+
return Promise.resolve();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
collate(tableName, collation) {
|
|
136
|
+
const client = this.knex.client.config.client;
|
|
137
|
+
if (client === 'mysql2') {
|
|
138
|
+
return this.knex.raw(`ALTER TABLE ${tableName} COLLATE ${collation}`);
|
|
139
|
+
} else if (client === 'pg') {
|
|
140
|
+
return this.knex.raw(`ALTER TABLE ${tableName} ALTER COLUMN name TYPE TEXT COLLATE "${collation}"`);
|
|
141
|
+
}
|
|
142
|
+
return Promise.resolve();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Enhanced PostgreSQL types
|
|
146
|
+
array(columnName, type = 'text') {
|
|
147
|
+
if (this.knex.client.config.client === 'pg') {
|
|
148
|
+
return this.knex.schema.specificType(columnName, `${type}[]`);
|
|
149
|
+
}
|
|
150
|
+
return this.knex.schema.json(columnName);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
numrange(columnName) {
|
|
154
|
+
return this.knex.schema.specificType(columnName, 'numrange');
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
daterange(columnName) {
|
|
158
|
+
return this.knex.schema.specificType(columnName, 'daterange');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
tsvector(columnName) {
|
|
162
|
+
return this.knex.schema.specificType(columnName, 'tsvector');
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Enhanced MySQL types
|
|
166
|
+
fulltext(columns, indexName) {
|
|
167
|
+
if (this.knex.client.config.client === 'mysql2') {
|
|
168
|
+
const name = indexName || `${columns.join('_')}_fulltext`;
|
|
169
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD FULLTEXT INDEX ${name} (${columns.join(', ')})`);
|
|
170
|
+
}
|
|
171
|
+
return Promise.resolve();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
spatial(column, indexName) {
|
|
175
|
+
if (this.knex.client.config.client === 'mysql2') {
|
|
176
|
+
const name = indexName || `${column}_spatial`;
|
|
177
|
+
return this.knex.raw(`ALTER TABLE ${this.currentTable} ADD SPATIAL INDEX ${name} (${column})`);
|
|
178
|
+
}
|
|
179
|
+
return Promise.resolve();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
setCurrentTable(tableName) {
|
|
183
|
+
this.currentTable = tableName;
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Enhanced utility methods
|
|
188
|
+
get client() {
|
|
189
|
+
return this.knex.client;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
get fn() {
|
|
193
|
+
return this.knex.fn;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Database-specific utilities
|
|
197
|
+
enableExtension(name) {
|
|
198
|
+
if (this.knex.client.config.client === 'pg') {
|
|
199
|
+
return this.knex.raw(`CREATE EXTENSION IF NOT EXISTS "${name}"`);
|
|
200
|
+
}
|
|
201
|
+
return Promise.resolve();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
createEnum(name, values) {
|
|
205
|
+
if (this.knex.client.config.client === 'pg') {
|
|
206
|
+
return this.knex.raw(`CREATE TYPE ${name} AS ENUM (${values.map(v => `'${v}'`).join(', ')})`);
|
|
207
|
+
}
|
|
208
|
+
return Promise.resolve();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
dropEnum(name) {
|
|
212
|
+
if (this.knex.client.config.client === 'pg') {
|
|
213
|
+
return this.knex.raw(`DROP TYPE IF EXISTS ${name}`);
|
|
214
|
+
}
|
|
215
|
+
return Promise.resolve();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = SchemaBuilder;
|
package/ilana.config.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const Database = require('ilana/database/connection').default;
|
|
2
|
+
|
|
3
|
+
const config = {
|
|
4
|
+
default: 'sqlite',
|
|
5
|
+
|
|
6
|
+
connections: {
|
|
7
|
+
sqlite: {
|
|
8
|
+
client: 'sqlite3',
|
|
9
|
+
connection: {
|
|
10
|
+
filename: './database.sqlite'
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
// mysql: {
|
|
15
|
+
// client: 'mysql2',
|
|
16
|
+
// connection: {
|
|
17
|
+
// host: 'localhost',
|
|
18
|
+
// port: 3306,
|
|
19
|
+
// user: 'your_username',
|
|
20
|
+
// password: 'your_password',
|
|
21
|
+
// database: 'your_database'
|
|
22
|
+
// }
|
|
23
|
+
// },
|
|
24
|
+
|
|
25
|
+
// postgres: {
|
|
26
|
+
// client: 'pg',
|
|
27
|
+
// connection: {
|
|
28
|
+
// host: 'localhost',
|
|
29
|
+
// port: 5432,
|
|
30
|
+
// user: 'your_username',
|
|
31
|
+
// password: 'your_password',
|
|
32
|
+
// database: 'your_database'
|
|
33
|
+
// }
|
|
34
|
+
// },
|
|
35
|
+
|
|
36
|
+
// mysql_secondary: {
|
|
37
|
+
// client: 'mysql2',
|
|
38
|
+
// connection: {
|
|
39
|
+
// host: 'secondary.mysql.com',
|
|
40
|
+
// port: 3306,
|
|
41
|
+
// user: 'secondary_user',
|
|
42
|
+
// password: 'secondary_password',
|
|
43
|
+
// database: 'secondary_db'
|
|
44
|
+
// }
|
|
45
|
+
// }
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
migrations: {
|
|
49
|
+
directory: './migrations',
|
|
50
|
+
tableName: 'migrations'
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
seeds: {
|
|
54
|
+
directory: './seeds'
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Auto-initialize database connections
|
|
59
|
+
Database.configure(config);
|
|
60
|
+
|
|
61
|
+
module.exports = config;
|
package/ilana.png
ADDED
|
Binary file
|
package/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Main exports
|
|
2
|
+
const Model = require('./orm/Model');
|
|
3
|
+
const QueryBuilder = require('./orm/QueryBuilder');
|
|
4
|
+
const Collection = require('./orm/Collection');
|
|
5
|
+
const Database = require('./database/connection');
|
|
6
|
+
const DB = require('./database/DB');
|
|
7
|
+
const SchemaBuilder = require('./database/schema-builder');
|
|
8
|
+
const MigrationRunner = require('./orm/MigrationRunner');
|
|
9
|
+
const Seeder = require('./orm/Seeder');
|
|
10
|
+
const Factory = require('./orm/Factory');
|
|
11
|
+
const Relation = require('./orm/Relation');
|
|
12
|
+
const CustomCasts = require('./orm/CustomCasts');
|
|
13
|
+
|
|
14
|
+
module.exports = {
|
|
15
|
+
Model,
|
|
16
|
+
QueryBuilder,
|
|
17
|
+
Collection,
|
|
18
|
+
Database,
|
|
19
|
+
DB,
|
|
20
|
+
SchemaBuilder,
|
|
21
|
+
MigrationRunner,
|
|
22
|
+
Seeder,
|
|
23
|
+
Factory: Factory.Factory,
|
|
24
|
+
defineFactory: Factory.defineFactory,
|
|
25
|
+
|
|
26
|
+
// Relationships
|
|
27
|
+
...Relation,
|
|
28
|
+
|
|
29
|
+
// Custom Casts
|
|
30
|
+
...CustomCasts
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// Default export
|
|
34
|
+
module.exports.default = module.exports.Model;
|