@zuzjs/orm 0.3.4 → 0.3.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.
@@ -156,6 +156,51 @@ class MySqlDriver {
156
156
  WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND REFERENCED_TABLE_NAME IS NOT NULL`, [this.conn.database, tableName]);
157
157
  foreignKeys[tableName] = fkResults;
158
158
  }
159
+ // Track inverse relations: { tableName: { fkColumn: targetTable } }
160
+ const inverseRelations = {};
161
+ // Populate inverse map
162
+ for (const [tableName, fks] of Object.entries(foreignKeys)) {
163
+ for (const fk of fks) {
164
+ const targetTable = fk.REFERENCED_TABLE_NAME;
165
+ const fkColumn = fk.COLUMN_NAME;
166
+ const fkPropName = `fk${(0, index_js_1.toPascalCase)(targetTable)}`;
167
+ if (!inverseRelations[targetTable]) {
168
+ inverseRelations[targetTable] = [];
169
+ }
170
+ inverseRelations[targetTable].push({
171
+ fkColumn,
172
+ fkPropName,
173
+ targetTable: tableName,
174
+ targetEntity: (0, index_js_1.toPascalCase)(tableName),
175
+ });
176
+ }
177
+ }
178
+ // Detect 2 Column Junction Tables for ManyToMany
179
+ const junctionTables = {};
180
+ for (const tableName of tableNames) {
181
+ const [cols] = await this.pool.execute(`SELECT COLUMN_NAME, COLUMN_KEY, EXTRA FROM INFORMATION_SCHEMA.COLUMNS
182
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`, [this.conn.database, tableName]);
183
+ const fks = foreignKeys[String(tableName)] || [];
184
+ if (fks.length !== 2)
185
+ continue;
186
+ // Must have exactly 2 columns
187
+ if (cols.length !== 2)
188
+ continue;
189
+ // Both columns must be primary key
190
+ if (cols.filter(c => c.COLUMN_KEY !== 'PRI').length > 0)
191
+ continue;
192
+ const [left, right] = fks;
193
+ const [t1, t2] = [left.REFERENCED_TABLE_NAME, right.REFERENCED_TABLE_NAME].sort();
194
+ const key = `${t1}_${t2}`;
195
+ if (!junctionTables[key]) {
196
+ junctionTables[key] = {
197
+ left: t1,
198
+ right: t2,
199
+ leftCol: left.COLUMN_NAME,
200
+ rightCol: right.COLUMN_NAME
201
+ };
202
+ }
203
+ }
159
204
  for (const tableName of tableNames) {
160
205
  const enums = [];
161
206
  const imports = [];
@@ -222,6 +267,44 @@ class MySqlDriver {
222
267
  }
223
268
  }
224
269
  }
270
+ // Add OneToMany Relations
271
+ const inverse = inverseRelations[String(tableName)] || [];
272
+ for (const rel of inverse) {
273
+ const propName = rel.targetTable.endsWith('s') ? rel.targetTable : `${rel.targetTable}s`;
274
+ if (entityCode.some(line => line.includes(` ${propName}!:`)))
275
+ continue;
276
+ const importLine = `import { ${rel.targetEntity} } from "./${rel.targetTable}";`;
277
+ if (!imports.includes(importLine))
278
+ imports.push(importLine);
279
+ if (!_imports.includes('OneToMany'))
280
+ _imports.push('OneToMany');
281
+ // CORRECT: Inverse is fk + referenced table (e.g. fkUsers)
282
+ entityCode.push(`\t@OneToMany(() => ${rel.targetEntity}, r => r.${rel.fkPropName})`);
283
+ entityCode.push(`\tfk${(0, index_js_1.toPascalCase)(propName)}!: ${rel.targetEntity}[];\n`);
284
+ // entityCode.push(`\t@OneToMany(() => ${targetEntity}, r => r.${rel.fkColumn})`);
285
+ // entityCode.push(`\tfk${toPascalCase(propName)}!: ${targetEntity}[];\n`);
286
+ }
287
+ // Add Many-to-Many Relations
288
+ const junctions = Object.values(junctionTables)
289
+ .filter(j => j.left === tableName || j.right === tableName);
290
+ for (const j of junctions) {
291
+ const targetTable = j.left === tableName ? j.right : j.left;
292
+ const targetEntity = (0, index_js_1.toPascalCase)(targetTable);
293
+ const propName = targetTable.endsWith('s') ? targetTable : `${targetTable}s`;
294
+ if (entityCode.some(line => line.includes(`@${propName}`)))
295
+ continue;
296
+ const importLine = `import { ${targetEntity} } from "./${targetTable}";`;
297
+ if (!imports.includes(importLine)) {
298
+ imports.push(importLine);
299
+ }
300
+ if (!_imports.includes('ManyToMany'))
301
+ _imports.push('ManyToMany');
302
+ if (!_imports.includes('JoinTable'))
303
+ _imports.push('JoinTable');
304
+ entityCode.push(`\t@ManyToMany(() => ${targetEntity})`);
305
+ entityCode.push(`\t@JoinTable()`);
306
+ entityCode.push(`\tom${propName}!: ${targetEntity}[];\n`);
307
+ }
225
308
  const Code = [
226
309
  `/**`,
227
310
  `* AutoGenerated by @zuzjs/orm.`,
@@ -241,6 +324,11 @@ class MySqlDriver {
241
324
  // Write entity file
242
325
  fs_1.default.writeFileSync(path_1.default.join(this.dist, `${tableName}.ts`), Code.join(`\n`));
243
326
  }
327
+ // Write entry file i.e index.ts
328
+ const entry = tableNames
329
+ .map(tableName => `import { ${(0, index_js_1.toPascalCase)(tableName)} } from "./${tableName}";`);
330
+ entry.push(`import Zorm from "@zuzjs/orm";`, `import de from "dotenv";`, `de.config()`, `const zorm = Zorm.get(process.env.DATABASE_URL!);`, `zorm.connect([${tableNames.map(t => (0, index_js_1.toPascalCase)(t)).join(`, `)}]);`, `export default zorm`, `export { ${tableNames.map(t => (0, index_js_1.toPascalCase)(t)).join(`, `)} }`);
331
+ fs_1.default.writeFileSync(path_1.default.join(this.dist, `index.ts`), entry.join(`\n`));
244
332
  await self.pool.end();
245
333
  console.log(picocolors_1.default.green(`✓ ${tables.length} Tables Processed.`));
246
334
  }
@@ -13,6 +13,7 @@ declare class ZormQueryBuilder<T extends ObjectLiteral, R = QueryResult> extends
13
13
  private whereCount;
14
14
  private isActiveRecord;
15
15
  private activeRecord;
16
+ private joinedAliases;
16
17
  constructor(repository: Repository<T>, _action: QueryAction, _usePromise?: boolean);
17
18
  _create(): this;
18
19
  upsert(): this;
@@ -16,6 +16,8 @@ class ZormQueryBuilder extends Promise {
16
16
  whereCount = 0;
17
17
  isActiveRecord = false;
18
18
  activeRecord;
19
+ joinedAliases = {};
20
+ // private currentWhereLogic: 'AND' | 'OR' = 'AND';
19
21
  constructor(repository, _action, _usePromise) {
20
22
  super(() => { }); // Required for extending Promise
21
23
  this.repository = repository;
@@ -146,7 +148,7 @@ class ZormQueryBuilder extends Promise {
146
148
  const match = value.match(/^(!=|>=|<=|>|<|=)\s*(.+)$/); // Improved regex
147
149
  if (match) {
148
150
  const [, operator, rawValue] = match;
149
- const sqlOperator = operator; // Directly use the matched operator
151
+ sqlOperator = operator; // Directly use the matched operator
150
152
  const parsedValue = !isNaN(Number(rawValue)) ? Number(rawValue) : rawValue.trim(); // Convert to number if possible
151
153
  qb[type](`${qb.alias}.${key} ${sqlOperator} :${paramKey}`, { [paramKey]: parsedValue });
152
154
  return;
@@ -273,6 +275,7 @@ class ZormQueryBuilder extends Promise {
273
275
  else {
274
276
  this.queryBuilder.innerJoin(`${this.entityAlias}.${relation}`, alias);
275
277
  }
278
+ this.joinedAliases[alias] = relation;
276
279
  return this;
277
280
  }
278
281
  /**
@@ -289,6 +292,7 @@ class ZormQueryBuilder extends Promise {
289
292
  else {
290
293
  this.queryBuilder.leftJoin(`${this.entityAlias}.${relation}`, alias);
291
294
  }
295
+ this.joinedAliases[alias] = relation;
292
296
  return this;
293
297
  }
294
298
  /**
package/dist/types.d.ts CHANGED
@@ -101,4 +101,4 @@ export type DeleteQueryResult = {
101
101
  count: number;
102
102
  error?: QueryError;
103
103
  };
104
- export { BaseEntity, Column, Entity, JoinColumn, OneToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
104
+ export { BaseEntity, Column, Entity, JoinColumn, ManyToMany, ManyToOne, OneToMany, OneToOne, PrimaryColumn, PrimaryGeneratedColumn } from "typeorm";
package/dist/types.js CHANGED
@@ -1,11 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PrimaryGeneratedColumn = exports.PrimaryColumn = exports.OneToOne = exports.JoinColumn = exports.Entity = exports.Column = exports.BaseEntity = void 0;
3
+ exports.PrimaryGeneratedColumn = exports.PrimaryColumn = exports.OneToOne = exports.OneToMany = exports.ManyToOne = exports.ManyToMany = exports.JoinColumn = exports.Entity = exports.Column = exports.BaseEntity = void 0;
4
4
  var typeorm_1 = require("typeorm");
5
5
  Object.defineProperty(exports, "BaseEntity", { enumerable: true, get: function () { return typeorm_1.BaseEntity; } });
6
6
  Object.defineProperty(exports, "Column", { enumerable: true, get: function () { return typeorm_1.Column; } });
7
7
  Object.defineProperty(exports, "Entity", { enumerable: true, get: function () { return typeorm_1.Entity; } });
8
8
  Object.defineProperty(exports, "JoinColumn", { enumerable: true, get: function () { return typeorm_1.JoinColumn; } });
9
+ Object.defineProperty(exports, "ManyToMany", { enumerable: true, get: function () { return typeorm_1.ManyToMany; } });
10
+ Object.defineProperty(exports, "ManyToOne", { enumerable: true, get: function () { return typeorm_1.ManyToOne; } });
11
+ Object.defineProperty(exports, "OneToMany", { enumerable: true, get: function () { return typeorm_1.OneToMany; } });
9
12
  Object.defineProperty(exports, "OneToOne", { enumerable: true, get: function () { return typeorm_1.OneToOne; } });
10
13
  Object.defineProperty(exports, "PrimaryColumn", { enumerable: true, get: function () { return typeorm_1.PrimaryColumn; } });
11
14
  Object.defineProperty(exports, "PrimaryGeneratedColumn", { enumerable: true, get: function () { return typeorm_1.PrimaryGeneratedColumn; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/orm",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "keywords": [
5
5
  "orm",
6
6
  "zuz",