@tablecraft/engine 0.1.5 → 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.
- package/dist/core/queryBuilder.d.ts.map +1 -1
- package/dist/core/queryBuilder.js +29 -17
- package/dist/core/queryBuilder.js.map +1 -1
- package/dist/core/subqueryBuilder.d.ts +17 -0
- package/dist/core/subqueryBuilder.d.ts.map +1 -1
- package/dist/core/subqueryBuilder.js +58 -11
- package/dist/core/subqueryBuilder.js.map +1 -1
- package/dist/define.d.ts +85 -15
- package/dist/define.d.ts.map +1 -1
- package/dist/define.js +171 -43
- package/dist/define.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +18 -14
- package/dist/engine.js.map +1 -1
- package/dist/types/table.d.ts +292 -2
- package/dist/types/table.d.ts.map +1 -1
- package/dist/types/table.js +29 -2
- package/dist/types/table.js.map +1 -1
- package/dist/utils/openapi.d.ts.map +1 -1
- package/dist/utils/openapi.js +25 -2
- package/dist/utils/openapi.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/queryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,MAAM,EACN,GAAG,EAIJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"queryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/queryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,MAAM,EACN,GAAG,EAIJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAIzD,qBAAa,YAAY;IACX,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC;IAgE5E,OAAO,CAAC,kBAAkB;IA8B1B;;;OAGG;IACH,UAAU,CACR,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,WAAW,EACnB,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAC/B,GAAG;IAUN;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,GAAG;IAO9B,OAAO,CAAC,SAAS;IA6BjB,sBAAsB,CACpB,MAAM,EAAE,WAAW,EACnB,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAChC,GAAG,GAAG,SAAS;CAoCnB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { sql, getTableColumns, and, } from 'drizzle-orm';
|
|
2
2
|
import { applyOperator } from '../utils/operators';
|
|
3
|
+
import { ConfigError } from '../errors';
|
|
3
4
|
export class QueryBuilder {
|
|
4
5
|
schema;
|
|
5
6
|
constructor(schema) {
|
|
@@ -38,16 +39,22 @@ export class QueryBuilder {
|
|
|
38
39
|
if (!col)
|
|
39
40
|
continue;
|
|
40
41
|
if (colConfig.dbTransform && colConfig.dbTransform.length > 0) {
|
|
41
|
-
// Apply SQL transforms
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
else {
|
|
49
|
-
selection[colConfig.name] = col;
|
|
42
|
+
// Apply SQL transforms. col must be a Column object with a .name string;
|
|
43
|
+
// SQL expressions (e.g. from computed columns) do not have .name and
|
|
44
|
+
// cannot be wrapped in a function call.
|
|
45
|
+
if (!('name' in col) || typeof col.name !== 'string') {
|
|
46
|
+
throw new ConfigError(`[TableCraft] dbTransform on '${colConfig.name}' failed: ` +
|
|
47
|
+
`the resolved column is not a plain Column (it may be a SQL expression). ` +
|
|
48
|
+
`Use rawSelect() with an explicit SQL expression instead.`);
|
|
50
49
|
}
|
|
50
|
+
const colName = col.name;
|
|
51
|
+
const expressionStr = colConfig.dbTransform.reduce((acc, func) => {
|
|
52
|
+
if (func.includes('?')) {
|
|
53
|
+
return func.replaceAll('?', acc);
|
|
54
|
+
}
|
|
55
|
+
return `${func}(${acc})`;
|
|
56
|
+
}, colName);
|
|
57
|
+
selection[colConfig.name] = sql.raw(expressionStr);
|
|
51
58
|
}
|
|
52
59
|
else {
|
|
53
60
|
selection[colConfig.name] = col;
|
|
@@ -71,7 +78,11 @@ export class QueryBuilder {
|
|
|
71
78
|
const colName = colConfig.field ?? colConfig.name;
|
|
72
79
|
const col = tableCols[colName];
|
|
73
80
|
if (col) {
|
|
74
|
-
|
|
81
|
+
if (Object.prototype.hasOwnProperty.call(selection, colConfig.name)) {
|
|
82
|
+
throw new ConfigError(`[TableCraft] Name collision: join column '${colConfig.name}' from table '${join.table}' ` +
|
|
83
|
+
`conflicts with an existing selection key. ` +
|
|
84
|
+
`Rename the column using the 'field' property or give it a unique alias.`);
|
|
85
|
+
}
|
|
75
86
|
selection[colConfig.name] = col;
|
|
76
87
|
}
|
|
77
88
|
}
|
|
@@ -89,8 +100,9 @@ export class QueryBuilder {
|
|
|
89
100
|
buildJoins(query, config, sqlConditions) {
|
|
90
101
|
if (!config.joins)
|
|
91
102
|
return query;
|
|
103
|
+
query = query.$dynamic();
|
|
92
104
|
for (const join of config.joins) {
|
|
93
|
-
this.applyJoin(query, join, sqlConditions);
|
|
105
|
+
query = this.applyJoin(query, join, sqlConditions);
|
|
94
106
|
}
|
|
95
107
|
return query;
|
|
96
108
|
}
|
|
@@ -108,28 +120,28 @@ export class QueryBuilder {
|
|
|
108
120
|
if (!joinedTable) {
|
|
109
121
|
throw new Error(`Joined table '${join.table}' not found in schema`);
|
|
110
122
|
}
|
|
111
|
-
// Use SQL object if available, otherwise fall back to raw string
|
|
112
123
|
const key = join.alias ?? join.table;
|
|
113
124
|
const onCondition = sqlConditions?.get(key) ?? sql.raw(join.on);
|
|
114
125
|
switch (join.type) {
|
|
115
126
|
case 'left':
|
|
116
|
-
query.leftJoin(joinedTable, onCondition);
|
|
127
|
+
query = query.leftJoin(joinedTable, onCondition);
|
|
117
128
|
break;
|
|
118
129
|
case 'right':
|
|
119
|
-
query.rightJoin(joinedTable, onCondition);
|
|
130
|
+
query = query.rightJoin(joinedTable, onCondition);
|
|
120
131
|
break;
|
|
121
132
|
case 'inner':
|
|
122
|
-
query.innerJoin(joinedTable, onCondition);
|
|
133
|
+
query = query.innerJoin(joinedTable, onCondition);
|
|
123
134
|
break;
|
|
124
135
|
case 'full':
|
|
125
|
-
query.fullJoin(joinedTable, onCondition);
|
|
136
|
+
query = query.fullJoin(joinedTable, onCondition);
|
|
126
137
|
break;
|
|
127
138
|
}
|
|
128
139
|
if (join.joins) {
|
|
129
140
|
for (const nested of join.joins) {
|
|
130
|
-
this.applyJoin(query, nested, sqlConditions);
|
|
141
|
+
query = this.applyJoin(query, nested, sqlConditions);
|
|
131
142
|
}
|
|
132
143
|
}
|
|
144
|
+
return query;
|
|
133
145
|
}
|
|
134
146
|
buildBackendConditions(config, context = {}) {
|
|
135
147
|
if (!config.backendConditions || config.backendConditions.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryBuilder.js","sourceRoot":"","sources":["../../src/core/queryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,GAAG,EACH,eAAe,EACf,GAAG,GACJ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"queryBuilder.js","sourceRoot":"","sources":["../../src/core/queryBuilder.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,5 +15,22 @@ export declare class SubqueryBuilder {
|
|
|
15
15
|
*/
|
|
16
16
|
buildSubqueries(config: TableConfig, dialect?: Dialect): Record<string, SQL> | undefined;
|
|
17
17
|
private buildSingle;
|
|
18
|
+
/**
|
|
19
|
+
* Builds the WHERE clause SQL for a subquery.
|
|
20
|
+
*
|
|
21
|
+
* Priority:
|
|
22
|
+
* 1. `filterSql` — Drizzle SQL expression (full Drizzle DX, passed through as-is)
|
|
23
|
+
* 2. `filterConditions` — structured array of conditions (typed, safe, recommended)
|
|
24
|
+
* 3. `filter` — raw SQL string (@deprecated, developer-authored only)
|
|
25
|
+
* 4. fallback — `true` (uncorrelated, scans whole table)
|
|
26
|
+
*/
|
|
27
|
+
private buildFilter;
|
|
28
|
+
/**
|
|
29
|
+
* Converts a `SubqueryCondition[]` into a single AND-combined SQL expression.
|
|
30
|
+
*
|
|
31
|
+
* Column references → emitted via sql.raw() — developer-defined, not user input
|
|
32
|
+
* Literal values → parameterized via sql`${value}` to prevent injection
|
|
33
|
+
*/
|
|
34
|
+
private buildStructuredFilter;
|
|
18
35
|
}
|
|
19
36
|
//# sourceMappingURL=subqueryBuilder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subqueryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/subqueryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAEJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"subqueryBuilder.d.ts","sourceRoot":"","sources":["../../src/core/subqueryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAEJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAqC,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAepC,qBAAa,eAAe;IACd,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;;;;;;OAQG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;IAuBxF,OAAO,CAAC,WAAW;IAoBnB;;;;;;;;OAQG;IACH,OAAO,CAAC,WAAW;IAanB;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;CAsB9B"}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { sql, } from 'drizzle-orm';
|
|
2
2
|
import { DialectError } from '../errors';
|
|
3
|
+
// Maps our operator enum to the SQL operator string
|
|
4
|
+
const OP_MAP = {
|
|
5
|
+
eq: '=',
|
|
6
|
+
neq: '!=',
|
|
7
|
+
gt: '>',
|
|
8
|
+
gte: '>=',
|
|
9
|
+
lt: '<',
|
|
10
|
+
lte: '<=',
|
|
11
|
+
like: 'LIKE',
|
|
12
|
+
ilike: 'ILIKE',
|
|
13
|
+
};
|
|
3
14
|
export class SubqueryBuilder {
|
|
4
15
|
schema;
|
|
5
16
|
constructor(schema) {
|
|
@@ -34,15 +45,7 @@ export class SubqueryBuilder {
|
|
|
34
45
|
return Object.keys(result).length > 0 ? result : undefined;
|
|
35
46
|
}
|
|
36
47
|
buildSingle(sub, subTable, dialect) {
|
|
37
|
-
|
|
38
|
-
// SQL correlation condition (e.g. "orders.user_id = users.id").
|
|
39
|
-
// It is written by the application developer in source code — not by end users —
|
|
40
|
-
// so raw injection risk is low. However, to prevent accidental developer mistakes
|
|
41
|
-
// we keep the TODO comment and ensure this is clearly documented.
|
|
42
|
-
//
|
|
43
|
-
// TODO: replace with a structured, parameterised representation so the filter
|
|
44
|
-
// can be validated and cannot accidentally include user-supplied strings.
|
|
45
|
-
const filterSql = sub.filter ? sql.raw(sub.filter) : sql `true`;
|
|
48
|
+
const filterSql = this.buildFilter(sub, dialect);
|
|
46
49
|
switch (sub.type) {
|
|
47
50
|
case 'count':
|
|
48
51
|
return sql `(SELECT count(*) FROM ${subTable} WHERE ${filterSql})`;
|
|
@@ -50,8 +53,6 @@ export class SubqueryBuilder {
|
|
|
50
53
|
return sql `EXISTS (SELECT 1 FROM ${subTable} WHERE ${filterSql})`;
|
|
51
54
|
case 'first': {
|
|
52
55
|
// 'first' uses row_to_json() which is PostgreSQL-only.
|
|
53
|
-
// Throw a clear DialectError rather than silently generating invalid SQL
|
|
54
|
-
// that will crash at query-execution time with a cryptic DB error.
|
|
55
56
|
if (dialect && dialect !== 'unknown' && dialect !== 'postgresql') {
|
|
56
57
|
throw new DialectError('first', dialect);
|
|
57
58
|
}
|
|
@@ -61,5 +62,51 @@ export class SubqueryBuilder {
|
|
|
61
62
|
return undefined;
|
|
62
63
|
}
|
|
63
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Builds the WHERE clause SQL for a subquery.
|
|
67
|
+
*
|
|
68
|
+
* Priority:
|
|
69
|
+
* 1. `filterSql` — Drizzle SQL expression (full Drizzle DX, passed through as-is)
|
|
70
|
+
* 2. `filterConditions` — structured array of conditions (typed, safe, recommended)
|
|
71
|
+
* 3. `filter` — raw SQL string (@deprecated, developer-authored only)
|
|
72
|
+
* 4. fallback — `true` (uncorrelated, scans whole table)
|
|
73
|
+
*/
|
|
74
|
+
buildFilter(sub, dialect) {
|
|
75
|
+
if (sub.filterSql) {
|
|
76
|
+
return sub.filterSql;
|
|
77
|
+
}
|
|
78
|
+
if (sub.filterConditions && sub.filterConditions.length > 0) {
|
|
79
|
+
return this.buildStructuredFilter(sub.filterConditions, dialect);
|
|
80
|
+
}
|
|
81
|
+
if (sub.filter) {
|
|
82
|
+
return sql.raw(sub.filter);
|
|
83
|
+
}
|
|
84
|
+
return sql `true`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Converts a `SubqueryCondition[]` into a single AND-combined SQL expression.
|
|
88
|
+
*
|
|
89
|
+
* Column references → emitted via sql.raw() — developer-defined, not user input
|
|
90
|
+
* Literal values → parameterized via sql`${value}` to prevent injection
|
|
91
|
+
*/
|
|
92
|
+
buildStructuredFilter(conditions, dialect) {
|
|
93
|
+
if (conditions.length === 0)
|
|
94
|
+
return sql `true`;
|
|
95
|
+
const parts = conditions.map((cond) => {
|
|
96
|
+
const leftSql = 'column' in cond.left ? sql.raw(cond.left.column) : sql `${cond.left.value}`;
|
|
97
|
+
const rightSql = 'column' in cond.right ? sql.raw(cond.right.column) : sql `${cond.right.value}`;
|
|
98
|
+
const op = cond.op ?? 'eq';
|
|
99
|
+
if (op === 'ilike') {
|
|
100
|
+
if (dialect && dialect !== 'unknown' && dialect !== 'postgresql') {
|
|
101
|
+
// MySQL/SQLite don't support ILIKE directly. We rewrite to LOWER() LIKE LOWER().
|
|
102
|
+
return sql `LOWER(${leftSql}) LIKE LOWER(${rightSql})`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const opStr = OP_MAP[op];
|
|
106
|
+
return sql `${leftSql} ${sql.raw(opStr)} ${rightSql}`;
|
|
107
|
+
});
|
|
108
|
+
// AND-combine all parts
|
|
109
|
+
return parts.reduce((acc, part) => sql `${acc} AND ${part}`);
|
|
110
|
+
}
|
|
64
111
|
}
|
|
65
112
|
//# sourceMappingURL=subqueryBuilder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subqueryBuilder.js","sourceRoot":"","sources":["../../src/core/subqueryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,GACJ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;IAAG,CAAC;IAEvD;;;;;;;;OAQG;IACH,eAAe,CAAC,MAAmB,EAAE,OAAiB;QACpD,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAU,CAAC;QACpD,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAEjC,MAAM,MAAM,GAAwB,EAAE,CAAC;QAEvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAU,CAAC;YACjD,IAAI,CAAC,QAAQ;gBAAE,SAAS;YAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAC1D,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,CAAC;IAEO,WAAW,CAAC,GAAmB,EAAE,QAAe,EAAE,OAAiB;QACzE,
|
|
1
|
+
{"version":3,"file":"subqueryBuilder.js","sourceRoot":"","sources":["../../src/core/subqueryBuilder.ts"],"names":[],"mappings":"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"}
|
package/dist/define.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { and, between, exists, ilike, inArray, isNotNull, isNull, like, not, notBetween, notExists, notInArray, or, SQL, sql, type Table } from "drizzle-orm";
|
|
2
2
|
export declare const drizzleOperators: {
|
|
3
3
|
eq: import("drizzle-orm").BinaryOperator;
|
|
4
4
|
ne: import("drizzle-orm").BinaryOperator;
|
|
@@ -21,8 +21,9 @@ export declare const drizzleOperators: {
|
|
|
21
21
|
not: typeof not;
|
|
22
22
|
sql: typeof sql;
|
|
23
23
|
};
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
24
|
+
import type { CountMode, EngineContext, EngineParams } from "./types/engine";
|
|
25
|
+
import type { ColumnConfig, ColumnFormat, DatePreset, FilterExpression, Operator, SubqueryCondition, TableConfig } from "./types/table";
|
|
26
|
+
export declare const TABLECRAFT_EXTENSIONS_KEY = "__tablecraft_ext";
|
|
26
27
|
type InferColumns<T> = T extends {
|
|
27
28
|
_: {
|
|
28
29
|
columns: infer C;
|
|
@@ -50,6 +51,8 @@ export interface RuntimeExtensions<T extends Table = Table> {
|
|
|
50
51
|
rawOrderBys: SQL[];
|
|
51
52
|
ctes: Map<string, SQL>;
|
|
52
53
|
sqlJoinConditions: Map<string, SQL>;
|
|
54
|
+
/** How row counting is performed. Defaults to 'exact' when not set. */
|
|
55
|
+
countMode?: CountMode;
|
|
53
56
|
hooks?: {
|
|
54
57
|
beforeQuery?: (params: any, context: any) => any;
|
|
55
58
|
afterQuery?: (data: Record<string, unknown>[], params: any, context: any) => any;
|
|
@@ -64,7 +67,7 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
64
67
|
/** Set display format for a column */
|
|
65
68
|
format(column: InferColumns<T>, fmt: ColumnFormat): this;
|
|
66
69
|
/** Set column alignment */
|
|
67
|
-
align(column: InferColumns<T>, alignment:
|
|
70
|
+
align(column: InferColumns<T>, alignment: "left" | "center" | "right"): this;
|
|
68
71
|
/** Set column width (px) */
|
|
69
72
|
width(column: InferColumns<T>, w: number, options?: {
|
|
70
73
|
min?: number;
|
|
@@ -136,7 +139,7 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
136
139
|
* ]},
|
|
137
140
|
* ])
|
|
138
141
|
*/
|
|
139
|
-
whereGroup(type:
|
|
142
|
+
whereGroup(type: "and" | "or", conditions: FilterExpression[]): this;
|
|
140
143
|
sort(...specs: string[]): this;
|
|
141
144
|
sortable(...columns: InferColumns<T>[]): this;
|
|
142
145
|
noSort(): this;
|
|
@@ -146,12 +149,12 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
146
149
|
noPagination(): this;
|
|
147
150
|
join(table: Table, options?: {
|
|
148
151
|
on?: string | SQL;
|
|
149
|
-
type?:
|
|
152
|
+
type?: "left" | "right" | "inner" | "full";
|
|
150
153
|
alias?: string;
|
|
151
154
|
columns?: string[];
|
|
152
155
|
}): this;
|
|
153
156
|
computed(name: string, expression: SQL, options?: {
|
|
154
|
-
type?: ColumnConfig[
|
|
157
|
+
type?: ColumnConfig["type"];
|
|
155
158
|
label?: string;
|
|
156
159
|
sortable?: boolean;
|
|
157
160
|
}): this;
|
|
@@ -168,7 +171,7 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
168
171
|
transform(column: InferColumns<T>, fn: (value: unknown) => unknown): this;
|
|
169
172
|
groupBy(...fields: InferColumns<T>[]): this;
|
|
170
173
|
having(alias: string, operator: Operator, value: unknown): this;
|
|
171
|
-
aggregate(alias: string, type:
|
|
174
|
+
aggregate(alias: string, type: "count" | "sum" | "avg" | "min" | "max", field: InferColumns<T>): this;
|
|
172
175
|
include(table: Table, options: {
|
|
173
176
|
foreignKey: string;
|
|
174
177
|
localKey?: string;
|
|
@@ -216,10 +219,10 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
216
219
|
* })
|
|
217
220
|
*/
|
|
218
221
|
columnMeta(column: string, meta: {
|
|
219
|
-
type?: ColumnConfig[
|
|
222
|
+
type?: ColumnConfig["type"];
|
|
220
223
|
label?: string;
|
|
221
224
|
format?: ColumnFormat;
|
|
222
|
-
align?:
|
|
225
|
+
align?: "left" | "center" | "right";
|
|
223
226
|
width?: number;
|
|
224
227
|
minWidth?: number;
|
|
225
228
|
maxWidth?: number;
|
|
@@ -255,10 +258,10 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
255
258
|
* .columnMeta('revenue', { type: 'number', label: 'Revenue', format: 'currency' })
|
|
256
259
|
*/
|
|
257
260
|
rawSelect(alias: string, sqlExpr: SQL, options?: {
|
|
258
|
-
type?: ColumnConfig[
|
|
261
|
+
type?: ColumnConfig["type"];
|
|
259
262
|
label?: string;
|
|
260
263
|
format?: ColumnFormat;
|
|
261
|
-
align?:
|
|
264
|
+
align?: "left" | "center" | "right";
|
|
262
265
|
sortable?: boolean;
|
|
263
266
|
filterable?: boolean;
|
|
264
267
|
hidden?: boolean;
|
|
@@ -282,22 +285,89 @@ export declare class TableDefinitionBuilder<T extends Table = Table> {
|
|
|
282
285
|
*/
|
|
283
286
|
rawOrderBy(sqlExpr: SQL): this;
|
|
284
287
|
cte(name: string, sqlExpr: SQL): this;
|
|
285
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Attach a correlated subquery to every row.
|
|
290
|
+
*
|
|
291
|
+
* The `filter` parameter controls the subquery's WHERE clause and accepts
|
|
292
|
+
* **three forms** — pick whichever fits your style:
|
|
293
|
+
*
|
|
294
|
+
* ---
|
|
295
|
+
*
|
|
296
|
+
* ### 1. Drizzle `sql\`...\`` expression *(best DX — use your schema columns directly)*
|
|
297
|
+
*
|
|
298
|
+
* Import `sql` from `drizzle-orm` and write the WHERE clause exactly as you
|
|
299
|
+
* would in any Drizzle query. TableCraft passes the expression through unchanged,
|
|
300
|
+
* so the full power of Drizzle is available — joins, functions, OR logic, anything.
|
|
301
|
+
* You own the safety of the expression.
|
|
302
|
+
*
|
|
303
|
+
* ```ts
|
|
304
|
+
* import { sql } from 'drizzle-orm';
|
|
305
|
+
* import { orders, orderItems } from '../db/schema';
|
|
306
|
+
*
|
|
307
|
+
* .subquery('itemCount', orderItems, 'count',
|
|
308
|
+
* sql`${orderItems.orderId} = ${orders.id}`)
|
|
309
|
+
*
|
|
310
|
+
* // With an extra condition:
|
|
311
|
+
* .subquery('activeItemCount', orderItems, 'count',
|
|
312
|
+
* sql`${orderItems.orderId} = ${orders.id} AND ${orderItems.status} = ${'active'}`)
|
|
313
|
+
* ```
|
|
314
|
+
*
|
|
315
|
+
* ---
|
|
316
|
+
*
|
|
317
|
+
* ### 2. Structured `SubqueryCondition[]` *(typed, injection-safe)*
|
|
318
|
+
*
|
|
319
|
+
* Pass an array of condition objects. Each has `left`, `op` (default `'eq'`),
|
|
320
|
+
* and `right` operands — either `{ column: 'table.column' }` or `{ value: literal }`.
|
|
321
|
+
* Conditions are AND-combined. Literal values are parameterized automatically.
|
|
322
|
+
*
|
|
323
|
+
* ```ts
|
|
324
|
+
* // Simple column-to-column join:
|
|
325
|
+
* .subquery('itemCount', orderItems, 'count', [
|
|
326
|
+
* { left: { column: 'order_items.order_id' }, op: 'eq', right: { column: 'orders.id' } },
|
|
327
|
+
* ])
|
|
328
|
+
*
|
|
329
|
+
* // With a literal value filter:
|
|
330
|
+
* .subquery('activeItemCount', orderItems, 'count', [
|
|
331
|
+
* { left: { column: 'order_items.order_id' }, op: 'eq', right: { column: 'orders.id' } },
|
|
332
|
+
* { left: { column: 'order_items.status' }, op: 'eq', right: { value: 'active' } },
|
|
333
|
+
* ])
|
|
334
|
+
* ```
|
|
335
|
+
*
|
|
336
|
+
* ---
|
|
337
|
+
*
|
|
338
|
+
* ### 3. Raw SQL string *(@deprecated — developer-authored constants only)*
|
|
339
|
+
*
|
|
340
|
+
* Still accepted for backwards compatibility. Must be a hardcoded string authored
|
|
341
|
+
* by the developer — never derived from user input. Prefer form 1 or 2 instead.
|
|
342
|
+
*
|
|
343
|
+
* ```ts
|
|
344
|
+
* // @deprecated
|
|
345
|
+
* .subquery('itemCount', orderItems, 'count', 'order_items.order_id = orders.id')
|
|
346
|
+
* ```
|
|
347
|
+
*
|
|
348
|
+
* ---
|
|
349
|
+
*
|
|
350
|
+
* Omitting `filter` creates an uncorrelated subquery (full table scan).
|
|
351
|
+
*/
|
|
352
|
+
subquery(alias: string, table: Table, type: "count" | "exists" | "first", filter?: string | SubqueryCondition[] | SQL): this;
|
|
286
353
|
softDelete(field?: string): this;
|
|
287
354
|
tenant(field?: string): this;
|
|
288
|
-
exportable(...formats: (
|
|
355
|
+
exportable(...formats: ("csv" | "json")[]): this;
|
|
289
356
|
access(options: {
|
|
290
357
|
roles?: string[];
|
|
291
358
|
permissions?: string[];
|
|
292
359
|
}): this;
|
|
360
|
+
/** Set a custom display name for this table definition. */
|
|
293
361
|
as(name: string): this;
|
|
362
|
+
/** Alias for `.as()` — sets the table's display name. */
|
|
363
|
+
name(name: string): this;
|
|
294
364
|
/**
|
|
295
365
|
* Control how row counting works.
|
|
296
366
|
* 'exact' = SELECT COUNT(*) — accurate but slow on large tables
|
|
297
367
|
* 'estimated' = PostgreSQL's reltuples — fast but approximate
|
|
298
368
|
* 'none' = skip counting entirely — fastest
|
|
299
369
|
*/
|
|
300
|
-
countMode(mode:
|
|
370
|
+
countMode(mode: CountMode): this;
|
|
301
371
|
/** Enable DISTINCT on queries */
|
|
302
372
|
distinct(): this;
|
|
303
373
|
/** Add a hook that runs before every query */
|
package/dist/define.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"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"}
|