@cheetah.js/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.
- package/README.md +228 -0
- package/build.ts +14 -0
- package/cheetah.config.ts +14 -0
- package/dist/SqlBuilder.d.ts +57 -0
- package/dist/SqlBuilder.js +436 -0
- package/dist/SqlBuilder.js.map +1 -0
- package/dist/bun/index.d.ts +13 -0
- package/dist/bun/index.js +224319 -0
- package/dist/bun/index.js.map +306 -0
- package/dist/cheetah.d.ts +1 -0
- package/dist/cheetah.js +24 -0
- package/dist/cheetah.js.map +1 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +5 -0
- package/dist/constants.js.map +1 -0
- package/dist/decorators/entity.decorator.d.ts +3 -0
- package/dist/decorators/entity.decorator.js +10 -0
- package/dist/decorators/entity.decorator.js.map +1 -0
- package/dist/decorators/index.decorator.d.ts +3 -0
- package/dist/decorators/index.decorator.js +17 -0
- package/dist/decorators/index.decorator.js.map +1 -0
- package/dist/decorators/one-many.decorator.d.ts +3 -0
- package/dist/decorators/one-many.decorator.js +17 -0
- package/dist/decorators/one-many.decorator.js.map +1 -0
- package/dist/decorators/primary-key.decorator.d.ts +2 -0
- package/dist/decorators/primary-key.decorator.js +6 -0
- package/dist/decorators/primary-key.decorator.js.map +1 -0
- package/dist/decorators/property.decorator.d.ts +15 -0
- package/dist/decorators/property.decorator.js +25 -0
- package/dist/decorators/property.decorator.js.map +1 -0
- package/dist/domain/base-entity.d.ts +42 -0
- package/dist/domain/base-entity.js +106 -0
- package/dist/domain/base-entity.js.map +1 -0
- package/dist/domain/collection.d.ts +6 -0
- package/dist/domain/collection.js +11 -0
- package/dist/domain/collection.js.map +1 -0
- package/dist/domain/entities.d.ts +40 -0
- package/dist/domain/entities.js +137 -0
- package/dist/domain/entities.js.map +1 -0
- package/dist/domain/reference.d.ts +4 -0
- package/dist/domain/reference.js +7 -0
- package/dist/domain/reference.js.map +1 -0
- package/dist/driver/driver.interface.d.ts +270 -0
- package/dist/driver/driver.interface.js +2 -0
- package/dist/driver/driver.interface.js.map +1 -0
- package/dist/driver/pg-driver.d.ts +43 -0
- package/dist/driver/pg-driver.js +255 -0
- package/dist/driver/pg-driver.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/migration/diff-calculator.d.ts +17 -0
- package/dist/migration/diff-calculator.js +230 -0
- package/dist/migration/diff-calculator.js.map +1 -0
- package/dist/migration/migrator.d.ts +18 -0
- package/dist/migration/migrator.js +233 -0
- package/dist/migration/migrator.js.map +1 -0
- package/dist/orm.d.ts +14 -0
- package/dist/orm.js +23 -0
- package/dist/orm.js.map +1 -0
- package/dist/orm.service.d.ts +8 -0
- package/dist/orm.service.js +115 -0
- package/dist/orm.service.js.map +1 -0
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +16 -0
- package/dist/utils.js.map +1 -0
- package/package.json +50 -0
- package/src/SqlBuilder.ts +542 -0
- package/src/cheetah.ts +28 -0
- package/src/constants.ts +4 -0
- package/src/decorators/entity.decorator.ts +10 -0
- package/src/decorators/index.decorator.ts +18 -0
- package/src/decorators/one-many.decorator.ts +19 -0
- package/src/decorators/primary-key.decorator.ts +6 -0
- package/src/decorators/property.decorator.ts +41 -0
- package/src/domain/base-entity.ts +149 -0
- package/src/domain/collection.ts +10 -0
- package/src/domain/entities.ts +159 -0
- package/src/domain/reference.ts +5 -0
- package/src/driver/driver.interface.ts +331 -0
- package/src/driver/pg-driver.ts +308 -0
- package/src/index.ts +17 -0
- package/src/migration/diff-calculator.ts +258 -0
- package/src/migration/migrator.ts +278 -0
- package/src/orm.service.ts +115 -0
- package/src/orm.ts +30 -0
- package/src/utils.ts +18 -0
- package/test/domain/base-entity.spec.ts +463 -0
- package/test/migration/.sql +5 -0
- package/test/migration/cheetah.config.ts +13 -0
- package/test/migration/migator.spec.ts +251 -0
- package/test/migration/test.sql +5 -0
- package/test/node-database.ts +32 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { SqlBuilder } from '../SqlBuilder';
|
|
2
|
+
import { FilterQuery, FindOneOption, FindOptions, InstanceOf } from '../driver/driver.interface';
|
|
3
|
+
|
|
4
|
+
export abstract class BaseEntity {
|
|
5
|
+
private _oldValues: any = {};
|
|
6
|
+
private _changedValues: any = {};
|
|
7
|
+
private $_isPersisted: boolean = false;
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
return new Proxy(this, {
|
|
11
|
+
set(target: any, p: string, newValue: any): boolean {
|
|
12
|
+
|
|
13
|
+
if (p.startsWith('$')) {
|
|
14
|
+
target[p] = newValue;
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// se oldvalue não existir, é porque é a primeira vez que o atributo está sendo setado
|
|
19
|
+
if (!target._oldValues[p]) {
|
|
20
|
+
target._oldValues[p] = newValue;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// se o valor for diferente do valor antigo, é porque o valor foi alterado
|
|
24
|
+
if (target._oldValues[p] !== newValue) {
|
|
25
|
+
target._changedValues[p] = newValue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
target[p] = newValue;
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Gets current entity's Repository.
|
|
37
|
+
*/
|
|
38
|
+
static createQueryBuilder<T>(
|
|
39
|
+
this: { new(): T } & typeof BaseEntity,
|
|
40
|
+
): SqlBuilder<T> {
|
|
41
|
+
return new SqlBuilder<T>(this);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets current entity's Repository.
|
|
46
|
+
*/
|
|
47
|
+
private createQueryBuilder<T>(): SqlBuilder<T> {
|
|
48
|
+
// @ts-ignore
|
|
49
|
+
return new SqlBuilder<T>(this.constructor);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static async find<T, Hint extends string = never>(
|
|
53
|
+
this: { new(): T } & typeof BaseEntity,
|
|
54
|
+
where: FilterQuery<T>,
|
|
55
|
+
options?: FindOptions<T, Hint>
|
|
56
|
+
): Promise<T[]> {
|
|
57
|
+
return this.createQueryBuilder<T>()
|
|
58
|
+
.select(options?.fields as any)
|
|
59
|
+
.where(where)
|
|
60
|
+
.limit(options?.limit)
|
|
61
|
+
.offset(options?.offset)
|
|
62
|
+
.orderBy(options?.orderBy as string[])
|
|
63
|
+
.executeAndReturnAll();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async findOne<T, Hint extends string = never>(
|
|
67
|
+
this: { new(): T } & typeof BaseEntity,
|
|
68
|
+
where: FilterQuery<T>,
|
|
69
|
+
options?: FindOneOption<T, Hint>
|
|
70
|
+
): Promise<T | undefined> {
|
|
71
|
+
return this.createQueryBuilder<T>()
|
|
72
|
+
.select(options?.fields as any)
|
|
73
|
+
.where(where)
|
|
74
|
+
.executeAndReturnFirst();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Find a record in the database based on the provided query where and return it, or throw an error if not found.
|
|
79
|
+
*
|
|
80
|
+
* @param {FilterQuery<T>} where - The query where used to search for the record.
|
|
81
|
+
* @param options
|
|
82
|
+
* @return {Promise<T>} - A promise that resolves with the found record.
|
|
83
|
+
*/
|
|
84
|
+
static async findOneOrFail<T, Hint extends string = never>(
|
|
85
|
+
this: { new(): T } & typeof BaseEntity,
|
|
86
|
+
where: FilterQuery<T>,
|
|
87
|
+
options?: FindOneOption<T, Hint>
|
|
88
|
+
): Promise<T> {
|
|
89
|
+
return this.createQueryBuilder<T>()
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
.select(options?.fields)
|
|
92
|
+
.where(where)
|
|
93
|
+
.orderBy(options?.orderBy as string[])
|
|
94
|
+
.executeAndReturnFirstOrFail();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
static async findAll<
|
|
98
|
+
T extends object,
|
|
99
|
+
Hint extends string = never
|
|
100
|
+
>(
|
|
101
|
+
this: { new(): T } & typeof BaseEntity,
|
|
102
|
+
options: FindOptions<T, Hint>
|
|
103
|
+
): Promise<T[]> {
|
|
104
|
+
const builder = this.createQueryBuilder<T>()
|
|
105
|
+
.select(options.fields as any)
|
|
106
|
+
.offset(options?.offset)
|
|
107
|
+
.limit(options.limit)
|
|
108
|
+
.orderBy(options?.orderBy as string[]);
|
|
109
|
+
|
|
110
|
+
return builder.executeAndReturnAll();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
static async create<T extends BaseEntity>(
|
|
114
|
+
this: { new(): T } & typeof BaseEntity,
|
|
115
|
+
where: Partial<InstanceOf<T>>,
|
|
116
|
+
): Promise<T> {
|
|
117
|
+
return this.createQueryBuilder<T>()
|
|
118
|
+
.insert(where)
|
|
119
|
+
.executeAndReturnFirstOrFail();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
static getTableName(): string {
|
|
123
|
+
if ('tableName' in this) {
|
|
124
|
+
return (this as any).tableName;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return this.name.toLowerCase();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public async save() {
|
|
131
|
+
const qb = this.createQueryBuilder()
|
|
132
|
+
|
|
133
|
+
if (this.$_isPersisted) {
|
|
134
|
+
qb.update(this._changedValues)
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
.where({id: this._oldValues.id})
|
|
137
|
+
} else {
|
|
138
|
+
qb.insert(this._oldValues)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await qb.execute()
|
|
142
|
+
|
|
143
|
+
this._oldValues = {
|
|
144
|
+
...this._oldValues,
|
|
145
|
+
...this._changedValues,
|
|
146
|
+
}
|
|
147
|
+
this._changedValues = {}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export class ArrayCollection<T extends object, O extends object> {
|
|
2
|
+
getItems(): T[] {
|
|
3
|
+
return [];
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
export class Collection<T extends object, O extends object = object> extends ArrayCollection<T, O> {
|
|
7
|
+
constructor(owner: O, items?: T[], initialized = true) {
|
|
8
|
+
super();
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Metadata, Service } from '@cheetah.js/core';
|
|
2
|
+
import { PropertyOptions } from '../decorators/property.decorator';
|
|
3
|
+
import { ColumnsInfo, Relationship, SnapshotIndexInfo, SnapshotTable } from '../driver/driver.interface';
|
|
4
|
+
import { getDefaultLength } from '../utils';
|
|
5
|
+
|
|
6
|
+
export type Property = {
|
|
7
|
+
options: PropertyOptions;
|
|
8
|
+
type: Function;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type Options = {
|
|
12
|
+
showProperties: { [key: string]: Property };
|
|
13
|
+
hideProperties: string[];
|
|
14
|
+
indexes?: SnapshotIndexInfo[];
|
|
15
|
+
relations: Relationship<any>[];
|
|
16
|
+
tableName: string;
|
|
17
|
+
schema?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@Service()
|
|
21
|
+
export class EntityStorage {
|
|
22
|
+
static instance: EntityStorage;
|
|
23
|
+
|
|
24
|
+
private entities: Map<Function, Options> = new Map();
|
|
25
|
+
|
|
26
|
+
constructor() {
|
|
27
|
+
EntityStorage.instance = this;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
add(entity: { target: Function, options: any }, properties: {[key: string]: Property}, relations: Relationship<any>[]) {
|
|
31
|
+
const entityName = entity.options?.tableName || entity.target.name.toLowerCase();
|
|
32
|
+
const indexes = Metadata.get('indexes', entity.target) || [];
|
|
33
|
+
this.entities.set(entity.target, {
|
|
34
|
+
showProperties: properties,
|
|
35
|
+
hideProperties: [],
|
|
36
|
+
relations,
|
|
37
|
+
indexes: indexes.map((index: {name: string, properties: string[]}) => {
|
|
38
|
+
return {
|
|
39
|
+
table: entityName,
|
|
40
|
+
indexName: index.name.replace('[TABLE]', entityName),
|
|
41
|
+
columnName: index.properties.join(','),
|
|
42
|
+
}
|
|
43
|
+
}),
|
|
44
|
+
tableName: entityName,
|
|
45
|
+
...entity.options
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get(entity: Function) {
|
|
50
|
+
return this.entities.get(entity);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
entries() {
|
|
54
|
+
return this.entities.entries();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static getInstance() {
|
|
58
|
+
return EntityStorage.instance;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async snapshot(values: Options): Promise<SnapshotTable> {
|
|
62
|
+
return {
|
|
63
|
+
tableName: values.tableName,
|
|
64
|
+
schema: values.schema || 'public',
|
|
65
|
+
indexes: values.indexes || [],
|
|
66
|
+
columns: this.snapshotColumns(values),
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private snapshotColumns(values: Options): ColumnsInfo[] {
|
|
71
|
+
|
|
72
|
+
let properties: ColumnsInfo[] = Object.entries(values.showProperties).map(([key, value]) => {
|
|
73
|
+
return {
|
|
74
|
+
name: key,
|
|
75
|
+
type: value.type.name,
|
|
76
|
+
nullable: value.options?.nullable,
|
|
77
|
+
default: value.options?.default,
|
|
78
|
+
primary: value.options?.isPrimary,
|
|
79
|
+
unique: value.options?.unique,
|
|
80
|
+
length: value.options?.length,
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
let relations: ColumnsInfo[] = values.relations && values.relations.map((relation) => {
|
|
85
|
+
const type = this.getFkType(relation)
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
name: relation.propertyKey as string,
|
|
89
|
+
type,
|
|
90
|
+
nullable: relation.nullable,
|
|
91
|
+
unique: relation.unique,
|
|
92
|
+
length: relation.length || getDefaultLength(type),
|
|
93
|
+
default: relation.default,
|
|
94
|
+
primary: relation.isPrimary,
|
|
95
|
+
foreignKeys: [
|
|
96
|
+
{
|
|
97
|
+
referencedColumnName: this.getFkKey(relation),
|
|
98
|
+
referencedTableName: this.get(relation.entity() as any)!.tableName,
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
if (!relations) {
|
|
105
|
+
relations = []
|
|
106
|
+
}
|
|
107
|
+
if (!properties) {
|
|
108
|
+
properties = []
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return [...properties, ...relations]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private snapshotIndexes(values: Options): SnapshotIndexInfo[] {
|
|
115
|
+
return Object.entries(values.showProperties).map(([key, value]) => {
|
|
116
|
+
return {
|
|
117
|
+
indexName: key,
|
|
118
|
+
columnName: key,
|
|
119
|
+
table: values.tableName,
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private getFkType(relation: Relationship<any>): any {
|
|
125
|
+
const entity = this.get(relation.entity() as any)
|
|
126
|
+
if (!entity) {
|
|
127
|
+
return 'unknown'
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return entity.showProperties[this.getFkKey(relation)].type.name
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* If fkKey is null, return the primary key of the entity
|
|
135
|
+
* @private
|
|
136
|
+
* @param relationShip
|
|
137
|
+
*/
|
|
138
|
+
private getFkKey(relationShip: Relationship<any>): string | number {
|
|
139
|
+
// se for nullable, deverá retornar o primary key da entidade target
|
|
140
|
+
if (typeof relationShip.fkKey === 'undefined') {
|
|
141
|
+
const entity = this.entities.get(relationShip.entity() as any);
|
|
142
|
+
const property = Object.entries(entity!.showProperties).find(([key, value]) => value.options.isPrimary === true);
|
|
143
|
+
if (!property) {
|
|
144
|
+
throw new Error(`Entity ${entity!.tableName} does not have a primary key`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return property[0];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// se o fkKey é uma função, ele retornará a propriedade da entidade que é a chave estrangeira
|
|
151
|
+
// precisamos pegar o nome dessa propriedade
|
|
152
|
+
if (typeof relationShip.fkKey === 'string') {
|
|
153
|
+
return relationShip.fkKey;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const match = /\.(?<propriedade>[\w]+)/.exec(relationShip.fkKey.toString());
|
|
157
|
+
return match ? match.groups!.propriedade : '';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { PropertyOptions } from '../decorators/property.decorator';
|
|
2
|
+
import { Collection } from '../domain/collection';
|
|
3
|
+
import { Reference } from '../domain/reference';
|
|
4
|
+
|
|
5
|
+
export interface DriverInterface {
|
|
6
|
+
connectionString: string;
|
|
7
|
+
executeStatement(statement: Statement<any>): Promise<{ query: any, startTime: number, sql: string }>;
|
|
8
|
+
connect(): Promise<void>;
|
|
9
|
+
disconnect(): Promise<void>;
|
|
10
|
+
executeSql(s: string): Promise<any>;
|
|
11
|
+
snapshot(tableName: string, options: any): Promise<SnapshotTable | undefined>;
|
|
12
|
+
|
|
13
|
+
getCreateTableInstruction(schema: string | undefined, tableName: string, creates: ColDiff[]): string;
|
|
14
|
+
getAlterTableFkInstruction(schema: string | undefined, tableName: string, colDiff: ColDiff, fk: ForeignKeyInfo) : string;
|
|
15
|
+
getCreateIndex(index: { name: string; properties?: string[] }, schema: string | undefined, tableName: string): string;
|
|
16
|
+
getAddColumn(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff, colDiffInstructions: string[]): void;
|
|
17
|
+
getDropColumn(colDiffInstructions: string[], schema: string | undefined, tableName: string, colName: string): void;
|
|
18
|
+
|
|
19
|
+
getDropIndex(index: {name: string; properties?: string[]}, schema: string | undefined, tableName: string): string;
|
|
20
|
+
|
|
21
|
+
getAlterTableType(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
22
|
+
|
|
23
|
+
getAlterTableDefaultInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
24
|
+
|
|
25
|
+
getAlterTablePrimaryKeyInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
26
|
+
|
|
27
|
+
getDropConstraint(param: {name: string}, schema: string | undefined, tableName: string): string;
|
|
28
|
+
|
|
29
|
+
getAddUniqueConstraint(schema: string | undefined, tableName: string, colName: string): string;
|
|
30
|
+
|
|
31
|
+
getAlterTableDropNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
32
|
+
|
|
33
|
+
getAlterTableDropNotNullInstruction(schema: string | undefined, tableName: string, colName: string, colDiff: ColDiff): string;
|
|
34
|
+
|
|
35
|
+
startTransaction(): Promise<void>;
|
|
36
|
+
commitTransaction(): Promise<void>;
|
|
37
|
+
rollbackTransaction(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type SnapshotConstraintInfo = {
|
|
41
|
+
indexName: string;
|
|
42
|
+
consDef: string;
|
|
43
|
+
type: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ConnectionSettings<T extends DriverInterface = DriverInterface> {
|
|
47
|
+
host?: string;
|
|
48
|
+
port?: number;
|
|
49
|
+
username?: string;
|
|
50
|
+
password?: string;
|
|
51
|
+
database?: string;
|
|
52
|
+
connectionString?: string;
|
|
53
|
+
ssl?: boolean;
|
|
54
|
+
driver: T;
|
|
55
|
+
entities?: Function[] | string;
|
|
56
|
+
migrationPath?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type ConditionOperators<T, C> = {
|
|
60
|
+
$ne?: T;
|
|
61
|
+
$in?: T[];
|
|
62
|
+
$nin?: T[];
|
|
63
|
+
$like?: string;
|
|
64
|
+
$gt?: T;
|
|
65
|
+
$gte?: T;
|
|
66
|
+
$lt?: T;
|
|
67
|
+
$lte?: T;
|
|
68
|
+
|
|
69
|
+
$and?: Condition<C>[];
|
|
70
|
+
$or?: Condition<C>[];
|
|
71
|
+
// adicione aqui os demais operadores que precisar
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export type Condition<T> = {
|
|
75
|
+
[P in keyof T]?: T[P] | ConditionOperators<T[P], T>;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export type InstanceOf<T> = {
|
|
79
|
+
[key in keyof T]: T[key]
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type JoinStatement<T> = {
|
|
83
|
+
type: 'INNER' | 'LEFT' | 'RIGHT';
|
|
84
|
+
originalEntity?: Function;
|
|
85
|
+
originTable: string;
|
|
86
|
+
originSchema: string;
|
|
87
|
+
originAlias: string;
|
|
88
|
+
joinTable: string;
|
|
89
|
+
joinSchema: string;
|
|
90
|
+
joinAlias: string;
|
|
91
|
+
joinEntity?: Function;
|
|
92
|
+
joinWhere?: string;
|
|
93
|
+
joinProperty: string;
|
|
94
|
+
on: string;
|
|
95
|
+
propertyKey: string | symbol;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export type Statement<T> = {
|
|
99
|
+
statement?: 'select' | 'insert' | 'update' | 'delete';
|
|
100
|
+
table?: string;
|
|
101
|
+
alias?: string;
|
|
102
|
+
columns?: Array<keyof T>;
|
|
103
|
+
join?: JoinStatement<T>[];
|
|
104
|
+
where?: string;
|
|
105
|
+
values?: any;
|
|
106
|
+
groupBy?: string[];
|
|
107
|
+
orderBy?: string[];
|
|
108
|
+
limit?: number;
|
|
109
|
+
offset?: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface SnapshotColumnInfo {
|
|
113
|
+
table_catalog: string;
|
|
114
|
+
table_schema: string;
|
|
115
|
+
table_name: string;
|
|
116
|
+
column_name: string;
|
|
117
|
+
ordinal_position: number;
|
|
118
|
+
column_default: string | null;
|
|
119
|
+
is_nullable: string;
|
|
120
|
+
data_type: string;
|
|
121
|
+
character_maximum_length: number | null;
|
|
122
|
+
character_octet_length: number | null;
|
|
123
|
+
numeric_precision: number | null;
|
|
124
|
+
numeric_scale: number | null;
|
|
125
|
+
datetime_precision: number | null;
|
|
126
|
+
character_set_name: string | null;
|
|
127
|
+
collation_name: string | null;
|
|
128
|
+
column_type: string;
|
|
129
|
+
column_key: string;
|
|
130
|
+
extra: string;
|
|
131
|
+
privileges: string;
|
|
132
|
+
column_comment: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export type SnapshotTable = {
|
|
136
|
+
tableName: string;
|
|
137
|
+
schema?: string;
|
|
138
|
+
columns: ColumnsInfo[];
|
|
139
|
+
indexes: SnapshotIndexInfo[];
|
|
140
|
+
foreignKeys?: ForeignKeyInfo[];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export type SnapshotIndexInfo = {
|
|
144
|
+
table: string;
|
|
145
|
+
indexName: string;
|
|
146
|
+
columnName: string;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export type ForeignKeyInfo = {
|
|
150
|
+
referencedTableName: string;
|
|
151
|
+
referencedColumnName: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export type ColumnsInfo = {
|
|
155
|
+
name: string;
|
|
156
|
+
type: string;
|
|
157
|
+
nullable?: boolean;
|
|
158
|
+
default?: string | null;
|
|
159
|
+
primary?: boolean;
|
|
160
|
+
unique?: boolean;
|
|
161
|
+
length?: number;
|
|
162
|
+
foreignKeys?: ForeignKeyInfo[];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export type SqlActionType = 'CREATE' | 'DELETE' | 'ALTER' | 'INDEX';
|
|
166
|
+
|
|
167
|
+
export type ColDiff = {
|
|
168
|
+
actionType: SqlActionType;
|
|
169
|
+
colName: string;
|
|
170
|
+
colType?: string;
|
|
171
|
+
colLength?: number;
|
|
172
|
+
indexTables?: { name: string, properties?: string[] }[];
|
|
173
|
+
colChanges?: {
|
|
174
|
+
default?: string | null;
|
|
175
|
+
primary?: boolean;
|
|
176
|
+
unique?: boolean;
|
|
177
|
+
nullable?: boolean;
|
|
178
|
+
foreignKeys?: ForeignKeyInfo[];
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export type TableDiff = {
|
|
183
|
+
tableName: string;
|
|
184
|
+
schema?: string;
|
|
185
|
+
newTable?: boolean;
|
|
186
|
+
colDiffs: ColDiff[];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export declare const PrimaryKeyType: unique symbol;
|
|
190
|
+
export declare const PrimaryKeyProp: unique symbol;
|
|
191
|
+
type ReadonlyPrimary<T> = T extends any[] ? Readonly<T> : T;
|
|
192
|
+
export type Primary<T> = T extends {
|
|
193
|
+
[PrimaryKeyType]?: infer PK;
|
|
194
|
+
} ? ReadonlyPrimary<PK> : T extends {
|
|
195
|
+
_id?: infer PK;
|
|
196
|
+
} ? ReadonlyPrimary<PK> | string : T extends {
|
|
197
|
+
uuid?: infer PK;
|
|
198
|
+
} ? ReadonlyPrimary<PK> : T extends {
|
|
199
|
+
id?: infer PK;
|
|
200
|
+
} ? ReadonlyPrimary<PK> : never;
|
|
201
|
+
export type PrimaryProperty<T> = T extends {
|
|
202
|
+
[PrimaryKeyProp]?: infer PK;
|
|
203
|
+
} ? PK : T extends {
|
|
204
|
+
_id?: any;
|
|
205
|
+
} ? '_id' | string : T extends {
|
|
206
|
+
uuid?: any;
|
|
207
|
+
} ? 'uuid' : T extends {
|
|
208
|
+
id?: any;
|
|
209
|
+
} ? 'id' : never;
|
|
210
|
+
export type IPrimaryKeyValue = number | string | bigint | Date | {
|
|
211
|
+
toHexString(): string;
|
|
212
|
+
};
|
|
213
|
+
export type IPrimaryKey<T extends IPrimaryKeyValue = IPrimaryKeyValue> = T;
|
|
214
|
+
export type OperatorMap<T> = {
|
|
215
|
+
$and?: Query<T>[];
|
|
216
|
+
$or?: Query<T>[];
|
|
217
|
+
$eq?: ExpandScalar<T> | ExpandScalar<T>[];
|
|
218
|
+
$ne?: ExpandScalar<T>;
|
|
219
|
+
$in?: ExpandScalar<T>[];
|
|
220
|
+
$nin?: ExpandScalar<T>[];
|
|
221
|
+
$not?: Query<T>;
|
|
222
|
+
$gt?: ExpandScalar<T>;
|
|
223
|
+
$gte?: ExpandScalar<T>;
|
|
224
|
+
$lt?: ExpandScalar<T>;
|
|
225
|
+
$lte?: ExpandScalar<T>;
|
|
226
|
+
$like?: string;
|
|
227
|
+
|
|
228
|
+
};
|
|
229
|
+
export type ExcludeFunctions<T, K extends keyof T> = T[K] extends Function ? never : (K extends symbol ? never : K);
|
|
230
|
+
export type Scalar = boolean | number | string | bigint | symbol | Date | RegExp | Uint8Array | {
|
|
231
|
+
toHexString(): string;
|
|
232
|
+
};
|
|
233
|
+
//TODO: editar
|
|
234
|
+
export type ExpandProperty<T> = T extends (infer U)[] ? NonNullable<U> : NonNullable<T> ;
|
|
235
|
+
export type ExpandScalar<T> = null | (T extends string ? T | RegExp : T extends Date ? Date | string : T);
|
|
236
|
+
type ExpandObject<T> = T extends object ? T extends Scalar ? never : {
|
|
237
|
+
-readonly [K in keyof T as ExcludeFunctions<T, K>]?: Query<ExpandProperty<T[K]>> | FilterValue<ExpandProperty<T[K]>> | null;
|
|
238
|
+
} : never;
|
|
239
|
+
export type EntityProps<T> = {
|
|
240
|
+
-readonly [K in keyof T as ExcludeFunctions<T, K>]?: T[K];
|
|
241
|
+
};
|
|
242
|
+
export type Query<T> = T extends object ? T extends Scalar ? never : FilterQuery<T> : FilterValue<T>;
|
|
243
|
+
export type FilterValue2<T> = T | ExpandScalar<T> | Primary<T>;
|
|
244
|
+
export type FilterValue<T> = OperatorMap<FilterValue2<T>> | FilterValue2<T> | FilterValue2<T>[] | null;
|
|
245
|
+
export type EntityClass<T> = Function & { prototype: T };
|
|
246
|
+
export type EntityName<T> = string | EntityClass<T> | { name: string };
|
|
247
|
+
export type ObjectQuery<T> = ExpandObject<T> & OperatorMap<T>;
|
|
248
|
+
export type FilterQuery<T> = ObjectQuery<T> | NonNullable<ExpandScalar<Primary<T>>> | NonNullable<EntityProps<T> & OperatorMap<T>> | FilterQuery<T>[];
|
|
249
|
+
|
|
250
|
+
export type Relationship<T> = {
|
|
251
|
+
isRelation?: boolean;
|
|
252
|
+
relation: 'one-to-many' | 'many-to-one';
|
|
253
|
+
type: Function;
|
|
254
|
+
fkKey?: (string & keyof T) | ((e: T) => any);
|
|
255
|
+
entity: () => EntityName<T>;
|
|
256
|
+
originalEntity?: EntityName<T>;
|
|
257
|
+
propertyKey: string | symbol;
|
|
258
|
+
} & Partial<PropertyOptions>;
|
|
259
|
+
|
|
260
|
+
export type Cast<T, R> = T extends R ? T : R;
|
|
261
|
+
export type IsUnknown<T> = T extends unknown ? unknown extends T ? true : never : never;
|
|
262
|
+
export type IdentifiedReference<T, PK extends keyof T | unknown = PrimaryProperty<T>> = true extends IsUnknown<PK> ? Reference<T> : ({
|
|
263
|
+
[K in Cast<PK, keyof T>]: T[K];
|
|
264
|
+
} & Reference<T>);
|
|
265
|
+
export type Ref<T, PK extends keyof T | unknown = PrimaryProperty<T>> = IdentifiedReference<T, PK>;
|
|
266
|
+
type Loadable<T extends object> = Collection<T, any> | Reference<T> | readonly T[];
|
|
267
|
+
type ExtractType<T> = T extends Loadable<infer U> ? U : T;
|
|
268
|
+
type StringKeys<T, E extends string = never> = T extends Collection<any, any> ? `${Exclude<keyof ExtractType<T> | E, symbol>}` : T extends Ref<any> ? `${Exclude<keyof ExtractType<T> | E, symbol>}` : T extends object ? `${Exclude<keyof ExtractType<T> | E, symbol>}` : never;
|
|
269
|
+
type Defined<T> = Exclude<T, null | undefined>;
|
|
270
|
+
type GetStringKey<T, K extends StringKeys<T, string>, E extends string> = K extends keyof T ? ExtractType<T[K]> : (K extends E ? keyof T : never);
|
|
271
|
+
type Prev = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
272
|
+
export type AutoPath<
|
|
273
|
+
O,
|
|
274
|
+
P extends string,
|
|
275
|
+
E extends string = never,
|
|
276
|
+
D extends Prev[number] = 5
|
|
277
|
+
> = [D] extends [never]
|
|
278
|
+
? string
|
|
279
|
+
: P extends any
|
|
280
|
+
? (P & `${string}.` extends never
|
|
281
|
+
? P
|
|
282
|
+
: P & `${string}.`) extends infer Q
|
|
283
|
+
? Q extends `${infer A}.${infer B}`
|
|
284
|
+
? A extends StringKeys<O, E>
|
|
285
|
+
? `${A}.${AutoPath<Defined<GetStringKey<O, A, E>>, B, E, Prev[D]>}`
|
|
286
|
+
: never
|
|
287
|
+
: Q extends StringKeys<O, E>
|
|
288
|
+
? (Defined<GetStringKey<O, Q, E>> extends unknown
|
|
289
|
+
? Exclude<P, `${string}.`>
|
|
290
|
+
: never) | (StringKeys<Defined<GetStringKey<O, Q, E>>, E> extends never
|
|
291
|
+
? never
|
|
292
|
+
: `${Q}.`)
|
|
293
|
+
: keyof ExtractType<O>
|
|
294
|
+
: never
|
|
295
|
+
: never;
|
|
296
|
+
|
|
297
|
+
export declare enum QueryOrder {
|
|
298
|
+
ASC = "ASC",
|
|
299
|
+
ASC_NULLS_LAST = "ASC NULLS LAST",
|
|
300
|
+
ASC_NULLS_FIRST = "ASC NULLS FIRST",
|
|
301
|
+
DESC = "DESC",
|
|
302
|
+
DESC_NULLS_LAST = "DESC NULLS LAST",
|
|
303
|
+
DESC_NULLS_FIRST = "DESC NULLS FIRST",
|
|
304
|
+
asc = "asc",
|
|
305
|
+
asc_nulls_last = "asc nulls last",
|
|
306
|
+
asc_nulls_first = "asc nulls first",
|
|
307
|
+
desc = "desc",
|
|
308
|
+
desc_nulls_last = "desc nulls last",
|
|
309
|
+
desc_nulls_first = "desc nulls first"
|
|
310
|
+
}
|
|
311
|
+
export declare enum QueryOrderNumeric {
|
|
312
|
+
ASC = 1,
|
|
313
|
+
DESC = -1
|
|
314
|
+
}
|
|
315
|
+
export type QueryOrderKeysFlat = QueryOrder | QueryOrderNumeric | keyof typeof QueryOrder;
|
|
316
|
+
export type QueryOrderKeys<T> = QueryOrderKeysFlat | QueryOrderMap<T>;
|
|
317
|
+
export type QueryOrderMap<T> = {
|
|
318
|
+
[K in keyof T as ExcludeFunctions<T, K>]?: QueryOrderKeys<ExpandProperty<T[K]>>;
|
|
319
|
+
};
|
|
320
|
+
export type EntityField<T, P extends string = never> = AutoPath<T, P, '*'>;
|
|
321
|
+
export interface FindOptions<T, P extends string = never> {
|
|
322
|
+
// populate?: readonly AutoPath<T, P>[] | boolean;
|
|
323
|
+
orderBy?: (QueryOrderMap<T> & {
|
|
324
|
+
0?: never;
|
|
325
|
+
}) | QueryOrderMap<T>[];
|
|
326
|
+
// cache?: boolean | number | [string, number];
|
|
327
|
+
limit?: number;
|
|
328
|
+
offset?: number;
|
|
329
|
+
fields?: readonly EntityField<T, P>[];
|
|
330
|
+
}
|
|
331
|
+
export type FindOneOption<T, P extends string = never> = Omit<FindOptions<T, P>, 'limit'|'offset'>
|