@zuzjs/orm 0.1.4 → 0.1.6

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.
@@ -140,30 +140,41 @@ class MySqlDriver {
140
140
  console.log(picocolors_1.default.cyan(`○ ${tables.length} Tables Found.`));
141
141
  const tableNames = tables.map((row) => Object.values(row)[0]);
142
142
  console.log(picocolors_1.default.yellow(`○ Generating Models...`));
143
+ // Fetch foreign keys
144
+ const foreignKeys = {};
143
145
  for (const tableName of tableNames) {
146
+ const [fkResults] = await this.pool.execute(`SELECT COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
147
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
148
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND REFERENCED_TABLE_NAME IS NOT NULL`, [this.conn.database, tableName]);
149
+ foreignKeys[tableName] = fkResults;
150
+ }
151
+ for (const tableName of tableNames) {
152
+ const imports = [];
153
+ const _imports = [`Entity`, `BaseEntity`];
144
154
  // Get table structure
145
- const [columns] = await self.pool.execute(`DESCRIBE ${tableName}`);
146
- const entityCode = [
147
- `/**`,
148
- `* AutoGenerated by @zuzjs/orm.`,
149
- `* @ ${new Date().toString().split(` GMT`)[0].trim()}`,
150
- `*/`,
151
- `import { Entity, PrimaryColumn, PrimaryGeneratedColumn, Column, BaseEntity } from "@zuzjs/orm";\n`,
152
- `@Entity({ name: "${tableName}" })`,
153
- `export class ${(0, index_js_1.toPascalCase)(tableName)} extends BaseEntity {\n`
154
- ];
155
+ // const [columns]: [any[], any] = await self.pool!.execute(`DESCRIBE ${tableName}`);
156
+ const [columns] = await this.pool.execute(`SELECT COLUMN_NAME as \`Field\`, COLUMN_TYPE as \`Type\`, COLUMN_KEY as \`Key\`, IS_NULLABLE as \`Null\`, COLUMN_DEFAULT as \`Default\`, EXTRA as \`Extra\`, COLUMN_COMMENT as \`Comment\`
157
+ FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION ASC`, [this.conn.database, tableName]);
158
+ const entityCode = [];
155
159
  let hasPrimary = false;
156
160
  for (const column of columns) {
157
- // const { Field, Type, Key } = column;
158
- const { Field, Type, Key, Null, Default, Extra } = column;
161
+ // console.log(tableName, column)
162
+ const { Field, Type, Key, Null, Default, Extra, Comment } = column;
159
163
  const { tsType, columnType, length } = this.mapColumns(Type);
160
164
  // Handle primary key
161
165
  if (Key === "PRI") {
162
- entityCode.push(Extra.includes("auto_increment") ? `\t@PrimaryGeneratedColumn()` : `\t@PrimaryColumn()`);
166
+ const _priColumn = Extra.includes("auto_increment") ? `PrimaryGeneratedColumn` : `PrimaryColumn`;
167
+ if (!_imports.includes(_priColumn))
168
+ _imports.push(_priColumn);
169
+ entityCode.push(`\t@${_priColumn}()`);
163
170
  hasPrimary = true;
164
171
  }
165
172
  else {
173
+ // const hasForeignKey = foreignKeys[tableName as string].find((fk) => fk.COLUMN_NAME === Field);
174
+ // let columnDecorator = hasForeignKey ? `\t@JoinColumn({ type: "${columnType}"` : `\t@Column({ type: "${columnType}"`;
166
175
  let columnDecorator = `\t@Column({ type: "${columnType}"`;
176
+ if (!_imports.includes(`Column`))
177
+ _imports.push(`Column`);
167
178
  if (length)
168
179
  columnDecorator += `, length: ${length}`;
169
180
  if (Null === "YES")
@@ -173,14 +184,42 @@ class MySqlDriver {
173
184
  columnDecorator += ` })`;
174
185
  entityCode.push(columnDecorator);
175
186
  }
187
+ if (Comment && Comment.length > 0) {
188
+ entityCode.push(`\t/** @comment ${Comment} */`);
189
+ }
176
190
  entityCode.push(`\t${Field}!: ${tsType};\n`);
177
191
  }
178
- entityCode.push(`}`);
192
+ // Add foreign key relationships
193
+ if (foreignKeys[tableName]) {
194
+ for (const fk of foreignKeys[tableName] || []) {
195
+ const relatedEntity = (0, index_js_1.toPascalCase)(fk.REFERENCED_TABLE_NAME);
196
+ entityCode.push(`\t@OneToOne(() => ${relatedEntity})`);
197
+ entityCode.push(`\t@JoinColumn({ name: "${fk.COLUMN_NAME}" })`);
198
+ entityCode.push(`\tfk${relatedEntity}!: ${relatedEntity};\n`);
199
+ imports.push(`import { ${relatedEntity} } from "./${fk.REFERENCED_TABLE_NAME}";`);
200
+ if (!_imports.includes(`OneToOne`))
201
+ _imports.push(`OneToOne`);
202
+ if (!_imports.includes(`JoinColumn`))
203
+ _imports.push(`JoinColumn`);
204
+ }
205
+ }
206
+ const Code = [
207
+ `/**`,
208
+ `* AutoGenerated by @zuzjs/orm.`,
209
+ `* @ ${new Date().toString().split(` GMT`)[0].trim()}`,
210
+ `*/`,
211
+ `import { ${_imports.join(`, `)} } from "@zuzjs/orm";`,
212
+ imports.length > 0 ? imports.join(`\n`) : ``,
213
+ `${imports.length > 0 ? `\n` : ``}@Entity({ name: "${tableName}" })`,
214
+ `export class ${(0, index_js_1.toPascalCase)(tableName)} extends BaseEntity {\n`,
215
+ ...entityCode,
216
+ `}`
217
+ ];
179
218
  if (!hasPrimary) {
180
219
  console.log(picocolors_1.default.bgRed(picocolors_1.default.whiteBright(` WARNING `)), picocolors_1.default.yellow(`○ "${tableName}" does not have a primary column. Primary column is required.`));
181
220
  }
182
221
  // Write entity file
183
- fs_1.default.writeFileSync(path_1.default.join(this.dist, `${tableName}.ts`), entityCode.join(`\n`));
222
+ fs_1.default.writeFileSync(path_1.default.join(this.dist, `${tableName}.ts`), Code.join(`\n`));
184
223
  }
185
224
  await self.pool.end();
186
225
  console.log(picocolors_1.default.green(`✓ ${tables.length} Tables Processed.`));
@@ -1,4 +1,4 @@
1
- import { Repository, ObjectLiteral, FindOptionsWhere } from "typeorm";
1
+ import { Repository, ObjectLiteral } from "typeorm";
2
2
  import { QueryAction } from "../types";
3
3
  import { QueryResult } from "mysql2";
4
4
  import { QueryDeepPartialEntity } from "typeorm/query-builder/QueryPartialEntity";
@@ -22,6 +22,12 @@ declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends
22
22
  * @returns The current instance of ZormQueryBuilder.
23
23
  */
24
24
  with(data: QueryDeepPartialEntity<T> | QueryDeepPartialEntity<T[]>): this;
25
+ /**
26
+ * Sets the values for an insert or update query.
27
+ * @param data - The data to be inserted or updated.
28
+ * @returns The current instance of ZormQueryBuilder.
29
+ */
30
+ withData(data: QueryDeepPartialEntity<T> | QueryDeepPartialEntity<T[]>): this;
25
31
  /**
26
32
  * Specifies the fields to be selected in a select query.
27
33
  * @param fields - The fields to be selected.
@@ -40,7 +46,7 @@ declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends
40
46
  * @param condition - The condition to be added.
41
47
  * @returns The current instance of ZormQueryBuilder.
42
48
  */
43
- or(condition: FindOptionsWhere<T>): this;
49
+ or(condition: Partial<Record<keyof T, any>>): this;
44
50
  /**
45
51
  * Adds an ORDER BY clause to the query.
46
52
  * @param field - The field to order by.
@@ -65,7 +71,7 @@ declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends
65
71
  * @param relations - The relations to be included.
66
72
  * @returns The current instance of ZormQueryBuilder.
67
73
  */
68
- relations(relations: string[]): this;
74
+ withRelation(rel: string, ...more: string[]): this;
69
75
  /**
70
76
  * Adds an INNER JOIN clause to the query.
71
77
  * @param relation - The relation to join.
@@ -77,6 +77,15 @@ class ZormQueryBuilder extends Promise {
77
77
  this.queryValues = data;
78
78
  return this;
79
79
  }
80
+ /**
81
+ * Sets the values for an insert or update query.
82
+ * @param data - The data to be inserted or updated.
83
+ * @returns The current instance of ZormQueryBuilder.
84
+ */
85
+ withData(data) {
86
+ this.queryValues = data;
87
+ return this;
88
+ }
80
89
  /**
81
90
  * Specifies the fields to be selected in a select query.
82
91
  * @param fields - The fields to be selected.
@@ -88,20 +97,21 @@ class ZormQueryBuilder extends Promise {
88
97
  return this;
89
98
  }
90
99
  applyCondition(qb, condition, type) {
91
- Object.entries(condition).forEach(([key, value]) => {
100
+ Object.entries(condition).forEach(([key, value], index) => {
101
+ const paramKey = `${key}Param${index}_${this.whereCount}`; // Unique parameter name
92
102
  if (typeof value === "string") {
93
103
  const match = value.match(/^(!=|>=|<=|>|<|=)\s*(.+)$/); // Improved regex
94
104
  if (match) {
95
105
  const [, operator, rawValue] = match;
96
106
  const sqlOperator = operator; // Directly use the matched operator
97
- const paramKey = `${key}Param`; // Unique parameter name
98
107
  const parsedValue = !isNaN(Number(rawValue)) ? Number(rawValue) : rawValue.trim(); // Convert to number if possible
99
108
  qb[type](`${qb.alias}.${key} ${sqlOperator} :${paramKey}`, { [paramKey]: parsedValue });
100
109
  return;
101
110
  }
102
111
  }
103
112
  // Default case (normal equality condition)
104
- qb[type](`${this.entityAlias}.${key} = :${key}`, { [key]: value });
113
+ qb[type](`${this.entityAlias}.${key} = :${paramKey}`, { [paramKey]: value });
114
+ this.whereCount++;
105
115
  });
106
116
  }
107
117
  /**
@@ -112,7 +122,6 @@ class ZormQueryBuilder extends Promise {
112
122
  where(condition) {
113
123
  const qb = this.queryBuilder;
114
124
  this.applyCondition(qb, condition, `andWhere`);
115
- this.whereCount++;
116
125
  return this;
117
126
  }
118
127
  /**
@@ -158,8 +167,8 @@ class ZormQueryBuilder extends Promise {
158
167
  * @param relations - The relations to be included.
159
168
  * @returns The current instance of ZormQueryBuilder.
160
169
  */
161
- relations(relations) {
162
- relations.forEach(relation => this.queryBuilder.leftJoinAndSelect(`${this.entityAlias}.${relation}`, relation));
170
+ withRelation(rel, ...more) {
171
+ [rel, ...more].forEach(relation => this.queryBuilder.leftJoinAndSelect(`${this.entityAlias}.${relation}`, relation));
163
172
  return this;
164
173
  }
165
174
  /**
@@ -276,7 +285,6 @@ class ZormQueryBuilder extends Promise {
276
285
  case "create":
277
286
  this._create();
278
287
  const _create = await this.queryBuilder.execute();
279
- // console.log(_create)
280
288
  return {
281
289
  created: true,
282
290
  id: _create.raw.insertId,
package/dist/types.d.ts CHANGED
@@ -48,4 +48,4 @@ export type DeleteQueryResult = {
48
48
  count: number;
49
49
  error?: QueryError;
50
50
  };
51
- export { Entity, PrimaryColumn, PrimaryGeneratedColumn, Column, BaseEntity } from "typeorm";
51
+ export { Entity, PrimaryColumn, PrimaryGeneratedColumn, Column, BaseEntity, OneToOne, JoinColumn, } from "typeorm";
package/dist/types.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BaseEntity = exports.Column = exports.PrimaryGeneratedColumn = exports.PrimaryColumn = exports.Entity = void 0;
3
+ exports.JoinColumn = exports.OneToOne = exports.BaseEntity = exports.Column = exports.PrimaryGeneratedColumn = exports.PrimaryColumn = exports.Entity = void 0;
4
4
  var typeorm_1 = require("typeorm");
5
5
  Object.defineProperty(exports, "Entity", { enumerable: true, get: function () { return typeorm_1.Entity; } });
6
6
  Object.defineProperty(exports, "PrimaryColumn", { enumerable: true, get: function () { return typeorm_1.PrimaryColumn; } });
7
7
  Object.defineProperty(exports, "PrimaryGeneratedColumn", { enumerable: true, get: function () { return typeorm_1.PrimaryGeneratedColumn; } });
8
8
  Object.defineProperty(exports, "Column", { enumerable: true, get: function () { return typeorm_1.Column; } });
9
9
  Object.defineProperty(exports, "BaseEntity", { enumerable: true, get: function () { return typeorm_1.BaseEntity; } });
10
+ Object.defineProperty(exports, "OneToOne", { enumerable: true, get: function () { return typeorm_1.OneToOne; } });
11
+ Object.defineProperty(exports, "JoinColumn", { enumerable: true, get: function () { return typeorm_1.JoinColumn; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/orm",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "keywords": [
5
5
  "orm",
6
6
  "zuz",