@zuzjs/orm 0.2.3 → 0.2.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.
|
@@ -117,6 +117,13 @@ class MySqlDriver {
|
|
|
117
117
|
"time": { tsType: "string", columnType: "time" },
|
|
118
118
|
"json": { tsType: "any", columnType: "json" },
|
|
119
119
|
};
|
|
120
|
+
const enumMatch = sqlType.match(/^enum\((.*)\)$/i);
|
|
121
|
+
if (enumMatch) {
|
|
122
|
+
const enumValues = enumMatch[1]
|
|
123
|
+
.split(",")
|
|
124
|
+
.map((val) => val.trim().replace(/^'|'$/g, "")); // Remove single quotes
|
|
125
|
+
return { tsType: `"${enumValues.join('" | "')}"`, columnType: "enum", enumValues };
|
|
126
|
+
}
|
|
120
127
|
const match = sqlType.match(/^(\w+)(?:\((\d+)\))?/);
|
|
121
128
|
if (!match)
|
|
122
129
|
return { tsType: "any", columnType: "varchar", length: 255 };
|
|
@@ -150,6 +157,7 @@ class MySqlDriver {
|
|
|
150
157
|
foreignKeys[tableName] = fkResults;
|
|
151
158
|
}
|
|
152
159
|
for (const tableName of tableNames) {
|
|
160
|
+
const enums = [];
|
|
153
161
|
const imports = [];
|
|
154
162
|
const _imports = [`Entity`, `BaseEntity`];
|
|
155
163
|
// Get table structure
|
|
@@ -160,7 +168,13 @@ class MySqlDriver {
|
|
|
160
168
|
for (const column of columns) {
|
|
161
169
|
// console.log(tableName, column)
|
|
162
170
|
const { Field, Type, Key, Null, Default, Extra, Comment } = column;
|
|
163
|
-
const { tsType, columnType, length } = this.mapColumns(Type);
|
|
171
|
+
const { tsType, columnType, length, enumValues } = this.mapColumns(Type);
|
|
172
|
+
let enumName = null;
|
|
173
|
+
if (columnType === "enum" && enumValues) {
|
|
174
|
+
enumName = (0, index_js_1.toPascalCase)(Field);
|
|
175
|
+
enums.push(`export enum ${enumName} { ${enumValues.map(v => `${(0, index_js_1.toPascalCase)(v)} = "${v}"`).join(", ")} }`);
|
|
176
|
+
// entityCode.push(`\t@Column({ type: "enum", enum: ${enumName} })\n`);
|
|
177
|
+
}
|
|
164
178
|
// Handle primary key
|
|
165
179
|
if (Key === "PRI") {
|
|
166
180
|
const _priColumn = Extra.includes("auto_increment") ? `PrimaryGeneratedColumn` : `PrimaryColumn`;
|
|
@@ -179,6 +193,8 @@ class MySqlDriver {
|
|
|
179
193
|
columnDecorator += `, length: ${length}`;
|
|
180
194
|
if (Null === "YES")
|
|
181
195
|
columnDecorator += `, nullable: true`;
|
|
196
|
+
if (enumName)
|
|
197
|
+
columnDecorator += `, enum: ${enumName}`;
|
|
182
198
|
if (Default !== null)
|
|
183
199
|
columnDecorator += `, default: ${this.formatDefault(Default, tsType)}`;
|
|
184
200
|
columnDecorator += ` })`;
|
|
@@ -187,7 +203,7 @@ class MySqlDriver {
|
|
|
187
203
|
if (Comment && Comment.length > 0) {
|
|
188
204
|
entityCode.push(`\t/** @comment ${Comment} */`);
|
|
189
205
|
}
|
|
190
|
-
entityCode.push(`\t${Field}!: ${Key == `PRI` && numberTypes.includes(Type) ? `number` : numberTypes.includes(Type) ? `number` : tsType};\n`);
|
|
206
|
+
entityCode.push(`\t${Field}!: ${enumName ? enumName : Key == `PRI` && numberTypes.includes(Type) ? `number` : numberTypes.includes(Type) ? `number` : tsType};\n`);
|
|
191
207
|
}
|
|
192
208
|
// Add foreign key relationships
|
|
193
209
|
if (foreignKeys[tableName]) {
|
|
@@ -210,7 +226,8 @@ class MySqlDriver {
|
|
|
210
226
|
`*/`,
|
|
211
227
|
`import { ${_imports.join(`, `)} } from "@zuzjs/orm";`,
|
|
212
228
|
imports.length > 0 ? imports.join(`\n`) : ``,
|
|
213
|
-
|
|
229
|
+
enums.length > 0 ? enums.join(`\n`) : ``,
|
|
230
|
+
`${enums.length > 0 || imports.length > 0 ? `\n` : ``}@Entity({ name: "${tableName}" })`,
|
|
214
231
|
`export class ${(0, index_js_1.toPascalCase)(tableName)} extends BaseEntity {\n`,
|
|
215
232
|
...entityCode,
|
|
216
233
|
`}`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { QueryResult } from "mysql2";
|
|
2
2
|
import { ObjectLiteral, Repository } from "typeorm";
|
|
3
3
|
import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
|
|
4
|
-
import { QueryAction } from "../types";
|
|
4
|
+
import { PartialConditions, QueryAction } from "../types";
|
|
5
5
|
declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends Promise<R> {
|
|
6
6
|
private repository;
|
|
7
7
|
private queryBuilder;
|
|
@@ -44,13 +44,13 @@ declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends
|
|
|
44
44
|
* @param condition - The condition to be added.
|
|
45
45
|
* @returns The current instance of ZormQueryBuilder.
|
|
46
46
|
*/
|
|
47
|
-
where(condition:
|
|
47
|
+
where(condition: PartialConditions<T>): this;
|
|
48
48
|
/**
|
|
49
49
|
* Adds an OR condition to the query.
|
|
50
50
|
* @param condition - The condition to be added.
|
|
51
51
|
* @returns The current instance of ZormQueryBuilder.
|
|
52
52
|
*/
|
|
53
|
-
or(condition:
|
|
53
|
+
or(condition: PartialConditions<T>): this;
|
|
54
54
|
/**
|
|
55
55
|
* Adds an ORDER BY clause to the query.
|
|
56
56
|
* @param field - The field to order by.
|
|
@@ -124,7 +124,7 @@ declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends
|
|
|
124
124
|
* @returns The current instance of ZormQueryBuilder.
|
|
125
125
|
*/
|
|
126
126
|
distinct(): this;
|
|
127
|
-
count(): Promise<number>;
|
|
127
|
+
count(field?: keyof T): Promise<number>;
|
|
128
128
|
sum(field: keyof T): Promise<number>;
|
|
129
129
|
avg(field: keyof T): Promise<number>;
|
|
130
130
|
min(field: keyof T): Promise<number>;
|
|
@@ -111,6 +111,7 @@ class ZormQueryBuilder extends Promise {
|
|
|
111
111
|
applyCondition(qb, condition, type) {
|
|
112
112
|
Object.entries(condition).forEach(([key, value], index) => {
|
|
113
113
|
const paramKey = `${key}Param${index}_${this.whereCount}`; // Unique parameter name
|
|
114
|
+
let sqlOperator = "="; // Default to "="
|
|
114
115
|
if (typeof value === "string") {
|
|
115
116
|
const match = value.match(/^(!=|>=|<=|>|<|=)\s*(.+)$/); // Improved regex
|
|
116
117
|
if (match) {
|
|
@@ -121,6 +122,24 @@ class ZormQueryBuilder extends Promise {
|
|
|
121
122
|
return;
|
|
122
123
|
}
|
|
123
124
|
}
|
|
125
|
+
else if (typeof value === "object" && value !== null) {
|
|
126
|
+
// Support object-based conditions: { age: { gt: 18, lt: 20 } }
|
|
127
|
+
const operators = {
|
|
128
|
+
gt: ">",
|
|
129
|
+
gte: ">=",
|
|
130
|
+
lt: "<",
|
|
131
|
+
lte: "<=",
|
|
132
|
+
ne: "!=",
|
|
133
|
+
eq: "="
|
|
134
|
+
};
|
|
135
|
+
Object.entries(value).forEach(([opKey, opValue]) => {
|
|
136
|
+
if (operators[opKey]) {
|
|
137
|
+
const paramKey = `${key}Param_${opKey}_${this.whereCount++}`; // Unique param key
|
|
138
|
+
qb[type](`${qb.alias}.${key} ${operators[opKey]} :${paramKey}`, { [paramKey]: opValue });
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
return; // Prevent default equality case for objects
|
|
142
|
+
}
|
|
124
143
|
// Default case (normal equality condition)
|
|
125
144
|
qb[type](`${this.entityAlias}.${key} = :${paramKey}`, { [paramKey]: value });
|
|
126
145
|
this.whereCount++;
|
|
@@ -283,7 +302,10 @@ class ZormQueryBuilder extends Promise {
|
|
|
283
302
|
this.queryBuilder.distinct(true);
|
|
284
303
|
return this;
|
|
285
304
|
}
|
|
286
|
-
async count() {
|
|
305
|
+
async count(field) {
|
|
306
|
+
if (field) {
|
|
307
|
+
this.queryBuilder.select(`COUNT(${field})`);
|
|
308
|
+
}
|
|
287
309
|
return await this.queryBuilder.getCount();
|
|
288
310
|
}
|
|
289
311
|
async sum(field) {
|
package/dist/types.d.ts
CHANGED
|
@@ -17,6 +17,58 @@ export type ConnectionDetails = {
|
|
|
17
17
|
};
|
|
18
18
|
export type QueryAction = "create" | "upsert" | "select" | "update" | "delete";
|
|
19
19
|
export type QueryResult = InsertQueryResult | SelectQueryResult | UpdateQueryResult | DeleteQueryResult;
|
|
20
|
+
/**
|
|
21
|
+
* Defines supported comparison operators for filtering queries.
|
|
22
|
+
* Enables IntelliSense support in `.where()` conditions.
|
|
23
|
+
*
|
|
24
|
+
* @template T The type of the value being compared (e.g., number, string, Date).
|
|
25
|
+
*/
|
|
26
|
+
export type WhereOperators<T> = {
|
|
27
|
+
/**
|
|
28
|
+
* Greater than (`>`) operator.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* query.where({ age: { gt: 18 } }) // WHERE age > 18
|
|
32
|
+
*/
|
|
33
|
+
gt?: T;
|
|
34
|
+
/**
|
|
35
|
+
* Greater than or equal to (`>=`) operator.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* query.where({ price: { gte: 100 } }) // WHERE price >= 100
|
|
39
|
+
*/
|
|
40
|
+
gte?: T;
|
|
41
|
+
/**
|
|
42
|
+
* Less than (`<`) operator.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* query.where({ age: { lt: 30 } }) // WHERE age < 30
|
|
46
|
+
*/
|
|
47
|
+
lt?: T;
|
|
48
|
+
/**
|
|
49
|
+
* Less than or equal to (`<=`) operator.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* query.where({ date: { lte: '2024-01-01' } }) // WHERE date <= '2024-01-01'
|
|
53
|
+
*/
|
|
54
|
+
lte?: T;
|
|
55
|
+
/**
|
|
56
|
+
* Not equal (`!=`) operator.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* query.where({ status: { ne: 'inactive' } }) // WHERE status != 'inactive'
|
|
60
|
+
*/
|
|
61
|
+
ne?: T;
|
|
62
|
+
/**
|
|
63
|
+
* Equal (`=`) operator.
|
|
64
|
+
* This is typically unnecessary since `.where({ key: value })` already handles equality.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* query.where({ id: { eq: 1 } }) // WHERE id = 1
|
|
68
|
+
*/
|
|
69
|
+
eq?: T;
|
|
70
|
+
};
|
|
71
|
+
export type PartialConditions<T> = Partial<Record<keyof T, string | number | boolean | WhereOperators<any>>>;
|
|
20
72
|
export type QueryError = {
|
|
21
73
|
code: number | string;
|
|
22
74
|
message: string;
|