ilana-orm 1.0.2 → 1.0.5
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/cli/ilana.js +11 -11
- package/database/connection.d.ts +45 -0
- package/index.d.ts +9 -0
- package/orm/Collection.d.ts +53 -0
- package/orm/CustomCasts.d.ts +30 -0
- package/orm/Model.d.ts +160 -0
- package/orm/ModelRegistry.d.ts +11 -0
- package/orm/QueryBuilder.d.ts +155 -0
- package/orm/Relation.d.ts +99 -0
- package/package.json +8 -1
package/cli/ilana.js
CHANGED
|
@@ -131,8 +131,8 @@ function generateModel(name, options = {}) {
|
|
|
131
131
|
|
|
132
132
|
function getModelTemplate(className, tableName) {
|
|
133
133
|
if (isTypeScriptProject()) {
|
|
134
|
-
return `import Model from 'ilana-orm/orm/Model';
|
|
135
|
-
// import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts';
|
|
134
|
+
return `import Model from 'ilana-orm/orm/Model.js';
|
|
135
|
+
// import { MoneyCast, EncryptedCast } from 'ilana-orm/orm/CustomCasts.js';
|
|
136
136
|
|
|
137
137
|
export default class ${className} extends Model {
|
|
138
138
|
protected static table = '${tableName}';
|
|
@@ -223,7 +223,7 @@ module.exports = ${className};
|
|
|
223
223
|
|
|
224
224
|
function getPivotModelTemplate(className, tableName) {
|
|
225
225
|
if (isTypeScriptProject()) {
|
|
226
|
-
return `import Model from 'ilana-orm/orm/Model';
|
|
226
|
+
return `import Model from 'ilana-orm/orm/Model.js';
|
|
227
227
|
|
|
228
228
|
export default class ${className} extends Model {
|
|
229
229
|
protected static table = '${tableName}';
|
|
@@ -260,8 +260,8 @@ function generateFactory(className) {
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
const template = isTypeScriptProject() ?
|
|
263
|
-
`import { defineFactory } from 'ilana-orm/orm/Factory';
|
|
264
|
-
import ${className} from '../../models/${className}';
|
|
263
|
+
`import { defineFactory } from 'ilana-orm/orm/Factory.js';
|
|
264
|
+
import ${className} from '../../models/${className}.js';
|
|
265
265
|
|
|
266
266
|
export default defineFactory(${className}, (faker) => ({
|
|
267
267
|
// Define your factory attributes here
|
|
@@ -298,9 +298,9 @@ function generateSeeder(className) {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
const template = isTypeScriptProject() ?
|
|
301
|
-
`import Seeder from 'ilana-orm/orm/Seeder';
|
|
302
|
-
import ${className} from '../../models/${className}';
|
|
303
|
-
import '../factories/${className}Factory';
|
|
301
|
+
`import Seeder from 'ilana-orm/orm/Seeder.js';
|
|
302
|
+
import ${className} from '../../models/${className}.js';
|
|
303
|
+
import '../factories/${className}Factory.js';
|
|
304
304
|
|
|
305
305
|
export default class ${className}Seeder extends Seeder {
|
|
306
306
|
async run(): Promise<void> {
|
|
@@ -357,7 +357,7 @@ const commands = {
|
|
|
357
357
|
|
|
358
358
|
function getESModuleConfigTemplate() {
|
|
359
359
|
return `import 'dotenv/config';
|
|
360
|
-
import Database from 'ilana-orm/database/connection';
|
|
360
|
+
import Database from 'ilana-orm/database/connection.js';
|
|
361
361
|
|
|
362
362
|
const config = {
|
|
363
363
|
default: process.env.DB_CONNECTION || 'mysql',
|
|
@@ -863,7 +863,7 @@ DB_TIMEZONE=UTC
|
|
|
863
863
|
}
|
|
864
864
|
|
|
865
865
|
const template = isTypeScriptProject() ?
|
|
866
|
-
`${modelName ? `import ${modelName} from '../models/${modelName}';\n\n` : ''}export default class ${className}Observer {
|
|
866
|
+
`${modelName ? `import ${modelName} from '../models/${modelName}.js';\n\n` : ''}export default class ${className}Observer {
|
|
867
867
|
async creating(model: ${modelName || 'any'}): Promise<void> {}
|
|
868
868
|
async created(model: ${modelName || 'any'}): Promise<void> {}
|
|
869
869
|
async updating(model: ${modelName || 'any'}): Promise<void> {}
|
|
@@ -911,7 +911,7 @@ module.exports = ${className}Observer;
|
|
|
911
911
|
}
|
|
912
912
|
|
|
913
913
|
const template = isTypeScriptProject() ?
|
|
914
|
-
`import { CustomCast } from 'ilana-orm/orm/Model';
|
|
914
|
+
`import { CustomCast } from 'ilana-orm/orm/Model.js';
|
|
915
915
|
|
|
916
916
|
export default class ${className}Cast implements CustomCast {
|
|
917
917
|
get(value: any): any {
|
|
@@ -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
|
+
}
|
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';
|
|
@@ -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
|
+
}
|
|
@@ -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/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ilana-orm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
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",
|
|
6
7
|
"bin": {
|
|
7
8
|
"ilana": "cli/ilana.js"
|
|
8
9
|
},
|
|
@@ -38,9 +39,12 @@
|
|
|
38
39
|
},
|
|
39
40
|
"files": [
|
|
40
41
|
"*.js",
|
|
42
|
+
"*.d.ts",
|
|
41
43
|
"cli/**/*.js",
|
|
42
44
|
"database/**/*.js",
|
|
45
|
+
"database/**/*.d.ts",
|
|
43
46
|
"orm/**/*.js",
|
|
47
|
+
"orm/**/*.d.ts",
|
|
44
48
|
"README.md",
|
|
45
49
|
"LICENSE",
|
|
46
50
|
"ilana.png"
|
|
@@ -65,6 +69,9 @@
|
|
|
65
69
|
"@types/jest": "^29.0.0",
|
|
66
70
|
"ts-jest": "^29.0.0"
|
|
67
71
|
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"@types/node": ">=16.0.0"
|
|
74
|
+
},
|
|
68
75
|
"engines": {
|
|
69
76
|
"node": ">=16.0.0"
|
|
70
77
|
}
|