@typesql/drizzle 0.0.3 → 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 +18 -0
- package/README.md +49 -10
- package/dist/client.d.ts +20 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +34 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +10 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/package.json +6 -3
- package/src/client.ts +52 -0
- package/src/index.ts +12 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @typesql/drizzle
|
|
2
2
|
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- `createSql<typeof schema>(db)` takes a Drizzle database or transaction on node-postgres or postgres.js instead of an `Executor`, runs the queries on its driver client, and has `sql.transaction(fn)`, which runs in `db.transaction`.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies:
|
|
12
|
+
- @typesql/core@0.1.0
|
|
13
|
+
|
|
14
|
+
## 0.0.4
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies:
|
|
19
|
+
- @typesql/core@0.0.4
|
|
20
|
+
|
|
3
21
|
## 0.0.3
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -9,7 +9,8 @@ SQL you write is checked against the same tables Drizzle manages.
|
|
|
9
9
|
npm install @typesql/drizzle @typesql/core
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
`drizzle-orm` (0.45 or later) is a peer dependency.
|
|
12
|
+
`drizzle-orm` (0.45 or later) is a peer dependency. Queries run on node-postgres or postgres.js
|
|
13
|
+
databases.
|
|
13
14
|
|
|
14
15
|
## Usage
|
|
15
16
|
|
|
@@ -39,10 +40,13 @@ export const usersRelations = relations(users, ({ many }) => ({ posts: many(post
|
|
|
39
40
|
|
|
40
41
|
```ts
|
|
41
42
|
// db.ts
|
|
43
|
+
import { drizzle } from "drizzle-orm/node-postgres";
|
|
44
|
+
import { Pool } from "pg";
|
|
42
45
|
import { createSql } from "@typesql/drizzle";
|
|
43
|
-
import
|
|
46
|
+
import * as schema from "./schema";
|
|
44
47
|
|
|
45
|
-
const
|
|
48
|
+
const db = drizzle(new Pool(), { schema });
|
|
49
|
+
const sql = createSql<typeof schema>(db);
|
|
46
50
|
|
|
47
51
|
const q = sql(
|
|
48
52
|
"SELECT u.email, u.display_name, p.title FROM users u JOIN posts p ON p.author_id = u.id WHERE u.mood = $1",
|
|
@@ -50,23 +54,58 @@ const q = sql(
|
|
|
50
54
|
);
|
|
51
55
|
// Query<{ email: string; display_name: string | null; title: string }, ["happy" | "sad"]>
|
|
52
56
|
|
|
53
|
-
sql("INSERT INTO posts (author_id, title) VALUES ($1, $2) RETURNING id, created_at", 1, "Hello");
|
|
57
|
+
const post = await sql("INSERT INTO posts (author_id, title) VALUES ($1, $2) RETURNING id, created_at", 1, "Hello").executeTakeFirstOrThrow();
|
|
54
58
|
// id and created_at have defaults, so they can be left out
|
|
59
|
+
|
|
60
|
+
await sql.transaction(async (tx) => {
|
|
61
|
+
await tx("UPDATE posts SET title = upper(title) WHERE author_id = $1", 1).execute();
|
|
62
|
+
});
|
|
55
63
|
```
|
|
56
64
|
|
|
57
65
|
Queries use SQL names: `display_name`, not `displayName`. Relations and any other
|
|
58
66
|
non-table exports are ignored, so `typeof schema` can be passed as is.
|
|
59
67
|
|
|
60
|
-
`createSql<Schema, TypeMap, Options>()` uses core's `DefaultTypeMap` unless you pass
|
|
61
|
-
another one
|
|
62
|
-
|
|
68
|
+
`createSql<Schema, TypeMap, Options>(db)` uses core's `DefaultTypeMap` unless you pass
|
|
69
|
+
another one, such as `PgTypeMap` from `@typesql/pg` for node-postgres' exact types:
|
|
70
|
+
`createSql<typeof schema, PgTypeMap>(db)`.
|
|
71
|
+
|
|
72
|
+
## Running queries
|
|
73
|
+
|
|
74
|
+
`db` is a Drizzle database on node-postgres or postgres.js (`drizzle-orm/node-postgres`,
|
|
75
|
+
`drizzle-orm/postgres-js`), or a transaction from `db.transaction(fn)`. Queries run on the
|
|
76
|
+
driver client Drizzle holds: the `Pool`, `Client` or postgres.js `sql` you gave `drizzle()`, or
|
|
77
|
+
the transaction's connection. Rows are what the driver returns; Drizzle's column mappers and
|
|
78
|
+
its logger are not involved.
|
|
79
|
+
|
|
80
|
+
| | |
|
|
81
|
+
|---|---|
|
|
82
|
+
| `q.execute()`, `q.executeTakeFirst()`, `q.executeTakeFirstOrThrow()`, `q.executeCount()` | `Promise<Row[]>`, `Promise<Row \| undefined>`, `Promise<Row>` (`NoResultError` on 0 rows), `Promise<number>` (the driver's row count) |
|
|
83
|
+
| `sql.transaction(fn)` | `db.transaction(fn)` with `tx` bound to the transaction; `tx.transaction(fn)` is Drizzle's nested transaction (a savepoint) |
|
|
84
|
+
| `executor(db)` | an `Executor` for `q.execute(executor)` and core's `createSql(executor)` |
|
|
85
|
+
| `DrizzleSql<Schema, TM, Options>`, `DrizzleDatabase` | the type `createSql` returns, and what it accepts |
|
|
86
|
+
|
|
87
|
+
To mix ORM and SQL queries in one transaction, bind a `sql` to Drizzle's `tx`:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
await db.transaction(async (tx) => {
|
|
91
|
+
await tx.insert(schema.users).values({ email: "a@b.c" });
|
|
92
|
+
await createSql<typeof schema>(tx)("UPDATE users SET mood = 'happy' WHERE email = $1", "a@b.c").execute();
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
`drizzle-orm/postgres-js` turns off postgres.js' date parsers on the client it is given, so on
|
|
97
|
+
that driver `date`, `timestamp`, `timestamptz` and `interval` come back as strings: pass a type
|
|
98
|
+
map that says so.
|
|
99
|
+
|
|
100
|
+
To pair the schema with a driver adapter instead, convert it with `FromDrizzle` and use the
|
|
101
|
+
adapter's `createSql` on the same pool:
|
|
63
102
|
|
|
64
103
|
```ts
|
|
65
104
|
import { createSql } from "@typesql/pg";
|
|
66
105
|
import type { FromDrizzle } from "@typesql/drizzle";
|
|
67
106
|
import type * as schema from "./schema";
|
|
68
107
|
|
|
69
|
-
const sql = createSql<FromDrizzle<typeof schema>>();
|
|
108
|
+
const sql = createSql<FromDrizzle<typeof schema>>(pool);
|
|
70
109
|
```
|
|
71
110
|
|
|
72
111
|
`FromDrizzle` also accepts a single table (`FromDrizzle<typeof users>`) or a record of
|
|
@@ -129,7 +168,7 @@ type maps, but `timestamp` and `timestamptz` behave differently in SQL (`AT TIME
|
|
|
129
168
|
`date_trunc`, comparisons with `now()`). Either set the default for all of them:
|
|
130
169
|
|
|
131
170
|
```ts
|
|
132
|
-
createSql<typeof schema, DefaultTypeMap, { timestamp: "timestamptz"; time: "timetz" }>();
|
|
171
|
+
createSql<typeof schema, DefaultTypeMap, { timestamp: "timestamptz"; time: "timetz" }>(db);
|
|
133
172
|
// or: FromDrizzle<typeof schema, { timestamp: "timestamptz" }>
|
|
134
173
|
```
|
|
135
174
|
|
|
@@ -163,7 +202,7 @@ If you create Drizzle with `drizzle(client, { casing: "snake_case" })`, pass the
|
|
|
163
202
|
setting so column names match what Drizzle sends to Postgres:
|
|
164
203
|
|
|
165
204
|
```ts
|
|
166
|
-
createSql<typeof schema, DefaultTypeMap, { casing: "snake_case" }>();
|
|
205
|
+
createSql<typeof schema, DefaultTypeMap, { casing: "snake_case" }>(db);
|
|
167
206
|
// createdAt: timestamp() → column created_at
|
|
168
207
|
```
|
|
169
208
|
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Executor, SqlDriver } from "@typesql/core";
|
|
2
|
+
/**
|
|
3
|
+
* What the adapter uses from a Drizzle database (`drizzle(client)` from `drizzle-orm/node-postgres`,
|
|
4
|
+
* `drizzle-orm/postgres-js`, ...) or a transaction from `db.transaction(fn)`.
|
|
5
|
+
*/
|
|
6
|
+
export interface DrizzleDatabase {
|
|
7
|
+
readonly _: {
|
|
8
|
+
readonly session: object;
|
|
9
|
+
};
|
|
10
|
+
transaction<T>(fn: (tx: DrizzleDatabase) => Promise<T>): Promise<T>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* An `Executor` for core's `q.execute()`: runs queries on the driver client under `db`, so rows
|
|
14
|
+
* come back as the driver parses them (Drizzle's column mappers are not involved), and resolves to
|
|
15
|
+
* `{ rows, rowCount }` so `q.executeCount()` works.
|
|
16
|
+
*/
|
|
17
|
+
export declare function executor(db: DrizzleDatabase): Executor;
|
|
18
|
+
/** How `createSql(db)` runs queries and transactions. */
|
|
19
|
+
export declare const driver: SqlDriver<DrizzleDatabase>;
|
|
20
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,eAAe,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;AAmBD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EAAE,EAAE,eAAe,GAAG,QAAQ,CAUtD;AAOD,yDAAyD;AACzD,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,eAAe,CAA6B,CAAC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The driver client under `db`: the `Pool`, `Client` or postgres.js `sql` given to `drizzle()`,
|
|
3
|
+
* or, inside `db.transaction(fn)`, the connection the transaction runs on. Drizzle keeps it as
|
|
4
|
+
* `session.client`.
|
|
5
|
+
*/
|
|
6
|
+
function clientOf(db) {
|
|
7
|
+
const client = db._.session.client;
|
|
8
|
+
if (client && (typeof client.unsafe === "function" || typeof client.query === "function"))
|
|
9
|
+
return client;
|
|
10
|
+
throw new Error("typesql: createSql(db) needs a Drizzle database on node-postgres or postgres.js (its session client has no query or unsafe method)");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* An `Executor` for core's `q.execute()`: runs queries on the driver client under `db`, so rows
|
|
14
|
+
* come back as the driver parses them (Drizzle's column mappers are not involved), and resolves to
|
|
15
|
+
* `{ rows, rowCount }` so `q.executeCount()` works.
|
|
16
|
+
*/
|
|
17
|
+
export function executor(db) {
|
|
18
|
+
return async (text, values) => {
|
|
19
|
+
const client = clientOf(db);
|
|
20
|
+
if (client.unsafe) {
|
|
21
|
+
const result = (await client.unsafe(text, Array.from(values)));
|
|
22
|
+
return { rows: Array.from(result), rowCount: result.count ?? null };
|
|
23
|
+
}
|
|
24
|
+
const result = (await client.query(text, Array.from(values)));
|
|
25
|
+
return { rows: result.rows, rowCount: result.rowCount ?? null };
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/** Run `fn` inside `db.transaction(fn)`; Drizzle nests a transaction inside one with a savepoint. */
|
|
29
|
+
function transaction(db, _depth, fn) {
|
|
30
|
+
return db.transaction(fn);
|
|
31
|
+
}
|
|
32
|
+
/** How `createSql(db)` runs queries and transactions. */
|
|
33
|
+
export const driver = { executor, transaction };
|
|
34
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,SAAS,QAAQ,CAAC,EAAmB;IACnC,MAAM,MAAM,GAAI,EAAE,CAAC,CAAC,CAAC,OAA8C,CAAC,MAAM,CAAC;IAC3E,IAAI,MAAM,IAAI,CAAC,OAAO,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,UAAU,CAAC;QAAE,OAAO,MAAM,CAAC;IACzG,MAAM,IAAI,KAAK,CAAC,oIAAoI,CAAC,CAAC;AACxJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,EAAmB;IAC1C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAmD,CAAC;YACjH,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QACtE,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,KAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAkD,CAAC;QAChH,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;IAClE,CAAC,CAAC;AACJ,CAAC;AAED,qGAAqG;AACrG,SAAS,WAAW,CAAI,EAAmB,EAAE,MAAc,EAAE,EAAuC;IAClG,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,MAAM,MAAM,GAA+B,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import { type DefaultTypeMap, type
|
|
1
|
+
import { type DefaultTypeMap, type TransactionalSql } from "@typesql/core";
|
|
2
|
+
import { type DrizzleDatabase } from "./client.js";
|
|
2
3
|
import type { FromDrizzle, FromDrizzleOptions } from "./from-drizzle.js";
|
|
3
4
|
export type { FromDrizzle, FromDrizzleOptions, DrizzleColumnTypes } from "./from-drizzle.js";
|
|
4
5
|
export { pgType } from "./pg-type.js";
|
|
5
|
-
export
|
|
6
|
+
export { executor, type DrizzleDatabase } from "./client.js";
|
|
7
|
+
export type { Sql, Query, RowType, ParamsType, DefaultTypeMap, TypeMap, Executor, TransactionalSql } from "@typesql/core";
|
|
6
8
|
export { NoResultError } from "@typesql/core";
|
|
9
|
+
/** What `createSql<typeof schema>(db)` returns: core's `Sql` over `FromDrizzle<Schema, Opts>`, with `transaction(fn)`. */
|
|
10
|
+
export type DrizzleSql<Schema, TM = DefaultTypeMap, Opts extends FromDrizzleOptions = {}> = TransactionalSql<FromDrizzle<Schema, Opts>, TM>;
|
|
7
11
|
/**
|
|
8
12
|
* `createSql` from core with the schema converted from Drizzle definitions:
|
|
9
|
-
* `createSql<typeof schema>()`, or `createSql<typeof schema, PgTypeMap>()` for a driver's type map.
|
|
10
|
-
*
|
|
11
|
-
* `
|
|
13
|
+
* `createSql<typeof schema>(db)`, or `createSql<typeof schema, PgTypeMap>(db)` for a driver's type map.
|
|
14
|
+
* The queries' `execute*` methods run on `db` (a Drizzle database or transaction, on node-postgres
|
|
15
|
+
* or postgres.js), and `sql.transaction(fn)` runs `fn` with a `sql` bound to `db.transaction`.
|
|
12
16
|
*/
|
|
13
|
-
export declare function createSql<Schema, TM = DefaultTypeMap, Opts extends FromDrizzleOptions = {}>(
|
|
17
|
+
export declare function createSql<Schema, TM = DefaultTypeMap, Opts extends FromDrizzleOptions = {}>(db?: DrizzleDatabase): DrizzleSql<Schema, TM, Opts>;
|
|
14
18
|
//# 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,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnG,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC7D,YAAY,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,0HAA0H;AAC1H,MAAM,MAAM,UAAU,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,EAAE,IAAI,SAAS,kBAAkB,GAAG,EAAE,IAAI,gBAAgB,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;AAE5I;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,EAAE,GAAG,cAAc,EAAE,IAAI,SAAS,kBAAkB,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,eAAe,GAAG,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAE/I"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createTransactionalSql } from "@typesql/core";
|
|
2
|
+
import { driver } from "./client.js";
|
|
2
3
|
export { pgType } from "./pg-type.js";
|
|
4
|
+
export { executor } from "./client.js";
|
|
3
5
|
export { NoResultError } from "@typesql/core";
|
|
4
6
|
/**
|
|
5
7
|
* `createSql` from core with the schema converted from Drizzle definitions:
|
|
6
|
-
* `createSql<typeof schema>()`, or `createSql<typeof schema, PgTypeMap>()` for a driver's type map.
|
|
7
|
-
*
|
|
8
|
-
* `
|
|
8
|
+
* `createSql<typeof schema>(db)`, or `createSql<typeof schema, PgTypeMap>(db)` for a driver's type map.
|
|
9
|
+
* The queries' `execute*` methods run on `db` (a Drizzle database or transaction, on node-postgres
|
|
10
|
+
* or postgres.js), and `sql.transaction(fn)` runs `fn` with a `sql` bound to `db.transaction`.
|
|
9
11
|
*/
|
|
10
|
-
export function createSql(
|
|
11
|
-
return
|
|
12
|
+
export function createSql(db) {
|
|
13
|
+
return createTransactionalSql(db, driver);
|
|
12
14
|
}
|
|
13
15
|
//# 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,EAA8C,MAAM,eAAe,CAAC;AACnG,OAAO,EAAE,MAAM,EAAwB,MAAM,aAAa,CAAC;AAI3D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAwB,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK9C;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAoE,EAAoB;IAC/G,OAAO,sBAAsB,CAAiD,EAAE,EAAE,MAAM,CAAiC,CAAC;AAC5H,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typesql/drizzle",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Use Drizzle ORM table definitions as a typesql schema.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,14 +28,17 @@
|
|
|
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
|
"drizzle-orm": ">=0.45"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@
|
|
37
|
+
"@types/pg": "^8.23.1",
|
|
38
|
+
"@typesql/pg": "0.1.0",
|
|
38
39
|
"drizzle-orm": "^0.45.4",
|
|
40
|
+
"pg": "^8.23.1",
|
|
41
|
+
"postgres": "^3.4.9",
|
|
39
42
|
"typescript": "7.0.2",
|
|
40
43
|
"vitest": "^5.0.4"
|
|
41
44
|
},
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Executor, SqlDriver } from "@typesql/core";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What the adapter uses from a Drizzle database (`drizzle(client)` from `drizzle-orm/node-postgres`,
|
|
5
|
+
* `drizzle-orm/postgres-js`, ...) or a transaction from `db.transaction(fn)`.
|
|
6
|
+
*/
|
|
7
|
+
export interface DrizzleDatabase {
|
|
8
|
+
readonly _: { readonly session: object };
|
|
9
|
+
transaction<T>(fn: (tx: DrizzleDatabase) => Promise<T>): Promise<T>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** The driver client a Drizzle session holds: node-postgres' `query` or postgres.js' `unsafe`. */
|
|
13
|
+
interface DriverClient {
|
|
14
|
+
query?(text: string, values: unknown[]): Promise<unknown>;
|
|
15
|
+
unsafe?(text: string, values: unknown[]): PromiseLike<unknown>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The driver client under `db`: the `Pool`, `Client` or postgres.js `sql` given to `drizzle()`,
|
|
20
|
+
* or, inside `db.transaction(fn)`, the connection the transaction runs on. Drizzle keeps it as
|
|
21
|
+
* `session.client`.
|
|
22
|
+
*/
|
|
23
|
+
function clientOf(db: DrizzleDatabase): DriverClient {
|
|
24
|
+
const client = (db._.session as { readonly client?: DriverClient }).client;
|
|
25
|
+
if (client && (typeof client.unsafe === "function" || typeof client.query === "function")) return client;
|
|
26
|
+
throw new Error("typesql: createSql(db) needs a Drizzle database on node-postgres or postgres.js (its session client has no query or unsafe method)");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* An `Executor` for core's `q.execute()`: runs queries on the driver client under `db`, so rows
|
|
31
|
+
* come back as the driver parses them (Drizzle's column mappers are not involved), and resolves to
|
|
32
|
+
* `{ rows, rowCount }` so `q.executeCount()` works.
|
|
33
|
+
*/
|
|
34
|
+
export function executor(db: DrizzleDatabase): Executor {
|
|
35
|
+
return async (text, values) => {
|
|
36
|
+
const client = clientOf(db);
|
|
37
|
+
if (client.unsafe) {
|
|
38
|
+
const result = (await client.unsafe(text, Array.from(values))) as unknown[] & { readonly count?: number | null };
|
|
39
|
+
return { rows: Array.from(result), rowCount: result.count ?? null };
|
|
40
|
+
}
|
|
41
|
+
const result = (await client.query!(text, Array.from(values))) as { rows: unknown[]; rowCount?: number | null };
|
|
42
|
+
return { rows: result.rows, rowCount: result.rowCount ?? null };
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Run `fn` inside `db.transaction(fn)`; Drizzle nests a transaction inside one with a savepoint. */
|
|
47
|
+
function transaction<T>(db: DrizzleDatabase, _depth: number, fn: (tx: DrizzleDatabase) => Promise<T>): Promise<T> {
|
|
48
|
+
return db.transaction(fn);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** How `createSql(db)` runs queries and transactions. */
|
|
52
|
+
export const driver: SqlDriver<DrizzleDatabase> = { executor, transaction };
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createTransactionalSql, type DefaultTypeMap, type TransactionalSql } from "@typesql/core";
|
|
2
|
+
import { driver, type DrizzleDatabase } from "./client.js";
|
|
2
3
|
import type { FromDrizzle, FromDrizzleOptions } from "./from-drizzle.js";
|
|
3
4
|
|
|
4
5
|
export type { FromDrizzle, FromDrizzleOptions, DrizzleColumnTypes } from "./from-drizzle.js";
|
|
5
6
|
export { pgType } from "./pg-type.js";
|
|
6
|
-
export
|
|
7
|
+
export { executor, type DrizzleDatabase } from "./client.js";
|
|
8
|
+
export type { Sql, Query, RowType, ParamsType, DefaultTypeMap, TypeMap, Executor, TransactionalSql } from "@typesql/core";
|
|
7
9
|
export { NoResultError } from "@typesql/core";
|
|
8
10
|
|
|
11
|
+
/** What `createSql<typeof schema>(db)` returns: core's `Sql` over `FromDrizzle<Schema, Opts>`, with `transaction(fn)`. */
|
|
12
|
+
export type DrizzleSql<Schema, TM = DefaultTypeMap, Opts extends FromDrizzleOptions = {}> = TransactionalSql<FromDrizzle<Schema, Opts>, TM>;
|
|
13
|
+
|
|
9
14
|
/**
|
|
10
15
|
* `createSql` from core with the schema converted from Drizzle definitions:
|
|
11
|
-
* `createSql<typeof schema>()`, or `createSql<typeof schema, PgTypeMap>()` for a driver's type map.
|
|
12
|
-
*
|
|
13
|
-
* `
|
|
16
|
+
* `createSql<typeof schema>(db)`, or `createSql<typeof schema, PgTypeMap>(db)` for a driver's type map.
|
|
17
|
+
* The queries' `execute*` methods run on `db` (a Drizzle database or transaction, on node-postgres
|
|
18
|
+
* or postgres.js), and `sql.transaction(fn)` runs `fn` with a `sql` bound to `db.transaction`.
|
|
14
19
|
*/
|
|
15
|
-
export function createSql<Schema, TM = DefaultTypeMap, Opts extends FromDrizzleOptions = {}>(
|
|
16
|
-
return
|
|
20
|
+
export function createSql<Schema, TM = DefaultTypeMap, Opts extends FromDrizzleOptions = {}>(db?: DrizzleDatabase): DrizzleSql<Schema, TM, Opts> {
|
|
21
|
+
return createTransactionalSql<FromDrizzle<Schema, Opts>, TM, DrizzleDatabase>(db, driver) as DrizzleSql<Schema, TM, Opts>;
|
|
17
22
|
}
|