fastify-auto-sqlapi 0.1.6 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"tables-codegen.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/tables-codegen.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAuCpE;AAuCD,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,gBAAgB,EAAE,CAwB3E;AAID,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,MAAM,CA2HhG;AAID,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAqBrE;AAID,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CA6FlE"}
1
+ {"version":3,"file":"tables-codegen.d.ts","sourceRoot":"","sources":["../../../src/lib/cli/tables-codegen.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,0FAA0F;IAC1F,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAuCpE;AAuCD,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,gBAAgB,EAAE,CAwB3E;AAID,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,GAAG,MAAM,CA6HhG;AAID,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAqBrE;AAID,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CA6FlE"}
@@ -151,7 +151,9 @@ export function generateSingleTableFile(schema, allSchemas) {
151
151
  lines.push(` // Schema,`);
152
152
  lines.push(` // extraFiltersValidation,`);
153
153
  lines.push(` // (condition, filters) => {`);
154
- lines.push(` // if (filters.q) condition.isILike(Schema.col('${schema.fields.includes('name') ? 'name' : schema.fields[0]}'), \`%\${filters.q}%\`);`);
154
+ lines.push(` // // Prefix columns with the table name: the query may carry joins, and a`);
155
+ lines.push(` // // bare column shared with a joined table would be ambiguous.`);
156
+ lines.push(` // if (filters.q) condition.isILike(\`\${Schema.tableName}.\${Schema.col('${schema.fields.includes('name') ? 'name' : schema.fields[0]}')}\`, \`%\${filters.q}%\`);`);
155
157
  lines.push(` // }`);
156
158
  lines.push(` // ),`);
157
159
  lines.push(` defaultOrder: '${pkFirst(pk)}',`);
@@ -0,0 +1,40 @@
1
+ import type { ConditionBuilder } from 'node-condition-builder';
2
+ import type { QueryClient } from '../db.js';
3
+ /**
4
+ * Owns the bound values of a statement while it is being assembled.
5
+ *
6
+ * A statement is built from several fragments (WHERE condition, EXISTS subqueries,
7
+ * aggregation clauses, LEFT JOIN filters, ORDER BY), each of which must number its
8
+ * placeholders from wherever the preceding fragments left off. Computing that offset at the
9
+ * call site is how placeholders drift out of step with values — a query that binds a value
10
+ * nobody references does not fail, it silently reads the wrong parameter.
11
+ *
12
+ * Here the offset is derived in exactly one place. `emit` hands a producer the index its
13
+ * first placeholder must take and absorbs the values it returned in the same step, so SQL
14
+ * and values cannot be appended independently.
15
+ *
16
+ * Fragments must be emitted in the order their placeholders appear in the final SQL: MySQL
17
+ * binds `?` positionally, so a fragment numbered out of textual order would break there while
18
+ * working on PostgreSQL.
19
+ */
20
+ export declare class QueryParams {
21
+ private values;
22
+ /** Values bound so far. */
23
+ get length(): number;
24
+ /**
25
+ * Render a fragment at the current offset and record the values it bound.
26
+ * Returns whatever the producer returned, so callers can read its SQL and any extras.
27
+ */
28
+ emit<T extends {
29
+ values: unknown[];
30
+ }>(produce: (startIndex: number) => T): T;
31
+ /** Render a ConditionBuilder at the current offset and return its SQL. */
32
+ emitCondition(condition: ConditionBuilder, db: QueryClient): string;
33
+ /**
34
+ * Copy of the values bound so far. Take a snapshot before emitting a fragment that only
35
+ * the main query carries (ORDER BY), so the COUNT/aggregate queries can bind the subset
36
+ * they actually reference.
37
+ */
38
+ snapshot(): unknown[];
39
+ }
40
+ //# sourceMappingURL=query-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-params.d.ts","sourceRoot":"","sources":["../../../src/lib/engine/query-params.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAiB;IAE/B,2BAA2B;IAC3B,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;;OAGG;IACH,IAAI,CAAC,CAAC,SAAS;QAAE,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE,EAAE,OAAO,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC;IAM5E,0EAA0E;IAC1E,aAAa,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM;IAOnE;;;;OAIG;IACH,QAAQ,IAAI,OAAO,EAAE;CAGtB"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Owns the bound values of a statement while it is being assembled.
3
+ *
4
+ * A statement is built from several fragments (WHERE condition, EXISTS subqueries,
5
+ * aggregation clauses, LEFT JOIN filters, ORDER BY), each of which must number its
6
+ * placeholders from wherever the preceding fragments left off. Computing that offset at the
7
+ * call site is how placeholders drift out of step with values — a query that binds a value
8
+ * nobody references does not fail, it silently reads the wrong parameter.
9
+ *
10
+ * Here the offset is derived in exactly one place. `emit` hands a producer the index its
11
+ * first placeholder must take and absorbs the values it returned in the same step, so SQL
12
+ * and values cannot be appended independently.
13
+ *
14
+ * Fragments must be emitted in the order their placeholders appear in the final SQL: MySQL
15
+ * binds `?` positionally, so a fragment numbered out of textual order would break there while
16
+ * working on PostgreSQL.
17
+ */
18
+ export class QueryParams {
19
+ values = [];
20
+ /** Values bound so far. */
21
+ get length() {
22
+ return this.values.length;
23
+ }
24
+ /**
25
+ * Render a fragment at the current offset and record the values it bound.
26
+ * Returns whatever the producer returned, so callers can read its SQL and any extras.
27
+ */
28
+ emit(produce) {
29
+ const out = produce(this.values.length + 1);
30
+ this.values.push(...out.values);
31
+ return out;
32
+ }
33
+ /** Render a ConditionBuilder at the current offset and return its SQL. */
34
+ emitCondition(condition, db) {
35
+ return this.emit((startIndex) => ({
36
+ sql: condition.build(startIndex, db.ph),
37
+ values: condition.getValues(),
38
+ })).sql;
39
+ }
40
+ /**
41
+ * Copy of the values bound so far. Take a snapshot before emitting a fragment that only
42
+ * the main query carries (ORDER BY), so the COUNT/aggregate queries can bind the subset
43
+ * they actually reference.
44
+ */
45
+ snapshot() {
46
+ return [...this.values];
47
+ }
48
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/lib/engine/rest/get.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAuB,MAAM,mBAAmB,CAAC;AAEnF,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CA8BrE"}
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../../src/lib/engine/rest/get.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAuB,MAAM,mBAAmB,CAAC;AAEnF,wBAAsB,SAAS,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAgCrE"}
@@ -8,10 +8,12 @@ export async function getEngine(params) {
8
8
  const { db, tableConf, id, tenant } = params;
9
9
  const pkCol = tableConf.Schema.col(primaryAsString(tableConf.primary));
10
10
  const cb = new ConditionBuilder('AND', db.cbDialect);
11
- cb.isEqual(db.qi(pkCol), id);
11
+ // Table-qualified: the tenant scope may add a through-join, and a bare PK column
12
+ // shared with the through table would be ambiguous.
13
+ cb.isEqual(`${db.qi(tableConf.Schema.tableName)}.${db.qi(pkCol)}`, id);
12
14
  const joins = [];
13
15
  if (tenant) {
14
- cb.append(buildTenantCondition(db, tenant.scope, tenant.ids));
16
+ cb.append(buildTenantCondition(db, tenant.scope, tenant.ids, tableConf.Schema.tableName));
15
17
  if ('through' in tenant.scope) {
16
18
  joins.push(buildTenantJoin(db, tenant.scope, tableConf.Schema.tableName));
17
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/lib/engine/search/search.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EAcb,MAAM,mBAAmB,CAAC;AAmkC3B,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,YAAY,CAAC,CAkIvB"}
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/lib/engine/search/search.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,EAcb,MAAM,mBAAmB,CAAC;AAwlC3B,wBAAsB,YAAY,CAChC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,YAAY,CAAC,CA4HvB"}
@@ -1,5 +1,6 @@
1
1
  import { ConditionBuilder, Expression } from 'node-condition-builder';
2
2
  import { camelcaseObject } from '../../naming.js';
3
+ import { QueryParams } from '../query-params.js';
3
4
  import { buildTenantCondition, buildTenantJoin } from '../../tenant.js';
4
5
  import { assertReadable, assertFiltersReadable, readableSelectColumns } from '../../read-access.js';
5
6
  import { primaryAsString } from '../../../types.js';
@@ -32,7 +33,9 @@ function buildComputedContext(db, schema, alias) {
32
33
  err400(`Unknown field referenced by computed expression: ${field}`);
33
34
  }
34
35
  const col = db.qi(schema.col(field));
35
- const qualifier = opts?.qualifier ?? alias;
36
+ // Default to the owning table: the statement may carry joins, and a bare
37
+ // column shared with a joined table would be ambiguous.
38
+ const qualifier = opts?.qualifier ?? alias ?? schema.tableName;
36
39
  return qualifier ? `${db.qi(qualifier)}.${col}` : col;
37
40
  },
38
41
  };
@@ -41,7 +44,9 @@ function resolveFieldRef(field, schema, tableConf, db, alias) {
41
44
  if (field in schema.fields) {
42
45
  assertReadable(tableConf, field);
43
46
  const col = db.qi(schema.col(field));
44
- const expr = alias ? `${db.qi(alias)}.${col}` : col;
47
+ // Qualified with the alias or the owning table — never bare, so the reference
48
+ // stays unambiguous when the statement carries joins.
49
+ const expr = `${db.qi(alias ?? schema.tableName)}.${col}`;
45
50
  return { expr, computed: false };
46
51
  }
47
52
  const fn = tableConf?.computedFields?.[field];
@@ -57,16 +62,28 @@ function resolveFieldRef(field, schema, tableConf, db, alias) {
57
62
  * appends the tenant condition to `cb` (direct: `col IN ids`; indirect: condition on the
58
63
  * through table) and, for indirect scopes, pushes the INNER JOIN clause into `joins`.
59
64
  * No-op without a tenant context (admin) or when the join table is not tenant-scoped.
65
+ *
66
+ * `joinTableRef` is the raw name the join table goes by in the statement: its table name
67
+ * in plain side-queries, or the subquery alias inside an aliased, correlated EXISTS.
60
68
  */
61
- function appendJoinTenantScope(db, joinTableConf, tenant, joinTableName, cb, joins) {
69
+ function appendJoinTenantScope(db, joinTableConf, tenant, joinTableRef, cb, joins) {
62
70
  const scope = joinTableConf?.tenantScope;
63
71
  if (!tenant || !scope)
64
72
  return;
65
- cb.append(buildTenantCondition(db, scope, tenant.ids));
73
+ cb.append(buildTenantCondition(db, scope, tenant.ids, joinTableRef));
66
74
  if ('through' in scope) {
67
- joins?.push(buildTenantJoin(db, scope, joinTableName));
75
+ joins?.push(buildTenantJoin(db, scope, joinTableRef));
68
76
  }
69
77
  }
78
+ /**
79
+ * Alias for the FROM of a correlated subquery (EXISTS, aggregate). The subquery must not
80
+ * say `FROM <table>` bare: on a self-referencing relation the inner table would shadow the
81
+ * outer one and the correlation would silently compare each row with itself. The request
82
+ * alias is used, suffixed when it would itself collide with the outer table's name.
83
+ */
84
+ function subqueryAlias(alias, tableConf) {
85
+ return alias === tableConf.Schema.tableName ? `${alias}_sub` : alias;
86
+ }
70
87
  function findJoinByAlias(tableConf, alias) {
71
88
  return tableConf.allowedReadJoins?.find((j) => j.alias === alias);
72
89
  }
@@ -164,9 +181,10 @@ function buildSelectionColumns(selection, joinSchema, db, joinTableConf) {
164
181
  if (selection === '*') {
165
182
  return readableSelectColumns(joinTableConf, joinSchema, db) ?? '*';
166
183
  }
184
+ const table = db.qi(joinSchema.tableName);
167
185
  return selection
168
186
  .split(',')
169
- .map((c) => db.qi(validateSchemaField(c.trim(), joinSchema, joinTableConf)))
187
+ .map((c) => `${table}.${db.qi(validateSchemaField(c.trim(), joinSchema, joinTableConf))}`)
170
188
  .join(', ');
171
189
  }
172
190
  const AGG_FN = {
@@ -180,7 +198,12 @@ const AGG_FN = {
180
198
  function aggExpr(fn, qualifiedCol) {
181
199
  return fn.distinct ? `COUNT(DISTINCT ${qualifiedCol})` : `${fn.sql}(${qualifiedCol})`;
182
200
  }
183
- function buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup, startIdx) {
201
+ /**
202
+ * Correlated aggregate subquery for `<alias>.<fn>.<field>`, as an Expression carrying the
203
+ * values of its optional filter. Markers are `?`, so whoever embeds it — a ConditionBuilder
204
+ * or an ORDER BY list — decides the placeholder positions.
205
+ */
206
+ function buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup) {
184
207
  const aggFn = AGG_FN[fn];
185
208
  if (!aggFn)
186
209
  err400(`Invalid aggregation function: ${fn}`);
@@ -198,20 +221,24 @@ function buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup,
198
221
  }
199
222
  const fieldCol = validateSchemaField(field, joinSchema);
200
223
  const refs = extractJoinRefs(db, tableConf, joinDef);
224
+ // The subquery FROM is aliased so the correlation to the outer table survives a
225
+ // self-referencing relation; everything inside references the alias.
226
+ const subAlias = subqueryAlias(alias, tableConf);
227
+ const subRef = db.qi(subAlias);
201
228
  let filterWhere = '';
202
229
  let filterVals = [];
203
230
  const joinTableConf = dbTables[joinSchema.tableName];
204
231
  if (groupReq.filters || groupReq.conditions?.length) {
205
- const cb = buildJoinRefCondition(joinTableConf, joinSchema, { filters: groupReq.filters, conditions: groupReq.conditions }, db);
206
- const built = cb.build(startIdx, db.ph);
207
- if (built) {
208
- filterWhere = ` AND ${built}`;
209
- filterVals = cb.getValues();
232
+ const cb = buildJoinRefCondition(joinTableConf, joinSchema, { filters: groupReq.filters, conditions: groupReq.conditions }, db, subAlias);
233
+ const fragment = cb.toExpression();
234
+ if (fragment.value) {
235
+ filterWhere = ` AND ${fragment.value}`;
236
+ filterVals = [...fragment.values];
210
237
  }
211
238
  }
212
- const qualifiedCol = `${refs.joinTable}.${db.qi(fieldCol)}`;
213
- const expr = `COALESCE((SELECT ${aggExpr(aggFn, qualifiedCol)} FROM ${refs.joinTable} WHERE ${refs.joinTable}.${refs.fkCol} = ${refs.mainTable}.${refs.mainCol}${filterWhere}), 0)`;
214
- return { expr, values: filterVals };
239
+ const qualifiedCol = `${subRef}.${db.qi(fieldCol)}`;
240
+ const expr = `COALESCE((SELECT ${aggExpr(aggFn, qualifiedCol)} FROM ${refs.joinTable} AS ${subRef} WHERE ${subRef}.${refs.fkCol} = ${refs.mainTable}.${refs.mainCol}${filterWhere}), 0)`;
241
+ return new Expression(expr, filterVals);
215
242
  }
216
243
  /**
217
244
  * Pre-scan `orderBy` for the joinLeft aliases referenced in 2-parti notation (`<alias>.<field>`).
@@ -250,10 +277,11 @@ function validateOrderBy(orderBy, tableConf, db, dbTables, joinGroup, startIdx)
250
277
  err400('Cannot combine distinctResults with aggregation orderBy');
251
278
  }
252
279
  const [, alias, fn, field, dir] = dotted3;
253
- const { expr, values } = buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup, currentIdx);
254
- outParts.push(`${expr} ${(dir || 'ASC').toUpperCase()}`);
255
- outValues.push(...values);
256
- currentIdx += values.length;
280
+ const expr = buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup);
281
+ const aggVals = [...expr.values];
282
+ outParts.push(`${renderRef(expr, currentIdx, db)} ${(dir || 'ASC').toUpperCase()}`);
283
+ outValues.push(...aggVals);
284
+ currentIdx += aggVals.length;
257
285
  continue;
258
286
  }
259
287
  // 2-parti: <alias>.<field> [ASC|DESC] (joinLeft inline ordering)
@@ -368,7 +396,7 @@ function convertConfiguredOrder(order, tableConf, db) {
368
396
  const [, field, dir] = match;
369
397
  const suffix = dir ? ` ${dir.toUpperCase()}` : '';
370
398
  if (field in tableConf.Schema.fields) {
371
- return `${db.qi(tableConf.Schema.col(field))}${suffix}`;
399
+ return `${db.qi(tableConf.Schema.tableName)}.${db.qi(tableConf.Schema.col(field))}${suffix}`;
372
400
  }
373
401
  const computed = tableConf.computedFields?.[field];
374
402
  if (computed) {
@@ -463,7 +491,7 @@ async function executeJoinMultiple(db, dbTables, tableConf, mainResults, joinMul
463
491
  }
464
492
  const cb = buildJoinRefCondition(joinTableConf, joinSchema, ref || {}, db);
465
493
  const fkCol = joinSchema.col(joinField);
466
- cb.isIn(db.qi(fkCol), ids);
494
+ cb.isIn(`${db.qi(joinSchema.tableName)}.${db.qi(fkCol)}`, ids);
467
495
  const tenantJoins = [];
468
496
  appendJoinTenantScope(db, joinTableConf, tenant, joinSchema.tableName, cb, tenantJoins);
469
497
  const where = cb.build(1, db.ph);
@@ -497,7 +525,7 @@ async function executeJoinLeft(db, dbTables, tableConf, mainResults, joinLeft, t
497
525
  }
498
526
  const fkCol = joinSchema.col(joinField);
499
527
  const cb = new ConditionBuilder('AND', db.cbDialect);
500
- cb.isIn(db.qi(fkCol), ids);
528
+ cb.isIn(`${db.qi(joinSchema.tableName)}.${db.qi(fkCol)}`, ids);
501
529
  const tenantJoins = [];
502
530
  appendJoinTenantScope(db, joinTableConf, tenant, joinSchema.tableName, cb, tenantJoins);
503
531
  const where = cb.build(1, db.ph);
@@ -527,7 +555,7 @@ function buildByExpression(by, joinSchema, joinTableConf, db) {
527
555
  err400(`Invalid 'by' specification: expected a field or computed name`);
528
556
  }
529
557
  if (by in joinSchema.fields) {
530
- return db.qi(joinSchema.col(by));
558
+ return `${db.qi(joinSchema.tableName)}.${db.qi(joinSchema.col(by))}`;
531
559
  }
532
560
  const fn = joinTableConf?.computedFields?.[by];
533
561
  if (fn) {
@@ -561,7 +589,7 @@ async function executeJoinGroup(db, dbTables, tableConf, mainResults, joinGroup,
561
589
  const fn = AGG_FN[kind];
562
590
  for (const f of fields) {
563
591
  const col = validateSchemaField(f, joinSchema, joinTableConf);
564
- selectParts.push(`${aggExpr(fn, db.qi(col))} as "${kind}_${f}"`);
592
+ selectParts.push(`${aggExpr(fn, `${db.qi(joinSchema.tableName)}.${db.qi(col)}`)} as "${kind}_${f}"`);
565
593
  }
566
594
  };
567
595
  addAgg('distinctCount', aggregations.distinctCount);
@@ -577,7 +605,7 @@ async function executeJoinGroup(db, dbTables, tableConf, mainResults, joinGroup,
577
605
  const groupRef = { filters: groupFilters, conditions: groupConditions };
578
606
  const cb = buildJoinRefCondition(joinTableConf, joinSchema, groupRef, db);
579
607
  const fkCol = joinSchema.col(joinField);
580
- cb.isIn(db.qi(fkCol), ids);
608
+ cb.isIn(`${db.qi(joinSchema.tableName)}.${db.qi(fkCol)}`, ids);
581
609
  const tenantJoins = [];
582
610
  appendJoinTenantScope(db, joinTableConf, tenant, joinSchema.tableName, cb, tenantJoins);
583
611
  const where = cb.build(1, db.ph);
@@ -640,10 +668,13 @@ function dispatchConditionMethod(cb, method, colOrExpr, params) {
640
668
  cb[method](colOrExpr, true);
641
669
  }
642
670
  }
643
- function buildJoinRefCondition(joinTableConf, joinSchema, ref, db) {
671
+ function buildJoinRefCondition(joinTableConf, joinSchema, ref, db, qualifier) {
644
672
  assertFiltersReadable(ref.filters, joinTableConf);
673
+ // Bare table name for plain side-queries; the subquery alias when the condition lands
674
+ // inside an aliased, correlated FROM (there the table name would resolve to the outer query).
675
+ const colQualifier = qualifier ?? joinSchema.tableName;
645
676
  const cb = (ref.filters && joinTableConf)
646
- ? joinTableConf.filters(ref.filters, db.cbDialect)
677
+ ? joinTableConf.filters(ref.filters, db.cbDialect, colQualifier)
647
678
  : new ConditionBuilder('AND', db.cbDialect);
648
679
  // Equality filters targeting the join table's computed fields
649
680
  const computed = joinTableConf?.computedFields;
@@ -653,7 +684,7 @@ function buildJoinRefCondition(joinTableConf, joinSchema, ref, db) {
653
684
  continue;
654
685
  if (!computed[name])
655
686
  continue;
656
- const expr = evaluateComputedField(name, computed[name], joinTableConf.Schema, db, undefined, '', true);
687
+ const expr = evaluateComputedField(name, computed[name], joinTableConf.Schema, db, colQualifier, '', true);
657
688
  cb.isEqual(expr, value);
658
689
  }
659
690
  }
@@ -665,8 +696,8 @@ function buildJoinRefCondition(joinTableConf, joinSchema, ref, db) {
665
696
  // Computed fields resolve to an Expression carrying their own bound values, which
666
697
  // the ConditionBuilder places together with the compared value.
667
698
  const operand = computed?.[c.field]
668
- ? evaluateComputedField(c.field, computed[c.field], joinTableConf.Schema, db, undefined, '', true)
669
- : db.qi(validateSchemaField(c.field, joinSchema, joinTableConf));
699
+ ? evaluateComputedField(c.field, computed[c.field], joinTableConf.Schema, db, colQualifier, '', true)
700
+ : `${db.qi(colQualifier)}.${db.qi(validateSchemaField(c.field, joinSchema, joinTableConf))}`;
670
701
  dispatchConditionMethod(cb, c.method, operand, c.params ?? []);
671
702
  }
672
703
  }
@@ -710,9 +741,8 @@ function applyComputedFilters(condition, filters, tableConf, db) {
710
741
  condition.isEqual(expr, value);
711
742
  }
712
743
  }
713
- function appendAggConditions(currentWhere, currentValues, conditions, db, dbTables, tableConf, joinGroup) {
714
- let where = currentWhere;
715
- let values = [...currentValues];
744
+ function appendAggConditions(params, conditions, db, dbTables, tableConf, joinGroup) {
745
+ let where = '';
716
746
  for (const c of conditions) {
717
747
  if (!c.field.includes('.'))
718
748
  continue;
@@ -724,44 +754,38 @@ function appendAggConditions(currentWhere, currentValues, conditions, db, dbTabl
724
754
  err400(`Invalid dotted field in condition: ${c.field} (expected <alias>.<fn>.<field>)`);
725
755
  }
726
756
  const [alias, fn, field] = parts;
727
- const { expr, values: exprValues } = buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup, values.length + 1);
728
- values = [...values, ...exprValues];
757
+ // The aggregate carries the values of its own filter; passing it as the left-hand side
758
+ // lets the ConditionBuilder place those and the compared value in one step.
759
+ const expr = buildAggOrderExpr(db, dbTables, tableConf, alias, fn, field, joinGroup);
729
760
  const tmpCb = new ConditionBuilder('AND', db.cbDialect);
730
761
  dispatchConditionMethod(tmpCb, c.method, expr, c.params);
731
- const startIdx = values.length + 1;
732
- const clause = tmpCb.build(startIdx, db.ph);
733
- where += ` AND ${clause}`;
734
- values.push(...tmpCb.getValues());
762
+ where += ` AND ${params.emitCondition(tmpCb, db)}`;
735
763
  }
736
- return { where, values };
764
+ return where;
737
765
  }
738
766
  // ─── joinMustExist (EXISTS subquery filter on main) ─────────
739
- function buildJoinMustExistClauses(db, dbTables, tableConf, joinMustExist, currentWhere, currentValues, tenant) {
740
- let where = currentWhere;
741
- const values = [...currentValues];
767
+ function buildJoinMustExistClauses(params, db, dbTables, tableConf, joinMustExist, tenant) {
768
+ let where = '';
742
769
  for (const [alias, ref] of Object.entries(joinMustExist)) {
743
770
  const joinDef = requireJoin(tableConf, alias, false);
744
771
  const { joinSchema } = joinDef;
745
772
  const joinTableConf = dbTables[joinSchema.tableName];
746
773
  const refs = extractJoinRefs(db, tableConf, joinDef);
747
- const filterCondition = buildJoinRefCondition(joinTableConf, joinSchema, ref, db);
774
+ // The EXISTS FROM is aliased so the correlation to the outer table survives a
775
+ // self-referencing relation; everything inside references the alias.
776
+ const subAlias = subqueryAlias(alias, tableConf);
777
+ const subRef = db.qi(subAlias);
778
+ const filterCondition = buildJoinRefCondition(joinTableConf, joinSchema, ref, db, subAlias);
748
779
  const tenantJoins = [];
749
- appendJoinTenantScope(db, joinTableConf, tenant, joinSchema.tableName, filterCondition, tenantJoins);
750
- // The sub-condition (computed fields included) is built by the ConditionBuilder, which
751
- // numbers its placeholders from where the outer values end.
752
- const startIdx = values.length + 1;
753
- const filterWhere = filterCondition.build(startIdx, db.ph);
754
- const filterVals = [...filterCondition.getValues()];
755
- // Qualify the FK with the join table: the EXISTS FROM may include the tenant
756
- // through-join, so a bare column could become ambiguous.
780
+ appendJoinTenantScope(db, joinTableConf, tenant, subAlias, filterCondition, tenantJoins);
781
+ const filterWhere = params.emitCondition(filterCondition, db);
757
782
  const innerWhere = filterWhere
758
- ? `${refs.joinTable}.${refs.fkCol} = ${refs.mainTable}.${refs.mainCol} AND ${filterWhere}`
759
- : `${refs.joinTable}.${refs.fkCol} = ${refs.mainTable}.${refs.mainCol}`;
783
+ ? `${subRef}.${refs.fkCol} = ${refs.mainTable}.${refs.mainCol} AND ${filterWhere}`
784
+ : `${subRef}.${refs.fkCol} = ${refs.mainTable}.${refs.mainCol}`;
760
785
  const existsJoins = tenantJoins.length > 0 ? ` ${tenantJoins.join(' ')}` : '';
761
- where += ` AND EXISTS (SELECT 1 FROM ${refs.joinTable}${existsJoins} WHERE ${innerWhere})`;
762
- values.push(...filterVals);
786
+ where += ` AND EXISTS (SELECT 1 FROM ${refs.joinTable} AS ${subRef}${existsJoins} WHERE ${innerWhere})`;
763
787
  }
764
- return { where, values };
788
+ return where;
765
789
  }
766
790
  // ─── searchEngine entrypoint ────────────────────────────────
767
791
  export async function searchEngine(dbTables, params) {
@@ -794,23 +818,24 @@ export async function searchEngine(dbTables, params) {
794
818
  // Tenant
795
819
  const tenantJoins = [];
796
820
  if (tenant) {
797
- condition.append(buildTenantCondition(db, tenant.scope, tenant.ids));
821
+ condition.append(buildTenantCondition(db, tenant.scope, tenant.ids, tableConf.Schema.tableName));
798
822
  if ('through' in tenant.scope) {
799
823
  tenantJoins.push(buildTenantJoin(db, tenant.scope, tableConf.Schema.tableName));
800
824
  }
801
825
  }
802
- let where = condition.build(1, db.ph);
803
- let values = [...condition.getValues()];
826
+ // From here the statement is assembled fragment by fragment. `bound` owns the values and
827
+ // hands each fragment the placeholder index it must start from, so no offset is computed
828
+ // at any call site. Fragments must be emitted in the order their placeholders appear in
829
+ // the final SQL — MySQL binds `?` positionally.
830
+ const bound = new QueryParams();
831
+ let where = bound.emitCondition(condition, db);
804
832
  // joinMustExist (EXISTS)
805
833
  if (joinMustExist && Object.keys(joinMustExist).length > 0) {
806
- ({ where, values } = buildJoinMustExistClauses(db, dbTables, tableConf, joinMustExist, where, values, tenant));
834
+ where += buildJoinMustExistClauses(bound, db, dbTables, tableConf, joinMustExist, tenant);
807
835
  }
808
836
  // Aggregation conditions (HAVING-style)
809
- if (conditions?.length) {
810
- const hasAggConditions = conditions.some((c) => c.field.includes('.'));
811
- if (hasAggConditions) {
812
- ({ where, values } = appendAggConditions(where, values, conditions, db, dbTables, tableConf, joinGroup));
813
- }
837
+ if (conditions?.length && conditions.some((c) => c.field.includes('.'))) {
838
+ where += appendAggConditions(bound, conditions, db, dbTables, tableConf, joinGroup);
814
839
  }
815
840
  // Determine which joinLeft aliases need a LEFT JOIN on the main query:
816
841
  // - any alias used in 2-parti orderBy
@@ -826,32 +851,24 @@ export async function searchEngine(dbTables, params) {
826
851
  aliasesNeedingLeftJoin.add(alias);
827
852
  }
828
853
  }
829
- // Build LEFT JOIN clauses + extra WHERE for filtered parents. Their placeholders start right
830
- // after the WHERE values; the same clause SQL is reused by the pagination COUNT/compute queries,
831
- // whose value array is [...WHERE, ...leftJoin] — so this base MUST stay `values.length + 1`.
854
+ // LEFT JOIN clauses + extra WHERE for filtered parents.
832
855
  const extraJoinClauses = [...tenantJoins];
833
- let leftJoinValues = [];
834
856
  if (aliasesNeedingLeftJoin.size > 0) {
835
- const lj = buildLeftJoinClauses(db, dbTables, tableConf, aliasesNeedingLeftJoin, joinLeft, values.length + 1);
857
+ const lj = bound.emit((startIndex) => buildLeftJoinClauses(db, dbTables, tableConf, aliasesNeedingLeftJoin, joinLeft, startIndex));
836
858
  extraJoinClauses.push(...lj.joinClauses);
837
- leftJoinValues = lj.values;
838
859
  for (const w of lj.whereExtras)
839
860
  where += ` AND ${w}`;
840
861
  }
841
- // orderBy is parsed AFTER the LEFT JOIN values so aggregation-orderBy placeholders start past
842
- // them (main query binds [...WHERE, ...leftJoin, ...orderBy]). Parsing it earlier with base
843
- // `values.length + 1` misbinds when BOTH an aggregation orderBy and a filtered joinLeft exist.
862
+ // The pagination COUNT and the compute* queries reuse the WHERE and its joins but drop the
863
+ // ORDER BY, so they bind everything up to this point and nothing after it.
864
+ const whereAndJoinValues = bound.snapshot();
865
+ // ORDER BY is emitted last, so an aggregation-orderBy numbers its placeholders past the
866
+ // WHERE and LEFT JOIN values.
844
867
  let safeOrderBy;
845
- let orderByValues = [];
846
868
  if (orderBy) {
847
- const obResult = validateOrderBy(orderBy, tableConf, db, dbTables, joinGroup, values.length + leftJoinValues.length + 1);
848
- safeOrderBy = obResult.sql;
849
- orderByValues = obResult.values;
850
- }
851
- // Bind WHERE values + LEFT JOIN values + orderBy aggregation values for main query.
852
- // Pagination COUNT/compute include WHERE + LEFT JOIN values (no orderBy).
853
- const whereAndJoinValues = [...values, ...leftJoinValues];
854
- const mainValues = [...whereAndJoinValues, ...orderByValues];
869
+ safeOrderBy = bound.emit((startIndex) => validateOrderBy(orderBy, tableConf, db, dbTables, joinGroup, startIndex)).sql;
870
+ }
871
+ const mainValues = bound.snapshot();
855
872
  const main = await executeMainQuery(db, tableConf, where, mainValues, safeOrderBy, paginator, extraJoinClauses, params.selectComputed, params.maxRows);
856
873
  let pagination;
857
874
  if (paginator) {
@@ -1 +1 @@
1
- {"version":3,"file":"table-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/table-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,yBAAyB,EAAiC,MAAM,wBAAwB,CAAC;AACzH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,MAAM,EACP,MAAM,aAAa,CAAC;AAarB,KAAK,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAExH,wBAAgB,eAAe,CAC7B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,EAAE,SAAS,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAErE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,YAAY,GAAE,EAAa,EAC3B,iBAAiB,CAAC,EAAE,CAClB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,yBAAyB;CAAE,KAC3E,IAAI,GACR;IAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CA0BhG;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,MAAM,CAAC,CAAC,CAAC,CAMX;AAkED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,EAClD,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,EAC3B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,cAAc,CAShB;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,GAC5B,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAE9B;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,KAAK,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,EAAE,GACvC,GAAG,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAEjC"}
1
+ {"version":3,"file":"table-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/table-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,yBAAyB,EAAiC,MAAM,wBAAwB,CAAC;AACzH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,MAAM,EACP,MAAM,aAAa,CAAC;AAarB,KAAK,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAExH,wBAAgB,eAAe,CAC7B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,EAAE,SAAS,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAErE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,YAAY,GAAE,EAAa,EAC3B,iBAAiB,CAAC,EAAE,CAClB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,yBAAyB;CAAE,KAC3E,IAAI,GACR;IAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CA8BhG;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,MAAM,CAAC,CAAC,CAAC,CAMX;AAkED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,EAClD,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,EAC3B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,cAAc,CAShB;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,GAC5B,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAE9B;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,KAAK,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,EAAE,GACvC,GAAG,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAEjC"}
@@ -9,12 +9,16 @@ function qi(field, dialect) {
9
9
  return getDialect(dialect ?? ConditionBuilder.DIALECT).qi(field);
10
10
  }
11
11
  export function exportTableInfo(Schema, extraFilters = {}, extendedCondition) {
12
- const filters = (filterValues, dialect) => {
12
+ const filters = (filterValues, dialect, qualifier) => {
13
13
  const condition = new ConditionBuilder('AND', dialect);
14
- // Only auto-match real schema fields (DB columns)
14
+ // Only auto-match real schema fields (DB columns). Columns are table-qualified:
15
+ // the statement may carry joins (LEFT JOIN parents, tenant through-joins), and a
16
+ // bare column shared with a joined table would be ambiguous. A caller-provided
17
+ // qualifier (a subquery alias) takes precedence over the table name.
18
+ const table = qi(qualifier ?? Schema.tableName, dialect);
15
19
  for (const field of Object.keys(Schema.fields)) {
16
20
  if (field in filterValues && filterValues[field] !== null && filterValues[field] !== undefined) {
17
- condition.isEqual(qi(Schema.col(field), dialect), filterValues[field]);
21
+ condition.isEqual(`${table}.${qi(Schema.col(field), dialect)}`, filterValues[field]);
18
22
  }
19
23
  }
20
24
  // extraFilters are handled exclusively by extendedCondition
@@ -3,7 +3,7 @@ import type { QueryClient } from './db.js';
3
3
  import { ConditionBuilder, type ConditionValue, type ConditionValueOrUndefined } from 'node-condition-builder';
4
4
  import type { ITable, SqlApiPluginOptions, TenantId, TenantScope, TenantScopeIndirect, TenantContext } from '../types.js';
5
5
  export declare function resolveTenant(options: SqlApiPluginOptions, tableConf: ITable, request: FastifyRequest): Promise<TenantContext | undefined>;
6
- export declare function buildTenantCondition(db: QueryClient, scope: TenantScope, tenantIds: TenantId[]): ConditionBuilder;
6
+ export declare function buildTenantCondition(db: QueryClient, scope: TenantScope, tenantIds: TenantId[], ownTable: string): ConditionBuilder;
7
7
  export declare function buildTenantJoin(db: QueryClient, scope: TenantScopeIndirect, mainTableName: string): string;
8
8
  export declare function injectTenantValue(record: Record<string, unknown>, scope: TenantScope, tenantIds: TenantId[]): void;
9
9
  export declare function validateTenantFK(db: QueryClient, scope: TenantScopeIndirect, tenantIds: TenantId[], fkValues: unknown[]): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/lib/tenant.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/lib/tenant.ts"],"names":[],"mappings":"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"}
Binary file
@@ -16,8 +16,13 @@ export type ExtendedConditionFn = (condition: ConditionBuilder, filters: FilterR
16
16
  * `dialect` selects identifier quoting and builder behavior per call (the engines pass
17
17
  * the dialect of the QueryClient that runs the query); when omitted, the global
18
18
  * `ConditionBuilder.DIALECT` is used.
19
+ *
20
+ * `qualifier` is the raw (unquoted) table name or alias to prefix columns with; it
21
+ * defaults to the table's own name. The engines pass an alias when the condition lands
22
+ * inside a correlated subquery whose FROM is aliased — there the bare table name would
23
+ * resolve against the OUTER query.
19
24
  */
20
- export type TableFilterFn = (filters: FilterRecord, dialect?: CbDialect) => ConditionBuilder;
25
+ export type TableFilterFn = (filters: FilterRecord, dialect?: CbDialect, qualifier?: string) => ConditionBuilder;
21
26
  export interface ITable<F extends Record<string, TSchema> = Record<string, TSchema>> {
22
27
  primary: (string & keyof F) | (string & keyof F)[];
23
28
  Schema: SchemaDefinition<F>;
@@ -1 +1 @@
1
- {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/types/table.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/types/table.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastify-auto-sqlapi",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Fastify plugin for automatic CRUD API generation from PostgreSQL, MySQL and MariaDB tables",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",