@typesql/postgres 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 +28 -0
- package/README.md +24 -20
- package/dist/client.d.ts +11 -29
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +22 -58
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +23 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -12
- package/dist/index.js.map +1 -1
- package/dist/type-map.d.ts +22 -1
- package/dist/type-map.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/client.ts +29 -65
- package/src/index.ts +20 -16
- package/src/type-map.ts +23 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @typesql/postgres
|
|
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
|
+
- The README links to the type map tables on the new node-postgres and postgres.js adapter pages of the docs.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies:
|
|
14
|
+
- @typesql/core@0.1.0
|
|
15
|
+
|
|
16
|
+
## 0.0.4
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- Queries have `executeCount()`, which resolves to the affected row count: an `Executor` may resolve to `{ rows, rowCount }` instead of the rows, as the `executor()` of `@typesql/pg`, `@typesql/postgres` and `@typesql/kysely` now do.
|
|
21
|
+
|
|
22
|
+
- `execute(db, q)` resolves to 0 instead of `null` for statements without a count, such as DDL, and `PostgresJsRows["count"]` is `number | null`.
|
|
23
|
+
|
|
24
|
+
- `createSql(executor, { rowKeys: "camelCase" })` (and the adapters' `createSql(client, { rowKeys: "camelCase" })`) camelCases the top-level row keys the way Kysely's `CamelCasePlugin` does, in the row types and in the rows `execute*` and the `query`/`one`/`maybeOne`/`many` helpers return, leaving JSON values untouched.
|
|
25
|
+
|
|
26
|
+
- The type maps declare what parameters accept (`PgParamTypeMap`, `PostgresJsParamTypeMap`), so `int8`/`numeric` parameters take numbers and bigints and timestamp parameters take strings; postgres.js timestamp parameters also take epoch milliseconds.
|
|
27
|
+
|
|
28
|
+
- Updated dependencies:
|
|
29
|
+
- @typesql/core@0.0.4
|
|
30
|
+
|
|
3
31
|
## 0.0.3
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[postgres.js](https://github.com/porsager/postgres) (`postgres` 3.x) adapter for
|
|
4
4
|
[`@typesql/core`](https://www.npmjs.com/package/@typesql/core): a `createSql` bound to the type
|
|
5
|
-
map of postgres.js' default parsers,
|
|
5
|
+
map of postgres.js' default parsers, whose queries run on your `sql` instance and return rows
|
|
6
|
+
typed from the SQL.
|
|
6
7
|
|
|
7
8
|
```sh
|
|
8
9
|
pnpm add @typesql/core @typesql/postgres postgres
|
|
@@ -12,29 +13,29 @@ pnpm add @typesql/core @typesql/postgres postgres
|
|
|
12
13
|
|
|
13
14
|
```ts
|
|
14
15
|
import postgres from "postgres";
|
|
15
|
-
import { createSql
|
|
16
|
+
import { createSql } from "@typesql/postgres";
|
|
16
17
|
import type { DB } from "./schema";
|
|
17
18
|
|
|
18
19
|
const db = postgres(process.env.DATABASE_URL!);
|
|
19
|
-
const sql = createSql<DB>(); // PostgresJsTypeMap
|
|
20
|
+
const sql = createSql<DB>(db); // PostgresJsTypeMap
|
|
20
21
|
|
|
21
|
-
const posts = await
|
|
22
|
+
const posts = await sql("SELECT id, title FROM posts WHERE author_id = $1", 1).execute();
|
|
22
23
|
// { id: string; title: string }[] int8 is a string by default
|
|
23
24
|
|
|
24
|
-
await transaction(
|
|
25
|
-
await
|
|
25
|
+
await sql.transaction(async (tx) => {
|
|
26
|
+
await tx("UPDATE posts SET title = upper(title) WHERE author_id = $1", 1).execute();
|
|
26
27
|
});
|
|
27
28
|
```
|
|
28
29
|
|
|
29
30
|
With bigint parsing enabled on the connection, use `createBigIntSql`:
|
|
30
31
|
|
|
31
32
|
```ts
|
|
32
|
-
import { createBigIntSql
|
|
33
|
+
import { createBigIntSql } from "@typesql/postgres";
|
|
33
34
|
|
|
34
35
|
const dbBig = postgres(process.env.DATABASE_URL!, { types: { bigint: postgres.BigInt } });
|
|
35
|
-
const big = createBigIntSql<DB>(); // PostgresJsBigIntTypeMap
|
|
36
|
+
const big = createBigIntSql<DB>(dbBig); // PostgresJsBigIntTypeMap
|
|
36
37
|
|
|
37
|
-
const counts = await
|
|
38
|
+
const counts = await big("SELECT author_id, count(*) AS n FROM posts GROUP BY author_id").execute();
|
|
38
39
|
// { author_id: number; n: bigint }[]
|
|
39
40
|
```
|
|
40
41
|
|
|
@@ -42,17 +43,15 @@ const counts = await query(dbBig, big("SELECT author_id, count(*) AS n FROM post
|
|
|
42
43
|
|
|
43
44
|
| Export | |
|
|
44
45
|
|---|---|
|
|
45
|
-
| `createSql<DB>()` | core's `createSql<DB, PostgresJsTypeMap>()` |
|
|
46
|
-
| `createBigIntSql<DB>()` |
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `many(db, q)` | `Promise<[Row, ...Row[]]>`; `RowCountError` on zero rows |
|
|
51
|
-
| `execute(db, q)` | `Promise<number>`, the affected row count |
|
|
52
|
-
| `transaction(db, fn)` | `db.begin(fn)` |
|
|
46
|
+
| `createSql<DB>(db, options?)` | core's `createSql<DB, PostgresJsTypeMap>()` with the queries running on `db`; `{ rowKeys: "camelCase" }` camelCases the row keys |
|
|
47
|
+
| `createBigIntSql<DB>(db, options?)` | the same with `PostgresJsBigIntTypeMap`, for `types: { bigint: postgres.BigInt }` |
|
|
48
|
+
| `q.execute()`, `q.executeTakeFirst()`, `q.executeTakeFirstOrThrow()`, `q.executeCount()` | `Promise<Row[]>` (a plain array, result metadata stripped), `Promise<Row \| undefined>`, `Promise<Row>` (`NoResultError` on 0 rows), `Promise<number>` (`.count`, 0 for DDL) |
|
|
49
|
+
| `sql.transaction(fn)` | `db.begin(fn)` with `tx` bound to the transaction; `tx.transaction(fn)` is `savepoint(fn)` |
|
|
50
|
+
| `executor(db)` | an `Executor` for `q.execute(executor)` and core's `createSql(executor)` (reports `.count`) |
|
|
53
51
|
| `migrate(db, m)` | runs `m.statements` (e.g. from core's `migrations()`) in one transaction |
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
52
|
+
| `PostgresJsSql<DB, Keys>`, `PostgresJsBigIntSql<DB, Keys>` | the types `createSql` and `createBigIntSql` return |
|
|
53
|
+
| `PostgresJsTypeMap`, `PostgresJsBigIntTypeMap`, `PostgresJsParamTypeMap` | the type maps (rows), and what parameters also accept |
|
|
54
|
+
| `NoResultError`, `PostgresJsQueryable`, `PostgresJsTransactable`, `PostgresJsRows`, `MigrationSource` | errors and parameter types |
|
|
56
55
|
|
|
57
56
|
Queries run with `db.unsafe(text, values)`, so the text reaches the server unchanged and values
|
|
58
57
|
are bind parameters. `db` is the `Sql` instance, a `TransactionSql` or a `ReservedSql`.
|
|
@@ -72,4 +71,9 @@ postgres.js parses only a few types by default; everything else is the text Post
|
|
|
72
71
|
| `numeric`, `interval`, `point`, text-like and other types | `string` | `string` |
|
|
73
72
|
|
|
74
73
|
Arrays map element-wise. Details in the
|
|
75
|
-
[
|
|
74
|
+
[postgres.js adapter page](https://github.com/ismailkarsli/typesql/blob/main/packages/docs/adapters/postgres.md).
|
|
75
|
+
|
|
76
|
+
Parameters accept the row type and what postgres.js serializes for the type
|
|
77
|
+
(`PostgresJsParamTypeMap`): `number | bigint | string` for `int8`, `numeric` and `money`,
|
|
78
|
+
`Date | string | number` (epoch ms) for dates and timestamps, `string` for `interval`,
|
|
79
|
+
`Uint8Array` for `bytea`.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type { Executor,
|
|
2
|
-
/**
|
|
1
|
+
import type { Executor, SqlDriver } from "@typesql/core";
|
|
2
|
+
/**
|
|
3
|
+
* The shape of a resolved `sql.unsafe()` result the adapter relies on: an array with `count`
|
|
4
|
+
* (`null` for statements without a count, such as DDL).
|
|
5
|
+
*/
|
|
3
6
|
export type PostgresJsRows = readonly unknown[] & {
|
|
4
|
-
readonly count: number;
|
|
7
|
+
readonly count: number | null;
|
|
5
8
|
};
|
|
6
9
|
/**
|
|
7
10
|
* Anything with postgres.js' `unsafe(query, parameters)` method: the `Sql` instance,
|
|
@@ -14,33 +17,13 @@ export interface PostgresJsQueryable {
|
|
|
14
17
|
export interface PostgresJsTransactable<Tx extends PostgresJsQueryable = PostgresJsQueryable> {
|
|
15
18
|
begin(fn: (tx: Tx) => Promise<unknown>): Promise<unknown>;
|
|
16
19
|
}
|
|
17
|
-
/** Thrown by `one`, `maybeOne` and `many` when the row count does not match. */
|
|
18
|
-
export declare class RowCountError extends Error {
|
|
19
|
-
readonly code: "NO_ROWS" | "TOO_MANY_ROWS";
|
|
20
|
-
readonly expected: string;
|
|
21
|
-
readonly actual: number;
|
|
22
|
-
readonly text: string;
|
|
23
|
-
readonly name = "RowCountError";
|
|
24
|
-
constructor(code: "NO_ROWS" | "TOO_MANY_ROWS", expected: string, actual: number, text: string);
|
|
25
|
-
}
|
|
26
|
-
type AnyQuery = Query<unknown, readonly unknown[]>;
|
|
27
|
-
/** An `Executor` for core's `q.execute()`: runs queries through `sql.unsafe` and resolves to the rows. */
|
|
28
|
-
export declare function executor(sql: PostgresJsQueryable): Executor;
|
|
29
|
-
/** Run a query and return all rows (a plain array, without postgres.js' result metadata). */
|
|
30
|
-
export declare function query<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<RowType<Q>[]>;
|
|
31
|
-
/** Exactly one row, otherwise throws `RowCountError`. */
|
|
32
|
-
export declare function one<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<RowType<Q>>;
|
|
33
|
-
/** Zero or one row (`null` for zero); throws `RowCountError` on more than one. */
|
|
34
|
-
export declare function maybeOne<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<RowType<Q> | null>;
|
|
35
|
-
/** At least one row, otherwise throws `RowCountError`. */
|
|
36
|
-
export declare function many<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<[RowType<Q>, ...RowType<Q>[]]>;
|
|
37
|
-
/** Run a statement for its side effect and return the affected row count (postgres.js' `.count`). */
|
|
38
|
-
export declare function execute(sql: PostgresJsQueryable, q: AnyQuery): Promise<number>;
|
|
39
20
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
21
|
+
* An `Executor` for core's `q.execute()`: runs queries through `sql.unsafe` and resolves to
|
|
22
|
+
* `{ rows, rowCount }` (postgres.js' `.count`, so `q.executeCount()` works).
|
|
42
23
|
*/
|
|
43
|
-
export declare function
|
|
24
|
+
export declare function executor(sql: PostgresJsQueryable): Executor;
|
|
25
|
+
/** How `createSql(sql)` runs queries and transactions. */
|
|
26
|
+
export declare const driver: SqlDriver<PostgresJsQueryable>;
|
|
44
27
|
/** Anything carrying an ordered list of DDL statements, e.g. a `migrations()` builder from core. */
|
|
45
28
|
export interface MigrationSource {
|
|
46
29
|
readonly statements: readonly string[];
|
|
@@ -51,5 +34,4 @@ export interface MigrationSource {
|
|
|
51
34
|
* `$$`-quoted function bodies work.
|
|
52
35
|
*/
|
|
53
36
|
export declare function migrate<Tx extends PostgresJsQueryable>(sql: PostgresJsTransactable<Tx>, m: MigrationSource): Promise<void>;
|
|
54
|
-
export {};
|
|
55
37
|
//# 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,KAAK,EAAE,QAAQ,EAAE,
|
|
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,MAAM,cAAc,GAAG,SAAS,OAAO,EAAE,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAEpF;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,OAAO,EAAE,GAAG,WAAW,CAAC,cAAc,CAAC,CAAC;CAC5E;AAED,qFAAqF;AACrF,MAAM,WAAW,sBAAsB,CAAC,EAAE,SAAS,mBAAmB,GAAG,mBAAmB;IAC1F,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AAOD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,mBAAmB,GAAG,QAAQ,CAK3D;AAcD,0DAA0D;AAC1D,eAAO,MAAM,MAAM,EAAE,SAAS,CAAC,mBAAmB,CAA6B,CAAC;AAEhF,oGAAoG;AACpG,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,EAAE,SAAS,mBAAmB,EAAE,GAAG,EAAE,sBAAsB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhI"}
|
package/dist/client.js
CHANGED
|
@@ -1,71 +1,35 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
actual;
|
|
6
|
-
text;
|
|
7
|
-
name = "RowCountError";
|
|
8
|
-
constructor(code, expected, actual, text) {
|
|
9
|
-
super(`Expected ${expected} row(s) but the query returned ${actual}`);
|
|
10
|
-
this.code = code;
|
|
11
|
-
this.expected = expected;
|
|
12
|
-
this.actual = actual;
|
|
13
|
-
this.text = text;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
function run(sql, q) {
|
|
17
|
-
return sql.unsafe(q.text, Array.from(q.values));
|
|
18
|
-
}
|
|
19
|
-
/** An `Executor` for core's `q.execute()`: runs queries through `sql.unsafe` and resolves to the rows. */
|
|
1
|
+
/**
|
|
2
|
+
* An `Executor` for core's `q.execute()`: runs queries through `sql.unsafe` and resolves to
|
|
3
|
+
* `{ rows, rowCount }` (postgres.js' `.count`, so `q.executeCount()` works).
|
|
4
|
+
*/
|
|
20
5
|
export function executor(sql) {
|
|
21
|
-
return async (text, values) =>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const result = await run(sql, q);
|
|
26
|
-
return Array.from(result);
|
|
27
|
-
}
|
|
28
|
-
/** Exactly one row, otherwise throws `RowCountError`. */
|
|
29
|
-
export async function one(sql, q) {
|
|
30
|
-
const rows = await query(sql, q);
|
|
31
|
-
if (rows.length !== 1) {
|
|
32
|
-
throw new RowCountError(rows.length === 0 ? "NO_ROWS" : "TOO_MANY_ROWS", "exactly 1", rows.length, q.text);
|
|
33
|
-
}
|
|
34
|
-
return rows[0];
|
|
35
|
-
}
|
|
36
|
-
/** Zero or one row (`null` for zero); throws `RowCountError` on more than one. */
|
|
37
|
-
export async function maybeOne(sql, q) {
|
|
38
|
-
const rows = await query(sql, q);
|
|
39
|
-
if (rows.length > 1)
|
|
40
|
-
throw new RowCountError("TOO_MANY_ROWS", "at most 1", rows.length, q.text);
|
|
41
|
-
return rows.length === 0 ? null : rows[0];
|
|
42
|
-
}
|
|
43
|
-
/** At least one row, otherwise throws `RowCountError`. */
|
|
44
|
-
export async function many(sql, q) {
|
|
45
|
-
const rows = await query(sql, q);
|
|
46
|
-
if (rows.length === 0)
|
|
47
|
-
throw new RowCountError("NO_ROWS", "at least 1", 0, q.text);
|
|
48
|
-
return rows;
|
|
49
|
-
}
|
|
50
|
-
/** Run a statement for its side effect and return the affected row count (postgres.js' `.count`). */
|
|
51
|
-
export async function execute(sql, q) {
|
|
52
|
-
const result = await run(sql, q);
|
|
53
|
-
return result.count;
|
|
6
|
+
return async (text, values) => {
|
|
7
|
+
const result = await sql.unsafe(text, Array.from(values));
|
|
8
|
+
return { rows: Array.from(result), rowCount: result.count ?? null };
|
|
9
|
+
};
|
|
54
10
|
}
|
|
55
11
|
/**
|
|
56
|
-
* Run `fn` inside `
|
|
57
|
-
*
|
|
12
|
+
* Run `fn` inside a transaction: `tx.savepoint(fn)` on a `TransactionSql` (only those have it),
|
|
13
|
+
* otherwise `sql.begin(fn)`. postgres.js issues BEGIN (or SAVEPOINT), runs the callback with a
|
|
14
|
+
* transaction-bound `sql`, then COMMIT, or ROLLBACK and rethrow when the callback throws.
|
|
58
15
|
*/
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
16
|
+
async function transaction(sql, _depth, fn) {
|
|
17
|
+
const { savepoint, begin } = sql;
|
|
18
|
+
if (savepoint)
|
|
19
|
+
return (await savepoint.call(sql, fn));
|
|
20
|
+
if (begin)
|
|
21
|
+
return (await begin.call(sql, fn));
|
|
22
|
+
throw new Error("typesql: sql.transaction() needs a postgres.js Sql, ReservedSql or TransactionSql (with begin or savepoint)");
|
|
23
|
+
}
|
|
24
|
+
/** How `createSql(sql)` runs queries and transactions. */
|
|
25
|
+
export const driver = { executor, transaction };
|
|
62
26
|
/**
|
|
63
27
|
* Run a migration's statements in order inside one transaction (`sql.begin`), all or nothing.
|
|
64
28
|
* Each statement goes through `unsafe` without parameters (simple protocol), so scripts with
|
|
65
29
|
* `$$`-quoted function bodies work.
|
|
66
30
|
*/
|
|
67
31
|
export async function migrate(sql, m) {
|
|
68
|
-
await
|
|
32
|
+
await sql.begin(async (tx) => {
|
|
69
33
|
for (const statement of m.statements)
|
|
70
34
|
await tx.unsafe(statement);
|
|
71
35
|
});
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAwB;IAC/C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;IACtE,CAAC,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,WAAW,CAAI,GAAwB,EAAE,MAAc,EAAE,EAA2C;IACjH,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,GAAgE,CAAC;IAC9F,IAAI,SAAS;QAAE,OAAO,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAM,CAAC;IAC3D,IAAI,KAAK;QAAE,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAM,CAAC;IACnD,MAAM,IAAI,KAAK,CAAC,6GAA6G,CAAC,CAAC;AACjI,CAAC;AAED,0DAA0D;AAC1D,MAAM,CAAC,MAAM,MAAM,GAAmC,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AAOhF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAiC,GAA+B,EAAE,CAAkB;IAC/G,MAAM,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE;QAC3B,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC,UAAU;YAAE,MAAM,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,30 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RowKeys, type TransactionalSql } from "@typesql/core";
|
|
2
2
|
import { type PostgresJsQueryable } from "./client.js";
|
|
3
3
|
import type { PostgresJsBigIntTypeMap, PostgresJsTypeMap } from "./type-map.js";
|
|
4
|
-
export { NoResultError, type Executor } from "@typesql/core";
|
|
5
|
-
export type { PostgresJsTypeMap, PostgresJsBigIntTypeMap } from "./type-map.js";
|
|
6
|
-
export {
|
|
4
|
+
export { NoResultError, type Executor, type TransactionalSql } from "@typesql/core";
|
|
5
|
+
export type { PostgresJsTypeMap, PostgresJsBigIntTypeMap, PostgresJsParamTypeMap } from "./type-map.js";
|
|
6
|
+
export { executor, migrate, type MigrationSource, type PostgresJsQueryable, type PostgresJsRows, type PostgresJsTransactable, } from "./client.js";
|
|
7
|
+
/** What `createSql<DB>(sql)` returns: core's `Sql` under `PostgresJsTypeMap`, with `transaction(fn)`. */
|
|
8
|
+
export type PostgresJsSql<DB, Keys extends RowKeys = "preserve"> = TransactionalSql<DB, PostgresJsTypeMap, Keys>;
|
|
9
|
+
/** What `createBigIntSql<DB>(sql)` returns: core's `Sql` under `PostgresJsBigIntTypeMap`, with `transaction(fn)`. */
|
|
10
|
+
export type PostgresJsBigIntSql<DB, Keys extends RowKeys = "preserve"> = TransactionalSql<DB, PostgresJsBigIntTypeMap, Keys>;
|
|
7
11
|
/**
|
|
8
12
|
* `createSql<DB>()` from core, pre-bound to `PostgresJsTypeMap` (default parsers: `int8` and `count(*)` are `string`).
|
|
9
|
-
*
|
|
13
|
+
* The queries' `execute*` methods run on the postgres.js `sql` instance (or a `TransactionSql`,
|
|
14
|
+
* `ReservedSql`), and `sql.transaction(fn)` runs `fn` with a `sql` bound to one transaction.
|
|
15
|
+
* `{ rowKeys: "camelCase" }` camelCases the rows' keys, in the types and at runtime.
|
|
10
16
|
*/
|
|
11
|
-
export declare function createSql<DB>(sql
|
|
17
|
+
export declare function createSql<DB>(sql: PostgresJsQueryable | undefined, options: {
|
|
18
|
+
readonly rowKeys: "camelCase";
|
|
19
|
+
}): PostgresJsSql<DB, "camelCase">;
|
|
20
|
+
export declare function createSql<DB>(sql?: PostgresJsQueryable, options?: {
|
|
21
|
+
readonly rowKeys?: "preserve";
|
|
22
|
+
}): PostgresJsSql<DB>;
|
|
12
23
|
/** For `postgres({ types: { bigint: postgres.BigInt } })` connections: `int8` and `count(*)` are `bigint`. */
|
|
13
|
-
export declare function createBigIntSql<DB>(sql
|
|
24
|
+
export declare function createBigIntSql<DB>(sql: PostgresJsQueryable | undefined, options: {
|
|
25
|
+
readonly rowKeys: "camelCase";
|
|
26
|
+
}): PostgresJsBigIntSql<DB, "camelCase">;
|
|
27
|
+
export declare function createBigIntSql<DB>(sql?: PostgresJsQueryable, options?: {
|
|
28
|
+
readonly rowKeys?: "preserve";
|
|
29
|
+
}): PostgresJsBigIntSql<DB>;
|
|
14
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,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAU,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACpF,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACxG,OAAO,EACL,QAAQ,EACR,OAAO,EACP,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,sBAAsB,GAC5B,MAAM,aAAa,CAAC;AAErB,yGAAyG;AACzG,MAAM,MAAM,aAAa,CAAC,EAAE,EAAE,IAAI,SAAS,OAAO,GAAG,UAAU,IAAI,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,CAAC,CAAC;AACjH,qHAAqH;AACrH,MAAM,MAAM,mBAAmB,CAAC,EAAE,EAAE,IAAI,SAAS,OAAO,GAAG,UAAU,IAAI,gBAAgB,CAAC,EAAE,EAAE,uBAAuB,EAAE,IAAI,CAAC,CAAC;AAE7H;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,GAAG,EAAE,mBAAmB,GAAG,SAAS,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,aAAa,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;AAChJ,wBAAgB,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAA;CAAE,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;AAKzH,8GAA8G;AAC9G,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,EAAE,mBAAmB,GAAG,SAAS,EAAE,OAAO,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;CAAE,GAAG,mBAAmB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;AAC5J,wBAAgB,eAAe,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,mBAAmB,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,UAAU,CAAA;CAAE,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
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 {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* With a postgres.js `sql` instance, the queries' `execute*` methods run on it.
|
|
8
|
-
*/
|
|
9
|
-
export function createSql(sql) {
|
|
10
|
-
return createCoreSql(sql && executor(sql));
|
|
4
|
+
export { executor, migrate, } from "./client.js";
|
|
5
|
+
export function createSql(sql, options) {
|
|
6
|
+
return createTransactionalSql(sql, driver, options);
|
|
11
7
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return createCoreSql(sql && executor(sql));
|
|
8
|
+
export function createBigIntSql(sql, options) {
|
|
9
|
+
return createTransactionalSql(sql, driver, options);
|
|
15
10
|
}
|
|
16
11
|
//# 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,EAAwD,MAAM,eAAe,CAAC;AAC7G,OAAO,EAAE,MAAM,EAA4B,MAAM,aAAa,CAAC;AAG/D,OAAO,EAAE,aAAa,EAAwC,MAAM,eAAe,CAAC;AAEpF,OAAO,EACL,QAAQ,EACR,OAAO,GAKR,MAAM,aAAa,CAAC;AAerB,MAAM,UAAU,SAAS,CAAK,GAAyB,EAAE,OAAoB;IAC3E,OAAO,sBAAsB,CAA6C,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAClG,CAAC;AAKD,MAAM,UAAU,eAAe,CAAK,GAAyB,EAAE,OAAoB;IACjF,OAAO,sBAAsB,CAAmD,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACxG,CAAC"}
|
package/dist/type-map.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DefaultTypeMap } from "@typesql/core";
|
|
1
|
+
import type { DefaultParamTypeMap, DefaultTypeMap } from "@typesql/core";
|
|
2
2
|
/**
|
|
3
3
|
* Canonical Postgres type name → TS type as postgres.js 3.x returns it with its default
|
|
4
4
|
* parsers. Verified against `postgres/src/types.js` (3.4.9), which parses only:
|
|
@@ -22,6 +22,8 @@ import type { DefaultTypeMap } from "@typesql/core";
|
|
|
22
22
|
* element-type[] mapping is exact (int8[] → string[], timestamptz[] → Date[], ...).
|
|
23
23
|
*/
|
|
24
24
|
export interface PostgresJsTypeMap extends Omit<DefaultTypeMap, "bytea" | "interval" | "point" | "circle" | "record" | "void"> {
|
|
25
|
+
/** What parameters accept on top of the row types. */
|
|
26
|
+
$params: PostgresJsParamTypeMap;
|
|
25
27
|
bytea: Buffer;
|
|
26
28
|
/** No default parser: the Postgres text form, e.g. `"1 day 02:00:00"`. */
|
|
27
29
|
interval: string;
|
|
@@ -34,6 +36,25 @@ export interface PostgresJsTypeMap extends Omit<DefaultTypeMap, "bytea" | "inter
|
|
|
34
36
|
/** `void`-returning functions (`pg_sleep`) yield an empty string. */
|
|
35
37
|
void: string;
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* TS types postgres.js parameters accept on top of the row type
|
|
41
|
+
* (`PostgresJsTypeMap["$params"]`). Verified against `postgres/src/types.js` and `Bind` in
|
|
42
|
+
* `connection.js` (3.4.9): a value is serialized by the serializer of the parameter type the
|
|
43
|
+
* server reports, and types without one (int8, numeric, money, interval, …) with `'' + x`.
|
|
44
|
+
*
|
|
45
|
+
* int8, numeric, money number | bigint | string
|
|
46
|
+
* date, timestamp, timestamptz Date | string | number: serialized as `new Date(x).toISOString()`,
|
|
47
|
+
* so a string must be one JS `Date` parses, a number is epoch ms
|
|
48
|
+
* interval string
|
|
49
|
+
* bytea Uint8Array, besides `Buffer`
|
|
50
|
+
*
|
|
51
|
+
* `bool` takes only booleans: its serializer sends `'f'` for anything but `true`.
|
|
52
|
+
*/
|
|
53
|
+
export interface PostgresJsParamTypeMap extends Omit<DefaultParamTypeMap, "date" | "timestamp" | "timestamptz"> {
|
|
54
|
+
date: Date | string | number;
|
|
55
|
+
timestamp: Date | string | number;
|
|
56
|
+
timestamptz: Date | string | number;
|
|
57
|
+
}
|
|
37
58
|
/**
|
|
38
59
|
* Type map for connections created with `postgres({ types: { bigint: postgres.BigInt } })`,
|
|
39
60
|
* which registers a parser for int8 (20) that returns JS `bigint`. `count(*)`, `sum(int4)`
|
package/dist/type-map.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type-map.d.ts","sourceRoot":"","sources":["../src/type-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"type-map.d.ts","sourceRoot":"","sources":["../src/type-map.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEzE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,cAAc,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC5H,sDAAsD;IACtD,OAAO,EAAE,sBAAsB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC;IAC7G,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAC7B,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC,WAAW,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;CACrC;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAC9E,IAAI,EAAE,MAAM,CAAC;CACd"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typesql/postgres",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "postgres.js adapter for typesql.",
|
|
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
|
"postgres": ">=3"
|
package/src/client.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import type { Executor,
|
|
1
|
+
import type { Executor, SqlDriver } from "@typesql/core";
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* The shape of a resolved `sql.unsafe()` result the adapter relies on: an array with `count`
|
|
5
|
+
* (`null` for statements without a count, such as DDL).
|
|
6
|
+
*/
|
|
7
|
+
export type PostgresJsRows = readonly unknown[] & { readonly count: number | null };
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* Anything with postgres.js' `unsafe(query, parameters)` method: the `Sql` instance,
|
|
@@ -16,76 +19,37 @@ export interface PostgresJsTransactable<Tx extends PostgresJsQueryable = Postgre
|
|
|
16
19
|
begin(fn: (tx: Tx) => Promise<unknown>): Promise<unknown>;
|
|
17
20
|
}
|
|
18
21
|
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
constructor(
|
|
23
|
-
readonly code: "NO_ROWS" | "TOO_MANY_ROWS",
|
|
24
|
-
readonly expected: string,
|
|
25
|
-
readonly actual: number,
|
|
26
|
-
readonly text: string,
|
|
27
|
-
) {
|
|
28
|
-
super(`Expected ${expected} row(s) but the query returned ${actual}`);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
type AnyQuery = Query<unknown, readonly unknown[]>;
|
|
33
|
-
|
|
34
|
-
function run(sql: PostgresJsQueryable, q: AnyQuery): PromiseLike<PostgresJsRows> {
|
|
35
|
-
return sql.unsafe(q.text, Array.from(q.values));
|
|
22
|
+
/** A `TransactionSql`'s `savepoint(fn)`. */
|
|
23
|
+
interface PostgresJsSavepointable {
|
|
24
|
+
savepoint(fn: (tx: PostgresJsQueryable) => Promise<unknown>): Promise<unknown>;
|
|
36
25
|
}
|
|
37
26
|
|
|
38
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* An `Executor` for core's `q.execute()`: runs queries through `sql.unsafe` and resolves to
|
|
29
|
+
* `{ rows, rowCount }` (postgres.js' `.count`, so `q.executeCount()` works).
|
|
30
|
+
*/
|
|
39
31
|
export function executor(sql: PostgresJsQueryable): Executor {
|
|
40
|
-
return async (text, values) =>
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
export async function query<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<RowType<Q>[]> {
|
|
45
|
-
const result = await run(sql, q);
|
|
46
|
-
return Array.from(result) as RowType<Q>[];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/** Exactly one row, otherwise throws `RowCountError`. */
|
|
50
|
-
export async function one<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<RowType<Q>> {
|
|
51
|
-
const rows = await query(sql, q);
|
|
52
|
-
if (rows.length !== 1) {
|
|
53
|
-
throw new RowCountError(rows.length === 0 ? "NO_ROWS" : "TOO_MANY_ROWS", "exactly 1", rows.length, q.text);
|
|
54
|
-
}
|
|
55
|
-
return rows[0] as RowType<Q>;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Zero or one row (`null` for zero); throws `RowCountError` on more than one. */
|
|
59
|
-
export async function maybeOne<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<RowType<Q> | null> {
|
|
60
|
-
const rows = await query(sql, q);
|
|
61
|
-
if (rows.length > 1) throw new RowCountError("TOO_MANY_ROWS", "at most 1", rows.length, q.text);
|
|
62
|
-
return rows.length === 0 ? null : (rows[0] as RowType<Q>);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** At least one row, otherwise throws `RowCountError`. */
|
|
66
|
-
export async function many<Q extends AnyQuery>(sql: PostgresJsQueryable, q: Q): Promise<[RowType<Q>, ...RowType<Q>[]]> {
|
|
67
|
-
const rows = await query(sql, q);
|
|
68
|
-
if (rows.length === 0) throw new RowCountError("NO_ROWS", "at least 1", 0, q.text);
|
|
69
|
-
return rows as [RowType<Q>, ...RowType<Q>[]];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** Run a statement for its side effect and return the affected row count (postgres.js' `.count`). */
|
|
73
|
-
export async function execute(sql: PostgresJsQueryable, q: AnyQuery): Promise<number> {
|
|
74
|
-
const result = await run(sql, q);
|
|
75
|
-
return result.count;
|
|
32
|
+
return async (text, values) => {
|
|
33
|
+
const result = await sql.unsafe(text, Array.from(values));
|
|
34
|
+
return { rows: Array.from(result), rowCount: result.count ?? null };
|
|
35
|
+
};
|
|
76
36
|
}
|
|
77
37
|
|
|
78
38
|
/**
|
|
79
|
-
* Run `fn` inside `
|
|
80
|
-
*
|
|
39
|
+
* Run `fn` inside a transaction: `tx.savepoint(fn)` on a `TransactionSql` (only those have it),
|
|
40
|
+
* otherwise `sql.begin(fn)`. postgres.js issues BEGIN (or SAVEPOINT), runs the callback with a
|
|
41
|
+
* transaction-bound `sql`, then COMMIT, or ROLLBACK and rethrow when the callback throws.
|
|
81
42
|
*/
|
|
82
|
-
|
|
83
|
-
sql
|
|
84
|
-
|
|
85
|
-
)
|
|
86
|
-
|
|
43
|
+
async function transaction<T>(sql: PostgresJsQueryable, _depth: number, fn: (tx: PostgresJsQueryable) => Promise<T>): Promise<T> {
|
|
44
|
+
const { savepoint, begin } = sql as Partial<PostgresJsSavepointable & PostgresJsTransactable>;
|
|
45
|
+
if (savepoint) return (await savepoint.call(sql, fn)) as T;
|
|
46
|
+
if (begin) return (await begin.call(sql, fn)) as T;
|
|
47
|
+
throw new Error("typesql: sql.transaction() needs a postgres.js Sql, ReservedSql or TransactionSql (with begin or savepoint)");
|
|
87
48
|
}
|
|
88
49
|
|
|
50
|
+
/** How `createSql(sql)` runs queries and transactions. */
|
|
51
|
+
export const driver: SqlDriver<PostgresJsQueryable> = { executor, transaction };
|
|
52
|
+
|
|
89
53
|
/** Anything carrying an ordered list of DDL statements, e.g. a `migrations()` builder from core. */
|
|
90
54
|
export interface MigrationSource {
|
|
91
55
|
readonly statements: readonly string[];
|
|
@@ -97,7 +61,7 @@ export interface MigrationSource {
|
|
|
97
61
|
* `$$`-quoted function bodies work.
|
|
98
62
|
*/
|
|
99
63
|
export async function migrate<Tx extends PostgresJsQueryable>(sql: PostgresJsTransactable<Tx>, m: MigrationSource): Promise<void> {
|
|
100
|
-
await
|
|
64
|
+
await sql.begin(async (tx) => {
|
|
101
65
|
for (const statement of m.statements) await tx.unsafe(statement);
|
|
102
66
|
});
|
|
103
67
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,34 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { createTransactionalSql, type RowKeys, type SqlOptions, type TransactionalSql } from "@typesql/core";
|
|
2
|
+
import { driver, type PostgresJsQueryable } from "./client.js";
|
|
3
3
|
import type { PostgresJsBigIntTypeMap, PostgresJsTypeMap } from "./type-map.js";
|
|
4
4
|
|
|
5
|
-
export { NoResultError, type Executor } from "@typesql/core";
|
|
6
|
-
export type { PostgresJsTypeMap, PostgresJsBigIntTypeMap } from "./type-map.js";
|
|
5
|
+
export { NoResultError, type Executor, type TransactionalSql } from "@typesql/core";
|
|
6
|
+
export type { PostgresJsTypeMap, PostgresJsBigIntTypeMap, PostgresJsParamTypeMap } from "./type-map.js";
|
|
7
7
|
export {
|
|
8
|
-
query,
|
|
9
|
-
one,
|
|
10
|
-
maybeOne,
|
|
11
|
-
many,
|
|
12
|
-
execute,
|
|
13
8
|
executor,
|
|
14
|
-
transaction,
|
|
15
9
|
migrate,
|
|
16
10
|
type MigrationSource,
|
|
17
|
-
RowCountError,
|
|
18
11
|
type PostgresJsQueryable,
|
|
19
12
|
type PostgresJsRows,
|
|
20
13
|
type PostgresJsTransactable,
|
|
21
14
|
} from "./client.js";
|
|
22
15
|
|
|
16
|
+
/** What `createSql<DB>(sql)` returns: core's `Sql` under `PostgresJsTypeMap`, with `transaction(fn)`. */
|
|
17
|
+
export type PostgresJsSql<DB, Keys extends RowKeys = "preserve"> = TransactionalSql<DB, PostgresJsTypeMap, Keys>;
|
|
18
|
+
/** What `createBigIntSql<DB>(sql)` returns: core's `Sql` under `PostgresJsBigIntTypeMap`, with `transaction(fn)`. */
|
|
19
|
+
export type PostgresJsBigIntSql<DB, Keys extends RowKeys = "preserve"> = TransactionalSql<DB, PostgresJsBigIntTypeMap, Keys>;
|
|
20
|
+
|
|
23
21
|
/**
|
|
24
22
|
* `createSql<DB>()` from core, pre-bound to `PostgresJsTypeMap` (default parsers: `int8` and `count(*)` are `string`).
|
|
25
|
-
*
|
|
23
|
+
* The queries' `execute*` methods run on the postgres.js `sql` instance (or a `TransactionSql`,
|
|
24
|
+
* `ReservedSql`), and `sql.transaction(fn)` runs `fn` with a `sql` bound to one transaction.
|
|
25
|
+
* `{ rowKeys: "camelCase" }` camelCases the rows' keys, in the types and at runtime.
|
|
26
26
|
*/
|
|
27
|
-
export function createSql<DB>(sql
|
|
28
|
-
|
|
27
|
+
export function createSql<DB>(sql: PostgresJsQueryable | undefined, options: { readonly rowKeys: "camelCase" }): PostgresJsSql<DB, "camelCase">;
|
|
28
|
+
export function createSql<DB>(sql?: PostgresJsQueryable, options?: { readonly rowKeys?: "preserve" }): PostgresJsSql<DB>;
|
|
29
|
+
export function createSql<DB>(sql?: PostgresJsQueryable, options?: SqlOptions): PostgresJsSql<DB, RowKeys> {
|
|
30
|
+
return createTransactionalSql<DB, PostgresJsTypeMap, PostgresJsQueryable>(sql, driver, options);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
/** For `postgres({ types: { bigint: postgres.BigInt } })` connections: `int8` and `count(*)` are `bigint`. */
|
|
32
|
-
export function createBigIntSql<DB>(sql
|
|
33
|
-
|
|
34
|
+
export function createBigIntSql<DB>(sql: PostgresJsQueryable | undefined, options: { readonly rowKeys: "camelCase" }): PostgresJsBigIntSql<DB, "camelCase">;
|
|
35
|
+
export function createBigIntSql<DB>(sql?: PostgresJsQueryable, options?: { readonly rowKeys?: "preserve" }): PostgresJsBigIntSql<DB>;
|
|
36
|
+
export function createBigIntSql<DB>(sql?: PostgresJsQueryable, options?: SqlOptions): PostgresJsBigIntSql<DB, RowKeys> {
|
|
37
|
+
return createTransactionalSql<DB, PostgresJsBigIntTypeMap, PostgresJsQueryable>(sql, driver, options);
|
|
34
38
|
}
|
package/src/type-map.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DefaultTypeMap } from "@typesql/core";
|
|
1
|
+
import type { DefaultParamTypeMap, DefaultTypeMap } from "@typesql/core";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Canonical Postgres type name → TS type as postgres.js 3.x returns it with its default
|
|
@@ -23,6 +23,8 @@ import type { DefaultTypeMap } from "@typesql/core";
|
|
|
23
23
|
* element-type[] mapping is exact (int8[] → string[], timestamptz[] → Date[], ...).
|
|
24
24
|
*/
|
|
25
25
|
export interface PostgresJsTypeMap extends Omit<DefaultTypeMap, "bytea" | "interval" | "point" | "circle" | "record" | "void"> {
|
|
26
|
+
/** What parameters accept on top of the row types. */
|
|
27
|
+
$params: PostgresJsParamTypeMap;
|
|
26
28
|
bytea: Buffer;
|
|
27
29
|
/** No default parser: the Postgres text form, e.g. `"1 day 02:00:00"`. */
|
|
28
30
|
interval: string;
|
|
@@ -36,6 +38,26 @@ export interface PostgresJsTypeMap extends Omit<DefaultTypeMap, "bytea" | "inter
|
|
|
36
38
|
void: string;
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
/**
|
|
42
|
+
* TS types postgres.js parameters accept on top of the row type
|
|
43
|
+
* (`PostgresJsTypeMap["$params"]`). Verified against `postgres/src/types.js` and `Bind` in
|
|
44
|
+
* `connection.js` (3.4.9): a value is serialized by the serializer of the parameter type the
|
|
45
|
+
* server reports, and types without one (int8, numeric, money, interval, …) with `'' + x`.
|
|
46
|
+
*
|
|
47
|
+
* int8, numeric, money number | bigint | string
|
|
48
|
+
* date, timestamp, timestamptz Date | string | number: serialized as `new Date(x).toISOString()`,
|
|
49
|
+
* so a string must be one JS `Date` parses, a number is epoch ms
|
|
50
|
+
* interval string
|
|
51
|
+
* bytea Uint8Array, besides `Buffer`
|
|
52
|
+
*
|
|
53
|
+
* `bool` takes only booleans: its serializer sends `'f'` for anything but `true`.
|
|
54
|
+
*/
|
|
55
|
+
export interface PostgresJsParamTypeMap extends Omit<DefaultParamTypeMap, "date" | "timestamp" | "timestamptz"> {
|
|
56
|
+
date: Date | string | number;
|
|
57
|
+
timestamp: Date | string | number;
|
|
58
|
+
timestamptz: Date | string | number;
|
|
59
|
+
}
|
|
60
|
+
|
|
39
61
|
/**
|
|
40
62
|
* Type map for connections created with `postgres({ types: { bigint: postgres.BigInt } })`,
|
|
41
63
|
* which registers a parser for int8 (20) that returns JS `bigint`. `count(*)`, `sum(int4)`
|