@typesql/drizzle 0.0.4 → 0.1.1
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 +20 -0
- package/README.md +54 -15
- 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/from-drizzle.d.ts +1 -1
- 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 +7 -4
- package/src/client.ts +52 -0
- package/src/from-drizzle.ts +1 -1
- package/src/index.ts +12 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @typesql/drizzle
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Docs, package descriptions and error messages spell the project name TypeSQL.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @typesql/core@0.1.1
|
|
11
|
+
|
|
12
|
+
## 0.1.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- `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`.
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Updated dependencies:
|
|
21
|
+
- @typesql/core@0.1.0
|
|
22
|
+
|
|
3
23
|
## 0.0.4
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @typesql/drizzle
|
|
2
2
|
|
|
3
|
-
Use your Drizzle ORM schema as a
|
|
3
|
+
Use your Drizzle ORM schema as a TypeSQL schema. `FromDrizzle<typeof schema>` turns
|
|
4
4
|
`pgTable`, `pgView`, `pgMaterializedView`, `pgEnum` and `pgSchema` definitions into the
|
|
5
5
|
`DB` type that `createSql` expects, entirely at the type level: no code generation, and the
|
|
6
6
|
SQL you write is checked against the same tables Drizzle manages.
|
|
@@ -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
|
|
@@ -74,7 +113,7 @@ tables (`FromDrizzle<{ users: typeof users; posts: typeof posts }>`).
|
|
|
74
113
|
|
|
75
114
|
## What gets converted
|
|
76
115
|
|
|
77
|
-
| Drizzle |
|
|
116
|
+
| Drizzle | TypeSQL |
|
|
78
117
|
|---|---|
|
|
79
118
|
| `pgTable("users", …)` | `DB["users"]`, keyed by the SQL table name, not the export name |
|
|
80
119
|
| `displayName: text("display_name")` | column `display_name`; columns without an explicit name use the key |
|
|
@@ -89,7 +128,7 @@ tables (`FromDrizzle<{ users: typeof users; posts: typeof posts }>`).
|
|
|
89
128
|
## Column types
|
|
90
129
|
|
|
91
130
|
The Postgres type comes from Drizzle's column kind. Drizzle's `mode` options change the JS
|
|
92
|
-
value Drizzle produces, but
|
|
131
|
+
value Drizzle produces, but TypeSQL queries go straight to the driver, so the row type comes
|
|
93
132
|
from the type map: `bigint({ mode: "number" })` is `int8`, a `string` under node-postgres.
|
|
94
133
|
|
|
95
134
|
| Drizzle | Postgres |
|
|
@@ -118,7 +157,7 @@ from the type map: `bigint({ mode: "number" })` is `int8`, a `string` under node
|
|
|
118
157
|
| `customType(…)` | `unknown`, unless pinned with `pgType` |
|
|
119
158
|
| `.array()`, `.array().array()` | `T[]`, `T[][]` |
|
|
120
159
|
|
|
121
|
-
Types
|
|
160
|
+
Types TypeSQL has no TS mapping for (`geometry`, `vector`, …) read as `unknown` unless your
|
|
122
161
|
type map has an entry for them.
|
|
123
162
|
|
|
124
163
|
### `timestamp` with time zone, and other types Drizzle's types do not record
|
|
@@ -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,14 +202,14 @@ 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
|
|
|
170
209
|
## Limitations
|
|
171
210
|
|
|
172
211
|
- **Generated-always columns** (`generatedAlwaysAs`, `generatedAlwaysAsIdentity`) are treated
|
|
173
|
-
as columns with a default.
|
|
212
|
+
as columns with a default. TypeSQL has no read-only columns, so an `INSERT` that sets one
|
|
174
213
|
type-checks but fails in Postgres (unless `OVERRIDING SYSTEM VALUE` for identities).
|
|
175
214
|
- **`$onUpdate` / `$onUpdateFn`** mark the column as having a default in Drizzle's types, with
|
|
176
215
|
no way to tell them from a SQL default, so such a column is optional in `INSERT` even
|
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/from-drizzle.d.ts
CHANGED
|
@@ -150,7 +150,7 @@ type Flat<T> = {
|
|
|
150
150
|
[K in keyof T]: T[K];
|
|
151
151
|
} & {};
|
|
152
152
|
/**
|
|
153
|
-
* A
|
|
153
|
+
* A TypeSQL schema from Drizzle `pg-core` definitions: `FromDrizzle<typeof schema>` with
|
|
154
154
|
* `import * as schema from "./schema"`. Also accepts a record of tables or a single table.
|
|
155
155
|
*
|
|
156
156
|
* Keys are SQL names (tables, columns, `pgSchema` namespaces); views become `View<…>`;
|
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,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typesql/drizzle",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Use Drizzle ORM table definitions as a
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Use Drizzle ORM table definitions as a TypeSQL schema.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -28,14 +28,17 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@typesql/core": "0.
|
|
31
|
+
"@typesql/core": "0.1.1"
|
|
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.1",
|
|
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/from-drizzle.ts
CHANGED
|
@@ -145,7 +145,7 @@ type Build<S, Opts, E = Enums<S>> =
|
|
|
145
145
|
type Flat<T> = { [K in keyof T]: T[K] } & {};
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
|
-
* A
|
|
148
|
+
* A TypeSQL schema from Drizzle `pg-core` definitions: `FromDrizzle<typeof schema>` with
|
|
149
149
|
* `import * as schema from "./schema"`. Also accepts a record of tables or a single table.
|
|
150
150
|
*
|
|
151
151
|
* Keys are SQL names (tables, columns, `pgSchema` namespaces); views become `View<…>`;
|
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
|
}
|