@zuzjs/orm 0.3.5 → 0.3.7

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.
@@ -163,13 +163,15 @@ class MySqlDriver {
163
163
  for (const fk of fks) {
164
164
  const targetTable = fk.REFERENCED_TABLE_NAME;
165
165
  const fkColumn = fk.COLUMN_NAME;
166
+ const fkPropName = `fk${(0, index_js_1.toPascalCase)(targetTable)}`;
166
167
  if (!inverseRelations[targetTable]) {
167
168
  inverseRelations[targetTable] = [];
168
169
  }
169
170
  inverseRelations[targetTable].push({
170
171
  fkColumn,
172
+ fkPropName,
171
173
  targetTable: tableName,
172
- targetEntity: (0, index_js_1.toPascalCase)(tableName)
174
+ targetEntity: (0, index_js_1.toPascalCase)(tableName),
173
175
  });
174
176
  }
175
177
  }
@@ -269,17 +271,18 @@ class MySqlDriver {
269
271
  const inverse = inverseRelations[String(tableName)] || [];
270
272
  for (const rel of inverse) {
271
273
  const propName = rel.targetTable.endsWith('s') ? rel.targetTable : `${rel.targetTable}s`;
272
- // Avoid duplicate
273
- if (entityCode.some(line => line.includes(`@${propName}`)))
274
+ if (entityCode.some(line => line.includes(` ${propName}!:`)))
274
275
  continue;
275
276
  const importLine = `import { ${rel.targetEntity} } from "./${rel.targetTable}";`;
276
- if (!imports.includes(importLine)) {
277
+ if (!imports.includes(importLine))
277
278
  imports.push(importLine);
278
- }
279
279
  if (!_imports.includes('OneToMany'))
280
280
  _imports.push('OneToMany');
281
- entityCode.push(`\t@OneToMany(() => ${rel.targetEntity}, r => r.${rel.fkColumn})`);
281
+ // CORRECT: Inverse is fk + referenced table (e.g. fkUsers)
282
+ entityCode.push(`\t@OneToMany(() => ${rel.targetEntity}, r => r.${rel.fkPropName})`);
282
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`);
283
286
  }
284
287
  // Add Many-to-Many Relations
285
288
  const junctions = Object.values(junctionTables)
@@ -321,6 +324,11 @@ class MySqlDriver {
321
324
  // Write entity file
322
325
  fs_1.default.writeFileSync(path_1.default.join(this.dist, `${tableName}.ts`), Code.join(`\n`));
323
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 zormEntities = [${tableNames.map(t => (0, index_js_1.toPascalCase)(t)).join(`, `)}];`, `const zorm = Zorm.get(`, `\tprocess.env.DATABASE_URL!,`, `\tzormEntities`, `);`, `zorm.connect(zormEntities);`, `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`));
324
332
  await self.pool.end();
325
333
  console.log(picocolors_1.default.green(`✓ ${tables.length} Tables Processed.`));
