sqlite-zod-orm 3.4.0 → 3.4.1

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/dist/index.js CHANGED
@@ -112,6 +112,8 @@ function compileIQO(tableName, iqo) {
112
112
  sql += ` WHERE ${compiled.sql}`;
113
113
  params.push(...compiled.params);
114
114
  } else if (iqo.wheres.length > 0) {
115
+ const hasJoins = iqo.joins.length > 0;
116
+ const qualify = (field) => hasJoins && !field.includes(".") ? `${tableName}.${field}` : field;
115
117
  const whereParts = [];
116
118
  for (const w of iqo.wheres) {
117
119
  if (w.operator === "IN") {
@@ -120,11 +122,11 @@ function compileIQO(tableName, iqo) {
120
122
  whereParts.push("1 = 0");
121
123
  } else {
122
124
  const placeholders = arr.map(() => "?").join(", ");
123
- whereParts.push(`${w.field} IN (${placeholders})`);
125
+ whereParts.push(`${qualify(w.field)} IN (${placeholders})`);
124
126
  params.push(...arr.map(transformValueForStorage));
125
127
  }
126
128
  } else {
127
- whereParts.push(`${w.field} ${w.operator} ?`);
129
+ whereParts.push(`${qualify(w.field)} ${w.operator} ?`);
128
130
  params.push(transformValueForStorage(w.value));
129
131
  }
130
132
  }
@@ -4955,7 +4957,29 @@ class _Database {
4955
4957
  return null;
4956
4958
  };
4957
4959
  const revisionGetter = () => this._getRevision(entityName);
4958
- const builder = new QueryBuilder(entityName, executor, singleExecutor, joinResolver, null, revisionGetter);
4960
+ const conditionResolver = (conditions) => {
4961
+ const resolved = {};
4962
+ for (const [key, value] of Object.entries(conditions)) {
4963
+ if (value && typeof value === "object" && typeof value.id === "number" && typeof value.delete === "function") {
4964
+ const fkCol = key + "_id";
4965
+ const rel = this.relationships.find((r) => r.type === "belongs-to" && r.from === entityName && r.foreignKey === fkCol);
4966
+ if (rel) {
4967
+ resolved[fkCol] = value.id;
4968
+ } else {
4969
+ const relByNav = this.relationships.find((r) => r.type === "belongs-to" && r.from === entityName && r.to === key + "s") || this.relationships.find((r) => r.type === "belongs-to" && r.from === entityName && r.to === key);
4970
+ if (relByNav) {
4971
+ resolved[relByNav.foreignKey] = value.id;
4972
+ } else {
4973
+ resolved[key] = value;
4974
+ }
4975
+ }
4976
+ } else {
4977
+ resolved[key] = value;
4978
+ }
4979
+ }
4980
+ return resolved;
4981
+ };
4982
+ const builder = new QueryBuilder(entityName, executor, singleExecutor, joinResolver, conditionResolver, revisionGetter);
4959
4983
  if (initialCols.length > 0)
4960
4984
  builder.select(...initialCols);
4961
4985
  return builder;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sqlite-zod-orm",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "description": "Type-safe SQLite ORM for Bun — Zod schemas, fluent queries, auto relationships, zero SQL",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/database.ts CHANGED
@@ -453,7 +453,40 @@ class _Database<Schemas extends SchemaMap> {
453
453
  // Pass revision getter — allows .subscribe() to detect ALL changes
454
454
  const revisionGetter = () => this._getRevision(entityName);
455
455
 
456
- const builder = new QueryBuilder(entityName, executor, singleExecutor, joinResolver, null, revisionGetter);
456
+ // Condition resolver: { author: aliceEntity } { author_id: 1 }
457
+ const conditionResolver = (conditions: Record<string, any>): Record<string, any> => {
458
+ const resolved: Record<string, any> = {};
459
+ for (const [key, value] of Object.entries(conditions)) {
460
+ // Detect entity references: objects with `id` and `delete` (augmented entities)
461
+ if (value && typeof value === 'object' && typeof value.id === 'number' && typeof value.delete === 'function') {
462
+ // Find a belongs-to relationship: entityName has a FK named `key_id` pointing to another table
463
+ const fkCol = key + '_id';
464
+ const rel = this.relationships.find(
465
+ r => r.type === 'belongs-to' && r.from === entityName && r.foreignKey === fkCol
466
+ );
467
+ if (rel) {
468
+ resolved[fkCol] = value.id;
469
+ } else {
470
+ // Fallback: try any relationship that matches the key as the nav name
471
+ const relByNav = this.relationships.find(
472
+ r => r.type === 'belongs-to' && r.from === entityName && r.to === key + 's'
473
+ ) || this.relationships.find(
474
+ r => r.type === 'belongs-to' && r.from === entityName && r.to === key
475
+ );
476
+ if (relByNav) {
477
+ resolved[relByNav.foreignKey] = value.id;
478
+ } else {
479
+ resolved[key] = value; // pass through
480
+ }
481
+ }
482
+ } else {
483
+ resolved[key] = value;
484
+ }
485
+ }
486
+ return resolved;
487
+ };
488
+
489
+ const builder = new QueryBuilder(entityName, executor, singleExecutor, joinResolver, conditionResolver, revisionGetter);
457
490
  if (initialCols.length > 0) builder.select(...initialCols);
458
491
  return builder;
459
492
  }
@@ -86,6 +86,11 @@ export function compileIQO(tableName: string, iqo: IQO): { sql: string; params:
86
86
  sql += ` WHERE ${compiled.sql}`;
87
87
  params.push(...compiled.params);
88
88
  } else if (iqo.wheres.length > 0) {
89
+ const hasJoins = iqo.joins.length > 0;
90
+ // When joins exist, qualify bare column names with the main table
91
+ const qualify = (field: string) =>
92
+ hasJoins && !field.includes('.') ? `${tableName}.${field}` : field;
93
+
89
94
  const whereParts: string[] = [];
90
95
  for (const w of iqo.wheres) {
91
96
  if (w.operator === 'IN') {
@@ -94,11 +99,11 @@ export function compileIQO(tableName: string, iqo: IQO): { sql: string; params:
94
99
  whereParts.push('1 = 0');
95
100
  } else {
96
101
  const placeholders = arr.map(() => '?').join(', ');
97
- whereParts.push(`${w.field} IN (${placeholders})`);
102
+ whereParts.push(`${qualify(w.field)} IN (${placeholders})`);
98
103
  params.push(...arr.map(transformValueForStorage));
99
104
  }
100
105
  } else {
101
- whereParts.push(`${w.field} ${w.operator} ?`);
106
+ whereParts.push(`${qualify(w.field)} ${w.operator} ?`);
102
107
  params.push(transformValueForStorage(w.value));
103
108
  }
104
109
  }