ilana-orm 1.0.3 → 1.0.7
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 +21 -4
- package/cli/ilana.js +102 -19
- package/database/connection.d.ts +45 -0
- package/database/connection.mjs +7 -0
- package/example.config.mjs +44 -0
- package/index.d.ts +9 -0
- package/index.mjs +33 -0
- package/orm/Collection.d.ts +53 -0
- package/orm/Collection.mjs +7 -0
- package/orm/CustomCasts.d.ts +30 -0
- package/orm/Model.d.ts +160 -0
- package/orm/Model.js +21 -7
- package/orm/Model.mjs +7 -0
- package/orm/ModelRegistry.d.ts +11 -0
- package/orm/ModelRegistry.mjs +7 -0
- package/orm/QueryBuilder.d.ts +155 -0
- package/orm/QueryBuilder.mjs +7 -0
- package/orm/Relation.d.ts +99 -0
- package/orm/Relation.mjs +7 -0
- package/package.json +38 -1
package/README.md
CHANGED
|
@@ -150,10 +150,13 @@ touch ilana.config.js
|
|
|
150
150
|
|
|
151
151
|
### 2. Configure Database
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
**For CommonJS projects**, create `ilana.config.js` in your project root:
|
|
154
|
+
|
|
155
|
+
**For ES Module projects** (with `"type": "module"` in package.json), create `ilana.config.mjs`:
|
|
154
156
|
|
|
155
157
|
```javascript
|
|
156
|
-
|
|
158
|
+
// ilana.config.mjs
|
|
159
|
+
export default {
|
|
157
160
|
default: "sqlite",
|
|
158
161
|
|
|
159
162
|
connections: {
|
|
@@ -212,11 +215,18 @@ This creates:
|
|
|
212
215
|
|
|
213
216
|
### 4. Define the Model
|
|
214
217
|
|
|
215
|
-
**JavaScript:**
|
|
218
|
+
**JavaScript (CommonJS):**
|
|
216
219
|
|
|
217
220
|
```javascript
|
|
218
221
|
// models/User.js
|
|
219
222
|
const Model = require("ilana-orm/orm/Model");
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**JavaScript (ES Modules):**
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
// models/User.js
|
|
229
|
+
import Model from "ilana-orm/orm/Model";
|
|
220
230
|
|
|
221
231
|
class User extends Model {
|
|
222
232
|
static table = "users";
|
|
@@ -246,7 +256,8 @@ class User extends Model {
|
|
|
246
256
|
}
|
|
247
257
|
}
|
|
248
258
|
|
|
249
|
-
|
|
259
|
+
export default User; // For ES modules
|
|
260
|
+
// module.exports = User; // For CommonJS
|
|
250
261
|
```
|
|
251
262
|
|
|
252
263
|
**TypeScript (auto-generated when `tsconfig.json` detected):**
|
|
@@ -294,8 +305,14 @@ npx ilana migrate
|
|
|
294
305
|
|
|
295
306
|
### 6. Start Using the Model
|
|
296
307
|
|
|
308
|
+
**CommonJS:**
|
|
297
309
|
```javascript
|
|
298
310
|
const User = require("./models/User");
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**ES Modules:**
|
|
314
|
+
```javascript
|
|
315
|
+
import User from "./models/User.js";
|
|
299
316
|
|
|
300
317
|
// Create user
|
|
301
318
|
const user = await User.create({
|
package/cli/ilana.js
CHANGED
|
@@ -31,26 +31,39 @@ const defaultConfig = {
|
|
|
31
31
|
|
|
32
32
|
// Load configuration and auto-initialize
|
|
33
33
|
async function loadConfig() {
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
const configPathJs = path.join(process.cwd(), 'ilana.config.js');
|
|
35
|
+
const configPathMjs = path.join(process.cwd(), 'ilana.config.mjs');
|
|
36
|
+
|
|
37
|
+
// Try .mjs first (ES modules)
|
|
38
|
+
if (fs.existsSync(configPathMjs)) {
|
|
39
|
+
try {
|
|
40
|
+
const configModule = await import(configPathMjs);
|
|
41
|
+
const config = configModule.default || configModule;
|
|
42
|
+
return config;
|
|
43
|
+
} catch (error) {
|
|
44
|
+
console.error('Error loading ilana.config.mjs:', error.message);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Try .js (CommonJS)
|
|
50
|
+
if (fs.existsSync(configPathJs)) {
|
|
51
|
+
delete require.cache[configPathJs];
|
|
37
52
|
try {
|
|
38
|
-
const config = require(
|
|
39
|
-
// Config file already initializes database
|
|
53
|
+
const config = require(configPathJs);
|
|
40
54
|
return config;
|
|
41
55
|
} catch (error) {
|
|
42
56
|
if (error.code === 'ERR_REQUIRE_ESM') {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const config = configModule.default || configModule;
|
|
46
|
-
return config;
|
|
57
|
+
console.error('Found ilana.config.js but project uses ES modules. Rename to ilana.config.mjs');
|
|
58
|
+
process.exit(1);
|
|
47
59
|
} else {
|
|
48
60
|
throw error;
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
}
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
|
|
65
|
+
// No config file found
|
|
66
|
+
console.error('No ilana.config.js or ilana.config.mjs found. Run "npx ilana setup" first.');
|
|
54
67
|
process.exit(1);
|
|
55
68
|
}
|
|
56
69
|
|
|
@@ -130,9 +143,11 @@ function generateModel(name, options = {}) {
|
|
|
130
143
|
}
|
|
131
144
|
|
|
132
145
|
function getModelTemplate(className, tableName) {
|
|
146
|
+
const isESModule = isESModuleProject();
|
|
147
|
+
|
|
133
148
|
if (isTypeScriptProject()) {
|
|
134
|
-
return `import Model from 'ilana-orm/orm/Model
|
|
135
|
-
// import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts
|
|
149
|
+
return `import Model from 'ilana-orm/orm/Model';
|
|
150
|
+
// import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts';
|
|
136
151
|
|
|
137
152
|
export default class ${className} extends Model {
|
|
138
153
|
protected static table = '${tableName}';
|
|
@@ -175,6 +190,53 @@ export default class ${className} extends Model {
|
|
|
175
190
|
`;
|
|
176
191
|
}
|
|
177
192
|
|
|
193
|
+
if (isESModule) {
|
|
194
|
+
return `import Model from 'ilana-orm/orm/Model';
|
|
195
|
+
// import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts';
|
|
196
|
+
|
|
197
|
+
class ${className} extends Model {
|
|
198
|
+
static table = '${tableName}';
|
|
199
|
+
static timestamps = true;
|
|
200
|
+
static softDeletes = false;
|
|
201
|
+
|
|
202
|
+
// For UUID primary keys, uncomment:
|
|
203
|
+
// static keyType = 'string';
|
|
204
|
+
// static incrementing = false;
|
|
205
|
+
|
|
206
|
+
fillable = [];
|
|
207
|
+
hidden = [];
|
|
208
|
+
appends = [];
|
|
209
|
+
casts = {
|
|
210
|
+
// Basic casts
|
|
211
|
+
// is_active: 'boolean',
|
|
212
|
+
// metadata: 'json',
|
|
213
|
+
// tags: 'array',
|
|
214
|
+
|
|
215
|
+
// Custom casts
|
|
216
|
+
// price: new MoneyCast(),
|
|
217
|
+
// secret: new EncryptedCast('your-key'),
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// Define relationships here
|
|
221
|
+
// example() {
|
|
222
|
+
// return this.hasMany(RelatedModel, 'foreign_key');
|
|
223
|
+
// }
|
|
224
|
+
|
|
225
|
+
// Define scopes here
|
|
226
|
+
// static scopeActive(query) {
|
|
227
|
+
// query.where('is_active', true);
|
|
228
|
+
// }
|
|
229
|
+
|
|
230
|
+
// Register for polymorphic relationships
|
|
231
|
+
// static {
|
|
232
|
+
// this.register();
|
|
233
|
+
// }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export default ${className};
|
|
237
|
+
`;
|
|
238
|
+
}
|
|
239
|
+
|
|
178
240
|
return `const Model = require('ilana-orm/orm/Model');
|
|
179
241
|
// const { MoneyCast, EncryptedCast } = require('ilana-orm/orm/CustomCasts');
|
|
180
242
|
|
|
@@ -222,8 +284,10 @@ module.exports = ${className};
|
|
|
222
284
|
}
|
|
223
285
|
|
|
224
286
|
function getPivotModelTemplate(className, tableName) {
|
|
287
|
+
const isESModule = isESModuleProject();
|
|
288
|
+
|
|
225
289
|
if (isTypeScriptProject()) {
|
|
226
|
-
return `import Model from 'ilana-orm/orm/Model
|
|
290
|
+
return `import Model from 'ilana-orm/orm/Model';
|
|
227
291
|
|
|
228
292
|
export default class ${className} extends Model {
|
|
229
293
|
protected static table = '${tableName}';
|
|
@@ -236,6 +300,22 @@ export default class ${className} extends Model {
|
|
|
236
300
|
`;
|
|
237
301
|
}
|
|
238
302
|
|
|
303
|
+
if (isESModule) {
|
|
304
|
+
return `import Model from 'ilana-orm/orm/Model';
|
|
305
|
+
|
|
306
|
+
class ${className} extends Model {
|
|
307
|
+
static table = '${tableName}';
|
|
308
|
+
static timestamps = true;
|
|
309
|
+
|
|
310
|
+
fillable = [];
|
|
311
|
+
|
|
312
|
+
// Define pivot relationships here
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export default ${className};
|
|
316
|
+
`;
|
|
317
|
+
}
|
|
318
|
+
|
|
239
319
|
return `const Model = require('ilana-orm/orm/Model');
|
|
240
320
|
|
|
241
321
|
class ${className} extends Model {
|
|
@@ -350,10 +430,16 @@ const commands = {
|
|
|
350
430
|
}
|
|
351
431
|
|
|
352
432
|
// Create config file if it doesn't exist
|
|
353
|
-
const
|
|
433
|
+
const isESModule = isESModuleProject();
|
|
434
|
+
const configPath = isESModule ? 'ilana.config.mjs' : 'ilana.config.js';
|
|
435
|
+
|
|
354
436
|
if (!fs.existsSync(configPath)) {
|
|
355
|
-
const isESModule = isESModuleProject();
|
|
356
437
|
const configTemplate = isESModule ? getESModuleConfigTemplate() : getCommonJSConfigTemplate();
|
|
438
|
+
fs.writeFileSync(configPath, configTemplate);
|
|
439
|
+
console.log(`Created config file: ${configPath}`);
|
|
440
|
+
}
|
|
441
|
+
},
|
|
442
|
+
};
|
|
357
443
|
|
|
358
444
|
function getESModuleConfigTemplate() {
|
|
359
445
|
return `import 'dotenv/config';
|
|
@@ -470,9 +556,6 @@ Database.configure(config);
|
|
|
470
556
|
module.exports = config;
|
|
471
557
|
`;
|
|
472
558
|
}
|
|
473
|
-
fs.writeFileSync(configPath, configTemplate);
|
|
474
|
-
console.log(`Created config file: ${configPath}`);
|
|
475
|
-
}
|
|
476
559
|
|
|
477
560
|
// Create .env file if it doesn't exist
|
|
478
561
|
const envPath = '.env';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Knex } from 'knex';
|
|
2
|
+
|
|
3
|
+
export interface DatabaseConfig {
|
|
4
|
+
default: string;
|
|
5
|
+
connections: {
|
|
6
|
+
[name: string]: Knex.Config;
|
|
7
|
+
};
|
|
8
|
+
migrations?: {
|
|
9
|
+
directory?: string;
|
|
10
|
+
tableName?: string;
|
|
11
|
+
};
|
|
12
|
+
seeds?: {
|
|
13
|
+
directory?: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface Transaction extends Knex.Transaction {
|
|
18
|
+
commit(): Promise<void>;
|
|
19
|
+
rollback(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default class Database {
|
|
23
|
+
static connections: Map<string, Knex>;
|
|
24
|
+
static config: DatabaseConfig;
|
|
25
|
+
static defaultConnection: string;
|
|
26
|
+
static instance: Knex;
|
|
27
|
+
private static _currentTransaction: Knex.Transaction | null;
|
|
28
|
+
|
|
29
|
+
static configure(config: DatabaseConfig): void;
|
|
30
|
+
static connection(name?: string): Knex;
|
|
31
|
+
static getDefaultConnection(): string;
|
|
32
|
+
static hasConnection(name: string): boolean;
|
|
33
|
+
static getInstance(): Knex;
|
|
34
|
+
static transaction<T>(
|
|
35
|
+
callback: (trx: Knex.Transaction) => Promise<T>,
|
|
36
|
+
attempts?: number,
|
|
37
|
+
connection?: string
|
|
38
|
+
): Promise<T>;
|
|
39
|
+
static beginTransaction(connection?: string): Promise<Transaction>;
|
|
40
|
+
static commit(trx: Knex.Transaction): Promise<void>;
|
|
41
|
+
static rollback(trx: Knex.Transaction): Promise<void>;
|
|
42
|
+
static getCurrentTransaction(): Knex.Transaction | null;
|
|
43
|
+
static table(tableName: string, connectionName?: string): Knex.QueryBuilder;
|
|
44
|
+
static raw(sql: string, bindings?: any[]): Knex.Raw;
|
|
45
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// ilana.config.mjs - ES Module config example
|
|
2
|
+
export default {
|
|
3
|
+
default: "sqlite",
|
|
4
|
+
|
|
5
|
+
connections: {
|
|
6
|
+
sqlite: {
|
|
7
|
+
client: "sqlite3",
|
|
8
|
+
connection: {
|
|
9
|
+
filename: "./database.sqlite",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
mysql: {
|
|
14
|
+
client: "mysql2",
|
|
15
|
+
connection: {
|
|
16
|
+
host: "localhost",
|
|
17
|
+
port: 3306,
|
|
18
|
+
user: "your_username",
|
|
19
|
+
password: "your_password",
|
|
20
|
+
database: "your_database",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
postgres: {
|
|
25
|
+
client: "pg",
|
|
26
|
+
connection: {
|
|
27
|
+
host: "localhost",
|
|
28
|
+
port: 5432,
|
|
29
|
+
user: "your_username",
|
|
30
|
+
password: "your_password",
|
|
31
|
+
database: "your_database",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
migrations: {
|
|
37
|
+
directory: "./migrations",
|
|
38
|
+
tableName: "migrations",
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
seeds: {
|
|
42
|
+
directory: "./seeds",
|
|
43
|
+
},
|
|
44
|
+
};
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { default as Model } from './orm/Model';
|
|
2
|
+
export { default as QueryBuilder } from './orm/QueryBuilder';
|
|
3
|
+
export { default as Collection } from './orm/Collection';
|
|
4
|
+
export { default as Database } from './database/connection';
|
|
5
|
+
export * from './orm/Relation';
|
|
6
|
+
export * from './orm/CustomCasts';
|
|
7
|
+
|
|
8
|
+
// Default export
|
|
9
|
+
export { default } from './orm/Model';
|
package/index.mjs
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// index.mjs - ES Module wrapper
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
const exports = require('./index.js');
|
|
6
|
+
|
|
7
|
+
export const {
|
|
8
|
+
Model,
|
|
9
|
+
QueryBuilder,
|
|
10
|
+
Collection,
|
|
11
|
+
Database,
|
|
12
|
+
DB,
|
|
13
|
+
SchemaBuilder,
|
|
14
|
+
MigrationRunner,
|
|
15
|
+
Seeder,
|
|
16
|
+
Factory,
|
|
17
|
+
defineFactory,
|
|
18
|
+
Relation,
|
|
19
|
+
HasOne,
|
|
20
|
+
HasMany,
|
|
21
|
+
BelongsTo,
|
|
22
|
+
BelongsToMany,
|
|
23
|
+
HasManyThrough,
|
|
24
|
+
MorphTo,
|
|
25
|
+
MorphMany,
|
|
26
|
+
MoneyCast,
|
|
27
|
+
EncryptedCast,
|
|
28
|
+
JsonCast,
|
|
29
|
+
ArrayCast,
|
|
30
|
+
DateCast
|
|
31
|
+
} = exports;
|
|
32
|
+
|
|
33
|
+
export default exports.Model;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export default class Collection<T = any> extends Array<T> {
|
|
2
|
+
constructor(items?: T[]);
|
|
3
|
+
|
|
4
|
+
// Static factory methods
|
|
5
|
+
static make<T>(items?: T[]): Collection<T>;
|
|
6
|
+
static times<T>(count: number, callback: (index: number) => T): Collection<T>;
|
|
7
|
+
static range(start: number, end: number): Collection<number>;
|
|
8
|
+
|
|
9
|
+
// Collection methods
|
|
10
|
+
filter(callback: (item: T, index: number) => boolean): Collection<T>;
|
|
11
|
+
map<U>(callback: (item: T, index: number) => U): Collection<U>;
|
|
12
|
+
first(): T | undefined;
|
|
13
|
+
last(): T | undefined;
|
|
14
|
+
pluck<K extends keyof T>(key: K): Collection<T[K]>;
|
|
15
|
+
unique(): Collection<T>;
|
|
16
|
+
unique<K extends keyof T>(key: K): Collection<T>;
|
|
17
|
+
groupBy<K extends keyof T>(key: K): { [key: string]: Collection<T> };
|
|
18
|
+
sortBy<K extends keyof T>(key: K): Collection<T>;
|
|
19
|
+
sortByDesc<K extends keyof T>(key: K): Collection<T>;
|
|
20
|
+
where<K extends keyof T>(key: K, value: T[K]): Collection<T>;
|
|
21
|
+
firstWhere<K extends keyof T>(key: K, value: T[K]): T | undefined;
|
|
22
|
+
sum(): number;
|
|
23
|
+
sum<K extends keyof T>(key: K): number;
|
|
24
|
+
avg(): number;
|
|
25
|
+
avg<K extends keyof T>(key: K): number;
|
|
26
|
+
min(): T | undefined;
|
|
27
|
+
min<K extends keyof T>(key: K): T[K] | undefined;
|
|
28
|
+
max(): T | undefined;
|
|
29
|
+
max<K extends keyof T>(key: K): T[K] | undefined;
|
|
30
|
+
chunk(size: number): Collection<Collection<T>>;
|
|
31
|
+
toJSON(): any[];
|
|
32
|
+
|
|
33
|
+
// Advanced collection methods
|
|
34
|
+
reject(callback: (item: T, index: number) => boolean): Collection<T>;
|
|
35
|
+
partition(callback: (item: T, index: number) => boolean): [Collection<T>, Collection<T>];
|
|
36
|
+
keyBy<K extends keyof T>(key: K): { [key: string]: T };
|
|
37
|
+
countBy<K extends keyof T>(key: K): { [key: string]: number };
|
|
38
|
+
flatten(): Collection<any>;
|
|
39
|
+
take(count: number): Collection<T>;
|
|
40
|
+
skip(count: number): Collection<T>;
|
|
41
|
+
random(): T | undefined;
|
|
42
|
+
random(count: number): Collection<T>;
|
|
43
|
+
shuffle(): Collection<T>;
|
|
44
|
+
tap(callback: (collection: this) => void): this;
|
|
45
|
+
pipe<U>(callback: (collection: this) => U): U;
|
|
46
|
+
whenEmpty(callback: (collection: this) => void): this;
|
|
47
|
+
whenNotEmpty(callback: (collection: this) => void): this;
|
|
48
|
+
unless(condition: boolean, callback: (collection: this) => void): this;
|
|
49
|
+
when(condition: boolean, callback: (collection: this) => void): this;
|
|
50
|
+
toArray(): T[];
|
|
51
|
+
isEmpty(): boolean;
|
|
52
|
+
isNotEmpty(): boolean;
|
|
53
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface Cast {
|
|
2
|
+
get(value: any): any;
|
|
3
|
+
set(value: any): any;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export class MoneyCast implements Cast {
|
|
7
|
+
get(value: any): number | null;
|
|
8
|
+
set(value: any): number | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class EncryptedCast implements Cast {
|
|
12
|
+
constructor(key?: string);
|
|
13
|
+
get(value: any): string | null;
|
|
14
|
+
set(value: any): string | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class JsonCast implements Cast {
|
|
18
|
+
get(value: any): any;
|
|
19
|
+
set(value: any): string | null;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class ArrayCast implements Cast {
|
|
23
|
+
get(value: any): any[] | null;
|
|
24
|
+
set(value: any): string | null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class DateCast implements Cast {
|
|
28
|
+
get(value: any): Date | null;
|
|
29
|
+
set(value: any): string | null;
|
|
30
|
+
}
|
package/orm/Model.d.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import QueryBuilder from './QueryBuilder';
|
|
2
|
+
import { HasOne, HasMany, BelongsTo, BelongsToMany, HasManyThrough, MorphTo, MorphMany } from './Relation';
|
|
3
|
+
|
|
4
|
+
export interface ModelAttributes {
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ModelCasts {
|
|
9
|
+
[key: string]: 'string' | 'number' | 'boolean' | 'date' | 'json' | 'array' | 'object' | 'float';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface ModelEvents {
|
|
13
|
+
[event: string]: Array<(model: any) => Promise<boolean | void> | boolean | void>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface Observer {
|
|
17
|
+
creating?(model: any): Promise<void> | void;
|
|
18
|
+
created?(model: any): Promise<void> | void;
|
|
19
|
+
updating?(model: any): Promise<void> | void;
|
|
20
|
+
updated?(model: any): Promise<void> | void;
|
|
21
|
+
saving?(model: any): Promise<void> | void;
|
|
22
|
+
saved?(model: any): Promise<void> | void;
|
|
23
|
+
deleting?(model: any): Promise<void> | void;
|
|
24
|
+
deleted?(model: any): Promise<void> | void;
|
|
25
|
+
restoring?(model: any): Promise<void> | void;
|
|
26
|
+
restored?(model: any): Promise<void> | void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default class Model {
|
|
30
|
+
// Static properties
|
|
31
|
+
protected static table: string;
|
|
32
|
+
protected static connection?: string;
|
|
33
|
+
protected static primaryKey: string;
|
|
34
|
+
protected static keyType: 'number' | 'string';
|
|
35
|
+
protected static incrementing: boolean;
|
|
36
|
+
protected static timestamps: boolean;
|
|
37
|
+
protected static softDeletes: boolean;
|
|
38
|
+
protected static fillable: string[];
|
|
39
|
+
protected static guarded: string[];
|
|
40
|
+
protected static casts: ModelCasts;
|
|
41
|
+
protected static events: ModelEvents;
|
|
42
|
+
protected static globalScopes: Map<string, (query: QueryBuilder) => void>;
|
|
43
|
+
protected static appends: string[];
|
|
44
|
+
protected static timezone: string;
|
|
45
|
+
|
|
46
|
+
// Instance properties
|
|
47
|
+
attributes: ModelAttributes;
|
|
48
|
+
original: ModelAttributes;
|
|
49
|
+
relations: { [key: string]: any };
|
|
50
|
+
exists: boolean;
|
|
51
|
+
wasRecentlyCreated: boolean;
|
|
52
|
+
protected _dirty: Set<string>;
|
|
53
|
+
protected fillable: string[];
|
|
54
|
+
protected guarded: string[];
|
|
55
|
+
protected casts: ModelCasts;
|
|
56
|
+
protected hidden?: string[];
|
|
57
|
+
protected appends?: string[];
|
|
58
|
+
protected _deferred?: ModelAttributes;
|
|
59
|
+
|
|
60
|
+
constructor(attributes?: ModelAttributes);
|
|
61
|
+
|
|
62
|
+
// Static methods
|
|
63
|
+
static register(): void;
|
|
64
|
+
static resolveRelatedModel(related: string | typeof Model): typeof Model;
|
|
65
|
+
static query(): QueryBuilder;
|
|
66
|
+
static with(...relations: string[]): QueryBuilder;
|
|
67
|
+
static on(connectionOrTrx: string | any): QueryBuilder;
|
|
68
|
+
static all(): Promise<Model[]>;
|
|
69
|
+
static find(id: any): Promise<Model | null>;
|
|
70
|
+
static findBy(column: string, value: any): Promise<Model | null>;
|
|
71
|
+
static first(): Promise<Model | null>;
|
|
72
|
+
static firstOrFail(): Promise<Model>;
|
|
73
|
+
static latest(column?: string): QueryBuilder;
|
|
74
|
+
static oldest(column?: string): QueryBuilder;
|
|
75
|
+
static make(attributes?: ModelAttributes): Model;
|
|
76
|
+
static create(attributes?: ModelAttributes): Promise<Model>;
|
|
77
|
+
static generateUuid(): string;
|
|
78
|
+
static insert(data: ModelAttributes | ModelAttributes[]): Promise<any>;
|
|
79
|
+
static destroy(ids: any | any[]): Promise<number>;
|
|
80
|
+
static firstOrCreate(attributes: ModelAttributes, values?: ModelAttributes): Promise<Model>;
|
|
81
|
+
static firstOrNew(attributes: ModelAttributes, values?: ModelAttributes): Promise<Model>;
|
|
82
|
+
static updateOrCreate(attributes: ModelAttributes, values?: ModelAttributes): Promise<Model>;
|
|
83
|
+
|
|
84
|
+
// Scopes
|
|
85
|
+
static addGlobalScope(name: string, scope: (query: QueryBuilder) => void): void;
|
|
86
|
+
static removeGlobalScope(name: string): void;
|
|
87
|
+
static withoutGlobalScope(name: string): QueryBuilder;
|
|
88
|
+
static applyGlobalScopes(query: QueryBuilder): void;
|
|
89
|
+
|
|
90
|
+
// Events
|
|
91
|
+
static creating(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
92
|
+
static created(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
93
|
+
static updating(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
94
|
+
static updated(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
95
|
+
static saving(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
96
|
+
static saved(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
97
|
+
static deleting(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
98
|
+
static deleted(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
99
|
+
static restoring(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
100
|
+
static restored(callback: (model: Model) => Promise<boolean | void> | boolean | void): void;
|
|
101
|
+
static observe(observer: Observer | (new () => Observer)): void;
|
|
102
|
+
static fireEvent(event: string, model: Model): Promise<boolean>;
|
|
103
|
+
|
|
104
|
+
// Table info
|
|
105
|
+
protected static getTableName(): string;
|
|
106
|
+
protected static getPrimaryKey(): string;
|
|
107
|
+
protected static getKeyType(): string;
|
|
108
|
+
protected static getIncrementing(): boolean;
|
|
109
|
+
protected static getConnectionName(): string | undefined;
|
|
110
|
+
|
|
111
|
+
// Instance methods
|
|
112
|
+
getKey(): any;
|
|
113
|
+
fill(attributes: ModelAttributes): this;
|
|
114
|
+
isFillable(key: string): boolean;
|
|
115
|
+
getAttribute(key: string): any;
|
|
116
|
+
setAttribute(key: string, value: any): this;
|
|
117
|
+
syncOriginal(): void;
|
|
118
|
+
save(): Promise<boolean>;
|
|
119
|
+
update(attributes?: ModelAttributes): Promise<boolean>;
|
|
120
|
+
isDirty(key?: string): boolean;
|
|
121
|
+
getDirty(): ModelAttributes;
|
|
122
|
+
delete(): Promise<boolean>;
|
|
123
|
+
restore(): Promise<boolean>;
|
|
124
|
+
trashed(): boolean;
|
|
125
|
+
only(keys: string[]): ModelAttributes;
|
|
126
|
+
except(keys: string[]): ModelAttributes;
|
|
127
|
+
forceDelete(): Promise<boolean>;
|
|
128
|
+
toJSON(): any;
|
|
129
|
+
|
|
130
|
+
// Relationships
|
|
131
|
+
hasOne(related: string | typeof Model, foreignKey?: string, localKey?: string): HasOne;
|
|
132
|
+
hasMany(related: string | typeof Model, foreignKey?: string, localKey?: string): HasMany;
|
|
133
|
+
belongsTo(related: string | typeof Model, foreignKey?: string, ownerKey?: string): BelongsTo;
|
|
134
|
+
belongsToMany(
|
|
135
|
+
related: string | typeof Model,
|
|
136
|
+
pivotTable?: string,
|
|
137
|
+
foreignPivotKey?: string,
|
|
138
|
+
relatedPivotKey?: string,
|
|
139
|
+
parentKey?: string,
|
|
140
|
+
relatedKey?: string
|
|
141
|
+
): BelongsToMany;
|
|
142
|
+
hasManyThrough(
|
|
143
|
+
related: string | typeof Model,
|
|
144
|
+
through: string | typeof Model,
|
|
145
|
+
firstKey?: string,
|
|
146
|
+
secondKey?: string,
|
|
147
|
+
localKey?: string,
|
|
148
|
+
secondLocalKey?: string
|
|
149
|
+
): HasManyThrough;
|
|
150
|
+
morphTo(typeColumn?: string, idColumn?: string): MorphTo;
|
|
151
|
+
morphMany(related: string | typeof Model, typeColumn?: string, idColumn?: string): MorphMany;
|
|
152
|
+
|
|
153
|
+
// Protected methods
|
|
154
|
+
protected _initialize(): void;
|
|
155
|
+
protected _createAttributeGetters(): void;
|
|
156
|
+
protected _getCurrentTimestamp(): Date;
|
|
157
|
+
protected _getTimezoneOffset(timezone: string, date: Date): number;
|
|
158
|
+
protected _getConfig(): any;
|
|
159
|
+
protected _resolveRelatedName(related: string | typeof Model): string;
|
|
160
|
+
}
|
package/orm/Model.js
CHANGED
|
@@ -8,10 +8,14 @@ const Database = require('../database/connection');
|
|
|
8
8
|
(function autoLoadConfig() {
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const path = require('path');
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
const configPathJs = path.join(process.cwd(), 'ilana.config.js');
|
|
12
|
+
const configPathMjs = path.join(process.cwd(), 'ilana.config.mjs');
|
|
13
|
+
|
|
14
|
+
if (fs.existsSync(configPathJs)) {
|
|
15
|
+
delete require.cache[configPathJs];
|
|
16
|
+
require(configPathJs);
|
|
17
|
+
} else if (fs.existsSync(configPathMjs)) {
|
|
18
|
+
// For ES modules, we'll handle this in the _getConfig method
|
|
15
19
|
}
|
|
16
20
|
})();
|
|
17
21
|
|
|
@@ -371,9 +375,19 @@ class Model {
|
|
|
371
375
|
_getConfig() {
|
|
372
376
|
try {
|
|
373
377
|
const path = require('path');
|
|
374
|
-
const
|
|
375
|
-
|
|
376
|
-
|
|
378
|
+
const fs = require('fs');
|
|
379
|
+
const configPathJs = path.join(process.cwd(), 'ilana.config.js');
|
|
380
|
+
const configPathMjs = path.join(process.cwd(), 'ilana.config.mjs');
|
|
381
|
+
|
|
382
|
+
if (fs.existsSync(configPathJs)) {
|
|
383
|
+
delete require.cache[configPathJs];
|
|
384
|
+
return require(configPathJs);
|
|
385
|
+
} else if (fs.existsSync(configPathMjs)) {
|
|
386
|
+
// For ES modules, return a promise or handle async import
|
|
387
|
+
// For now, return null and let the caller handle it
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
return null;
|
|
377
391
|
} catch (e) {
|
|
378
392
|
return null;
|
|
379
393
|
}
|
package/orm/Model.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import Model from './Model';
|
|
2
|
+
|
|
3
|
+
export default class ModelRegistry {
|
|
4
|
+
private static models: Map<string, typeof Model>;
|
|
5
|
+
|
|
6
|
+
static register(name: string, model: typeof Model): void;
|
|
7
|
+
static get(name: string): typeof Model | undefined;
|
|
8
|
+
static has(name: string): boolean;
|
|
9
|
+
static all(): Map<string, typeof Model>;
|
|
10
|
+
static clear(): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import Collection from './Collection';
|
|
2
|
+
import Model from './Model';
|
|
3
|
+
|
|
4
|
+
export interface PaginationResult<T> {
|
|
5
|
+
data: Collection<T>;
|
|
6
|
+
total: number;
|
|
7
|
+
perPage: number;
|
|
8
|
+
currentPage: number;
|
|
9
|
+
lastPage: number;
|
|
10
|
+
from: number | null;
|
|
11
|
+
to: number | null;
|
|
12
|
+
nextPage: number | null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SimplePaginationResult<T> {
|
|
16
|
+
data: Collection<T>;
|
|
17
|
+
hasMore: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CursorPaginationResult<T> {
|
|
21
|
+
data: Collection<T>;
|
|
22
|
+
nextCursor?: string;
|
|
23
|
+
prevCursor?: string;
|
|
24
|
+
hasNextPage: boolean;
|
|
25
|
+
hasPrevPage: boolean;
|
|
26
|
+
path: string;
|
|
27
|
+
perPage: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default class QueryBuilder {
|
|
31
|
+
protected query: any;
|
|
32
|
+
protected modelClass: typeof Model;
|
|
33
|
+
protected connectionName?: string;
|
|
34
|
+
protected eagerLoad: string[];
|
|
35
|
+
protected eagerLoadConstraints: { [key: string]: (query: QueryBuilder) => void };
|
|
36
|
+
protected _transaction?: any;
|
|
37
|
+
protected _includeTrashed?: boolean;
|
|
38
|
+
protected _onlyTrashed?: boolean;
|
|
39
|
+
protected _withoutTrashed?: boolean;
|
|
40
|
+
|
|
41
|
+
constructor(tableName: string, modelClass: typeof Model, connectionName?: string);
|
|
42
|
+
|
|
43
|
+
// Where clauses
|
|
44
|
+
where(column: string, value: any): this;
|
|
45
|
+
where(column: string, operator: string, value: any): this;
|
|
46
|
+
orWhere(column: string, value: any): this;
|
|
47
|
+
orWhere(column: string, operator: string, value: any): this;
|
|
48
|
+
whereIn(column: string, values: any[]): this;
|
|
49
|
+
whereNotIn(column: string, values: any[]): this;
|
|
50
|
+
whereNull(column: string): this;
|
|
51
|
+
whereNotNull(column: string): this;
|
|
52
|
+
whereBetween(column: string, range: [any, any]): this;
|
|
53
|
+
whereJsonContains(column: string, value: any): this;
|
|
54
|
+
whereJsonLength(column: string, operator: string, value: number): this;
|
|
55
|
+
whereDate(column: string, value: string): this;
|
|
56
|
+
whereDate(column: string, operator: string, value: string): this;
|
|
57
|
+
whereMonth(column: string, month: number): this;
|
|
58
|
+
whereYear(column: string, year: number): this;
|
|
59
|
+
whereExists(callback: (query: QueryBuilder) => void): this;
|
|
60
|
+
when<T>(condition: T, callback: (query: this, condition: T) => void, otherwise?: (query: this) => void): this;
|
|
61
|
+
|
|
62
|
+
// Joins
|
|
63
|
+
join(table: string, first: string, operator: string, second: string): this;
|
|
64
|
+
leftJoin(table: string, first: string, operator: string, second: string): this;
|
|
65
|
+
rightJoin(table: string, first: string, operator: string, second: string): this;
|
|
66
|
+
|
|
67
|
+
// Ordering and limits
|
|
68
|
+
orderBy(column: string, direction?: 'asc' | 'desc'): this;
|
|
69
|
+
latest(column?: string): this;
|
|
70
|
+
oldest(column?: string): this;
|
|
71
|
+
limit(count: number): this;
|
|
72
|
+
offset(count: number): this;
|
|
73
|
+
take(count: number): this;
|
|
74
|
+
skip(count: number): this;
|
|
75
|
+
|
|
76
|
+
// Grouping
|
|
77
|
+
groupBy(...columns: string[]): this;
|
|
78
|
+
having(column: string, operator: string, value: any): this;
|
|
79
|
+
having(rawSql: string): this;
|
|
80
|
+
|
|
81
|
+
// Locking
|
|
82
|
+
lockForUpdate(): this;
|
|
83
|
+
sharedLock(): this;
|
|
84
|
+
skipLocked(): this;
|
|
85
|
+
noWait(): this;
|
|
86
|
+
|
|
87
|
+
// Selection
|
|
88
|
+
select(...columns: string[]): this;
|
|
89
|
+
distinct(): this;
|
|
90
|
+
|
|
91
|
+
// Raw queries
|
|
92
|
+
whereRaw(sql: string, bindings?: any[]): this;
|
|
93
|
+
selectRaw(sql: string, bindings?: any[]): this;
|
|
94
|
+
|
|
95
|
+
// Aggregates
|
|
96
|
+
count(column?: string): Promise<number>;
|
|
97
|
+
sum(column: string): Promise<number>;
|
|
98
|
+
avg(column: string): Promise<number>;
|
|
99
|
+
min(column: string): Promise<any>;
|
|
100
|
+
max(column: string): Promise<any>;
|
|
101
|
+
|
|
102
|
+
// Eager loading
|
|
103
|
+
with(...relations: string[]): this;
|
|
104
|
+
withConstraints(relation: string, callback: (query: QueryBuilder) => void): this;
|
|
105
|
+
withConstraints(relations: { [key: string]: (query: QueryBuilder) => void }): this;
|
|
106
|
+
withCount(...relations: string[]): this;
|
|
107
|
+
whereHas(relation: string, callback?: (query: QueryBuilder) => void): this;
|
|
108
|
+
|
|
109
|
+
// Execution methods
|
|
110
|
+
get(): Promise<Collection<Model>>;
|
|
111
|
+
first(): Promise<Model | null>;
|
|
112
|
+
find(id: any): Promise<Model | null>;
|
|
113
|
+
findOrFail(id: any): Promise<Model>;
|
|
114
|
+
pluck(column: string): Promise<any[]>;
|
|
115
|
+
exists(): Promise<boolean>;
|
|
116
|
+
|
|
117
|
+
// Pagination
|
|
118
|
+
paginate(page?: number, perPage?: number): Promise<PaginationResult<Model>>;
|
|
119
|
+
simplePaginate(page?: number, perPage?: number): Promise<SimplePaginationResult<Model>>;
|
|
120
|
+
cursorPaginate(perPage?: number, cursor?: string, column?: string, direction?: 'asc' | 'desc'): Promise<CursorPaginationResult<Model>>;
|
|
121
|
+
|
|
122
|
+
// Chunking
|
|
123
|
+
chunk(size: number, callback: (models: Collection<Model>) => Promise<void>): Promise<void>;
|
|
124
|
+
cursor(chunkSize?: number): AsyncGenerator<Model, void, unknown>;
|
|
125
|
+
lazy(chunkSize?: number): AsyncGenerator<Model, void, unknown>;
|
|
126
|
+
|
|
127
|
+
// Insert/Update/Delete
|
|
128
|
+
insert(data: any | any[]): Promise<any>;
|
|
129
|
+
insertGetId(data: any): Promise<any>;
|
|
130
|
+
update(data: any): Promise<number>;
|
|
131
|
+
delete(): Promise<number>;
|
|
132
|
+
upsert(data: any[], uniqueBy: string[], update?: string[]): Promise<any>;
|
|
133
|
+
|
|
134
|
+
// Connection switching
|
|
135
|
+
connection(name: string): QueryBuilder;
|
|
136
|
+
on(connectionOrTrx: string | any): QueryBuilder;
|
|
137
|
+
|
|
138
|
+
// Clone query
|
|
139
|
+
clone(): QueryBuilder;
|
|
140
|
+
|
|
141
|
+
// Get underlying Knex query
|
|
142
|
+
toKnex(): any;
|
|
143
|
+
|
|
144
|
+
// Soft delete methods
|
|
145
|
+
withTrashed(): this;
|
|
146
|
+
onlyTrashed(): this;
|
|
147
|
+
withoutTrashed(): this;
|
|
148
|
+
|
|
149
|
+
// Debug
|
|
150
|
+
toSql(): string;
|
|
151
|
+
|
|
152
|
+
// Protected methods
|
|
153
|
+
protected loadRelations(models: Model[]): Promise<void>;
|
|
154
|
+
protected loadRelation(models: Model[], relationName: string): Promise<void>;
|
|
155
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import QueryBuilder from './QueryBuilder';
|
|
2
|
+
import Model from './Model';
|
|
3
|
+
import Collection from './Collection';
|
|
4
|
+
|
|
5
|
+
export class Relation {
|
|
6
|
+
protected parent: Model;
|
|
7
|
+
protected related: string | typeof Model;
|
|
8
|
+
protected foreignKey: string;
|
|
9
|
+
protected localKey: string;
|
|
10
|
+
|
|
11
|
+
constructor(parent: Model, related: string | typeof Model, foreignKey: string, localKey?: string);
|
|
12
|
+
|
|
13
|
+
getRelatedClass(): typeof Model;
|
|
14
|
+
newQuery(): QueryBuilder;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class HasOne extends Relation {
|
|
18
|
+
addConstraints(): void;
|
|
19
|
+
getResults(): Promise<Model | null>;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class HasMany extends Relation {
|
|
23
|
+
addConstraints(): void;
|
|
24
|
+
getResults(): Promise<Collection<Model>>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class BelongsTo extends Relation {
|
|
28
|
+
addConstraints(): void;
|
|
29
|
+
getResults(): Promise<Model | null>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class BelongsToMany extends Relation {
|
|
33
|
+
protected pivotTable: string;
|
|
34
|
+
protected parentPivotKey: string;
|
|
35
|
+
protected relatedPivotKey: string;
|
|
36
|
+
protected parentKey: string;
|
|
37
|
+
protected relatedKey: string;
|
|
38
|
+
protected pivotColumns: string[];
|
|
39
|
+
protected pivotTimestamps: boolean;
|
|
40
|
+
|
|
41
|
+
constructor(
|
|
42
|
+
parent: Model,
|
|
43
|
+
related: string | typeof Model,
|
|
44
|
+
pivotTable?: string,
|
|
45
|
+
foreignPivotKey?: string,
|
|
46
|
+
relatedPivotKey?: string,
|
|
47
|
+
parentKey?: string,
|
|
48
|
+
relatedKey?: string
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
withPivot(...columns: string[]): this;
|
|
52
|
+
withTimestamps(): this;
|
|
53
|
+
addConstraints(): void;
|
|
54
|
+
getResults(): Promise<Model[]>;
|
|
55
|
+
attach(id: any, attributes?: any): Promise<void>;
|
|
56
|
+
detach(id?: any): Promise<number>;
|
|
57
|
+
sync(ids: any[]): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class HasManyThrough extends Relation {
|
|
61
|
+
protected through: string | typeof Model;
|
|
62
|
+
protected firstKey: string;
|
|
63
|
+
protected secondKey: string;
|
|
64
|
+
protected secondLocalKey: string;
|
|
65
|
+
|
|
66
|
+
constructor(
|
|
67
|
+
parent: Model,
|
|
68
|
+
related: string | typeof Model,
|
|
69
|
+
through: string | typeof Model,
|
|
70
|
+
firstKey?: string,
|
|
71
|
+
secondKey?: string,
|
|
72
|
+
localKey?: string,
|
|
73
|
+
secondLocalKey?: string
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
addConstraints(): void;
|
|
77
|
+
getResults(): Promise<Collection<Model>>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export class MorphTo extends Relation {
|
|
81
|
+
protected morphType: string;
|
|
82
|
+
protected morphId: string;
|
|
83
|
+
|
|
84
|
+
constructor(parent: Model, morphType: string, morphId: string);
|
|
85
|
+
|
|
86
|
+
addConstraints(): void;
|
|
87
|
+
getResults(): Promise<Model | null>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export class MorphMany extends Relation {
|
|
91
|
+
protected morphType: string;
|
|
92
|
+
protected morphId: string;
|
|
93
|
+
protected morphClass: string;
|
|
94
|
+
|
|
95
|
+
constructor(parent: Model, related: string | typeof Model, morphType: string, morphId: string, morphClass: string);
|
|
96
|
+
|
|
97
|
+
addConstraints(): void;
|
|
98
|
+
getResults(): Promise<Collection<Model>>;
|
|
99
|
+
}
|
package/orm/Relation.mjs
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Relation.mjs - ES Module wrapper
|
|
2
|
+
import { createRequire } from 'module';
|
|
3
|
+
const require = createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
const Relations = require('./Relation.js');
|
|
6
|
+
|
|
7
|
+
export const { Relation, HasOne, HasMany, BelongsTo, BelongsToMany, HasManyThrough, MorphTo, MorphMany } = Relations;
|
package/package.json
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ilana-orm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "A fully-featured, Eloquent-style ORM for Node.js with TypeScript support",
|
|
5
5
|
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./index.mjs",
|
|
10
|
+
"require": "./index.js",
|
|
11
|
+
"types": "./index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./orm/Model": {
|
|
14
|
+
"import": "./orm/Model.mjs",
|
|
15
|
+
"require": "./orm/Model.js",
|
|
16
|
+
"types": "./orm/Model.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./orm/QueryBuilder": {
|
|
19
|
+
"import": "./orm/QueryBuilder.mjs",
|
|
20
|
+
"require": "./orm/QueryBuilder.js",
|
|
21
|
+
"types": "./orm/QueryBuilder.d.ts"
|
|
22
|
+
},
|
|
23
|
+
"./orm/Collection": {
|
|
24
|
+
"import": "./orm/Collection.mjs",
|
|
25
|
+
"require": "./orm/Collection.js",
|
|
26
|
+
"types": "./orm/Collection.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./database/connection": {
|
|
29
|
+
"import": "./database/connection.mjs",
|
|
30
|
+
"require": "./database/connection.js",
|
|
31
|
+
"types": "./database/connection.d.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
6
34
|
"bin": {
|
|
7
35
|
"ilana": "cli/ilana.js"
|
|
8
36
|
},
|
|
@@ -38,9 +66,15 @@
|
|
|
38
66
|
},
|
|
39
67
|
"files": [
|
|
40
68
|
"*.js",
|
|
69
|
+
"*.mjs",
|
|
70
|
+
"*.d.ts",
|
|
41
71
|
"cli/**/*.js",
|
|
42
72
|
"database/**/*.js",
|
|
73
|
+
"database/**/*.mjs",
|
|
74
|
+
"database/**/*.d.ts",
|
|
43
75
|
"orm/**/*.js",
|
|
76
|
+
"orm/**/*.mjs",
|
|
77
|
+
"orm/**/*.d.ts",
|
|
44
78
|
"README.md",
|
|
45
79
|
"LICENSE",
|
|
46
80
|
"ilana.png"
|
|
@@ -65,6 +99,9 @@
|
|
|
65
99
|
"@types/jest": "^29.0.0",
|
|
66
100
|
"ts-jest": "^29.0.0"
|
|
67
101
|
},
|
|
102
|
+
"peerDependencies": {
|
|
103
|
+
"@types/node": ">=16.0.0"
|
|
104
|
+
},
|
|
68
105
|
"engines": {
|
|
69
106
|
"node": ">=16.0.0"
|
|
70
107
|
}
|