326
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/index.d.ts CHANGED
@@ -26,6 +26,7 @@ declare class Zorm {
26
26
  * @private
27
27
  */
28
28
  private usePromise;
29
+ private _init;
29
30
  /**
30
31
  * Private constructor to enforce singleton pattern.
31
32
  * @param {string} connectionString - The database connection string.
@@ -41,13 +42,15 @@ declare class Zorm {
41
42
  * @param {boolean} [usePromise] - Whether to use Promises for queries.
42
43
  * @returns {Zorm} The singleton instance of Zorm.
43
44
  */
44
- static get(connectionString: string, entitiesPath?: string | null, usePromise?: boolean): Zorm;
45
+ static get(connectionString: string, entities?: MixedList<string | Function | EntitySchema<any>>, entitiesPath?: string | null, usePromise?: boolean): Zorm;
45
46
  /**
46
47
  * Connects to the database and initializes entities.
47
48
  * @param {MixedList<string | Function | EntitySchema<any>>} entities - List of entity schemas.
48
49
  * @returns {Promise<void>} Resolves when the connection is initialized.
49
50
  */
50
- connect(entities: MixedList<string | Function | EntitySchema<any>>): Promise<void>;
51
+ connect(entities?: MixedList<string | Function | EntitySchema<any>>): Promise<void>;
52
+ whenReady<T = this>(): T;
53
+ private wrapQueryBuilder;
51
54
  /**
52
55
  * Returns the appropriate QueryBuilder based on the database type.
53
56
  * @param {EntityTarget<T>} entity - The entity target.
package/dist/index.js CHANGED
@@ -48,6 +48,7 @@ class Zorm {
48
48
  * @private
49
49
  */
50
50
  usePromise = false;
51
+ _init;
51
52
  /**
52
53
  * Private constructor to enforce singleton pattern.
53
54
  * @param {string} connectionString - The database connection string.
@@ -55,7 +56,7 @@ class Zorm {
55
56
  * @param {boolean} [usePromise] - Whether to use Promises for queries.
56
57
  * @private
57
58
  */
58
- constructor(connectionString, entitiesPath, usePromise) {
59
+ constructor(connectionString, entities, entitiesPath, usePromise) {
59
60
  const _dist = entitiesPath || path_1.default.join(`src`, `zorm`);
60
61
  const dist = path_1.default.join(process.cwd(), _dist);
61
62
  const _checkDist = (0, index_js_1.checkDirectory)(dist, false);
@@ -73,8 +74,10 @@ class Zorm {
73
74
  password: conn.password,
74
75
  host: conn.host,
75
76
  port: Number(conn.port),
76
- database: conn.database
77
+ database: conn.database,
78
+ entities: entities || []
77
79
  });
80
+ this._init = this.dataSource.initialize.bind(this.dataSource);
78
81
  }
79
82
  else {
80
83
  console.log(`Only MySQL is supported for now`);
@@ -88,9 +91,9 @@ class Zorm {
88
91
  * @param {boolean} [usePromise] - Whether to use Promises for queries.
89
92
  * @returns {Zorm} The singleton instance of Zorm.
90
93
  */
91
- static get(connectionString, entitiesPath, usePromise) {
94
+ static get(connectionString, entities, entitiesPath, usePromise) {
92
95
  if (!Zorm.instance) {
93
- Zorm.instance = new Zorm(connectionString, entitiesPath, usePromise);
96
+ Zorm.instance = new Zorm(connectionString, entities, entitiesPath, usePromise);
94
97
  }
95
98
  return Zorm.instance;
96
99
  }
@@ -102,8 +105,10 @@ class Zorm {
102
105
  async connect(entities) {
103
106
  if (!this.initialized) {
104
107
  try {
105
- this.dataSource.setOptions({ entities });
106
- await this.dataSource.initialize();
108
+ if (entities && !this.dataSource.options.entities?.length) {
109
+ this.dataSource.setOptions({ entities });
110
+ }
111
+ await this._init();
107
112
  this.initialized = true;
108
113
  console.log(picocolors_1.default.green("○ Zorm is connected"));
109
114
  }
@@ -112,6 +117,50 @@ class Zorm {
112
117
  }
113
118
  }
114
119
  }
120
+ whenReady() {
121
+ if (this.initialized)
122
+ return this;
123
+ const handler = {
124
+ get: (target, prop) => {
125
+ if (prop === 'then')
126
+ return undefined;
127
+ const value = target[prop];
128
+ if (typeof value === 'function') {
129
+ return (...args) => {
130
+ const result = value.apply(target, args);
131
+ if (result && result.constructor.name === 'ZormQueryBuilder') {
132
+ return this.wrapQueryBuilder(result);
133
+ }
134
+ this._init().then(() => result);
135
+ };
136
+ }
137
+ return value;
138
+ }
139
+ };
140
+ return new Proxy(this, handler);
141
+ }
142
+ wrapQueryBuilder(qb) {
143
+ const handler = {
144
+ get: (target, prop) => {
145
+ if (prop === 'then')
146
+ return undefined;
147
+ const value = target[prop];
148
+ if (typeof value === 'function') {
149
+ return (...args) => {
150
+ const result = value.apply(target, args);
151
+ // Chain: if returns new QB, wrap it
152
+ if (result && result.constructor.name === 'ZormQueryBuilder') {
153
+ return this.wrapQueryBuilder(result);
154
+ }
155
+ // Final: return Promise
156
+ return this._init().then(() => result);
157
+ };
158
+ }
159
+ return value;
160
+ }
161
+ };
162
+ return new Proxy(qb, handler);
163
+ }
115
164
  /**
116
165
  * Returns the appropriate QueryBuilder based on the database type.
117
166
  * @param {EntityTarget<T>} entity - The entity target.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuzjs/orm",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "keywords": [
5
5
  "orm",
6
6
  "zuz",