@typesql/kysely 0.0.4 → 0.1.0
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/CHANGELOG.md +11 -0
- package/README.md +22 -16
- package/dist/client.d.ts +8 -11
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +9 -10
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +12 -14
- package/src/index.ts +20 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @typesql/kysely
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Queries run from the `sql` bound to your client: `createSql<DB>(client)` then `sql("…").execute()` (or `executeTakeFirst`, `executeTakeFirstOrThrow`, `executeCount`), and `sql.transaction(async (tx) => …)` for transactions, nested with savepoints; the `query`, `one`, `maybeOne`, `many`, `execute`, `transaction` and `RowCountError` exports of `@typesql/pg` and `@typesql/postgres`, `query` and `execute` of `@typesql/kysely`, and `queryRaw` and `executeRaw` of `@typesql/prisma` are removed.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies:
|
|
12
|
+
- @typesql/core@0.1.0
|
|
13
|
+
|
|
3
14
|
## 0.0.4
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -10,10 +10,10 @@ pnpm add @typesql/core @typesql/kysely kysely
|
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
|
-
import { createSql
|
|
13
|
+
import { createSql } from "@typesql/kysely";
|
|
14
14
|
import type { DB } from "./db"; // kysely-codegen output
|
|
15
15
|
|
|
16
|
-
const sql = createSql<DB>();
|
|
16
|
+
const sql = createSql<DB>(db); // db: your Kysely<DB> instance, or a Transaction<DB>
|
|
17
17
|
|
|
18
18
|
const q = sql(
|
|
19
19
|
`SELECT u.id, u.email, p.title, p.views
|
|
@@ -23,18 +23,23 @@ const q = sql(
|
|
|
23
23
|
);
|
|
24
24
|
// ^? Query<{ id: number; email: string; title: string; views: string }, [number | null, boolean | null]>
|
|
25
25
|
|
|
26
|
-
const rows = await
|
|
26
|
+
const rows = await q.execute();
|
|
27
|
+
|
|
28
|
+
await sql.transaction(async (tx) => {
|
|
29
|
+
await tx("UPDATE posts SET published = true WHERE author_id = $1", 1).execute();
|
|
30
|
+
});
|
|
27
31
|
```
|
|
28
32
|
|
|
29
33
|
## API
|
|
30
34
|
|
|
31
35
|
| Export | What it is |
|
|
32
36
|
|---|---|
|
|
33
|
-
| `createSql<DB, TM = DefaultTypeMap, Overrides = {}, Options = {}>(db
|
|
34
|
-
| `
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
37
|
+
| `createSql<DB, TM = DefaultTypeMap, Overrides = {}, Options = {}>(db, options?)` | core's `createSql<FromKysely<DB, Overrides, Options>, TM>()` with the queries running on `db`; `{ rowKeys: "camelCase" }` gives `CamelCasePlugin`-style row keys |
|
|
38
|
+
| `q.execute()`, `q.executeTakeFirst()`, `q.executeTakeFirstOrThrow()`, `q.executeCount()` | `Promise<Row[]>`, `Promise<Row \| undefined>`, `Promise<Row>` (`NoResultError` on 0 rows), `Promise<number>` (`numAffectedRows`; for other statements the number of rows returned, 0 for DDL) |
|
|
39
|
+
| `sql.transaction(fn)` | `db.transaction().execute(...)` with `tx` bound to the transaction; on a `Transaction`, and for `tx.transaction(fn)`, a savepoint |
|
|
40
|
+
| `FromKysely<DB, Overrides = {}, Options = {}>` | the converted schema type, for use with core's `createSql<Schema, TM>()` or the adapters' `createSql<Schema>(client)` |
|
|
41
|
+
| `KyselySql<DB, TM, Overrides, Options, Keys>` | the type `createSql` returns |
|
|
42
|
+
| `executor(db)` | an `Executor` for `q.execute(executor)` and core's `createSql(executor)`, also bypassing plugins |
|
|
38
43
|
| `InferColumn<T>` | the descriptor inferred for one Kysely column type (handy to check a mapping) |
|
|
39
44
|
| `SnakeCase<S>` | `CamelCasePlugin`'s default camelCase → snake_case mapping, at the type level |
|
|
40
45
|
| `KyselyOverrides`, `TableOverride`, `ColumnOverride`, `KyselyOptions`, `KyselyExecutor` | parameter types |
|
|
@@ -48,15 +53,16 @@ import type { PgTypeMap } from "@typesql/pg";
|
|
|
48
53
|
import { createSql, type FromKysely } from "@typesql/kysely";
|
|
49
54
|
import { createSql as createCoreSql } from "@typesql/core";
|
|
50
55
|
|
|
51
|
-
const sql = createSql<DB, PgTypeMap>();
|
|
52
|
-
const same = createCoreSql<FromKysely<DB>, PgTypeMap>();
|
|
56
|
+
const sql = createSql<DB, PgTypeMap>(db);
|
|
57
|
+
const same = createCoreSql<FromKysely<DB>, PgTypeMap>(); // types only, no client
|
|
53
58
|
```
|
|
54
59
|
|
|
55
|
-
|
|
60
|
+
Queries are sent as `CompiledQuery.raw(q.text, q.values)` through
|
|
56
61
|
`db.withoutPlugins().executeQuery(...)`. Plugins are bypassed on purpose: typesql's row types
|
|
57
62
|
describe what Postgres returns (`created_at`), and a result transformer such as
|
|
58
|
-
`CamelCasePlugin` would rename the keys (use `{ rowKeys: "camelCase" }` for camelCase rows).
|
|
59
|
-
|
|
63
|
+
`CamelCasePlugin` would rename the keys (use `{ rowKeys: "camelCase" }` for camelCase rows).
|
|
64
|
+
Logging, the dialect and the connection pool are unaffected. Inside a Kysely transaction,
|
|
65
|
+
`createSql<DB>(trx)` binds a `sql` to it, so builder and SQL queries share the transaction.
|
|
60
66
|
|
|
61
67
|
## How columns are converted
|
|
62
68
|
|
|
@@ -104,7 +110,7 @@ const sql = createSql<DB, DefaultTypeMap, {
|
|
|
104
110
|
"auth.users": { id: "uuid" };
|
|
105
111
|
active_users: { $view: true }; // a view: INSERT/UPDATE/DELETE are rejected
|
|
106
112
|
$types: { mood: Mood; "auth.role": AuthRole }; // enum names, see below
|
|
107
|
-
}>();
|
|
113
|
+
}>(db);
|
|
108
114
|
```
|
|
109
115
|
|
|
110
116
|
A descriptor may set any of `type`, `nullable` and `hasDefault`; the others stay inferred.
|
|
@@ -136,7 +142,7 @@ under `$types` and every column whose values are **exactly** that union gets the
|
|
|
136
142
|
```ts
|
|
137
143
|
import type { Mood, AuthRole } from "./db"; // kysely-codegen exports one alias per enum
|
|
138
144
|
|
|
139
|
-
createSql<DB, DefaultTypeMap, { $types: { mood: Mood; "auth.role": AuthRole } }>();
|
|
145
|
+
createSql<DB, DefaultTypeMap, { $types: { mood: Mood; "auth.role": AuthRole } }>(db);
|
|
140
146
|
```
|
|
141
147
|
|
|
142
148
|
If two `$types` entries have the same values the column keeps its derived name; set the column's
|
|
@@ -152,7 +158,7 @@ back to the database's snake_case names the way `CamelCasePlugin` does by defaul
|
|
|
152
158
|
`created_at`, `userID` → `user_id`), so the SQL you write and the rows you get use the real names:
|
|
153
159
|
|
|
154
160
|
```ts
|
|
155
|
-
const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>();
|
|
161
|
+
const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>(db);
|
|
156
162
|
const q = sql("SELECT author_id, created_at FROM blog_posts WHERE id = $1", 1);
|
|
157
163
|
// ^? Query<{ author_id: number; created_at: Date }, [number | null]>
|
|
158
164
|
```
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CompiledQuery, type QueryResult } from "kysely";
|
|
2
|
-
import { type Executor, type
|
|
2
|
+
import { type Executor, type SqlDriver } from "@typesql/core";
|
|
3
3
|
/**
|
|
4
|
-
* What the
|
|
4
|
+
* What the adapter uses from a `Kysely<DB>` or `Transaction<DB>`. Queries run through
|
|
5
5
|
* `withoutPlugins()`: typesql's row types describe what the driver returns, so result
|
|
6
6
|
* transformers such as `CamelCasePlugin` must not rename the columns (`createSql(db,
|
|
7
7
|
* { rowKeys: "camelCase" })` renames the top-level keys instead, in the types too).
|
|
@@ -10,19 +10,16 @@ export interface KyselyExecutor {
|
|
|
10
10
|
withoutPlugins(): {
|
|
11
11
|
executeQuery<R>(query: CompiledQuery<R>): Promise<QueryResult<R>>;
|
|
12
12
|
};
|
|
13
|
+
transaction(): {
|
|
14
|
+
execute<T>(fn: (trx: KyselyExecutor) => Promise<T>): Promise<T>;
|
|
15
|
+
};
|
|
16
|
+
readonly isTransaction: boolean;
|
|
13
17
|
}
|
|
14
|
-
type AnyQuery = Query<unknown, readonly unknown[]>;
|
|
15
18
|
/**
|
|
16
19
|
* An `Executor` for core's `q.execute()`: runs queries on a Kysely instance (or transaction),
|
|
17
20
|
* without its plugins, and resolves to `{ rows, rowCount }` so `q.executeCount()` works.
|
|
18
21
|
*/
|
|
19
22
|
export declare function executor(db: KyselyExecutor): Executor;
|
|
20
|
-
/**
|
|
21
|
-
export declare
|
|
22
|
-
/**
|
|
23
|
-
* Run a statement for its side effect and return its row count: `numAffectedRows` for
|
|
24
|
-
* INSERT/UPDATE/DELETE/MERGE, otherwise the number of rows returned (0 for DDL).
|
|
25
|
-
*/
|
|
26
|
-
export declare function execute(db: KyselyExecutor, q: AnyQuery): Promise<number>;
|
|
27
|
-
export {};
|
|
23
|
+
/** How `createSql(db)` runs queries and transactions. */
|
|
24
|
+
export declare const driver: SqlDriver<KyselyExecutor>;
|
|
28
25
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,IAAI;QAAE,YAAY,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC;IACxF,WAAW,IAAI;QAAE,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC;IACnF,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAcD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,cAAc,GAAG,QAAQ,CAKrD;AAWD,yDAAyD;AACzD,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,cAAc,CAA6B,CAAC"}
|
package/dist/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CompiledQuery } from "kysely";
|
|
2
|
-
import {
|
|
2
|
+
import { runTransaction } from "@typesql/core";
|
|
3
3
|
function run(db, text, values) {
|
|
4
4
|
return db.withoutPlugins().executeQuery(CompiledQuery.raw(text, Array.from(values)));
|
|
5
5
|
}
|
|
@@ -20,16 +20,15 @@ export function executor(db) {
|
|
|
20
20
|
return { rows: result.rows, rowCount: rowCount(result) };
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
|
-
/** Run a typesql query on a Kysely instance (or transaction) and return its rows, typed from the query. */
|
|
24
|
-
export async function query(db, q) {
|
|
25
|
-
const result = await run(db, q.text, q.values);
|
|
26
|
-
return mapRows(q, result.rows);
|
|
27
|
-
}
|
|
28
23
|
/**
|
|
29
|
-
* Run
|
|
30
|
-
*
|
|
24
|
+
* Run `fn` inside `db.transaction().execute()`. A Kysely `Transaction` cannot start another one,
|
|
25
|
+
* so inside one `fn` runs in a savepoint.
|
|
31
26
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
function transaction(db, depth, fn) {
|
|
28
|
+
if (!db.isTransaction)
|
|
29
|
+
return db.transaction().execute(fn);
|
|
30
|
+
return runTransaction((statement) => run(db, statement, []), () => fn(db), { savepoint: `typesql_${depth + 1}` });
|
|
34
31
|
}
|
|
32
|
+
/** How `createSql(db)` runs queries and transactions. */
|
|
33
|
+
export const driver = { executor, transaction };
|
|
35
34
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,cAAc,EAAiC,MAAM,eAAe,CAAC;AAc9E,SAAS,GAAG,CAAI,EAAkB,EAAE,IAAY,EAAE,MAA0B;IAC1E,OAAO,EAAE,CAAC,cAAc,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAqB,CAAC,CAAC;AAC3G,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,MAA4B;IAC5C,OAAO,MAAM,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;AACpG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAkB;IACzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAU,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IAC3D,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAI,EAAkB,EAAE,KAAa,EAAE,EAAuC;IAChG,IAAI,CAAC,EAAE,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3D,OAAO,cAAc,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;AACpH,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,MAAM,GAA8B,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,30 @@
|
|
|
1
|
-
import { type DefaultTypeMap, type
|
|
1
|
+
import { type DefaultTypeMap, type RowKeys, type TransactionalSql } from "@typesql/core";
|
|
2
2
|
import { type KyselyExecutor } from "./client.js";
|
|
3
3
|
import type { FromKysely, KyselyOptions, KyselyOverrides } from "./from-kysely.js";
|
|
4
|
-
export { NoResultError, type Executor } from "@typesql/core";
|
|
4
|
+
export { NoResultError, type Executor, type TransactionalSql } from "@typesql/core";
|
|
5
5
|
export type { FromKysely, KyselyOverrides, KyselyOptions, TableOverride, ColumnOverride, InferColumn, SnakeCase } from "./from-kysely.js";
|
|
6
|
-
export {
|
|
6
|
+
export { executor, type KyselyExecutor } from "./client.js";
|
|
7
|
+
/** What `createSql<DB>(db)` returns: core's `Sql` over `FromKysely<DB, ...>`, with `transaction(fn)`. */
|
|
8
|
+
export type KyselySql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}, Keys extends RowKeys = "preserve"> = TransactionalSql<FromKysely<DB, Overrides, Options>, TM, Keys>;
|
|
7
9
|
/**
|
|
8
10
|
* `createSql` from core with a Kysely `DB` interface as the schema:
|
|
9
|
-
* `createSql<DB>()` is `createSql<FromKysely<DB>, DefaultTypeMap>()`.
|
|
11
|
+
* `createSql<DB>(db)` is `createSql<FromKysely<DB>, DefaultTypeMap>()` bound to `db`.
|
|
10
12
|
*
|
|
11
|
-
* const sql = createSql<DB>();
|
|
12
|
-
* const sql = createSql<DB, PgTypeMap, { users: { id: "int8" } }>();
|
|
13
|
-
* const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>();
|
|
13
|
+
* const sql = createSql<DB>(db);
|
|
14
|
+
* const sql = createSql<DB, PgTypeMap, { users: { id: "int8" } }>(db);
|
|
15
|
+
* const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>(db);
|
|
14
16
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `
|
|
17
|
+
* The queries' `execute*` methods run on `db` (a `Kysely` instance or transaction), bypassing
|
|
18
|
+
* its plugins, and `sql.transaction(fn)` runs `fn` with a `sql` bound to one transaction.
|
|
19
|
+
* `{ rowKeys: "camelCase" }` camelCases the rows' top-level keys as `CamelCasePlugin` does, in
|
|
20
|
+
* the types and at runtime, without touching JSON values:
|
|
18
21
|
*
|
|
19
22
|
* const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>(db, { rowKeys: "camelCase" });
|
|
20
23
|
*/
|
|
21
24
|
export declare function createSql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}>(db: KyselyExecutor | undefined, options: {
|
|
22
25
|
readonly rowKeys: "camelCase";
|
|
23
|
-
}):
|
|
26
|
+
}): KyselySql<DB, TM, Overrides, Options, "camelCase">;
|
|
24
27
|
export declare function createSql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}>(db?: KyselyExecutor, options?: {
|
|
25
28
|
readonly rowKeys?: "preserve";
|
|
26
|
-
}):
|
|
29
|
+
}): KyselySql<DB, TM, Overrides, Options>;
|
|
27
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,cAAc,EAAE,KAAK,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAClI,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACpF,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1I,OAAO,EAAE,QAAQ,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAE5D,yGAAyG;AACzG,MAAM,MAAM,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,cAAc,EAAE,SAAS,SAAS,eAAe,GAAG,EAAE,EAAE,OAAO,SAAS,aAAa,GAAG,EAAE,EAAE,IAAI,SAAS,OAAO,GAAG,UAAU,IAC1J,gBAAgB,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAEjE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,cAAc,EAAE,SAAS,SAAS,eAAe,GAAG,EAAE,EAAE,OAAO,SAAS,aAAa,GAAG,EAAE,EAC3H,EAAE,EAAE,cAAc,GAAG,SAAS,EAC9B,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GACzC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;AACtD,wBAAgB,SAAS,CAAC,EAAE,EAAE,EAAE,GAAG,cAAc,EAAE,SAAS,SAAS,eAAe,GAAG,EAAE,EAAE,OAAO,SAAS,aAAa,GAAG,EAAE,EAC3H,EAAE,CAAC,EAAE,cAAc,EACnB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAA;CAAE,GAC1C,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createTransactionalSql } from "@typesql/core";
|
|
2
|
+
import { driver } from "./client.js";
|
|
3
3
|
export { NoResultError } from "@typesql/core";
|
|
4
|
-
export {
|
|
4
|
+
export { executor } from "./client.js";
|
|
5
5
|
export function createSql(db, options) {
|
|
6
|
-
return
|
|
6
|
+
return createTransactionalSql(db, driver, options);
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA6E,MAAM,eAAe,CAAC;AAClI,OAAO,EAAE,MAAM,EAAuB,MAAM,aAAa,CAAC;AAG1D,OAAO,EAAE,aAAa,EAAwC,MAAM,eAAe,CAAC;AAEpF,OAAO,EAAE,QAAQ,EAAuB,MAAM,aAAa,CAAC;AA6B5D,MAAM,UAAU,SAAS,CACvB,EAAmB,EACnB,OAAoB;IAEpB,OAAO,sBAAsB,CAAyD,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAC7G,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typesql/kysely",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Use Kysely database interfaces (kysely-codegen, prisma-kysely) as a typesql schema.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@typesql/core": "0.0
|
|
31
|
+
"@typesql/core": "0.1.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"kysely": ">=0.27"
|
package/src/client.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { CompiledQuery, type QueryResult } from "kysely";
|
|
2
|
-
import {
|
|
2
|
+
import { runTransaction, type Executor, type SqlDriver } from "@typesql/core";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* What the
|
|
5
|
+
* What the adapter uses from a `Kysely<DB>` or `Transaction<DB>`. Queries run through
|
|
6
6
|
* `withoutPlugins()`: typesql's row types describe what the driver returns, so result
|
|
7
7
|
* transformers such as `CamelCasePlugin` must not rename the columns (`createSql(db,
|
|
8
8
|
* { rowKeys: "camelCase" })` renames the top-level keys instead, in the types too).
|
|
9
9
|
*/
|
|
10
10
|
export interface KyselyExecutor {
|
|
11
11
|
withoutPlugins(): { executeQuery<R>(query: CompiledQuery<R>): Promise<QueryResult<R>> };
|
|
12
|
+
transaction(): { execute<T>(fn: (trx: KyselyExecutor) => Promise<T>): Promise<T> };
|
|
13
|
+
readonly isTransaction: boolean;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
type AnyQuery = Query<unknown, readonly unknown[]>;
|
|
15
|
-
|
|
16
16
|
function run<R>(db: KyselyExecutor, text: string, values: readonly unknown[]): Promise<QueryResult<R>> {
|
|
17
17
|
return db.withoutPlugins().executeQuery(CompiledQuery.raw(text, Array.from(values)) as CompiledQuery<R>);
|
|
18
18
|
}
|
|
@@ -36,16 +36,14 @@ export function executor(db: KyselyExecutor): Executor {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
/** Run a typesql query on a Kysely instance (or transaction) and return its rows, typed from the query. */
|
|
40
|
-
export async function query<Q extends AnyQuery>(db: KyselyExecutor, q: Q): Promise<RowType<Q>[]> {
|
|
41
|
-
const result = await run<unknown>(db, q.text, q.values);
|
|
42
|
-
return mapRows(q, result.rows);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
39
|
/**
|
|
46
|
-
* Run
|
|
47
|
-
*
|
|
40
|
+
* Run `fn` inside `db.transaction().execute()`. A Kysely `Transaction` cannot start another one,
|
|
41
|
+
* so inside one `fn` runs in a savepoint.
|
|
48
42
|
*/
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
function transaction<T>(db: KyselyExecutor, depth: number, fn: (trx: KyselyExecutor) => Promise<T>): Promise<T> {
|
|
44
|
+
if (!db.isTransaction) return db.transaction().execute(fn);
|
|
45
|
+
return runTransaction((statement) => run(db, statement, []), () => fn(db), { savepoint: `typesql_${depth + 1}` });
|
|
51
46
|
}
|
|
47
|
+
|
|
48
|
+
/** How `createSql(db)` runs queries and transactions. */
|
|
49
|
+
export const driver: SqlDriver<KyselyExecutor> = { executor, transaction };
|
package/src/index.ts
CHANGED
|
@@ -1,36 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createTransactionalSql, type DefaultTypeMap, type RowKeys, type SqlOptions, type TransactionalSql } from "@typesql/core";
|
|
2
|
+
import { driver, type KyselyExecutor } from "./client.js";
|
|
3
3
|
import type { FromKysely, KyselyOptions, KyselyOverrides } from "./from-kysely.js";
|
|
4
4
|
|
|
5
|
-
export { NoResultError, type Executor } from "@typesql/core";
|
|
5
|
+
export { NoResultError, type Executor, type TransactionalSql } from "@typesql/core";
|
|
6
6
|
export type { FromKysely, KyselyOverrides, KyselyOptions, TableOverride, ColumnOverride, InferColumn, SnakeCase } from "./from-kysely.js";
|
|
7
|
-
export {
|
|
7
|
+
export { executor, type KyselyExecutor } from "./client.js";
|
|
8
|
+
|
|
9
|
+
/** What `createSql<DB>(db)` returns: core's `Sql` over `FromKysely<DB, ...>`, with `transaction(fn)`. */
|
|
10
|
+
export type KyselySql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}, Keys extends RowKeys = "preserve"> =
|
|
11
|
+
TransactionalSql<FromKysely<DB, Overrides, Options>, TM, Keys>;
|
|
8
12
|
|
|
9
13
|
/**
|
|
10
14
|
* `createSql` from core with a Kysely `DB` interface as the schema:
|
|
11
|
-
* `createSql<DB>()` is `createSql<FromKysely<DB>, DefaultTypeMap>()`.
|
|
15
|
+
* `createSql<DB>(db)` is `createSql<FromKysely<DB>, DefaultTypeMap>()` bound to `db`.
|
|
12
16
|
*
|
|
13
|
-
* const sql = createSql<DB>();
|
|
14
|
-
* const sql = createSql<DB, PgTypeMap, { users: { id: "int8" } }>();
|
|
15
|
-
* const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>();
|
|
17
|
+
* const sql = createSql<DB>(db);
|
|
18
|
+
* const sql = createSql<DB, PgTypeMap, { users: { id: "int8" } }>(db);
|
|
19
|
+
* const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>(db);
|
|
16
20
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `
|
|
21
|
+
* The queries' `execute*` methods run on `db` (a `Kysely` instance or transaction), bypassing
|
|
22
|
+
* its plugins, and `sql.transaction(fn)` runs `fn` with a `sql` bound to one transaction.
|
|
23
|
+
* `{ rowKeys: "camelCase" }` camelCases the rows' top-level keys as `CamelCasePlugin` does, in
|
|
24
|
+
* the types and at runtime, without touching JSON values:
|
|
20
25
|
*
|
|
21
26
|
* const sql = createSql<DB, DefaultTypeMap, {}, { camelCase: true }>(db, { rowKeys: "camelCase" });
|
|
22
27
|
*/
|
|
23
28
|
export function createSql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}>(
|
|
24
29
|
db: KyselyExecutor | undefined,
|
|
25
30
|
options: { readonly rowKeys: "camelCase" },
|
|
26
|
-
):
|
|
31
|
+
): KyselySql<DB, TM, Overrides, Options, "camelCase">;
|
|
27
32
|
export function createSql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}>(
|
|
28
33
|
db?: KyselyExecutor,
|
|
29
34
|
options?: { readonly rowKeys?: "preserve" },
|
|
30
|
-
):
|
|
35
|
+
): KyselySql<DB, TM, Overrides, Options>;
|
|
31
36
|
export function createSql<DB, TM = DefaultTypeMap, Overrides extends KyselyOverrides = {}, Options extends KyselyOptions = {}>(
|
|
32
37
|
db?: KyselyExecutor,
|
|
33
38
|
options?: SqlOptions,
|
|
34
|
-
):
|
|
35
|
-
return
|
|
39
|
+
): KyselySql<DB, TM, Overrides, Options, RowKeys> {
|
|
40
|
+
return createTransactionalSql<FromKysely<DB, Overrides, Options>, TM, KyselyExecutor>(db, driver, options);
|
|
36
41
|
}
|