sumak 0.0.1 → 0.0.3
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/README.md +76 -47
- package/dist/_chunks/errors.mjs +1 -1
- package/dist/_chunks/index.d.mts +31 -14
- package/dist/index.d.mts +133 -132
- package/dist/index.mjs +2 -2
- package/dist/schema.d.mts +1 -1
- package/package.json +15 -16
package/README.md
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<br>
|
|
3
|
-
<img src=".github/assets/cover.jpg" alt="
|
|
3
|
+
<img src=".github/assets/cover.jpg" alt="sumak — Type-safe SQL query builder" width="100%">
|
|
4
4
|
<br><br>
|
|
5
|
-
<b style="font-size: 2em;">
|
|
5
|
+
<b style="font-size: 2em;">sumak</b>
|
|
6
6
|
<br><br>
|
|
7
7
|
Type-safe SQL query builder with powerful SQL printers.
|
|
8
8
|
<br>
|
|
9
9
|
Zero dependencies, AST-first, hookable, tree-shakeable. Pure TypeScript, works everywhere.
|
|
10
10
|
<br><br>
|
|
11
|
-
<a href="https://npmjs.com/package/
|
|
12
|
-
<a href="https://npmjs.com/package/
|
|
13
|
-
<a href="https://bundlephobia.com/result?p=
|
|
14
|
-
<a href="https://github.com/productdevbook/
|
|
11
|
+
<a href="https://npmjs.com/package/sumak"><img src="https://img.shields.io/npm/v/sumak?style=flat&colorA=18181B&colorB=e11d48" alt="npm version"></a>
|
|
12
|
+
<a href="https://npmjs.com/package/sumak"><img src="https://img.shields.io/npm/dm/sumak?style=flat&colorA=18181B&colorB=e11d48" alt="npm downloads"></a>
|
|
13
|
+
<a href="https://bundlephobia.com/result?p=sumak"><img src="https://img.shields.io/bundlephobia/minzip/sumak?style=flat&colorA=18181B&colorB=e11d48" alt="bundle size"></a>
|
|
14
|
+
<a href="https://github.com/productdevbook/sumak/blob/main/LICENSE"><img src="https://img.shields.io/github/license/productdevbook/sumak?style=flat&colorA=18181B&colorB=e11d48" alt="license"></a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
19
|
```sh
|
|
20
|
-
npm install
|
|
20
|
+
npm install sumak
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
```ts
|
|
24
|
-
import {
|
|
24
|
+
import { sumak, pgDialect, serial, text, boolean, integer } from "sumak"
|
|
25
25
|
|
|
26
|
-
const db =
|
|
26
|
+
const db = sumak({
|
|
27
27
|
dialect: pgDialect(),
|
|
28
28
|
tables: {
|
|
29
29
|
users: {
|
|
@@ -38,7 +38,7 @@ const db = pamuk({
|
|
|
38
38
|
userId: integer().references("users", "id"),
|
|
39
39
|
},
|
|
40
40
|
},
|
|
41
|
-
})
|
|
41
|
+
})
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
## Query Building
|
|
@@ -50,8 +50,7 @@ db.selectFrom("users")
|
|
|
50
50
|
.where(({ age, active }) => and(age.gte(18), active.eq(true)))
|
|
51
51
|
.orderBy("name")
|
|
52
52
|
.limit(10)
|
|
53
|
-
.compile(db.printer())
|
|
54
|
-
// → SELECT "id", "name" FROM "users" WHERE ("age" >= $1 AND "active" = $2) ORDER BY "name" ASC LIMIT 10
|
|
53
|
+
.compile(db.printer())
|
|
55
54
|
|
|
56
55
|
// INSERT
|
|
57
56
|
db.insertInto("users")
|
|
@@ -60,19 +59,19 @@ db.insertInto("users")
|
|
|
60
59
|
email: "alice@example.com",
|
|
61
60
|
})
|
|
62
61
|
.returningAll()
|
|
63
|
-
.compile(db.printer())
|
|
62
|
+
.compile(db.printer())
|
|
64
63
|
|
|
65
64
|
// UPDATE
|
|
66
65
|
db.update("users")
|
|
67
66
|
.set({ active: false })
|
|
68
67
|
.where(({ id }) => id.eq(1))
|
|
69
|
-
.compile(db.printer())
|
|
68
|
+
.compile(db.printer())
|
|
70
69
|
|
|
71
70
|
// DELETE
|
|
72
71
|
db.deleteFrom("users")
|
|
73
72
|
.where(({ id }) => id.eq(1))
|
|
74
73
|
.returning("id")
|
|
75
|
-
.compile(db.printer())
|
|
74
|
+
.compile(db.printer())
|
|
76
75
|
```
|
|
77
76
|
|
|
78
77
|
## Joins
|
|
@@ -80,8 +79,7 @@ db.deleteFrom("users")
|
|
|
80
79
|
```ts
|
|
81
80
|
db.selectFrom("users")
|
|
82
81
|
.innerJoin("posts", ({ users, posts }) => users.id.eqCol(posts.userId))
|
|
83
|
-
.compile(db.printer())
|
|
84
|
-
// → SELECT * FROM "users" INNER JOIN "posts" ON ("users"."id" = "posts"."userId")
|
|
82
|
+
.compile(db.printer())
|
|
85
83
|
```
|
|
86
84
|
|
|
87
85
|
## Tree Shaking
|
|
@@ -89,11 +87,11 @@ db.selectFrom("users")
|
|
|
89
87
|
Import only the dialect you need:
|
|
90
88
|
|
|
91
89
|
```ts
|
|
92
|
-
import {
|
|
93
|
-
import { pgDialect } from "
|
|
94
|
-
import { mysqlDialect } from "
|
|
95
|
-
import { sqliteDialect } from "
|
|
96
|
-
import { serial, text } from "
|
|
90
|
+
import { sumak } from "sumak"
|
|
91
|
+
import { pgDialect } from "sumak/pg"
|
|
92
|
+
import { mysqlDialect } from "sumak/mysql"
|
|
93
|
+
import { sqliteDialect } from "sumak/sqlite"
|
|
94
|
+
import { serial, text } from "sumak/schema"
|
|
97
95
|
```
|
|
98
96
|
|
|
99
97
|
## Dialects
|
|
@@ -109,9 +107,9 @@ Same query, different SQL:
|
|
|
109
107
|
## Plugins
|
|
110
108
|
|
|
111
109
|
```ts
|
|
112
|
-
import { WithSchemaPlugin, SoftDeletePlugin, CamelCasePlugin } from "
|
|
110
|
+
import { WithSchemaPlugin, SoftDeletePlugin, CamelCasePlugin } from "sumak";
|
|
113
111
|
|
|
114
|
-
const db =
|
|
112
|
+
const db = sumak({
|
|
115
113
|
dialect: pgDialect(),
|
|
116
114
|
plugins: [
|
|
117
115
|
new WithSchemaPlugin("public"),
|
|
@@ -128,52 +126,83 @@ const db = pamuk({
|
|
|
128
126
|
```ts
|
|
129
127
|
// Query logging
|
|
130
128
|
db.hook("query:after", (ctx) => {
|
|
131
|
-
console.log(`[SQL] ${ctx.query.sql}`)
|
|
132
|
-
})
|
|
129
|
+
console.log(`[SQL] ${ctx.query.sql}`)
|
|
130
|
+
})
|
|
133
131
|
|
|
134
132
|
// Add request tracing
|
|
135
133
|
db.hook("query:after", (ctx) => {
|
|
136
134
|
return {
|
|
137
135
|
...ctx.query,
|
|
138
136
|
sql: `${ctx.query.sql} /* request_id=${requestId} */`,
|
|
139
|
-
}
|
|
140
|
-
})
|
|
137
|
+
}
|
|
138
|
+
})
|
|
141
139
|
|
|
142
140
|
// Modify AST before compilation
|
|
143
141
|
db.hook("select:before", (ctx) => {
|
|
144
142
|
// Add tenant isolation, audit filters, etc.
|
|
145
|
-
})
|
|
143
|
+
})
|
|
146
144
|
|
|
147
145
|
// Transform results
|
|
148
146
|
db.hook("result:transform", (rows) => {
|
|
149
|
-
return rows.map(toCamelCase)
|
|
150
|
-
})
|
|
147
|
+
return rows.map(toCamelCase)
|
|
148
|
+
})
|
|
151
149
|
|
|
152
150
|
// Unregister
|
|
153
|
-
const off = db.hook("query:before", handler)
|
|
154
|
-
off()
|
|
151
|
+
const off = db.hook("query:before", handler)
|
|
152
|
+
off()
|
|
155
153
|
```
|
|
156
154
|
|
|
157
155
|
## Expression API
|
|
158
156
|
|
|
159
157
|
```ts
|
|
160
|
-
|
|
161
|
-
.where(({
|
|
162
|
-
.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
.where(({
|
|
167
|
-
|
|
158
|
+
// Equality
|
|
159
|
+
.where(({ id }) =>
|
|
160
|
+
id.eq(42),
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
// String matching
|
|
164
|
+
.where(({ name }) =>
|
|
165
|
+
name.like("%ali%"),
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
// Range
|
|
169
|
+
.where(({ age }) =>
|
|
170
|
+
age.between(18, 65),
|
|
168
171
|
)
|
|
169
|
-
|
|
170
|
-
|
|
172
|
+
|
|
173
|
+
// List
|
|
174
|
+
.where(({ id }) =>
|
|
175
|
+
id.in([1, 2, 3]),
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
// Null checks
|
|
179
|
+
.where(({ bio }) =>
|
|
180
|
+
bio.isNull(),
|
|
181
|
+
)
|
|
182
|
+
.where(({ email }) =>
|
|
183
|
+
email.isNotNull(),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
// AND
|
|
187
|
+
.where(({ a, b }) =>
|
|
188
|
+
and(
|
|
189
|
+
a.gt(0),
|
|
190
|
+
b.neq("x"),
|
|
191
|
+
),
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
// OR
|
|
195
|
+
.where(({ a, b }) =>
|
|
196
|
+
or(
|
|
197
|
+
a.eq(1),
|
|
198
|
+
b.eq(2),
|
|
199
|
+
),
|
|
171
200
|
)
|
|
172
201
|
```
|
|
173
202
|
|
|
174
|
-
## Why
|
|
203
|
+
## Why sumak?
|
|
175
204
|
|
|
176
|
-
| |
|
|
205
|
+
| | sumak | Drizzle | Kysely |
|
|
177
206
|
| ------------------ | ----------------- | --------------- | -------------- |
|
|
178
207
|
| **Architecture** | AST-first | Template | AST (98 nodes) |
|
|
179
208
|
| **Type inference** | Auto (no codegen) | Auto | Manual DB type |
|
|
@@ -190,9 +219,9 @@ Schema → Builder → AST → Plugin/Hook → Printer → SQL
|
|
|
190
219
|
```
|
|
191
220
|
|
|
192
221
|
- **Schema Layer** — `defineTable()`, `ColumnType<S,I,U>`, auto type inference
|
|
193
|
-
- **Builder Layer** — `
|
|
222
|
+
- **Builder Layer** — `Sumak<DB>`, `TypedSelectBuilder<DB,TB,O>`, proxy-based expressions
|
|
194
223
|
- **AST Layer** — ~35 frozen node types, discriminated unions, visitor pattern
|
|
195
|
-
- **Plugin Layer** — `
|
|
224
|
+
- **Plugin Layer** — `SumakPlugin` interface, `Hookable` lifecycle hooks
|
|
196
225
|
- **Printer Layer** — `BasePrinter` with dialect subclasses, Wadler document algebra
|
|
197
226
|
|
|
198
227
|
## License
|
package/dist/_chunks/errors.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=class extends Error{constructor(e){super(e),this.name=`
|
|
1
|
+
var e=class extends Error{constructor(e){super(e),this.name=`SumakError`}},t=class extends e{constructor(e){super(e),this.name=`InvalidExpressionError`}},n=class extends e{constructor(e,t){super(`${t} is not supported in ${e}`),this.name=`UnsupportedDialectFeatureError`}},r=class extends e{constructor(e){super(`Cannot build ${e}: missing required clauses`),this.name=`EmptyQueryError`}};export{n as i,t as n,e as r,r as t};
|
package/dist/_chunks/index.d.mts
CHANGED
|
@@ -14,21 +14,34 @@ interface ColumnType<S, I = S, U = I> {
|
|
|
14
14
|
type Generated<T> = ColumnType<T, T | undefined, T | undefined>;
|
|
15
15
|
/** DB always generates (identity always). Never provided by user. */
|
|
16
16
|
type GeneratedAlways<T> = ColumnType<T, never, never>;
|
|
17
|
-
/**
|
|
18
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Extract the SELECT type from a column.
|
|
19
|
+
* Works with both ColumnType and ColumnBuilder (both declare __select).
|
|
20
|
+
*/
|
|
21
|
+
type SelectType<C> = C extends {
|
|
22
|
+
readonly __select: infer S;
|
|
23
|
+
} ? S : C;
|
|
19
24
|
/** Extract the INSERT type from a column. */
|
|
20
|
-
type InsertType<C> = C extends
|
|
25
|
+
type InsertType<C> = C extends {
|
|
26
|
+
readonly __insert: infer I;
|
|
27
|
+
} ? I : C;
|
|
21
28
|
/** Extract the UPDATE type from a column. */
|
|
22
|
-
type UpdateType<C> = C extends
|
|
29
|
+
type UpdateType<C> = C extends {
|
|
30
|
+
readonly __update: infer U;
|
|
31
|
+
} ? U : C;
|
|
23
32
|
/** Make all properties nullable. */
|
|
24
|
-
type Nullable
|
|
33
|
+
type Nullable<T> = { [K in keyof T]: T[K] | null };
|
|
34
|
+
/**
|
|
35
|
+
* Select row type for a table. Cached alias — tsgo instantiation cache
|
|
36
|
+
* deduplicates across selectFrom, join, returning.
|
|
37
|
+
*/
|
|
38
|
+
type SelectRow<DB, TB extends keyof DB> = { [K in keyof DB[TB]]: SelectType<DB[TB][K]> };
|
|
25
39
|
/**
|
|
26
|
-
* Infer a SELECT row type from a
|
|
27
|
-
* Every column present, nullable columns include null.
|
|
40
|
+
* Infer a SELECT row type from a column map.
|
|
28
41
|
*/
|
|
29
42
|
type Selectable<T> = { [K in keyof T]: SelectType<T[K]> };
|
|
30
43
|
/**
|
|
31
|
-
* Infer an INSERT row type from a
|
|
44
|
+
* Infer an INSERT row type from a column map.
|
|
32
45
|
* Required columns: non-nullable without default.
|
|
33
46
|
* Optional columns: nullable, has default, or generated.
|
|
34
47
|
*/
|
|
@@ -55,8 +68,14 @@ interface ColumnDef {
|
|
|
55
68
|
declare class ColumnBuilder<S, I = S, U = I> {
|
|
56
69
|
/** @internal */
|
|
57
70
|
readonly _def: ColumnDef;
|
|
58
|
-
/**
|
|
59
|
-
|
|
71
|
+
/**
|
|
72
|
+
* Phantom branded fields — carry type info for indexed access.
|
|
73
|
+
* tsgo resolves `C["__select"]` via O(1) symbol table lookup,
|
|
74
|
+
* avoiding conditional type evaluation entirely.
|
|
75
|
+
*/
|
|
76
|
+
readonly __select: S;
|
|
77
|
+
readonly __insert: I;
|
|
78
|
+
readonly __update: U;
|
|
60
79
|
constructor(dataType: string, def?: Partial<ColumnDef>);
|
|
61
80
|
notNull(): ColumnBuilder<Exclude<S, null>, Exclude<I, null>, Exclude<U, null>>;
|
|
62
81
|
nullable(): ColumnBuilder<S | null, I | null | undefined, U | null | undefined>;
|
|
@@ -83,7 +102,7 @@ declare function jsonb<T = unknown>(): ColumnBuilder<T, T, T>;
|
|
|
83
102
|
declare function numeric(precision?: number, scale?: number): ColumnBuilder<string, string | number, string | number>;
|
|
84
103
|
declare function real(): ColumnBuilder<number, number, number>;
|
|
85
104
|
declare function doublePrecision(): ColumnBuilder<number, number, number>;
|
|
86
|
-
declare function bytea(): ColumnBuilder<
|
|
105
|
+
declare function bytea(): ColumnBuilder<Uint8Array, Uint8Array, Uint8Array>;
|
|
87
106
|
declare function enumType<T extends string>(...values: [T, ...T[]]): ColumnBuilder<T, T, T>;
|
|
88
107
|
interface TableDefinition<TName extends string = string, TColumns extends Record<string, ColumnBuilder<any, any, any>> = Record<string, ColumnBuilder<any, any, any>>> {
|
|
89
108
|
readonly name: TName;
|
|
@@ -114,6 +133,4 @@ declare function defineTable<TName extends string, TColumns extends Record<strin
|
|
|
114
133
|
* ```
|
|
115
134
|
*/
|
|
116
135
|
type InferTable<T extends TableDefinition> = T extends TableDefinition<any, infer Cols> ? { [K in keyof Cols]: Cols[K] extends ColumnBuilder<infer S, infer I, infer U> ? ColumnType<S, I, U> : never } : never;
|
|
117
|
-
|
|
118
|
-
type Nullable<T> = { [K in keyof T]: T[K] | null };
|
|
119
|
-
export { GeneratedAlways as A, time as C, varchar as D, uuid as E, Selectable as F, UpdateType as I, Updateable as L, Insertable as M, Nullable$1 as N, ColumnType as O, SelectType as P, text as S, timestamptz as T, jsonb as _, ColumnBuilder as a, serial as b, bigserial as c, char as d, date as f, json as g, integer as h, defineTable as i, InsertType as j, Generated as k, boolean as l, enumType as m, InferTable as n, ColumnDef as o, doublePrecision as p, TableDefinition as r, bigint as s, Nullable as t, bytea as u, numeric as v, timestamp as w, smallint as x, real as y };
|
|
136
|
+
export { InsertType as A, timestamp as C, ColumnType as D, varchar as E, Selectable as F, UpdateType as I, Updateable as L, Nullable as M, SelectRow as N, Generated as O, SelectType as P, time as S, uuid as T, numeric as _, ColumnDef as a, smallint as b, boolean as c, date as d, doublePrecision as f, jsonb as g, json as h, ColumnBuilder as i, Insertable as j, GeneratedAlways as k, bytea as l, integer as m, TableDefinition as n, bigint as o, enumType as p, defineTable as r, bigserial as s, InferTable as t, char as u, real as v, timestamptz as w, text as x, serial as y };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,7 +2,7 @@ import { A as RawNode, B as createSelectNode, C as IsNullNode, D as OnConflictNo
|
|
|
2
2
|
import { n as PgPrinter, t as pgDialect } from "./_chunks/pg.mjs";
|
|
3
3
|
import { n as MysqlPrinter, t as mysqlDialect } from "./_chunks/mysql.mjs";
|
|
4
4
|
import { n as SqlitePrinter, t as sqliteDialect } from "./_chunks/sqlite.mjs";
|
|
5
|
-
import { A as
|
|
5
|
+
import { A as InsertType, C as timestamp, D as ColumnType, E as varchar, F as Selectable, I as UpdateType, L as Updateable, M as Nullable, N as SelectRow, O as Generated, P as SelectType, S as time, T as uuid, _ as numeric, a as ColumnDef, b as smallint, c as boolean, d as date, f as doublePrecision, g as jsonb, h as json, i as ColumnBuilder, j as Insertable, k as GeneratedAlways, l as bytea, m as integer, n as TableDefinition, o as bigint, p as enumType, r as defineTable, s as bigserial, t as InferTable, u as char, v as real, w as timestamptz, x as text$1, y as serial } from "./_chunks/index.mjs";
|
|
6
6
|
declare function col(column: string, table?: string): ColumnRefNode;
|
|
7
7
|
declare function colAs(column: string, alias: string, table?: string): ColumnRefNode;
|
|
8
8
|
declare function lit(value: string | number | boolean | null): LiteralNode;
|
|
@@ -182,7 +182,7 @@ declare function formatParam(index: number, dialect: SQLDialect): string;
|
|
|
182
182
|
* // users.name.like("%ali%") → ("name" LIKE '%ali%')
|
|
183
183
|
* ```
|
|
184
184
|
*/
|
|
185
|
-
declare class Col
|
|
185
|
+
declare class Col<T> {
|
|
186
186
|
/** @internal */
|
|
187
187
|
readonly _node: ExpressionNode;
|
|
188
188
|
readonly _type: T;
|
|
@@ -200,7 +200,7 @@ declare class Col$1<T> {
|
|
|
200
200
|
/** <= */
|
|
201
201
|
lte(value: T): Expression<boolean>;
|
|
202
202
|
/** LIKE (string columns only) */
|
|
203
|
-
like(this: Col
|
|
203
|
+
like(this: Col<string>, pattern: string): Expression<boolean>;
|
|
204
204
|
/** IN (value1, value2, ...) */
|
|
205
205
|
in(values: T[]): Expression<boolean>;
|
|
206
206
|
/** NOT IN */
|
|
@@ -212,7 +212,7 @@ declare class Col$1<T> {
|
|
|
212
212
|
/** BETWEEN low AND high */
|
|
213
213
|
between(low: T, high: T): Expression<boolean>;
|
|
214
214
|
/** Compare with another column: col1.eqCol(col2) */
|
|
215
|
-
eqCol(other: Col
|
|
215
|
+
eqCol(other: Col<T>): Expression<boolean>;
|
|
216
216
|
/** As raw Expression<T> for advanced use */
|
|
217
217
|
toExpr(): Expression<T>;
|
|
218
218
|
}
|
|
@@ -222,7 +222,7 @@ declare function resetParams(): void;
|
|
|
222
222
|
*
|
|
223
223
|
* Type: { id: Col<number>, name: Col<string>, ... }
|
|
224
224
|
*/
|
|
225
|
-
type ColumnProxies<DB, TB extends keyof DB> = { [K in keyof DB[TB] & string]: Col
|
|
225
|
+
type ColumnProxies<DB, TB extends keyof DB> = { [K in keyof DB[TB] & string]: Col<SelectType<DB[TB][K]>> };
|
|
226
226
|
/**
|
|
227
227
|
* Expression builder callback type.
|
|
228
228
|
*
|
|
@@ -241,6 +241,80 @@ declare function val<T extends string | number | boolean | null>(value: T): Expr
|
|
|
241
241
|
declare function sqlFn(name: string, ...args: Expression<any>[]): Expression<any>;
|
|
242
242
|
/** COUNT(*) */
|
|
243
243
|
declare function count(): Expression<number>;
|
|
244
|
+
/**
|
|
245
|
+
* Type-safe DELETE query builder.
|
|
246
|
+
*/
|
|
247
|
+
declare class TypedDeleteBuilder<DB, TB extends keyof DB> {
|
|
248
|
+
/** @internal */
|
|
249
|
+
readonly _builder: DeleteBuilder;
|
|
250
|
+
constructor(table: TB & string);
|
|
251
|
+
/** @internal */
|
|
252
|
+
private _with;
|
|
253
|
+
/**
|
|
254
|
+
* WHERE — callback or raw Expression.
|
|
255
|
+
*/
|
|
256
|
+
where(exprOrCallback: Expression<boolean> | WhereCallback<DB, TB>): TypedDeleteBuilder<DB, TB>;
|
|
257
|
+
/**
|
|
258
|
+
* RETURNING specific columns.
|
|
259
|
+
*/
|
|
260
|
+
returning<K extends keyof DB[TB] & string>(...cols: K[]): TypedDeleteReturningBuilder<DB, TB, Pick<SelectRow<DB, TB>, K>>;
|
|
261
|
+
/**
|
|
262
|
+
* RETURNING all columns.
|
|
263
|
+
*/
|
|
264
|
+
returningAll(): TypedDeleteReturningBuilder<DB, TB, SelectRow<DB, TB>>;
|
|
265
|
+
build(): DeleteNode;
|
|
266
|
+
compile(printer: Printer): CompiledQuery;
|
|
267
|
+
}
|
|
268
|
+
declare class TypedDeleteReturningBuilder<DB, _TB extends keyof DB, _R> {
|
|
269
|
+
/** @internal */
|
|
270
|
+
readonly _builder: DeleteBuilder;
|
|
271
|
+
constructor(builder: DeleteBuilder);
|
|
272
|
+
build(): DeleteNode;
|
|
273
|
+
compile(printer: Printer): CompiledQuery;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Type-safe INSERT query builder.
|
|
277
|
+
*/
|
|
278
|
+
declare class TypedInsertBuilder<DB, TB extends keyof DB> {
|
|
279
|
+
/** @internal */
|
|
280
|
+
readonly _builder: InsertBuilder;
|
|
281
|
+
private _paramIdx;
|
|
282
|
+
constructor(table: TB & string, paramIdx?: number);
|
|
283
|
+
/** @internal */
|
|
284
|
+
private _withBuilder;
|
|
285
|
+
/**
|
|
286
|
+
* Insert a single row. Columns/values inferred from Insertable<DB[TB]>.
|
|
287
|
+
*/
|
|
288
|
+
values(row: Insertable<DB[TB]>): TypedInsertBuilder<DB, TB>;
|
|
289
|
+
/**
|
|
290
|
+
* RETURNING specific columns.
|
|
291
|
+
*/
|
|
292
|
+
returning<K extends keyof DB[TB] & string>(...cols: K[]): TypedInsertReturningBuilder<DB, TB, Pick<SelectRow<DB, TB>, K>>;
|
|
293
|
+
/**
|
|
294
|
+
* RETURNING all columns.
|
|
295
|
+
*/
|
|
296
|
+
returningAll(): TypedInsertReturningBuilder<DB, TB, SelectRow<DB, TB>>;
|
|
297
|
+
/**
|
|
298
|
+
* ON CONFLICT DO NOTHING.
|
|
299
|
+
*/
|
|
300
|
+
onConflictDoNothing(...columns: (keyof DB[TB] & string)[]): TypedInsertBuilder<DB, TB>;
|
|
301
|
+
/**
|
|
302
|
+
* ON CONFLICT DO UPDATE.
|
|
303
|
+
*/
|
|
304
|
+
onConflictDoUpdate(columns: (keyof DB[TB] & string)[], set: {
|
|
305
|
+
column: keyof DB[TB] & string;
|
|
306
|
+
value: Expression<any>;
|
|
307
|
+
}[]): TypedInsertBuilder<DB, TB>;
|
|
308
|
+
build(): InsertNode;
|
|
309
|
+
compile(printer: Printer): CompiledQuery;
|
|
310
|
+
}
|
|
311
|
+
declare class TypedInsertReturningBuilder<DB, _TB extends keyof DB, _R> {
|
|
312
|
+
/** @internal */
|
|
313
|
+
readonly _builder: InsertBuilder;
|
|
314
|
+
constructor(builder: InsertBuilder);
|
|
315
|
+
build(): InsertNode;
|
|
316
|
+
compile(printer: Printer): CompiledQuery;
|
|
317
|
+
}
|
|
244
318
|
/**
|
|
245
319
|
* Type-safe SELECT query builder.
|
|
246
320
|
*
|
|
@@ -281,13 +355,13 @@ declare class TypedSelectBuilder<DB, TB extends keyof DB, O> {
|
|
|
281
355
|
* .innerJoin("posts", ({ users, posts }) => users.id.eqCol(posts.userId))
|
|
282
356
|
* ```
|
|
283
357
|
*/
|
|
284
|
-
innerJoin<T extends keyof DB & string>(table: T, onOrCallback: Expression<boolean> | ((cols: JoinProxies<DB, TB, T>) => Expression<boolean>)): TypedSelectBuilder<DB, TB | T, O &
|
|
358
|
+
innerJoin<T extends keyof DB & string>(table: T, onOrCallback: Expression<boolean> | ((cols: JoinProxies<DB, TB, T>) => Expression<boolean>)): TypedSelectBuilder<DB, TB | T, O & SelectRow<DB, T>>;
|
|
285
359
|
/**
|
|
286
360
|
* LEFT JOIN — joined columns become nullable.
|
|
287
361
|
*/
|
|
288
|
-
leftJoin<T extends keyof DB & string>(table: T, onOrCallback: Expression<boolean> | ((cols: JoinProxies<DB, TB, T>) => Expression<boolean>)): TypedSelectBuilder<DB, TB | T, O & Nullable
|
|
362
|
+
leftJoin<T extends keyof DB & string>(table: T, onOrCallback: Expression<boolean> | ((cols: JoinProxies<DB, TB, T>) => Expression<boolean>)): TypedSelectBuilder<DB, TB | T, O & Nullable<SelectRow<DB, T>>>;
|
|
289
363
|
/** RIGHT JOIN */
|
|
290
|
-
rightJoin<T extends keyof DB & string>(table: T, onOrCallback: Expression<boolean> | ((cols: JoinProxies<DB, TB, T>) => Expression<boolean>)): TypedSelectBuilder<DB, TB | T, Nullable
|
|
364
|
+
rightJoin<T extends keyof DB & string>(table: T, onOrCallback: Expression<boolean> | ((cols: JoinProxies<DB, TB, T>) => Expression<boolean>)): TypedSelectBuilder<DB, TB | T, Nullable<O> & SelectRow<DB, T>>;
|
|
291
365
|
/** GROUP BY */
|
|
292
366
|
groupBy(...cols: (keyof O & string)[]): TypedSelectBuilder<DB, TB, O>;
|
|
293
367
|
/** HAVING */
|
|
@@ -311,50 +385,7 @@ declare class TypedSelectBuilder<DB, TB extends keyof DB, O> {
|
|
|
311
385
|
/** Compile to SQL. */
|
|
312
386
|
compile(printer: Printer): CompiledQuery;
|
|
313
387
|
}
|
|
314
|
-
type JoinProxies<DB, TB extends keyof DB, T extends keyof DB> = { [Table in (TB | T) & string]: ColumnProxies<DB, Table
|
|
315
|
-
/**
|
|
316
|
-
* Type-safe INSERT query builder.
|
|
317
|
-
*/
|
|
318
|
-
declare class TypedInsertBuilder<DB, TB extends keyof DB> {
|
|
319
|
-
/** @internal */
|
|
320
|
-
readonly _builder: InsertBuilder;
|
|
321
|
-
private _paramIdx;
|
|
322
|
-
constructor(table: TB & string, paramIdx?: number);
|
|
323
|
-
/** @internal */
|
|
324
|
-
private _withBuilder;
|
|
325
|
-
/**
|
|
326
|
-
* Insert a single row. Columns/values inferred from Insertable<DB[TB]>.
|
|
327
|
-
*/
|
|
328
|
-
values(row: Insertable<DB[TB]>): TypedInsertBuilder<DB, TB>;
|
|
329
|
-
/**
|
|
330
|
-
* RETURNING specific columns.
|
|
331
|
-
*/
|
|
332
|
-
returning<K extends keyof DB[TB] & string>(...cols: K[]): TypedInsertReturningBuilder<DB, TB, Pick<{ [C in keyof DB[TB]]: SelectType<DB[TB][C]> }, K>>;
|
|
333
|
-
/**
|
|
334
|
-
* RETURNING all columns.
|
|
335
|
-
*/
|
|
336
|
-
returningAll(): TypedInsertReturningBuilder<DB, TB, { [K in keyof DB[TB]]: SelectType<DB[TB][K]> }>;
|
|
337
|
-
/**
|
|
338
|
-
* ON CONFLICT DO NOTHING.
|
|
339
|
-
*/
|
|
340
|
-
onConflictDoNothing(...columns: (keyof DB[TB] & string)[]): TypedInsertBuilder<DB, TB>;
|
|
341
|
-
/**
|
|
342
|
-
* ON CONFLICT DO UPDATE.
|
|
343
|
-
*/
|
|
344
|
-
onConflictDoUpdate(columns: (keyof DB[TB] & string)[], set: {
|
|
345
|
-
column: keyof DB[TB] & string;
|
|
346
|
-
value: Expression<any>;
|
|
347
|
-
}[]): TypedInsertBuilder<DB, TB>;
|
|
348
|
-
build(): InsertNode;
|
|
349
|
-
compile(printer: Printer): CompiledQuery;
|
|
350
|
-
}
|
|
351
|
-
declare class TypedInsertReturningBuilder<DB, _TB extends keyof DB, _R> {
|
|
352
|
-
/** @internal */
|
|
353
|
-
readonly _builder: InsertBuilder;
|
|
354
|
-
constructor(builder: InsertBuilder);
|
|
355
|
-
build(): InsertNode;
|
|
356
|
-
compile(printer: Printer): CompiledQuery;
|
|
357
|
-
}
|
|
388
|
+
type JoinProxies<DB, TB extends keyof DB, T extends keyof DB> = { [Table in (TB | T) & string]: ColumnProxies<DB, Table> };
|
|
358
389
|
/**
|
|
359
390
|
* Type-safe UPDATE query builder.
|
|
360
391
|
*/
|
|
@@ -381,11 +412,11 @@ declare class TypedUpdateBuilder<DB, TB extends keyof DB> {
|
|
|
381
412
|
/**
|
|
382
413
|
* RETURNING specific columns.
|
|
383
414
|
*/
|
|
384
|
-
returning<K extends keyof DB[TB] & string>(...cols: K[]): TypedUpdateReturningBuilder<DB, TB, Pick<
|
|
415
|
+
returning<K extends keyof DB[TB] & string>(...cols: K[]): TypedUpdateReturningBuilder<DB, TB, Pick<SelectRow<DB, TB>, K>>;
|
|
385
416
|
/**
|
|
386
417
|
* RETURNING all columns.
|
|
387
418
|
*/
|
|
388
|
-
returningAll(): TypedUpdateReturningBuilder<DB, TB,
|
|
419
|
+
returningAll(): TypedUpdateReturningBuilder<DB, TB, SelectRow<DB, TB>>;
|
|
389
420
|
build(): UpdateNode;
|
|
390
421
|
compile(printer: Printer): CompiledQuery;
|
|
391
422
|
}
|
|
@@ -396,54 +427,6 @@ declare class TypedUpdateReturningBuilder<DB, _TB extends keyof DB, _R> {
|
|
|
396
427
|
build(): UpdateNode;
|
|
397
428
|
compile(printer: Printer): CompiledQuery;
|
|
398
429
|
}
|
|
399
|
-
/**
|
|
400
|
-
* Type-safe DELETE query builder.
|
|
401
|
-
*/
|
|
402
|
-
declare class TypedDeleteBuilder<DB, TB extends keyof DB> {
|
|
403
|
-
/** @internal */
|
|
404
|
-
readonly _builder: DeleteBuilder;
|
|
405
|
-
constructor(table: TB & string);
|
|
406
|
-
/** @internal */
|
|
407
|
-
private _with;
|
|
408
|
-
/**
|
|
409
|
-
* WHERE — callback or raw Expression.
|
|
410
|
-
*/
|
|
411
|
-
where(exprOrCallback: Expression<boolean> | WhereCallback<DB, TB>): TypedDeleteBuilder<DB, TB>;
|
|
412
|
-
/**
|
|
413
|
-
* RETURNING specific columns.
|
|
414
|
-
*/
|
|
415
|
-
returning<K extends keyof DB[TB] & string>(...cols: K[]): TypedDeleteReturningBuilder<DB, TB, Pick<{ [C in keyof DB[TB]]: SelectType<DB[TB][C]> }, K>>;
|
|
416
|
-
/**
|
|
417
|
-
* RETURNING all columns.
|
|
418
|
-
*/
|
|
419
|
-
returningAll(): TypedDeleteReturningBuilder<DB, TB, { [K in keyof DB[TB]]: SelectType<DB[TB][K]> }>;
|
|
420
|
-
build(): DeleteNode;
|
|
421
|
-
compile(printer: Printer): CompiledQuery;
|
|
422
|
-
}
|
|
423
|
-
declare class TypedDeleteReturningBuilder<DB, _TB extends keyof DB, _R> {
|
|
424
|
-
/** @internal */
|
|
425
|
-
readonly _builder: DeleteBuilder;
|
|
426
|
-
constructor(builder: DeleteBuilder);
|
|
427
|
-
build(): DeleteNode;
|
|
428
|
-
compile(printer: Printer): CompiledQuery;
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* Plugin interface for pamuk.
|
|
432
|
-
*
|
|
433
|
-
* Plugins can intercept at three points:
|
|
434
|
-
* 1. transformNode — modify the AST before compilation
|
|
435
|
-
* 2. transformQuery — modify the compiled SQL after generation
|
|
436
|
-
* 3. transformResult — modify result rows after execution
|
|
437
|
-
*/
|
|
438
|
-
interface PamukPlugin {
|
|
439
|
-
readonly name: string;
|
|
440
|
-
/** Transform AST before compilation. Return a new node (never mutate). */
|
|
441
|
-
transformNode?(node: ASTNode): ASTNode;
|
|
442
|
-
/** Transform compiled query after SQL generation. */
|
|
443
|
-
transformQuery?(query: CompiledQuery): CompiledQuery;
|
|
444
|
-
/** Transform result rows after execution. */
|
|
445
|
-
transformResult?(rows: Record<string, unknown>[]): Record<string, unknown>[];
|
|
446
|
-
}
|
|
447
430
|
/**
|
|
448
431
|
* Hook context passed to hook handlers.
|
|
449
432
|
*/
|
|
@@ -458,7 +441,7 @@ interface HookContext<T extends ASTNode = ASTNode> {
|
|
|
458
441
|
/**
|
|
459
442
|
* All available hook points in the query lifecycle.
|
|
460
443
|
*/
|
|
461
|
-
interface
|
|
444
|
+
interface SumakHooks {
|
|
462
445
|
/** Fires before any query is compiled. Can modify the AST. */
|
|
463
446
|
"query:before": (ctx: HookContext) => ASTNode | void;
|
|
464
447
|
/** Fires after a query is compiled to SQL. Can modify the compiled query. */
|
|
@@ -476,7 +459,7 @@ interface PamukHooks {
|
|
|
476
459
|
/** Transform result rows. */
|
|
477
460
|
"result:transform": (rows: Record<string, unknown>[]) => Record<string, unknown>[];
|
|
478
461
|
}
|
|
479
|
-
type HookName = keyof
|
|
462
|
+
type HookName = keyof SumakHooks;
|
|
480
463
|
/**
|
|
481
464
|
* Hookable system — register and execute hooks.
|
|
482
465
|
*
|
|
@@ -494,13 +477,13 @@ declare class Hookable {
|
|
|
494
477
|
* Register a hook handler.
|
|
495
478
|
* Returns an unregister function.
|
|
496
479
|
*/
|
|
497
|
-
hook<K extends HookName>(name: K, handler:
|
|
480
|
+
hook<K extends HookName>(name: K, handler: SumakHooks[K]): () => void;
|
|
498
481
|
/**
|
|
499
482
|
* Execute all handlers for a hook.
|
|
500
483
|
* For AST hooks: each handler can return a modified node, which feeds into the next.
|
|
501
484
|
* For result hooks: each handler transforms the rows.
|
|
502
485
|
*/
|
|
503
|
-
callHook<K extends HookName>(name: K, ...args: Parameters<
|
|
486
|
+
callHook<K extends HookName>(name: K, ...args: Parameters<SumakHooks[K]>): ReturnType<SumakHooks[K]> | undefined;
|
|
504
487
|
/**
|
|
505
488
|
* Check if any handlers are registered for a hook.
|
|
506
489
|
*/
|
|
@@ -515,42 +498,60 @@ declare class Hookable {
|
|
|
515
498
|
removeAllHooks(): void;
|
|
516
499
|
}
|
|
517
500
|
/**
|
|
518
|
-
*
|
|
501
|
+
* Plugin interface for sumak.
|
|
502
|
+
*
|
|
503
|
+
* Plugins can intercept at three points:
|
|
504
|
+
* 1. transformNode — modify the AST before compilation
|
|
505
|
+
* 2. transformQuery — modify the compiled SQL after generation
|
|
506
|
+
* 3. transformResult — modify result rows after execution
|
|
519
507
|
*/
|
|
520
|
-
|
|
521
|
-
|
|
508
|
+
interface SumakPlugin {
|
|
509
|
+
readonly name: string;
|
|
510
|
+
/** Transform AST before compilation. Return a new node (never mutate). */
|
|
511
|
+
transformNode?(node: ASTNode): ASTNode;
|
|
512
|
+
/** Transform compiled query after SQL generation. */
|
|
513
|
+
transformQuery?(query: CompiledQuery): CompiledQuery;
|
|
514
|
+
/** Transform result rows after execution. */
|
|
515
|
+
transformResult?(rows: Record<string, unknown>[]): Record<string, unknown>[];
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Tables config constraint.
|
|
519
|
+
* Each table = Record of ColumnBuilder instances.
|
|
520
|
+
*/
|
|
521
|
+
type TablesConfig = Record<string, Record<string, ColumnBuilder<any, any, any>>>;
|
|
522
|
+
interface SumakConfig<T extends TablesConfig> {
|
|
522
523
|
dialect: Dialect;
|
|
523
524
|
tables: T;
|
|
524
|
-
plugins?:
|
|
525
|
+
plugins?: SumakPlugin[];
|
|
525
526
|
}
|
|
526
527
|
/**
|
|
527
|
-
* Create a fully typed
|
|
528
|
+
* Create a fully typed sumak instance.
|
|
529
|
+
*
|
|
530
|
+
* DB type = typeof tables directly. No `InferDB` mapped type.
|
|
531
|
+
* ColumnBuilder carries __select/__insert/__update phantom fields,
|
|
532
|
+
* so SelectType/InsertType/UpdateType resolve via O(1) indexed access
|
|
533
|
+
* instead of conditional type evaluation.
|
|
528
534
|
*
|
|
529
535
|
* ```ts
|
|
530
|
-
* const db =
|
|
536
|
+
* const db = sumak({
|
|
531
537
|
* dialect: pgDialect(),
|
|
532
538
|
* tables: {
|
|
533
539
|
* users: { id: serial(), name: text().notNull() },
|
|
534
540
|
* },
|
|
535
541
|
* });
|
|
536
542
|
*
|
|
537
|
-
* // Hook into the query lifecycle
|
|
538
|
-
* db.hook("select:before", (ctx) => {
|
|
539
|
-
* console.log("Selecting from:", ctx.table);
|
|
540
|
-
* });
|
|
541
|
-
*
|
|
542
543
|
* db.selectFrom("users").select("id", "name")...
|
|
543
544
|
* ```
|
|
544
545
|
*/
|
|
545
|
-
declare function
|
|
546
|
+
declare function sumak<T extends TablesConfig>(config: SumakConfig<T>): Sumak<T>;
|
|
546
547
|
/**
|
|
547
|
-
* Core
|
|
548
|
+
* Core sumak instance with hook system.
|
|
548
549
|
*/
|
|
549
|
-
declare class
|
|
550
|
+
declare class Sumak<DB> {
|
|
550
551
|
private _dialect;
|
|
551
552
|
private _plugins;
|
|
552
553
|
private _hooks;
|
|
553
|
-
constructor(dialect: Dialect, plugins?:
|
|
554
|
+
constructor(dialect: Dialect, plugins?: SumakPlugin[]);
|
|
554
555
|
/**
|
|
555
556
|
* Register a hook handler. Returns an unregister function.
|
|
556
557
|
*
|
|
@@ -559,8 +560,8 @@ declare class Pamuk<DB> {
|
|
|
559
560
|
* off(); // unregister
|
|
560
561
|
* ```
|
|
561
562
|
*/
|
|
562
|
-
hook<K extends HookName>(name: K, handler:
|
|
563
|
-
selectFrom<T extends keyof DB & string>(table: T, alias?: string): TypedSelectBuilder<DB, T,
|
|
563
|
+
hook<K extends HookName>(name: K, handler: SumakHooks[K]): () => void;
|
|
564
|
+
selectFrom<T extends keyof DB & string>(table: T, alias?: string): TypedSelectBuilder<DB, T, SelectRow<DB, T>>;
|
|
564
565
|
insertInto<T extends keyof DB & string>(table: T): TypedInsertBuilder<DB, T>;
|
|
565
566
|
update<T extends keyof DB & string>(table: T): TypedUpdateBuilder<DB, T>;
|
|
566
567
|
deleteFrom<T extends keyof DB & string>(table: T): TypedDeleteBuilder<DB, T>;
|
|
@@ -582,7 +583,7 @@ declare class Pamuk<DB> {
|
|
|
582
583
|
*/
|
|
583
584
|
declare class PluginManager {
|
|
584
585
|
private readonly plugins;
|
|
585
|
-
constructor(plugins:
|
|
586
|
+
constructor(plugins: SumakPlugin[]);
|
|
586
587
|
/** Apply all transformNode phases in order. */
|
|
587
588
|
transformNode(node: ASTNode): ASTNode;
|
|
588
589
|
/** Apply all transformQuery phases in order. */
|
|
@@ -598,7 +599,7 @@ declare class PluginManager {
|
|
|
598
599
|
* // SELECT * FROM "users" → SELECT * FROM "public"."users"
|
|
599
600
|
* ```
|
|
600
601
|
*/
|
|
601
|
-
declare class WithSchemaPlugin implements
|
|
602
|
+
declare class WithSchemaPlugin implements SumakPlugin {
|
|
602
603
|
readonly name = "with-schema";
|
|
603
604
|
private schema;
|
|
604
605
|
constructor(schema: string);
|
|
@@ -618,7 +619,7 @@ declare class WithSchemaPlugin implements PamukPlugin {
|
|
|
618
619
|
* // SELECT * FROM "users" → SELECT * FROM "users" WHERE "deleted_at" IS NULL
|
|
619
620
|
* ```
|
|
620
621
|
*/
|
|
621
|
-
declare class SoftDeletePlugin implements
|
|
622
|
+
declare class SoftDeletePlugin implements SumakPlugin {
|
|
622
623
|
readonly name = "soft-delete";
|
|
623
624
|
private tables;
|
|
624
625
|
private column;
|
|
@@ -640,20 +641,20 @@ declare class SoftDeletePlugin implements PamukPlugin {
|
|
|
640
641
|
* This plugin operates on results only — it does NOT transform the AST.
|
|
641
642
|
* Use it when your database uses snake_case but your TypeScript code uses camelCase.
|
|
642
643
|
*/
|
|
643
|
-
declare class CamelCasePlugin implements
|
|
644
|
+
declare class CamelCasePlugin implements SumakPlugin {
|
|
644
645
|
readonly name = "camel-case";
|
|
645
646
|
transformResult(rows: Record<string, unknown>[]): Record<string, unknown>[];
|
|
646
647
|
}
|
|
647
|
-
declare class
|
|
648
|
+
declare class SumakError extends Error {
|
|
648
649
|
constructor(message: string);
|
|
649
650
|
}
|
|
650
|
-
declare class InvalidExpressionError extends
|
|
651
|
+
declare class InvalidExpressionError extends SumakError {
|
|
651
652
|
constructor(message: string);
|
|
652
653
|
}
|
|
653
|
-
declare class UnsupportedDialectFeatureError extends
|
|
654
|
+
declare class UnsupportedDialectFeatureError extends SumakError {
|
|
654
655
|
constructor(dialect: string, feature: string);
|
|
655
656
|
}
|
|
656
|
-
declare class EmptyQueryError extends
|
|
657
|
+
declare class EmptyQueryError extends SumakError {
|
|
657
658
|
constructor(queryType: string);
|
|
658
659
|
}
|
|
659
|
-
export { type ASTNode, ASTTransformer, type ASTVisitor, type ArrayExprNode, BasePrinter, type BetweenNode, type BinaryOpNode, type CTENode, CamelCasePlugin, type CaseNode, type CastNode, Col
|
|
660
|
+
export { type ASTNode, ASTTransformer, type ASTVisitor, type ArrayExprNode, BasePrinter, type BetweenNode, type BinaryOpNode, type CTENode, CamelCasePlugin, type CaseNode, type CastNode, Col, ColumnBuilder, type ColumnDef, type ColumnProxies, type ColumnRefNode, type ColumnType, type CompiledQuery, DeleteBuilder, type DeleteNode, type Dialect, type DialectConfig, type Doc, EmptyQueryError, type ExistsNode, type Expression, type ExpressionNode, type FormatOptions, type FrameBound, type FrameKind, type FrameSpec, type FunctionCallNode, type Generated, type GeneratedAlways, type HookContext, type HookName, Hookable, type InNode, type InferTable, InsertBuilder, type InsertNode, type InsertType, type Insertable, InvalidExpressionError, type IsNullNode, type JoinNode, type JoinType, type JsonAccessNode, type LiteralNode, MysqlPrinter, type Nullable, type OnConflictNode, type OrderByNode, type OrderDirection, type ParamNode, PgPrinter, PluginManager, type Primitive, type PrintMode, type Printer, type PrinterOptions, type RawNode, type SQLDialect, SelectBuilder, type SelectNode, type SelectRow, type SelectType, type Selectable, type SetOperator, SoftDeletePlugin, SqlitePrinter, type StarNode, type SubqueryNode, Sumak, type SumakConfig, SumakError, type SumakHooks, type SumakPlugin, type TableDefinition, type TableRefNode, TypedDeleteBuilder, TypedDeleteReturningBuilder, TypedInsertBuilder, TypedInsertReturningBuilder, TypedSelectBuilder, TypedUpdateBuilder, TypedUpdateReturningBuilder, type UnaryOpNode, UnsupportedDialectFeatureError, UpdateBuilder, type UpdateNode, type UpdateType, type Updateable, type WhereCallback, type WindowFunctionNode, WithSchemaPlugin, and, between, bigint, bigserial, binOp, boolean, bytea, cast, char, col, colAs, count, createDeleteNode, createInsertNode, createSelectNode, createUpdateNode, date, defineTable, deleteFrom, concat as docConcat, empty as docEmpty, group as docGroup, join as docJoin, line as docLine, nest as docNest, render as docRender, text as docText, textLine as docTextLine, doublePrecision, enumType, eq, exists, fn, formatParam, formatSQL, gt, gte, inList, insert, integer, isNull, json, jsonb, like, lit, lt, lte, mysqlDialect, neq, not, numeric, or, param, pgDialect, quoteIdentifier, quoteTableRef, raw, real, resetParams, select, serial, smallint, sqlFn, sqliteDialect, star, subquery, sumak, tableRef, text$1 as text, time, timestamp, timestamptz, unaryOp, update, uuid, val, varchar, visitNode };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{i as e,n as t,r as n,t as r}from"./_chunks/base.mjs";import{n as i,t as a}from"./_chunks/pg.mjs";import{i as o,n as s,r as ee,t as te}from"./_chunks/errors.mjs";import{n as ne,t as re}from"./_chunks/mysql.mjs";import{n as ie,t as ae}from"./_chunks/sqlite.mjs";import{C as oe,S as se,_ as ce,a as le,b as ue,c as de,d as fe,f as
|
|
1
|
+
import{i as e,n as t,r as n,t as r}from"./_chunks/base.mjs";import{n as i,t as a}from"./_chunks/pg.mjs";import{i as o,n as s,r as ee,t as te}from"./_chunks/errors.mjs";import{n as ne,t as re}from"./_chunks/mysql.mjs";import{n as ie,t as ae}from"./_chunks/sqlite.mjs";import{C as oe,S as se,_ as ce,a as le,b as ue,c as de,d as fe,f as pe,g as me,h as he,i as ge,l as _e,m as ve,n as ye,o as be,p as xe,r as Se,s as c,t as Ce,u as we,v as Te,x as Ee,y as De}from"./_chunks/schema.mjs";function Oe(e,t,n){return Object.freeze({type:`table_ref`,name:e,alias:t,schema:n})}function l(){return{type:`select`,distinct:!1,columns:[],joins:[],groupBy:[],orderBy:[],ctes:[],forUpdate:!1}}function u(e){return{type:`insert`,table:e,columns:[],values:[],returning:[],ctes:[]}}function d(e){return{type:`update`,table:e,set:[],returning:[],ctes:[]}}function f(e){return{type:`delete`,table:e,returning:[],ctes:[]}}function p(e,t){return{type:`column_ref`,column:e,table:t}}function ke(e,t,n){return{type:`column_ref`,column:e,table:n,alias:t}}function m(e){return{type:`literal`,value:e}}function h(e){return{type:`star`,table:e}}function g(e,t){return{type:`param`,index:e,value:t}}function Ae(e,t=[]){return{type:`raw`,sql:e,params:t}}function je(e,t){return{type:`subquery`,query:e,alias:t}}function _(e,t,n){return{type:`function_call`,name:e,args:t,alias:n}}function v(e,t,n){return{type:`binary_op`,op:e,left:t,right:n}}function y(e,t,n=`prefix`){return{type:`unary_op`,op:e,operand:t,position:n}}function b(e,t){return v(`AND`,e,t)}function x(e,t){return v(`OR`,e,t)}function S(e,t){return v(`=`,e,t)}function Me(e,t){return v(`!=`,e,t)}function Ne(e,t){return v(`>`,e,t)}function Pe(e,t){return v(`>=`,e,t)}function Fe(e,t){return v(`<`,e,t)}function Ie(e,t){return v(`<=`,e,t)}function Le(e,t){return v(`LIKE`,e,t)}function Re(e,t,n,r=!1){return{type:`between`,expr:e,low:t,high:n,negated:r}}function ze(e,t,n=!1){return{type:`in`,expr:e,values:t,negated:n}}function C(e,t=!1){return{type:`is_null`,expr:e,negated:t}}function Be(e,t){return{type:`cast`,expr:e,dataType:t}}function Ve(e,t=!1){return{type:`exists`,query:e,negated:t}}function He(e){return y(`NOT`,e)}var Ue=class{transform(e){switch(e.type){case`select`:return this.transformSelect(e);case`insert`:return this.transformInsert(e);case`update`:return this.transformUpdate(e);case`delete`:return this.transformDelete(e);default:return this.transformExpression(e)}}transformSelect(e){return{...e,columns:e.columns.map(e=>this.transformExpression(e)),where:e.where?this.transformExpression(e.where):void 0,having:e.having?this.transformExpression(e.having):void 0,joins:e.joins.map(e=>({...e,on:e.on?this.transformExpression(e.on):void 0})),orderBy:e.orderBy.map(e=>({...e,expr:this.transformExpression(e.expr)}))}}transformInsert(e){return{...e,values:e.values.map(e=>e.map(e=>this.transformExpression(e)))}}transformUpdate(e){return{...e,set:e.set.map(e=>({...e,value:this.transformExpression(e.value)})),where:e.where?this.transformExpression(e.where):void 0}}transformDelete(e){return{...e,where:e.where?this.transformExpression(e.where):void 0}}transformExpression(e){switch(e.type){case`binary_op`:return{...e,left:this.transformExpression(e.left),right:this.transformExpression(e.right)};case`unary_op`:return{...e,operand:this.transformExpression(e.operand)};case`function_call`:return{...e,args:e.args.map(e=>this.transformExpression(e))};case`between`:return{...e,expr:this.transformExpression(e.expr),low:this.transformExpression(e.low),high:this.transformExpression(e.high)};case`in`:return{...e,expr:this.transformExpression(e.expr),values:Array.isArray(e.values)?e.values.map(e=>this.transformExpression(e)):e.values};case`is_null`:return{...e,expr:this.transformExpression(e.expr)};case`cast`:return{...e,expr:this.transformExpression(e.expr)};case`json_access`:return{...e,expr:this.transformExpression(e.expr)};case`array_expr`:return{...e,elements:e.elements.map(e=>this.transformExpression(e))};case`window_function`:return{...e,fn:this.transformExpression(e.fn),partitionBy:e.partitionBy.map(e=>this.transformExpression(e)),orderBy:e.orderBy.map(e=>({...e,expr:this.transformExpression(e.expr)}))};default:return e}}};function We(e,t){switch(e.type){case`select`:return t.visitSelect(e);case`insert`:return t.visitInsert(e);case`update`:return t.visitUpdate(e);case`delete`:return t.visitDelete(e);default:return t.visitExpression(e)}}var w=class e{node;constructor(e){this.node=e??l()}columns(...t){let n=t.map(e=>typeof e==`string`?p(e):e);return new e({...this.node,columns:[...this.node.columns,...n]})}allColumns(){return new e({...this.node,columns:[...this.node.columns,h()]})}distinct(){return new e({...this.node,distinct:!0})}from(t,n){if(typeof t==`string`){let r={type:`table_ref`,name:t,alias:n};return new e({...this.node,from:r})}return n&&t.type!==`subquery`?new e({...this.node,from:{...t,alias:n}}):new e({...this.node,from:t})}where(t){return new e({...this.node,where:t})}join(t,n,r,i){let a={type:`join`,joinType:t,table:typeof n==`string`?{type:`table_ref`,name:n,alias:i}:n,on:r};return new e({...this.node,joins:[...this.node.joins,a]})}innerJoin(e,t,n){return this.join(`INNER`,e,t,n)}leftJoin(e,t,n){return this.join(`LEFT`,e,t,n)}rightJoin(e,t,n){return this.join(`RIGHT`,e,t,n)}groupBy(...t){let n=t.map(e=>typeof e==`string`?p(e):e);return new e({...this.node,groupBy:[...this.node.groupBy,...n]})}having(t){return new e({...this.node,having:t})}orderBy(t,n=`ASC`,r){let i={expr:typeof t==`string`?p(t):t,direction:n,nulls:r};return new e({...this.node,orderBy:[...this.node.orderBy,i]})}limit(t){return new e({...this.node,limit:t})}offset(t){return new e({...this.node,offset:t})}forUpdate(){return new e({...this.node,forUpdate:!0})}with(t,n,r=!1){let i={name:t,query:n,recursive:r};return new e({...this.node,ctes:[...this.node.ctes,i]})}union(e){return this.setOp(`UNION`,e)}unionAll(e){return this.setOp(`UNION ALL`,e)}intersect(e){return this.setOp(`INTERSECT`,e)}except(e){return this.setOp(`EXCEPT`,e)}setOp(t,n){return new e({...this.node,setOp:{op:t,query:n}})}build(){return{...this.node}}};function Ge(...e){let t=new w;return e.length>0?t.columns(...e):t.allColumns()}var T=class e{node;paramIndex;constructor(e,t=0){this.node=e??u({type:`table_ref`,name:``}),this.paramIndex=t}into(t){let n=typeof t==`string`?{type:`table_ref`,name:t}:t;return new e({...this.node,table:n},this.paramIndex)}columns(...t){return new e({...this.node,columns:[...this.node.columns,...t]},this.paramIndex)}values(...t){let n=this.paramIndex,r=t.map(e=>{let t=g(n,e);return n++,t});return new e({...this.node,values:[...this.node.values,r]},n)}returning(...t){return new e({...this.node,returning:[...this.node.returning,...t]},this.paramIndex)}onConflictDoNothing(...t){let n={columns:t,action:`nothing`};return new e({...this.node,onConflict:n},this.paramIndex)}onConflictDoUpdate(t,n,r){let i={columns:t,action:{set:n},where:r};return new e({...this.node,onConflict:i},this.paramIndex)}with(t,n,r=!1){let i={name:t,query:n,recursive:r};return new e({...this.node,ctes:[...this.node.ctes,i]},this.paramIndex)}build(){return{...this.node}}};function Ke(e){return new T().into(e)}var E=class e{node;constructor(e){this.node=e??d({type:`table_ref`,name:``})}table(t){let n=typeof t==`string`?{type:`table_ref`,name:t}:t;return new e({...this.node,table:n})}set(t,n){return new e({...this.node,set:[...this.node.set,{column:t,value:n}]})}where(t){return new e({...this.node,where:t})}from(t){let n=typeof t==`string`?{type:`table_ref`,name:t}:t;return new e({...this.node,from:n})}returning(...t){return new e({...this.node,returning:[...this.node.returning,...t]})}with(t,n,r=!1){let i={name:t,query:n,recursive:r};return new e({...this.node,ctes:[...this.node.ctes,i]})}build(){return{...this.node}}};function qe(e){return new E().table(e)}var D=class e{node;constructor(e){this.node=e??f({type:`table_ref`,name:``})}from(t){let n=typeof t==`string`?{type:`table_ref`,name:t}:t;return new e({...this.node,table:n})}where(t){return new e({...this.node,where:t})}returning(...t){return new e({...this.node,returning:[...this.node.returning,...t]})}with(t,n,r=!1){let i={name:t,query:n,recursive:r};return new e({...this.node,ctes:[...this.node.ctes,i]})}build(){return{...this.node}}};function O(e){return new D().from(e)}const k=new Set(`SELECT.FROM.WHERE.AND.OR.JOIN.INNER JOIN.LEFT JOIN.RIGHT JOIN.FULL JOIN.CROSS JOIN.ON.GROUP BY.HAVING.ORDER BY.LIMIT.OFFSET.INSERT INTO.VALUES.UPDATE.SET.DELETE FROM.RETURNING.WITH.WITH RECURSIVE.UNION.UNION ALL.INTERSECT.EXCEPT.FOR UPDATE.ON CONFLICT.DO NOTHING.DO UPDATE SET`.split(`.`));function Je(e,t={}){let n=t.indent??` `,r=[],i=0,a=Ye(e),o=0;for(;o<a.length;){let e=a[o];if(e===`(`){i++,A(r,e),o++;continue}if(e===`)`){i=Math.max(0,i-1),A(r,e),o++;continue}let t=o+1<a.length?`${e} ${a[o+1]}`:``,s=o+2<a.length?`${e} ${a[o+1]} ${a[o+2]}`:``;if(k.has(s.toUpperCase())){r.push(`${n.repeat(i)}${s}`),o+=3;continue}if(k.has(t.toUpperCase())){r.push(`${n.repeat(i)}${t}`),o+=2;continue}if(k.has(e.toUpperCase())){r.push(`${n.repeat(i)}${e}`),o++;continue}A(r,e),o++}return r.join(`
|
|
2
2
|
`)}function A(e,t){e.length===0?e.push(t):e[e.length-1]+=` ${t}`}function Ye(e){let t=[],n=``;for(let r=0;r<e.length;r++){let i=e[r];if(i===`'`||i===`"`){for(n+=i,r++;r<e.length&&e[r]!==i;){if(e[r]===i&&r+1<e.length&&e[r+1]===i){n+=i+i,r+=2;continue}n+=e[r],r++}r<e.length&&(n+=e[r]);continue}if(i===`(`||i===`)`){n.trim()&&(t.push(n.trim()),n=``),t.push(i);continue}if(i===`,`||i===`;`){n.trim()&&(t.push(n.trim()),n=``),t.push(i);continue}if(/\s/.test(i)){n.trim()&&(t.push(n.trim()),n=``);continue}n+=i}return n.trim()&&t.push(n.trim()),t}function j(){return{tag:`empty`}}function M(e){return{tag:`text`,text:e}}function N(){return{tag:`line`}}function Xe(e,t){return{tag:`nest`,indent:e,doc:t}}function Ze(e){return{tag:`group`,doc:e}}function P(...e){let t=e.filter(e=>e.tag!==`empty`);return t.length===0?j():t.length===1?t[0]:{tag:`concat`,docs:t}}function Qe(e,t){if(t.length===0)return j();let n=[];for(let r=0;r<t.length;r++)r>0&&n.push(e),n.push(t[r]);return P(...n)}function $e(e){return P(M(e),N())}function et(e,t=80){let n=``,r=0,i=[[0,`break`,e]];for(;i.length>0;){let[e,a,o]=i.pop();switch(o.tag){case`empty`:break;case`text`:n+=o.text,r+=o.text.length;break;case`line`:a===`flat`?(n+=` `,r+=1):(n+=`
|
|
3
|
-
`+` `.repeat(e),r=e);break;case`nest`:i.push([e+o.indent,a,o.doc]);break;case`group`:if(a===`flat`)i.push([e,`flat`,o.doc]);else{let n=tt(o.doc);n!==null&&r+n<=t?i.push([e,`flat`,o.doc]):i.push([e,`break`,o.doc])}break;case`concat`:for(let t=o.docs.length-1;t>=0;t--)i.push([e,a,o.docs[t]]);break}}return n}function tt(e){let t=0,n=[e];for(;n.length>0;){let e=n.pop();switch(e.tag){case`empty`:break;case`text`:t+=e.text.length;break;case`line`:t+=1;break;case`nest`:n.push(e.doc);break;case`group`:n.push(e.doc);break;case`concat`:for(let t=e.docs.length-1;t>=0;t--)n.push(e.docs[t]);break}}return t}var F=class{_node;constructor(e,t){this._node=m(e,t)}eq(e){return B(z(`=`,this._node,R(e)))}neq(e){return B(z(`!=`,this._node,R(e)))}gt(e){return B(z(`>`,this._node,R(e)))}gte(e){return B(z(`>=`,this._node,R(e)))}lt(e){return B(z(`<`,this._node,R(e)))}lte(e){return B(z(`<=`,this._node,R(e)))}like(e){return B(z(`LIKE`,this._node,h(e)))}in(e){return B({type:`in`,expr:this._node,values:e.map(e=>R(e)),negated:!1})}notIn(e){return B({type:`in`,expr:this._node,values:e.map(e=>R(e)),negated:!0})}isNull(){return B({type:`is_null`,expr:this._node,negated:!1})}isNotNull(){return B({type:`is_null`,expr:this._node,negated:!0})}between(e,t){return B({type:`between`,expr:this._node,low:R(e),high:R(t),negated:!1})}eqCol(e){return B(z(`=`,this._node,e._node))}toExpr(){return B(this._node)}};let I=0;function L(){I=0}function R(e){return _(I++,e)}function z(e,t,n){return{type:`binary_op`,op:e,left:t,right:n}}function B(e){return{node:e}}function V(e){return new Proxy({},{get(e,t){return new F(t,void 0)}})}function nt(e,t){return B(x(e.node,t.node))}function rt(e,t){return B(S(e.node,t.node))}function it(e){return B(h(e))}function at(e,...t){return B(v(e,t.map(e=>e.node)))}function ot(){return B(v(`COUNT`,[g()]))}function H(e){return e.node}var U=class e{_builder;_table;constructor(e,t){this._builder=e,this._table=t??``}select(...t){return new e(this._builder.columns(...t),this._table)}selectAll(){return new e(this._builder.allColumns(),this._table)}selectExpr(t,n){let r=H(t),i=r.type===`column_ref`||r.type===`function_call`?{...r,alias:n}:{type:`raw`,sql:``,params:[]};return new e(this._builder.columns(i),this._table)}distinct(){return new e(this._builder.distinct(),this._table)}where(t){if(typeof t==`function`){L();let n=t(V(this._table));return new e(this._builder.where(H(n)),this._table)}return new e(this._builder.where(H(t)),this._table)}innerJoin(t,n){let r=W(n,this._table,t);return new e(this._builder.innerJoin(t,H(r)),this._table)}leftJoin(t,n){let r=W(n,this._table,t);return new e(this._builder.leftJoin(t,H(r)),this._table)}rightJoin(t,n){let r=W(n,this._table,t);return new e(this._builder.rightJoin(t,H(r)),this._table)}groupBy(...t){return new e(this._builder.groupBy(...t),this._table)}having(t){if(typeof t==`function`){L();let n=t(V(this._table));return new e(this._builder.having(H(n)),this._table)}return new e(this._builder.having(H(t)),this._table)}orderBy(t,n=`ASC`,r){return new e(this._builder.orderBy(t,n,r),this._table)}limit(t){return new e(this._builder.limit({type:`literal`,value:t}),this._table)}offset(t){return new e(this._builder.offset({type:`literal`,value:t}),this._table)}forUpdate(){return new e(this._builder.forUpdate(),this._table)}with(t,n,r=!1){return new e(this._builder.with(t,n,r),this._table)}union(t){return new e(this._builder.union(t.build()),this._table)}unionAll(t){return new e(this._builder.unionAll(t.build()),this._table)}build(){return this._builder.build()}compile(e){return e.print(this.build())}};function st(e,t){return new Proxy({},{get(e,t){return new Proxy({},{get(e,n){return new F(n,t)}})}})}function W(e,t,n){return typeof e==`function`?e(st(t,n)):e}var G=class e{_builder;_paramIdx;constructor(e,t=0){this._builder=new E().into(e),this._paramIdx=t}_withBuilder(t,n){let r=new e(``);return r._builder=t,r._paramIdx=n,r}values(e){let t=Object.entries(e),n=t.map(([e])=>e),r=t.map(([e,t])=>{let n=_(this._paramIdx,t);return this._paramIdx++,n}),i=this._builder;return i.build().columns.length===0&&(i=i.columns(...n)),i=new E({...i.build(),values:[...i.build().values,r]},this._paramIdx),this._withBuilder(i,this._paramIdx)}returning(...e){let t=e.map(e=>({type:`column_ref`,column:e}));return new K(new E({...this._builder.build(),returning:t},this._paramIdx))}returningAll(){return new K(new E({...this._builder.build(),returning:[g()]},this._paramIdx))}onConflictDoNothing(...e){return this._withBuilder(this._builder.onConflictDoNothing(...e),this._paramIdx)}onConflictDoUpdate(e,t){return this._withBuilder(this._builder.onConflictDoUpdate(e,t.map(e=>({column:e.column,value:H(e.value)}))),this._paramIdx)}build(){return this._builder.build()}compile(e){return e.print(this.build())}},K=class{_builder;constructor(e){this._builder=e}build(){return this._builder.build()}compile(e){return e.print(this.build())}},q=class e{_builder;_paramIdx;constructor(e,t=0){this._builder=new D().table(e),this._paramIdx=t}_with(t,n){let r=new e(``);return r._builder=t,r._paramIdx=n,r}set(e){let t=this._builder,n=this._paramIdx;for(let[r,i]of Object.entries(e))i!==void 0&&(t=t.set(r,_(n,i)),n++);return this._with(t,n)}setExpr(e,t){return this._with(this._builder.set(e,H(t)),this._paramIdx)}where(e){if(typeof e==`function`){L();let t=e(V(this._table));return this._with(this._builder.where(H(t)),this._paramIdx)}return this._with(this._builder.where(H(e)),this._paramIdx)}get _table(){return this._builder.build().table.name}returning(...e){let t=e.map(e=>({type:`column_ref`,column:e}));return new J(new D({...this._builder.build(),returning:t}))}returningAll(){return new J(new D({...this._builder.build(),returning:[g()]}))}build(){return this._builder.build()}compile(e){return e.print(this.build())}},J=class{_builder;constructor(e){this._builder=e}build(){return this._builder.build()}compile(e){return e.print(this.build())}},Y=class e{_builder;constructor(e){this._builder=new O().from(e)}_with(t){let n=new e(``);return n._builder=t,n}where(e){if(typeof e==`function`){L();let t=this._builder.build().table.name,n=e(V(t));return this._with(this._builder.where(H(n)))}return this._with(this._builder.where(H(e)))}returning(...e){let t=e.map(e=>({type:`column_ref`,column:e}));return new X(new O({...this._builder.build(),returning:t}))}returningAll(){return new X(new O({...this._builder.build(),returning:[g()]}))}build(){return this._builder.build()}compile(e){return e.print(this.build())}},X=class{_builder;constructor(e){this._builder=e}build(){return this._builder.build()}compile(e){return e.print(this.build())}},Z=class{plugins;constructor(e){this.plugins=Object.freeze([...e])}transformNode(e){let t=e;for(let e of this.plugins)e.transformNode&&(t=e.transformNode(t));return t}transformQuery(e){let t=e;for(let e of this.plugins)e.transformQuery&&(t=e.transformQuery(t));return t}transformResult(e){let t=e;for(let e of this.plugins)e.transformResult&&(t=e.transformResult(t));return t}},Q=class{_hooks=new Map;hook(e,t){return this._hooks.has(e)||this._hooks.set(e,[]),this._hooks.get(e).push(t),()=>{let n=this._hooks.get(e);if(n){let e=n.indexOf(t);e!==-1&&n.splice(e,1)}}}callHook(e,...t){let n=this._hooks.get(e);if(!n||n.length===0)return;let r;for(let i of n){let n=i(...t);n!==void 0&&(r=n,e!==`result:transform`&&t[0]&&typeof t[0]==`object`&&`node`in t[0]&&(t[0].node=n))}return r}hasHook(e){let t=this._hooks.get(e);return t!==void 0&&t.length>0}removeHook(e){this._hooks.delete(e)}removeAllHooks(){this._hooks.clear()}};function ct(e){return new $(e.dialect,e.plugins??[])}var $=class{_dialect;_plugins;_hooks;constructor(e,t=[]){this._dialect=e,this._plugins=new Z(t),this._hooks=new Q}hook(e,t){return this._hooks.hook(e,t)}selectFrom(e,t){return new U(new T().from(e,t),e)}insertInto(e){return new G(e)}update(e){return new q(e)}deleteFrom(e){return new Y(e)}compile(e){let t=this._plugins.transformNode(e),n=this._extractTableName(t);switch(t.type){case`select`:{let e=this._hooks.callHook(`select:before`,{node:t,table:n});e&&(t=e);break}case`insert`:{let e=this._hooks.callHook(`insert:before`,{node:t,table:n});e&&(t=e);break}case`update`:{let e=this._hooks.callHook(`update:before`,{node:t,table:n});e&&(t=e);break}case`delete`:{let e=this._hooks.callHook(`delete:before`,{node:t,table:n});e&&(t=e);break}}let r=this._hooks.callHook(`query:before`,{node:t,table:n});r&&(t=r);let i=this._dialect.createPrinter().print(t);i=this._plugins.transformQuery(i);let a=this._hooks.callHook(`query:after`,{node:t,table:n,query:i});return a&&(i=a),i}transformResult(e){let t=this._plugins.transformResult(e),n=this._hooks.callHook(`result:transform`,t);return n&&(t=n),t}printer(){return this._dialect.createPrinter()}_extractTableName(e){switch(e.type){case`select`:return e.from?.type===`table_ref`?e.from.name:void 0;case`insert`:return e.table.name;case`update`:return e.table.name;case`delete`:return e.table.name;default:return}}},lt=class{name=`with-schema`;schema;constructor(e){this.schema=e}transformNode(e){switch(e.type){case`select`:return this.transformSelect(e);case`insert`:return this.transformInsert(e);case`update`:return this.transformUpdate(e);case`delete`:return this.transformDelete(e);default:return e}}addSchema(e){return e.schema?e:{...e,schema:this.schema}}transformSelect(e){return{...e,from:e.from?e.from.type===`table_ref`?this.addSchema(e.from):e.from:void 0,joins:e.joins.map(e=>({...e,table:e.table.type===`table_ref`?this.addSchema(e.table):e.table}))}}transformInsert(e){return{...e,table:this.addSchema(e.table)}}transformUpdate(e){return{...e,table:this.addSchema(e.table),from:e.from?this.addSchema(e.from):void 0}}transformDelete(e){return{...e,table:this.addSchema(e.table)}}},ut=class{name=`soft-delete`;tables;column;constructor(e){this.tables=new Set(e.tables),this.column=e.column??`deleted_at`}transformNode(e){switch(e.type){case`select`:return this.transformSelect(e);case`update`:return this.transformUpdate(e);case`delete`:return this.transformDelete(e);default:return e}}isTargetTable(e){return this.tables.has(e)}softDeleteCondition(){return w(m(this.column))}addCondition(e){let t=this.softDeleteCondition();return e?x(e,t):t}transformSelect(e){return!e.from||e.from.type!==`table_ref`||!this.isTargetTable(e.from.name)?e:{...e,where:this.addCondition(e.where)}}transformUpdate(e){return this.isTargetTable(e.table.name)?{...e,where:this.addCondition(e.where)}:e}transformDelete(e){return this.isTargetTable(e.table.name)?{...e,where:this.addCondition(e.where)}:e}},dt=class{name=`camel-case`;transformResult(e){return e.map(e=>{let t={};for(let n of Object.keys(e))t[ft(n)]=e[n];return t})}};function ft(e){return e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase())}export{He as ASTTransformer,r as BasePrinter,dt as CamelCasePlugin,F as Col,ve as ColumnBuilder,O as DeleteBuilder,te as EmptyQueryError,Q as Hookable,E as InsertBuilder,s as InvalidExpressionError,ne as MysqlPrinter,$ as Pamuk,ee as PamukError,i as PgPrinter,Z as PluginManager,T as SelectBuilder,ut as SoftDeletePlugin,ie as SqlitePrinter,Y as TypedDeleteBuilder,X as TypedDeleteReturningBuilder,G as TypedInsertBuilder,K as TypedInsertReturningBuilder,U as TypedSelectBuilder,q as TypedUpdateBuilder,J as TypedUpdateReturningBuilder,o as UnsupportedDialectFeatureError,D as UpdateBuilder,lt as WithSchemaPlugin,nt as and,Le as between,xe as bigint,he as bigserial,y as binOp,le as boolean,ye as bytea,ze as cast,Se as char,m as col,Oe as colAs,ot as count,p as createDeleteNode,d as createInsertNode,u as createSelectNode,f as createUpdateNode,de as date,Ce as defineTable,qe as deleteFrom,P as docConcat,j as docEmpty,Ze as docGroup,Qe as docJoin,N as docLine,Xe as docNest,et as docRender,M as docText,$e as docTextLine,ge as doublePrecision,we as enumType,C as eq,Be as exists,v as fn,t as formatParam,Je as formatSQL,Me as gt,Ne as gte,Re as inList,Ge as insert,fe as integer,w as isNull,c as json,be as jsonb,Ie as like,h as lit,Pe as lt,Fe as lte,re as mysqlDialect,je as neq,Ve as not,_e as numeric,rt as or,ct as pamuk,_ as param,a as pgDialect,n as quoteIdentifier,e as quoteTableRef,ke as raw,me as real,L as resetParams,We as select,pe as serial,ce as smallint,at as sqlFn,ae as sqliteDialect,g as star,Ae as subquery,l as tableRef,Te as text,De as time,ue as timestamp,Ee as timestamptz,b as unaryOp,Ke as update,se as uuid,it as val,oe as varchar,Ue as visitNode};
|
|
3
|
+
`+` `.repeat(e),r=e);break;case`nest`:i.push([e+o.indent,a,o.doc]);break;case`group`:if(a===`flat`)i.push([e,`flat`,o.doc]);else{let n=tt(o.doc);n!==null&&r+n<=t?i.push([e,`flat`,o.doc]):i.push([e,`break`,o.doc])}break;case`concat`:for(let t=o.docs.length-1;t>=0;t--)i.push([e,a,o.docs[t]]);break}}return n}function tt(e){let t=0,n=[e];for(;n.length>0;){let e=n.pop();switch(e.tag){case`empty`:break;case`text`:t+=e.text.length;break;case`line`:t+=1;break;case`nest`:n.push(e.doc);break;case`group`:n.push(e.doc);break;case`concat`:for(let t=e.docs.length-1;t>=0;t--)n.push(e.docs[t]);break}}return t}var F=class{_node;constructor(e,t){this._node=p(e,t)}eq(e){return B(z(`=`,this._node,R(e)))}neq(e){return B(z(`!=`,this._node,R(e)))}gt(e){return B(z(`>`,this._node,R(e)))}gte(e){return B(z(`>=`,this._node,R(e)))}lt(e){return B(z(`<`,this._node,R(e)))}lte(e){return B(z(`<=`,this._node,R(e)))}like(e){return B(z(`LIKE`,this._node,m(e)))}in(e){return B({type:`in`,expr:this._node,values:e.map(e=>R(e)),negated:!1})}notIn(e){return B({type:`in`,expr:this._node,values:e.map(e=>R(e)),negated:!0})}isNull(){return B({type:`is_null`,expr:this._node,negated:!1})}isNotNull(){return B({type:`is_null`,expr:this._node,negated:!0})}between(e,t){return B({type:`between`,expr:this._node,low:R(e),high:R(t),negated:!1})}eqCol(e){return B(z(`=`,this._node,e._node))}toExpr(){return B(this._node)}};let I=0;function L(){I=0}function R(e){return g(I++,e)}function z(e,t,n){return{type:`binary_op`,op:e,left:t,right:n}}function B(e){return{node:e}}function V(e){return new Proxy({},{get(e,t){return new F(t,void 0)}})}function nt(e,t){return B(b(e.node,t.node))}function rt(e,t){return B(x(e.node,t.node))}function it(e){return B(m(e))}function at(e,...t){return B(_(e,t.map(e=>e.node)))}function ot(){return B(_(`COUNT`,[h()]))}function H(e){return e.node}var U=class e{_builder;constructor(e){this._builder=new D().from(e)}_with(t){let n=new e(``);return n._builder=t,n}where(e){if(typeof e==`function`){L();let t=this._builder.build().table.name,n=e(V(t));return this._with(this._builder.where(H(n)))}return this._with(this._builder.where(H(e)))}returning(...e){let t=e.map(e=>({type:`column_ref`,column:e}));return new W(new D({...this._builder.build(),returning:t}))}returningAll(){return new W(new D({...this._builder.build(),returning:[h()]}))}build(){return this._builder.build()}compile(e){return e.print(this.build())}},W=class{_builder;constructor(e){this._builder=e}build(){return this._builder.build()}compile(e){return e.print(this.build())}},G=class e{_builder;_paramIdx;constructor(e,t=0){this._builder=new T().into(e),this._paramIdx=t}_withBuilder(t,n){let r=new e(``);return r._builder=t,r._paramIdx=n,r}values(e){let t=Object.entries(e),n=t.map(([e])=>e),r=t.map(([e,t])=>{let n=g(this._paramIdx,t);return this._paramIdx++,n}),i=this._builder;return i.build().columns.length===0&&(i=i.columns(...n)),i=new T({...i.build(),values:[...i.build().values,r]},this._paramIdx),this._withBuilder(i,this._paramIdx)}returning(...e){let t=e.map(e=>({type:`column_ref`,column:e}));return new K(new T({...this._builder.build(),returning:t},this._paramIdx))}returningAll(){return new K(new T({...this._builder.build(),returning:[h()]},this._paramIdx))}onConflictDoNothing(...e){return this._withBuilder(this._builder.onConflictDoNothing(...e),this._paramIdx)}onConflictDoUpdate(e,t){return this._withBuilder(this._builder.onConflictDoUpdate(e,t.map(e=>({column:e.column,value:H(e.value)}))),this._paramIdx)}build(){return this._builder.build()}compile(e){return e.print(this.build())}},K=class{_builder;constructor(e){this._builder=e}build(){return this._builder.build()}compile(e){return e.print(this.build())}},q=class e{_builder;_table;constructor(e,t){this._builder=e,this._table=t??``}select(...t){return new e(this._builder.columns(...t),this._table)}selectAll(){return new e(this._builder.allColumns(),this._table)}selectExpr(t,n){let r=H(t),i=r.type===`column_ref`||r.type===`function_call`?{...r,alias:n}:{type:`raw`,sql:``,params:[]};return new e(this._builder.columns(i),this._table)}distinct(){return new e(this._builder.distinct(),this._table)}where(t){if(typeof t==`function`){L();let n=t(V(this._table));return new e(this._builder.where(H(n)),this._table)}return new e(this._builder.where(H(t)),this._table)}innerJoin(t,n){let r=J(n,this._table,t);return new e(this._builder.innerJoin(t,H(r)),this._table)}leftJoin(t,n){let r=J(n,this._table,t);return new e(this._builder.leftJoin(t,H(r)),this._table)}rightJoin(t,n){let r=J(n,this._table,t);return new e(this._builder.rightJoin(t,H(r)),this._table)}groupBy(...t){return new e(this._builder.groupBy(...t),this._table)}having(t){if(typeof t==`function`){L();let n=t(V(this._table));return new e(this._builder.having(H(n)),this._table)}return new e(this._builder.having(H(t)),this._table)}orderBy(t,n=`ASC`,r){return new e(this._builder.orderBy(t,n,r),this._table)}limit(t){return new e(this._builder.limit({type:`literal`,value:t}),this._table)}offset(t){return new e(this._builder.offset({type:`literal`,value:t}),this._table)}forUpdate(){return new e(this._builder.forUpdate(),this._table)}with(t,n,r=!1){return new e(this._builder.with(t,n,r),this._table)}union(t){return new e(this._builder.union(t.build()),this._table)}unionAll(t){return new e(this._builder.unionAll(t.build()),this._table)}build(){return this._builder.build()}compile(e){return e.print(this.build())}};function st(e,t){return new Proxy({},{get(e,t){return new Proxy({},{get(e,n){return new F(n,t)}})}})}function J(e,t,n){return typeof e==`function`?e(st(t,n)):e}var Y=class e{_builder;_paramIdx;constructor(e,t=0){this._builder=new E().table(e),this._paramIdx=t}_with(t,n){let r=new e(``);return r._builder=t,r._paramIdx=n,r}set(e){let t=this._builder,n=this._paramIdx;for(let[r,i]of Object.entries(e))i!==void 0&&(t=t.set(r,g(n,i)),n++);return this._with(t,n)}setExpr(e,t){return this._with(this._builder.set(e,H(t)),this._paramIdx)}where(e){if(typeof e==`function`){L();let t=e(V(this._table));return this._with(this._builder.where(H(t)),this._paramIdx)}return this._with(this._builder.where(H(e)),this._paramIdx)}get _table(){return this._builder.build().table.name}returning(...e){let t=e.map(e=>({type:`column_ref`,column:e}));return new X(new E({...this._builder.build(),returning:t}))}returningAll(){return new X(new E({...this._builder.build(),returning:[h()]}))}build(){return this._builder.build()}compile(e){return e.print(this.build())}},X=class{_builder;constructor(e){this._builder=e}build(){return this._builder.build()}compile(e){return e.print(this.build())}},Z=class{_hooks=new Map;hook(e,t){return this._hooks.has(e)||this._hooks.set(e,[]),this._hooks.get(e).push(t),()=>{let n=this._hooks.get(e);if(n){let e=n.indexOf(t);e!==-1&&n.splice(e,1)}}}callHook(e,...t){let n=this._hooks.get(e);if(!n||n.length===0)return;let r;for(let i of n){let n=i(...t);n!==void 0&&(r=n,e!==`result:transform`&&t[0]&&typeof t[0]==`object`&&`node`in t[0]&&(t[0].node=n))}return r}hasHook(e){let t=this._hooks.get(e);return t!==void 0&&t.length>0}removeHook(e){this._hooks.delete(e)}removeAllHooks(){this._hooks.clear()}},Q=class{plugins;constructor(e){this.plugins=Object.freeze([...e])}transformNode(e){let t=e;for(let e of this.plugins)e.transformNode&&(t=e.transformNode(t));return t}transformQuery(e){let t=e;for(let e of this.plugins)e.transformQuery&&(t=e.transformQuery(t));return t}transformResult(e){let t=e;for(let e of this.plugins)e.transformResult&&(t=e.transformResult(t));return t}};function ct(e){return new $(e.dialect,e.plugins??[])}var $=class{_dialect;_plugins;_hooks;constructor(e,t=[]){this._dialect=e,this._plugins=new Q(t),this._hooks=new Z}hook(e,t){return this._hooks.hook(e,t)}selectFrom(e,t){return new q(new w().from(e,t),e)}insertInto(e){return new G(e)}update(e){return new Y(e)}deleteFrom(e){return new U(e)}compile(e){let t=this._plugins.transformNode(e),n=this._extractTableName(t);switch(t.type){case`select`:{let e=this._hooks.callHook(`select:before`,{node:t,table:n});e&&(t=e);break}case`insert`:{let e=this._hooks.callHook(`insert:before`,{node:t,table:n});e&&(t=e);break}case`update`:{let e=this._hooks.callHook(`update:before`,{node:t,table:n});e&&(t=e);break}case`delete`:{let e=this._hooks.callHook(`delete:before`,{node:t,table:n});e&&(t=e);break}}let r=this._hooks.callHook(`query:before`,{node:t,table:n});r&&(t=r);let i=this._dialect.createPrinter().print(t);i=this._plugins.transformQuery(i);let a=this._hooks.callHook(`query:after`,{node:t,table:n,query:i});return a&&(i=a),i}transformResult(e){let t=this._plugins.transformResult(e),n=this._hooks.callHook(`result:transform`,t);return n&&(t=n),t}printer(){return this._dialect.createPrinter()}_extractTableName(e){switch(e.type){case`select`:return e.from?.type===`table_ref`?e.from.name:void 0;case`insert`:return e.table.name;case`update`:return e.table.name;case`delete`:return e.table.name;default:return}}},lt=class{name=`with-schema`;schema;constructor(e){this.schema=e}transformNode(e){switch(e.type){case`select`:return this.transformSelect(e);case`insert`:return this.transformInsert(e);case`update`:return this.transformUpdate(e);case`delete`:return this.transformDelete(e);default:return e}}addSchema(e){return e.schema?e:{...e,schema:this.schema}}transformSelect(e){return{...e,from:e.from?e.from.type===`table_ref`?this.addSchema(e.from):e.from:void 0,joins:e.joins.map(e=>({...e,table:e.table.type===`table_ref`?this.addSchema(e.table):e.table}))}}transformInsert(e){return{...e,table:this.addSchema(e.table)}}transformUpdate(e){return{...e,table:this.addSchema(e.table),from:e.from?this.addSchema(e.from):void 0}}transformDelete(e){return{...e,table:this.addSchema(e.table)}}},ut=class{name=`soft-delete`;tables;column;constructor(e){this.tables=new Set(e.tables),this.column=e.column??`deleted_at`}transformNode(e){switch(e.type){case`select`:return this.transformSelect(e);case`update`:return this.transformUpdate(e);case`delete`:return this.transformDelete(e);default:return e}}isTargetTable(e){return this.tables.has(e)}softDeleteCondition(){return C(p(this.column))}addCondition(e){let t=this.softDeleteCondition();return e?b(e,t):t}transformSelect(e){return!e.from||e.from.type!==`table_ref`||!this.isTargetTable(e.from.name)?e:{...e,where:this.addCondition(e.where)}}transformUpdate(e){return this.isTargetTable(e.table.name)?{...e,where:this.addCondition(e.where)}:e}transformDelete(e){return this.isTargetTable(e.table.name)?{...e,where:this.addCondition(e.where)}:e}},dt=class{name=`camel-case`;transformResult(e){return e.map(e=>{let t={};for(let n of Object.keys(e))t[ft(n)]=e[n];return t})}};function ft(e){return e.replace(/_([a-z])/g,(e,t)=>t.toUpperCase())}export{Ue as ASTTransformer,r as BasePrinter,dt as CamelCasePlugin,F as Col,ye as ColumnBuilder,D as DeleteBuilder,te as EmptyQueryError,Z as Hookable,T as InsertBuilder,s as InvalidExpressionError,ne as MysqlPrinter,i as PgPrinter,Q as PluginManager,w as SelectBuilder,ut as SoftDeletePlugin,ie as SqlitePrinter,$ as Sumak,ee as SumakError,U as TypedDeleteBuilder,W as TypedDeleteReturningBuilder,G as TypedInsertBuilder,K as TypedInsertReturningBuilder,q as TypedSelectBuilder,Y as TypedUpdateBuilder,X as TypedUpdateReturningBuilder,o as UnsupportedDialectFeatureError,E as UpdateBuilder,lt as WithSchemaPlugin,nt as and,Re as between,Se as bigint,ge as bigserial,v as binOp,le as boolean,be as bytea,Be as cast,c as char,p as col,ke as colAs,ot as count,f as createDeleteNode,u as createInsertNode,l as createSelectNode,d as createUpdateNode,de as date,Ce as defineTable,O as deleteFrom,P as docConcat,j as docEmpty,Ze as docGroup,Qe as docJoin,N as docLine,Xe as docNest,et as docRender,M as docText,$e as docTextLine,_e as doublePrecision,we as enumType,S as eq,Ve as exists,_ as fn,t as formatParam,Je as formatSQL,Ne as gt,Pe as gte,ze as inList,Ke as insert,fe as integer,C as isNull,pe as json,xe as jsonb,Le as like,m as lit,Fe as lt,Ie as lte,re as mysqlDialect,Me as neq,He as not,ve as numeric,rt as or,g as param,a as pgDialect,n as quoteIdentifier,e as quoteTableRef,Ae as raw,he as real,L as resetParams,Ge as select,me as serial,ce as smallint,at as sqlFn,ae as sqliteDialect,h as star,je as subquery,ct as sumak,Oe as tableRef,Te as text,De as time,ue as timestamp,Ee as timestamptz,y as unaryOp,qe as update,se as uuid,it as val,oe as varchar,We as visitNode};
|
package/dist/schema.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as InsertType, C as timestamp, D as ColumnType, E as varchar, F as Selectable, I as UpdateType, L as Updateable, M as Nullable, O as Generated, P as SelectType, S as time, T as uuid, _ as numeric, a as ColumnDef, b as smallint, c as boolean, d as date, f as doublePrecision, g as jsonb, h as json, i as ColumnBuilder, j as Insertable, k as GeneratedAlways, l as bytea, m as integer, n as TableDefinition, o as bigint, p as enumType, r as defineTable, s as bigserial, t as InferTable, u as char, v as real, w as timestamptz, x as text, y as serial } from "./_chunks/index.mjs";
|
|
2
2
|
export { ColumnBuilder, type ColumnDef, type ColumnType, type Generated, type GeneratedAlways, type InferTable, type InsertType, type Insertable, type Nullable, type SelectType, type Selectable, type TableDefinition, type UpdateType, type Updateable, bigint, bigserial, boolean, bytea, char, date, defineTable, doublePrecision, enumType, integer, json, jsonb, numeric, real, serial, smallint, text, time, timestamp, timestamptz, uuid, varchar };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sumak",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Type-safe SQL query builder with powerful SQL printers. Zero dependencies, tree-shakeable. Pure TypeScript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -16,15 +16,15 @@
|
|
|
16
16
|
"typescript",
|
|
17
17
|
"zero-dependency"
|
|
18
18
|
],
|
|
19
|
-
"homepage": "https://github.com/productdevbook/
|
|
19
|
+
"homepage": "https://github.com/productdevbook/sumak",
|
|
20
20
|
"bugs": {
|
|
21
|
-
"url": "https://github.com/productdevbook/
|
|
21
|
+
"url": "https://github.com/productdevbook/sumak/issues"
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"author": "productdevbook",
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|
|
27
|
-
"url": "git+https://github.com/productdevbook/
|
|
27
|
+
"url": "git+https://github.com/productdevbook/sumak.git"
|
|
28
28
|
},
|
|
29
29
|
"funding": "https://github.com/sponsors/productdevbook",
|
|
30
30
|
"files": [
|
|
@@ -55,17 +55,6 @@
|
|
|
55
55
|
"default": "./dist/schema.mjs"
|
|
56
56
|
}
|
|
57
57
|
},
|
|
58
|
-
"scripts": {
|
|
59
|
-
"build": "obuild",
|
|
60
|
-
"dev": "vitest",
|
|
61
|
-
"lint": "oxlint . && oxfmt --check .",
|
|
62
|
-
"lint:fix": "oxlint . --fix && oxfmt .",
|
|
63
|
-
"fmt": "oxfmt .",
|
|
64
|
-
"test": "pnpm lint && pnpm typecheck && vitest run",
|
|
65
|
-
"typecheck": "tsgo --noEmit",
|
|
66
|
-
"release": "pnpm test && pnpm build && bumpp --commit --tag --push --all",
|
|
67
|
-
"prepack": "pnpm build"
|
|
68
|
-
},
|
|
69
58
|
"devDependencies": {
|
|
70
59
|
"@typescript/native-preview": "7.0.0-dev.20260316.1",
|
|
71
60
|
"@vitest/coverage-v8": "^4.1.1",
|
|
@@ -75,5 +64,15 @@
|
|
|
75
64
|
"oxlint": "^1.57.0",
|
|
76
65
|
"typescript": "^6.0.2",
|
|
77
66
|
"vitest": "^4.1.1"
|
|
67
|
+
},
|
|
68
|
+
"scripts": {
|
|
69
|
+
"build": "obuild",
|
|
70
|
+
"dev": "vitest",
|
|
71
|
+
"lint": "oxlint . && oxfmt --check .",
|
|
72
|
+
"lint:fix": "oxlint . --fix && oxfmt .",
|
|
73
|
+
"fmt": "oxfmt .",
|
|
74
|
+
"test": "pnpm lint && pnpm typecheck && vitest run",
|
|
75
|
+
"typecheck": "tsgo --noEmit",
|
|
76
|
+
"release": "pnpm test && pnpm build && bumpp --commit --tag --push --all"
|
|
78
77
|
}
|
|
79
|
-
}
|
|
78
|
+
}
|