@coffre/db 0.14.4 → 0.15.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.
Files changed (218) hide show
  1. package/README.md +2 -1
  2. package/dist/change-records-_fKvahvs.js +55 -0
  3. package/dist/connect.d.ts +22 -10
  4. package/dist/connect.js +74 -12
  5. package/dist/database-CVteLhp1.d.ts +410 -0
  6. package/dist/{database-BadNeeN-.js → database-D55ENPX-.js} +46 -25
  7. package/dist/dialect.d.ts +4 -3
  8. package/dist/dialect.js +14 -5
  9. package/dist/grants.d.ts +4 -4
  10. package/dist/grants.js +4 -4
  11. package/dist/hyperdrive.d.ts +48 -23
  12. package/dist/hyperdrive.js +168 -91
  13. package/dist/index.d.ts +3 -3
  14. package/dist/index.js +1 -1
  15. package/dist/log-DaD7fyUq.d.ts +722 -0
  16. package/dist/log.d.ts +2 -596
  17. package/dist/log.js +224 -10
  18. package/dist/migrate.d.ts +43 -3
  19. package/dist/migrate.js +149 -29
  20. package/dist/migrations/postgres/0021_prune_vault_releases.sql +19 -0
  21. package/dist/migrations/postgres/0022_log_015.sql +672 -0
  22. package/dist/migrations/postgres/0023_change_path.sql +153 -0
  23. package/dist/migrations/postgres/0024_use_015.sql +556 -0
  24. package/dist/migrations/postgres/0025_app_change.sql +221 -0
  25. package/dist/migrations/postgres/0026_issue_lock.sql +106 -0
  26. package/dist/migrations/postgres/0027_retention.sql +118 -0
  27. package/dist/migrations/postgres/0028_use_stalls.sql +594 -0
  28. package/dist/migrations/postgres/0029_use_objects.sql +887 -0
  29. package/dist/migrations/postgres/0030_unarchive_restores.sql +259 -0
  30. package/dist/migrations/postgres/0031_app_read.sql +65 -0
  31. package/dist/migrations/postgres/0032_secrets_live_index.sql +4 -0
  32. package/dist/migrations/postgres/0033_use_generations.sql +582 -0
  33. package/dist/migrations/postgres/0034_vault_credentials.sql +153 -0
  34. package/dist/migrations/postgres/0035_first_days.sql +3 -0
  35. package/dist/migrations/postgres/0036_vault_issues.sql +91 -0
  36. package/dist/migrations/postgres/0037_vault_bindings.sql +271 -0
  37. package/dist/migrations/postgres/0040_binding_origin.sql +159 -0
  38. package/dist/migrations/postgres/0041_cutover.sql +132 -0
  39. package/dist/migrations/postgres/0042_sign_in_index.sql +7 -0
  40. package/dist/migrations/postgres/0043_issue_revoke_index.sql +4 -0
  41. package/dist/migrations/postgres/0044_use_by_name.sql +705 -0
  42. package/dist/migrations/postgres/0045_decide_first.sql +878 -0
  43. package/dist/migrations/postgres/0046_way_in_uses.sql +1149 -0
  44. package/dist/migrations/postgres/0047_cutover_finish.sql +268 -0
  45. package/dist/migrations/postgres/0048_use_batch.sql +59 -0
  46. package/dist/migrations/postgres/0049_reads.sql +171 -0
  47. package/dist/migrations/postgres/meta/0021_snapshot.json +3334 -0
  48. package/dist/migrations/postgres/meta/0022_snapshot.json +3831 -0
  49. package/dist/migrations/postgres/meta/0023_snapshot.json +3831 -0
  50. package/dist/migrations/postgres/meta/0024_snapshot.json +3831 -0
  51. package/dist/migrations/postgres/meta/0025_snapshot.json +3831 -0
  52. package/dist/migrations/postgres/meta/0026_snapshot.json +3831 -0
  53. package/dist/migrations/postgres/meta/0027_snapshot.json +3853 -0
  54. package/dist/migrations/postgres/meta/0028_snapshot.json +3853 -0
  55. package/dist/migrations/postgres/meta/0029_snapshot.json +3859 -0
  56. package/dist/migrations/postgres/meta/0030_snapshot.json +3859 -0
  57. package/dist/migrations/postgres/meta/0031_snapshot.json +3859 -0
  58. package/dist/migrations/postgres/meta/0032_snapshot.json +3875 -0
  59. package/dist/migrations/postgres/meta/0033_snapshot.json +3875 -0
  60. package/dist/migrations/postgres/meta/0034_snapshot.json +3875 -0
  61. package/dist/migrations/postgres/meta/0035_snapshot.json +3875 -0
  62. package/dist/migrations/postgres/meta/0036_snapshot.json +3875 -0
  63. package/dist/migrations/postgres/meta/0037_snapshot.json +3875 -0
  64. package/dist/migrations/postgres/meta/0038_snapshot.json +3881 -0
  65. package/dist/migrations/postgres/meta/0039_snapshot.json +3881 -0
  66. package/dist/migrations/postgres/meta/0040_snapshot.json +3931 -0
  67. package/dist/migrations/postgres/meta/0041_snapshot.json +3981 -0
  68. package/dist/migrations/postgres/meta/0042_snapshot.json +3981 -0
  69. package/dist/migrations/postgres/meta/0043_snapshot.json +3981 -0
  70. package/dist/migrations/postgres/meta/0044_snapshot.json +3991 -0
  71. package/dist/migrations/postgres/meta/0045_snapshot.json +3997 -0
  72. package/dist/migrations/postgres/meta/0046_snapshot.json +3997 -0
  73. package/dist/migrations/postgres/meta/0047_snapshot.json +4234 -0
  74. package/dist/migrations/postgres/meta/_journal.json +189 -0
  75. package/dist/migrations/sqlite/0018_log_015.sql +84 -0
  76. package/dist/migrations/sqlite/0019_retention.sql +2 -0
  77. package/dist/migrations/sqlite/0020_ended_references.sql +1 -0
  78. package/dist/migrations/sqlite/0021_secrets_live_index.sql +1 -0
  79. package/dist/migrations/sqlite/0022_binding_origin.sql +1 -0
  80. package/dist/migrations/sqlite/0023_sign_in_index.sql +2 -0
  81. package/dist/migrations/sqlite/0024_issue_revoke_index.sql +2 -0
  82. package/dist/migrations/sqlite/0025_way_in_uses.sql +42 -0
  83. package/dist/migrations/sqlite/0026_cutover_finish.sql +11 -0
  84. package/dist/migrations/sqlite/0027_reads.sql +38 -0
  85. package/dist/migrations/sqlite/meta/0018_snapshot.json +3529 -0
  86. package/dist/migrations/sqlite/meta/0019_snapshot.json +3538 -0
  87. package/dist/migrations/sqlite/meta/0020_snapshot.json +3545 -0
  88. package/dist/migrations/sqlite/meta/0021_snapshot.json +3553 -0
  89. package/dist/migrations/sqlite/meta/0022_snapshot.json +3560 -0
  90. package/dist/migrations/sqlite/meta/0023_snapshot.json +3579 -0
  91. package/dist/migrations/sqlite/meta/0024_snapshot.json +3598 -0
  92. package/dist/migrations/sqlite/meta/0025_snapshot.json +3609 -0
  93. package/dist/migrations/sqlite/meta/0026_snapshot.json +3616 -0
  94. package/dist/migrations/sqlite/meta/0027_snapshot.json +3834 -0
  95. package/dist/migrations/sqlite/meta/_journal.json +70 -0
  96. package/dist/platform-Y3gICK6n.d.ts +58 -0
  97. package/dist/portable.d.ts +2 -2
  98. package/dist/postgres-BI3xTnyw.js +1718 -0
  99. package/dist/postgres-platform-node.d.ts +14 -0
  100. package/dist/postgres-platform-node.js +21 -0
  101. package/dist/postgres-platform-workerd.d.ts +61 -0
  102. package/dist/postgres-platform-workerd.js +163 -0
  103. package/dist/{schema-z8GcN_Xu.d.ts → schema-DgoPqqsI.d.ts} +1329 -9
  104. package/dist/schema-sqlite.d.ts +1308 -8
  105. package/dist/schema-sqlite.js +156 -20
  106. package/dist/schema-version.d.ts +1 -1
  107. package/dist/schema-version.js +261 -2
  108. package/dist/schema.d.ts +2 -2
  109. package/dist/schema.js +229 -22
  110. package/package.json +13 -5
  111. package/src/active-subject.ts +9 -0
  112. package/src/change-records.ts +38 -0
  113. package/src/connect.ts +67 -13
  114. package/src/database.ts +67 -51
  115. package/src/dialect.ts +17 -8
  116. package/src/grants.ts +3 -3
  117. package/src/hyperdrive.ts +181 -104
  118. package/src/log.ts +244 -11
  119. package/src/migrate.ts +157 -30
  120. package/src/migrations/postgres/0021_prune_vault_releases.sql +19 -0
  121. package/src/migrations/postgres/0022_log_015.sql +672 -0
  122. package/src/migrations/postgres/0023_change_path.sql +153 -0
  123. package/src/migrations/postgres/0024_use_015.sql +556 -0
  124. package/src/migrations/postgres/0025_app_change.sql +221 -0
  125. package/src/migrations/postgres/0026_issue_lock.sql +106 -0
  126. package/src/migrations/postgres/0027_retention.sql +118 -0
  127. package/src/migrations/postgres/0028_use_stalls.sql +594 -0
  128. package/src/migrations/postgres/0029_use_objects.sql +887 -0
  129. package/src/migrations/postgres/0030_unarchive_restores.sql +259 -0
  130. package/src/migrations/postgres/0031_app_read.sql +65 -0
  131. package/src/migrations/postgres/0032_secrets_live_index.sql +4 -0
  132. package/src/migrations/postgres/0033_use_generations.sql +582 -0
  133. package/src/migrations/postgres/0034_vault_credentials.sql +153 -0
  134. package/src/migrations/postgres/0035_first_days.sql +3 -0
  135. package/src/migrations/postgres/0036_vault_issues.sql +91 -0
  136. package/src/migrations/postgres/0037_vault_bindings.sql +271 -0
  137. package/src/migrations/postgres/0040_binding_origin.sql +159 -0
  138. package/src/migrations/postgres/0041_cutover.sql +132 -0
  139. package/src/migrations/postgres/0042_sign_in_index.sql +7 -0
  140. package/src/migrations/postgres/0043_issue_revoke_index.sql +4 -0
  141. package/src/migrations/postgres/0044_use_by_name.sql +705 -0
  142. package/src/migrations/postgres/0045_decide_first.sql +878 -0
  143. package/src/migrations/postgres/0046_way_in_uses.sql +1149 -0
  144. package/src/migrations/postgres/0047_cutover_finish.sql +268 -0
  145. package/src/migrations/postgres/0048_use_batch.sql +59 -0
  146. package/src/migrations/postgres/0049_reads.sql +171 -0
  147. package/src/migrations/postgres/meta/0021_snapshot.json +3334 -0
  148. package/src/migrations/postgres/meta/0022_snapshot.json +3831 -0
  149. package/src/migrations/postgres/meta/0023_snapshot.json +3831 -0
  150. package/src/migrations/postgres/meta/0024_snapshot.json +3831 -0
  151. package/src/migrations/postgres/meta/0025_snapshot.json +3831 -0
  152. package/src/migrations/postgres/meta/0026_snapshot.json +3831 -0
  153. package/src/migrations/postgres/meta/0027_snapshot.json +3853 -0
  154. package/src/migrations/postgres/meta/0028_snapshot.json +3853 -0
  155. package/src/migrations/postgres/meta/0029_snapshot.json +3859 -0
  156. package/src/migrations/postgres/meta/0030_snapshot.json +3859 -0
  157. package/src/migrations/postgres/meta/0031_snapshot.json +3859 -0
  158. package/src/migrations/postgres/meta/0032_snapshot.json +3875 -0
  159. package/src/migrations/postgres/meta/0033_snapshot.json +3875 -0
  160. package/src/migrations/postgres/meta/0034_snapshot.json +3875 -0
  161. package/src/migrations/postgres/meta/0035_snapshot.json +3875 -0
  162. package/src/migrations/postgres/meta/0036_snapshot.json +3875 -0
  163. package/src/migrations/postgres/meta/0037_snapshot.json +3875 -0
  164. package/src/migrations/postgres/meta/0038_snapshot.json +3881 -0
  165. package/src/migrations/postgres/meta/0039_snapshot.json +3881 -0
  166. package/src/migrations/postgres/meta/0040_snapshot.json +3931 -0
  167. package/src/migrations/postgres/meta/0041_snapshot.json +3981 -0
  168. package/src/migrations/postgres/meta/0042_snapshot.json +3981 -0
  169. package/src/migrations/postgres/meta/0043_snapshot.json +3981 -0
  170. package/src/migrations/postgres/meta/0044_snapshot.json +3991 -0
  171. package/src/migrations/postgres/meta/0045_snapshot.json +3997 -0
  172. package/src/migrations/postgres/meta/0046_snapshot.json +3997 -0
  173. package/src/migrations/postgres/meta/0047_snapshot.json +4234 -0
  174. package/src/migrations/postgres/meta/_journal.json +189 -0
  175. package/src/migrations/sqlite/0018_log_015.sql +84 -0
  176. package/src/migrations/sqlite/0019_retention.sql +2 -0
  177. package/src/migrations/sqlite/0020_ended_references.sql +1 -0
  178. package/src/migrations/sqlite/0021_secrets_live_index.sql +1 -0
  179. package/src/migrations/sqlite/0022_binding_origin.sql +1 -0
  180. package/src/migrations/sqlite/0023_sign_in_index.sql +2 -0
  181. package/src/migrations/sqlite/0024_issue_revoke_index.sql +2 -0
  182. package/src/migrations/sqlite/0025_way_in_uses.sql +42 -0
  183. package/src/migrations/sqlite/0026_cutover_finish.sql +11 -0
  184. package/src/migrations/sqlite/0027_reads.sql +38 -0
  185. package/src/migrations/sqlite/meta/0018_snapshot.json +3529 -0
  186. package/src/migrations/sqlite/meta/0019_snapshot.json +3538 -0
  187. package/src/migrations/sqlite/meta/0020_snapshot.json +3545 -0
  188. package/src/migrations/sqlite/meta/0021_snapshot.json +3553 -0
  189. package/src/migrations/sqlite/meta/0022_snapshot.json +3560 -0
  190. package/src/migrations/sqlite/meta/0023_snapshot.json +3579 -0
  191. package/src/migrations/sqlite/meta/0024_snapshot.json +3598 -0
  192. package/src/migrations/sqlite/meta/0025_snapshot.json +3609 -0
  193. package/src/migrations/sqlite/meta/0026_snapshot.json +3616 -0
  194. package/src/migrations/sqlite/meta/0027_snapshot.json +3834 -0
  195. package/src/migrations/sqlite/meta/_journal.json +70 -0
  196. package/src/postgres-js/README.md +183 -0
  197. package/src/postgres-js/UNLICENSE +24 -0
  198. package/src/postgres-js/bytes.ts +89 -0
  199. package/src/postgres-js/connection.ts +882 -0
  200. package/src/postgres-js/errors.ts +84 -0
  201. package/src/postgres-js/index.ts +516 -0
  202. package/src/postgres-js/platform.node.ts +29 -0
  203. package/src/postgres-js/platform.ts +60 -0
  204. package/src/postgres-js/platform.workerd.ts +225 -0
  205. package/src/postgres-js/query.ts +123 -0
  206. package/src/postgres-js/queue.ts +42 -0
  207. package/src/postgres-js/result.ts +46 -0
  208. package/src/postgres-js/types.ts +52 -0
  209. package/src/postgres.ts +375 -26
  210. package/src/schema-version.ts +2 -2
  211. package/src/schema.sqlite.ts +200 -9
  212. package/src/schema.ts +294 -8
  213. package/src/verify-runtime.ts +18 -29
  214. package/LICENSE +0 -21
  215. package/dist/database-CFhTnnzM.d.ts +0 -73
  216. package/dist/postgres-Bmar8y0q.js +0 -29
  217. package/dist/relations-BfR3JjT1.js +0 -38
  218. package/src/relations.ts +0 -40
package/README.md CHANGED
@@ -8,7 +8,8 @@ connections, Hyperdrive's included.
8
8
  A deployment does not import it. Its own CLI applies the migrations,
9
9
  `pnpm exec coffre migrate`, before the deploy; `coffre-server migrate` does
10
10
  the same for local SQLite and tests. The server and vault open the same database with
11
- separate logins, `coffre_runtime` and `coffre_vault_runtime`. The migrations
11
+ separate logins, `coffre_runtime` and `coffre_vault_runtime`, and the vault's
12
+ hot path, 0.15's uses, a third, `coffre_vault_hot`. The migrations
12
13
  grant each its own rights; only the owner runs migrations. The owner needs
13
14
  `CREATEROLE` and `CREATEDB`, and `ADMIN OPTION` on existing group roles.
14
15
  Superuser is not required.
@@ -0,0 +1,55 @@
1
+ import { sql } from "drizzle-orm";
2
+ //#region src/active-subject.ts
3
+ /**
4
+ * `identities.active_subject`: the subject while the account is bound, null
5
+ * once revoked. A unique index on (provider, issuer_hash, active_subject)
6
+ * binds an account to one person at a time. Plain column names, so the
7
+ * expression reads the same on both databases.
8
+ */
9
+ const ACTIVE_SUBJECT = sql`CASE WHEN revoked_at IS NULL THEN subject END`;
10
+ //#endregion
11
+ //#region src/change-records.ts
12
+ /**
13
+ * What a change of 0.15's log records besides its op, which the audit pages
14
+ * list where 0.14's entry stood (D147): a sign-in through a trust binding
15
+ * (`signIn`, T156); a token the vault issued (`issue`); a credential it
16
+ * revoked by request, or that signed itself out (a revoke's `reason`,
17
+ * T164). Each is known by text its payload holds (`holds`), and by how the
18
+ * payload starts (`starts`): the vault writes it canonical, its keys in
19
+ * order, so an issue's is `{"caller":…` and a revoke's
20
+ * `{"op":"credential.revoke",…`. A string the payload holds has its quotes
21
+ * escaped, but an object's keys need not be the vault's own (a role's
22
+ * name, in the roles' change: review r1), so where the text alone could be
23
+ * one, the start says whose payload it is. The partial indexes of
24
+ * `log_changes` hold each set, and a read that is to use one repeats its
25
+ * condition (`recorded`), word for word and with no parameter.
26
+ */
27
+ const RECORDS = {
28
+ signIn: { holds: "\"signIn\":{" },
29
+ issue: {
30
+ starts: "{\"caller\":\"",
31
+ holds: "\"issue\":{\"by\":\""
32
+ },
33
+ revoke: {
34
+ starts: "{\"op\":\"credential.revoke\",",
35
+ holds: "\"reason\":\"revoke\""
36
+ },
37
+ signOut: {
38
+ starts: "{\"op\":\"credential.revoke\",",
39
+ holds: "\"reason\":\"sign_out\""
40
+ }
41
+ };
42
+ /** Whether `payload` holds one of `records`, on Postgres or SQLite: an index's condition, and the reads' that use it. */
43
+ function recorded(engine, payload, ...records) {
44
+ const at = (text) => {
45
+ const marker = sql.raw(`'${text}'`);
46
+ return engine === "postgres" ? sql`strpos(${payload}, ${marker})` : sql`instr(${payload}, ${marker})`;
47
+ };
48
+ const each = records.map((record) => {
49
+ const { starts, holds } = RECORDS[record];
50
+ return starts === void 0 ? sql`${at(holds)} > 0` : sql`(${at(starts)} = 1 AND ${at(holds)} > 0)`;
51
+ });
52
+ return each.length === 1 ? each[0] : sql`(${sql.join(each, sql` OR `)})`;
53
+ }
54
+ //#endregion
55
+ export { recorded as n, ACTIVE_SUBJECT as r, RECORDS as t };
package/dist/connect.d.ts CHANGED
@@ -1,26 +1,38 @@
1
- import { t as Database } from "./database-CFhTnnzM.js";
1
+ import { _ as quoteIdentifier, d as ClientOptions, f as PostgresClient, g as postgresSession, h as postgresOptions, m as postgresClient, n as Database, p as SessionLost, v as quoteLiteral } from "./database-CVteLhp1.js";
2
2
  import { Engine } from "./dialect.js";
3
- import { ClientConfig } from "pg";
4
- //#region src/postgres.d.ts
5
- /** Keep libpq's system-root shortcut from being read as a certificate filename by pg. */
6
- export declare function postgresConnection(url: string): ClientConfig;
7
- //#endregion
8
3
  //#region src/connect.d.ts
9
4
  /**
10
5
  * Open a database from its URL, on a Node server:
11
6
  *
12
- * postgres://… or postgresql://… node-postgres
7
+ * postgres://… or postgresql://… postgres.js, a pool of up to 10 connections
13
8
  * file:… or libsql:… @libsql/client (SQLite)
14
9
  *
15
10
  * The SQLite driver loads only when asked for. The Worker does not
16
11
  * come through here; it builds its Postgres database from the Hyperdrive
17
- * pool with createDatabase.
12
+ * pool with createDatabase. `max`, for a pool of its own beside another,
13
+ * as the vault's checkpointer has (T169).
18
14
  */
19
- export declare function openDatabase(url: string): Promise<OpenDatabase>;
15
+ export declare function openDatabase(url: string, options?: {
16
+ max?: number;
17
+ }): Promise<OpenDatabase>;
18
+ /** `close` once what was asked has answered; `cut` at once, what is in flight failing (T169). */
20
19
  export type OpenDatabase = {
21
20
  engine: Engine;
22
21
  db: Database;
23
22
  close: () => Promise<void>;
23
+ cut: () => Promise<void>;
24
24
  };
25
25
  export declare function engineOfUrl(url: string): Engine;
26
- //#endregion
26
+ /**
27
+ * Whether a lone statement may write: all but a query (SELECT or VALUES, or
28
+ * a WITH whose statement is one) and EXPLAIN, read from its words outside
29
+ * parentheses, strings, quoted names and comments.
30
+ *
31
+ * select … from "mcp_approvals" where … reads
32
+ * WITH policy AS (SELECT …) SELECT json_object(…) reads
33
+ * WITH old AS (SELECT …) DELETE FROM … writes
34
+ * update "mcp_connections" set … writes
35
+ */
36
+ export declare function writes(statement: string): boolean;
37
+ //#endregion
38
+ export { type ClientOptions, type PostgresClient, SessionLost, postgresClient, postgresOptions, postgresSession, quoteIdentifier, quoteLiteral };
package/dist/connect.js CHANGED
@@ -1,27 +1,31 @@
1
- import { n as createDatabase } from "./database-BadNeeN-.js";
1
+ import { a as quoteIdentifier, i as postgresSession, n as postgresClient, o as quoteLiteral, r as postgresOptions, t as SessionLost } from "./postgres-BI3xTnyw.js";
2
+ import { n as createDatabase } from "./database-D55ENPX-.js";
2
3
  import { asPostgresDatabase } from "./portable.js";
3
- import { t as postgresConnection } from "./postgres-Bmar8y0q.js";
4
- import pg from "pg";
5
4
  import { resolve } from "node:path";
6
5
  //#region src/connect.ts
7
6
  /**
8
7
  * Open a database from its URL, on a Node server:
9
8
  *
10
- * postgres://… or postgresql://… node-postgres
9
+ * postgres://… or postgresql://… postgres.js, a pool of up to 10 connections
11
10
  * file:… or libsql:… @libsql/client (SQLite)
12
11
  *
13
12
  * The SQLite driver loads only when asked for. The Worker does not
14
13
  * come through here; it builds its Postgres database from the Hyperdrive
15
- * pool with createDatabase.
14
+ * pool with createDatabase. `max`, for a pool of its own beside another,
15
+ * as the vault's checkpointer has (T169).
16
16
  */
17
- async function openDatabase(url) {
17
+ async function openDatabase(url, options = {}) {
18
18
  switch (engineOfUrl(url)) {
19
19
  case "postgres": {
20
- const pool = new pg.Pool(postgresConnection(url));
20
+ const client = postgresClient(url, {
21
+ max: options.max ?? 10,
22
+ idle_timeout: 10
23
+ });
21
24
  return {
22
25
  engine: "postgres",
23
- db: createDatabase(pool),
24
- close: () => pool.end()
26
+ db: createDatabase(client),
27
+ close: () => client.end(),
28
+ cut: () => client.end({ timeout: 0 })
25
29
  };
26
30
  }
27
31
  case "sqlite": {
@@ -43,7 +47,8 @@ async function openDatabase(url) {
43
47
  return {
44
48
  engine: "sqlite",
45
49
  db: asPostgresDatabase(db),
46
- close: async () => client.close()
50
+ close: async () => client.close(),
51
+ cut: async () => client.close()
47
52
  };
48
53
  }
49
54
  }
@@ -63,6 +68,16 @@ function engineOfUrl(url) {
63
68
  * connections reach it. Each begins IMMEDIATE (libsql's default), taking the
64
69
  * write lock with its first statement, which is what makes a read inside it
65
70
  * as good as a locked one (see forUpdate).
71
+ *
72
+ * A lone statement that writes waits its turn too. It cannot wait for the
73
+ * lock itself: libsql's busy wait blocks the thread, so the transaction
74
+ * holding the lock, in this process, cannot go on to commit, and the write
75
+ * fails after `timeout`. A connection whose write failed that way still
76
+ * reads the file as it was then, until its statement is collected:
77
+ *
78
+ * six MCP calls at once the first's approval, in a transaction BEGIN IMMEDIATE, then awaits
79
+ * another's last_used_at a lone UPDATE, outside the queue the thread blocked 5 s, SQLITE_BUSY
80
+ * it reads the approval on that connection no row
66
81
  */
67
82
  var WriteQueue = class {
68
83
  #tail = Promise.resolve();
@@ -84,7 +99,16 @@ function writeQueueFor(url) {
84
99
  }
85
100
  function oneTransactionAtATime(client, queue) {
86
101
  return new Proxy(client, { get(target, key) {
87
- if (key === "execute") return async (...args) => numbers(await target.execute(...args));
102
+ if (key === "execute") return async (...args) => {
103
+ const [statement] = args;
104
+ if (!writes(typeof statement === "string" ? statement : statement.sql)) return numbers(await target.execute(...args));
105
+ const release = await queue.acquire();
106
+ try {
107
+ return numbers(await target.execute(...args));
108
+ } finally {
109
+ release();
110
+ }
111
+ };
88
112
  if (key === "transaction") return async (mode) => {
89
113
  const release = await queue.acquire();
90
114
  try {
@@ -140,6 +164,44 @@ function settling(tx, release) {
140
164
  };
141
165
  return tx;
142
166
  }
167
+ /**
168
+ * Whether a lone statement may write: all but a query (SELECT or VALUES, or
169
+ * a WITH whose statement is one) and EXPLAIN, read from its words outside
170
+ * parentheses, strings, quoted names and comments.
171
+ *
172
+ * select … from "mcp_approvals" where … reads
173
+ * WITH policy AS (SELECT …) SELECT json_object(…) reads
174
+ * WITH old AS (SELECT …) DELETE FROM … writes
175
+ * update "mcp_connections" set … writes
176
+ */
177
+ function writes(statement) {
178
+ let depth = 0;
179
+ let first = null;
180
+ for (const [token] of statement.matchAll(/--[^\n]*|\/\*[\s\S]*?(?:\*\/|$)|'(?:[^']|'')*'?|"(?:[^"]|"")*"?|`[^`]*`?|\[[^\]]*\]?|[()]|[A-Za-z_][\w$]*/g)) if (token === "(") depth += 1;
181
+ else if (token === ")") depth -= 1;
182
+ else if (depth === 0 && /^[A-Za-z_]/.test(token)) {
183
+ const word = token.toLowerCase();
184
+ if (first === null) {
185
+ first = word;
186
+ if (word !== "with") return !QUERIES.has(word);
187
+ } else if (STATEMENTS.has(word)) return !QUERIES.has(word);
188
+ }
189
+ return true;
190
+ }
191
+ const QUERIES = /* @__PURE__ */ new Set([
192
+ "select",
193
+ "values",
194
+ "explain"
195
+ ]);
196
+ /** The words a WITH's own statement starts with. */
197
+ const STATEMENTS = /* @__PURE__ */ new Set([
198
+ "select",
199
+ "values",
200
+ "insert",
201
+ "update",
202
+ "delete",
203
+ "replace"
204
+ ]);
143
205
  /** Keep large counters exact; Drizzle's booleans and dates still need safe numbers. */
144
206
  function numbers(result) {
145
207
  result.rows = result.rows.map((row) => {
@@ -153,4 +215,4 @@ function numbers(result) {
153
215
  return result;
154
216
  }
155
217
  //#endregion
156
- export { engineOfUrl, openDatabase, postgresConnection };
218
+ export { SessionLost, engineOfUrl, openDatabase, postgresClient, postgresOptions, postgresSession, quoteIdentifier, quoteLiteral, writes };
@@ -0,0 +1,410 @@
1
+ import { n as Socket, r as TlsOptions } from "./platform-Y3gICK6n.js";
2
+ import { T as schema_d_exports } from "./schema-DgoPqqsI.js";
3
+ import { Assume, Query, Table } from "drizzle-orm";
4
+ import { PgDatabase, PgQueryResultHKT } from "drizzle-orm/pg-core";
5
+ //#region src/postgres-js/errors.d.ts
6
+ /** What Postgres said in an ErrorResponse or a NoticeResponse, each field by its name. */
7
+ type Notice = Partial<Record<(typeof FIELDS)[keyof typeof FIELDS], string>>;
8
+ /** An ErrorResponse's fields, by their code. `data type_name` is upstream's spelling, kept. */
9
+ declare const FIELDS: {
10
+ readonly 83: "severity_local";
11
+ readonly 86: "severity";
12
+ readonly 67: "code";
13
+ readonly 77: "message";
14
+ readonly 68: "detail";
15
+ readonly 72: "hint";
16
+ readonly 80: "position";
17
+ readonly 112: "internal_position";
18
+ readonly 113: "internal_query";
19
+ readonly 87: "where";
20
+ readonly 115: "schema_name";
21
+ readonly 116: "table_name";
22
+ readonly 99: "column_name";
23
+ readonly 100: "data type_name";
24
+ readonly 110: "constraint_name";
25
+ readonly 70: "file";
26
+ readonly 76: "line";
27
+ readonly 82: "routine";
28
+ };
29
+ //#endregion
30
+ //#region src/postgres-js/result.d.ts
31
+ /** What Postgres said of a column, in a RowDescription. */
32
+ interface Column {
33
+ name: string;
34
+ /** How its text is read, by its type; as text when there is none. */
35
+ parser: ((text: string) => unknown) | undefined;
36
+ table: number;
37
+ number: number;
38
+ type: number;
39
+ }
40
+ //#endregion
41
+ //#region src/postgres-js/query.d.ts
42
+ /** A statement as sent: its text, its parameters' types (0 for the server to say), and its columns once described. */
43
+ interface Statement {
44
+ string: string;
45
+ types: number[];
46
+ /** Once described: by a RowDescription, or NoData's none. */
47
+ columns: Column[] | null;
48
+ }
49
+ interface QueryOptions {
50
+ /** Sent with the simple protocol, one Query message: what a statement with no parameters is, by default. */
51
+ simple: boolean;
52
+ }
53
+ /**
54
+ * One statement of a group (`group`, index.ts): its text and values, whether
55
+ * its rows come as arrays, and what the connection works out as it sends it.
56
+ */
57
+ interface Member {
58
+ text: string;
59
+ args: unknown[];
60
+ arrays: boolean;
61
+ parameters: unknown[];
62
+ statement: Statement | null;
63
+ }
64
+ /**
65
+ * A statement, sent once awaited (`then`, `catch`, `finally`) or `execute`d,
66
+ * a task later, through the pool or the transaction that made it: its
67
+ * `handler`. A promise of its result, its rows as objects or, after
68
+ * `values()`, as arrays.
69
+ */
70
+ declare class Query$1<T = unknown> extends Promise<T> {
71
+ #private;
72
+ readonly text: string;
73
+ readonly args: unknown[];
74
+ readonly options: QueryOptions;
75
+ /** Its rows as arrays of values rather than objects. */
76
+ arrays: boolean;
77
+ executed: boolean;
78
+ parameters: unknown[];
79
+ statement: Statement | null;
80
+ /** Whether its parameters' types are asked of the server before its values go (`typedByServer`, connection.ts). */
81
+ describeFirst: boolean;
82
+ /** A transaction's first statement: its BEGIN, sent ahead of it under its Sync (`begin`, index.ts); and whether it took. */
83
+ begin: string | null;
84
+ began: boolean;
85
+ /**
86
+ * Coffre: a group's statements, sent under one Sync and answered together, each its own result (`group`, index.ts),
87
+ * and the one answering now. Null for a statement of its own.
88
+ */
89
+ group: Member[] | null;
90
+ member: number;
91
+ readonly resolve: (value: unknown) => void;
92
+ readonly reject: (error: unknown) => void;
93
+ constructor(text: string, args: unknown[], handler: (query: Query$1) => void, options: QueryOptions, debug: boolean);
94
+ /** Where it was made, for its error's stack: nothing unless the client debugs. */
95
+ get origin(): string;
96
+ /** What `then` and the like make: a plain promise, not another statement. */
97
+ static get [Symbol.species](): PromiseConstructor;
98
+ values(): Query$1<RowList<unknown[][]>>;
99
+ execute(): this;
100
+ then<A = T, B = never>(onfulfilled?: ((value: T) => A | PromiseLike<A>) | null, onrejected?: ((reason: any) => B | PromiseLike<B>) | null): Promise<A | B>;
101
+ catch<B = never>(onrejected?: ((reason: any) => B | PromiseLike<B>) | null): Promise<T | B>;
102
+ finally(onfinally?: (() => void) | null): Promise<T>;
103
+ }
104
+ //#endregion
105
+ //#region src/postgres-js/types.d.ts
106
+ /** How a column's text is read, by its type's oid. */
107
+ type Parsers = Record<number, ((text: string) => unknown) | undefined>;
108
+ /** How a value is written as text, by its parameter's type's oid. */
109
+ type Serializers = Record<number, ((value: unknown) => unknown) | undefined>;
110
+ //#endregion
111
+ //#region src/postgres-js/index.d.ts
112
+ /** What a client is opened with. Nothing is read from the environment: what is not given is the default named. */
113
+ interface Options {
114
+ /** Default `localhost`. */
115
+ host?: string;
116
+ /** Default 5432. */
117
+ port?: number;
118
+ /** A Unix socket's path, in place of `host` and `port`. */
119
+ path?: string | undefined;
120
+ /** Default the server's: the user's name. */
121
+ database?: string | undefined;
122
+ user?: string;
123
+ pass?: string;
124
+ /** TLS, with Node's options for it; default none. */
125
+ ssl?: false | TlsOptions;
126
+ /** `direct`: TLS from the first byte, with no SSLRequest (Postgres 17). */
127
+ sslnegotiation?: 'direct' | null | undefined;
128
+ /** Connections at most. Default 10. */
129
+ max?: number;
130
+ /** Statements sent on a connection before the first has answered. Default 100. */
131
+ max_pipeline?: number;
132
+ /** Seconds a connection may be idle before it closes. Default none. */
133
+ idle_timeout?: number | null | undefined;
134
+ /** Seconds a connection may take to open. Default 30. */
135
+ connect_timeout?: number | null | undefined;
136
+ /** Seconds a connection may live, or a function that says how many. Default 30 to 60 minutes. */
137
+ max_lifetime?: number | null | (() => number);
138
+ /** Seconds before a closed connection is opened again, by how many in a row closed with an error. */
139
+ backoff?: number | ((retries: number) => number);
140
+ /** Seconds of TCP keep-alive. Default 60. */
141
+ keep_alive?: number | null;
142
+ /** True to keep where each statement was made, for its error's stack, and its text on its error; or a function told each statement. */
143
+ debug?: boolean | ((connection: number, query: string, parameters: unknown[], types: number[]) => void);
144
+ /** Run-time parameters sent as each connection starts. Default `application_name` postgres.js. */
145
+ connection?: Record<string, string | number | boolean | undefined>;
146
+ /** Each notice Postgres sends. Default: logged. */
147
+ onnotice?: (notice: Notice) => void;
148
+ /** Each connection's close, by its id. */
149
+ onclose?: (connectionId: number) => void;
150
+ /** The stream to speak Postgres on, made for each connection, rather than a TCP socket to `host`. */
151
+ socket?: () => Socket | Promise<Socket>;
152
+ }
153
+ /** A client's options, every one settled, and what it keeps beside them: `parsers` and `serializers`, which it may change. */
154
+ interface Settings {
155
+ host: string;
156
+ port: number;
157
+ path: string | undefined;
158
+ database: string | undefined;
159
+ user: string;
160
+ pass: string;
161
+ ssl: false | TlsOptions;
162
+ sslnegotiation: 'direct' | null | undefined;
163
+ max: number;
164
+ max_pipeline: number;
165
+ idle_timeout: number | null | undefined;
166
+ connect_timeout: number | null | undefined;
167
+ max_lifetime: number | null | undefined | (() => number);
168
+ backoff: number | ((retries: number) => number);
169
+ keep_alive: number | null | undefined;
170
+ debug: boolean | ((connection: number, query: string, parameters: unknown[], types: number[]) => void);
171
+ connection: Record<string, string | number | boolean | undefined>;
172
+ onnotice: ((notice: Notice) => void) | undefined;
173
+ onclose: ((connectionId: number) => void) | undefined;
174
+ socket: (() => Socket | Promise<Socket>) | undefined;
175
+ parsers: Parsers;
176
+ serializers: Serializers;
177
+ /** The server's run-time parameters, as its ParameterStatus messages said them. */
178
+ parameters: Record<string, string>;
179
+ /** What the pool's connections share: how many in a row closed with an error, which backs off reopening. */
180
+ shared: {
181
+ retries: number;
182
+ };
183
+ }
184
+ /** A row, by its columns' names: whatever a hand-written statement selects, as upstream types it. */
185
+ type Row = Record<string, any>;
186
+ /** What a statement's CommandComplete said, beside its rows. */
187
+ interface ResultMeta {
188
+ /** Rows inserted, updated, deleted or returned; null for a command that counts none. */
189
+ readonly count: number | null;
190
+ readonly command: string;
191
+ /** The backend that ran it: its process id and secret key, what a CancelRequest names. */
192
+ readonly state: {
193
+ readonly pid: number;
194
+ readonly secret: number;
195
+ };
196
+ readonly columns: Column[] | null;
197
+ }
198
+ /** A statement's rows, with what Postgres said of it. */
199
+ type RowList<T extends readonly unknown[]> = T & ResultMeta;
200
+ /** A statement, sent once awaited or `execute`d. */
201
+ type PendingQuery<T extends readonly unknown[]> = Query$1<RowList<T>>;
202
+ /** A transaction's statements, and its savepoints. */
203
+ interface TransactionSql {
204
+ unsafe<T extends readonly unknown[] = Row[]>(query: string, parameters?: unknown[], options?: {
205
+ simple?: boolean;
206
+ }): PendingQuery<T>;
207
+ /** A savepoint, rolled back to if `fn` fails. */
208
+ savepoint<T>(fn: (sql: TransactionSql) => T | Promise<T>): Promise<Settled<T>>;
209
+ }
210
+ /** A connection held until `release()`. */
211
+ interface ReservedSql {
212
+ unsafe<T extends readonly unknown[] = Row[]>(query: string, parameters?: unknown[], options?: {
213
+ simple?: boolean;
214
+ }): PendingQuery<T>;
215
+ release(): void;
216
+ }
217
+ /** A pool of connections to Postgres. */
218
+ interface Sql {
219
+ /**
220
+ * A statement: with `parameters`, the extended protocol, one round trip;
221
+ * without, the simple one, unless `simple: false`.
222
+ */
223
+ unsafe<T extends readonly unknown[] = Row[]>(query: string, parameters?: unknown[], options?: {
224
+ simple?: boolean;
225
+ }): PendingQuery<T>;
226
+ /**
227
+ * A transaction, on a connection held for it: BEGIN (`options` after it,
228
+ * `isolation level serializable` and the like), `fn`, then COMMIT, or
229
+ * ROLLBACK if `fn` fails, or a statement of it did that `fn` did not wait for.
230
+ */
231
+ begin<T>(fn: (sql: TransactionSql) => T | Promise<T>): Promise<Settled<T>>;
232
+ begin<T>(options: string, fn: (sql: TransactionSql) => T | Promise<T>): Promise<Settled<T>>;
233
+ /**
234
+ * Coffre: statements sent together under one Sync, a round trip in all
235
+ * through a pooler that sends a client's Syncs on one at a time, as
236
+ * Hyperdrive does; answered once the last has, each with its own rows,
237
+ * as an array (`arrays` for a statement's rows as arrays of values). They
238
+ * run as one implicit transaction: if one fails, Postgres skips those
239
+ * after it, and the group fails, with that error. Plain reads alone
240
+ * (`select …`), on the pool alone, never in a transaction, whose
241
+ * statements each go under its own; each with the extended protocol, as
242
+ * a statement with parameters.
243
+ */
244
+ group(statements: readonly {
245
+ query: string;
246
+ parameters?: unknown[];
247
+ arrays?: boolean;
248
+ }[]): PendingQuery<RowList<Row[]>[]>;
249
+ /** A connection of the pool, held for the caller until it releases it. */
250
+ reserve(): Promise<ReservedSql>;
251
+ /** Close every connection once what it was sent has answered; after `timeout` seconds, at once. */
252
+ end(options?: {
253
+ timeout?: number | null;
254
+ }): Promise<void>;
255
+ readonly options: Settings;
256
+ }
257
+ /** What a transaction's work answers: an array of promises, each awaited. */
258
+ type Settled<T> = T extends readonly unknown[] ? { -readonly [K in keyof T]: Awaited<T[K]>; } : Awaited<T>;
259
+ //#endregion
260
+ //#region src/postgres.d.ts
261
+ /**
262
+ * A client of coffre's postgres.js (`./postgres-js`): statements (`unsafe`),
263
+ * transactions (`begin`), a connection held (`reserve`), and closing it.
264
+ */
265
+ type PostgresClient = Sql;
266
+ /** What a client may be opened with beside its URL. */
267
+ type ClientOptions = Pick<Options, 'max' | 'idle_timeout' | 'connect_timeout' | 'max_lifetime' | 'onnotice' | 'debug' | 'onclose'> & {
268
+ /** The stream to speak Postgres on, made for each connection, rather than a TCP socket: a tunnel's. */
269
+ socket?: Options['socket'];
270
+ /** Postgres's `application_name` for the connection. */
271
+ application_name?: string;
272
+ /** Run-time parameters sent when the connection starts, `statement_timeout` and the like. */
273
+ connection?: Record<string, string | number | boolean>;
274
+ };
275
+ /**
276
+ * A client for `url`, as coffre opens every one: the driver's defaults (10
277
+ * connections, every statement unnamed, as node-postgres sends them), but
278
+ *
279
+ * - notices dropped rather than logged;
280
+ * - no connection closed for its age (`max_lifetime`), as node-postgres
281
+ * closed none: a backup's session holds its snapshot while pg_dump reads.
282
+ *
283
+ * The driver reads no array type from `pg_type` (postgres.js's
284
+ * `fetch_types`, a round trip more per connection), and would answer one as
285
+ * its text: Postgres's own are taken as known instead (`ARRAYS`). Arrays and
286
+ * dates go as node-postgres sends them (`asPgSends`).
287
+ */
288
+ declare function postgresClient(url: string, options?: ClientOptions): PostgresClient;
289
+ /** A statement asked of a session that lost its connection, and with it its transaction, its locks and its settings. */
290
+ declare class SessionLost extends Error {
291
+ constructor();
292
+ }
293
+ /**
294
+ * One connection to `url`, kept as a session, as node-postgres's Client
295
+ * kept one: what a statement sets (SET, BEGIN, a session's advisory lock)
296
+ * holds for every statement after. A client of postgres.js would dial a new
297
+ * connection for the next statement once its own closed, which holds none of
298
+ * it: a migration going on without its lock, a probe meant to be rolled back
299
+ * committed, a backup read outside its snapshot. A session does not: once
300
+ * its connection has closed, by the server, the network or `end`, every
301
+ * statement after fails, `SessionLost`.
302
+ */
303
+ declare function postgresSession(url: string, options?: Omit<ClientOptions, 'max'>): PostgresClient;
304
+ /**
305
+ * The connection `url` names, as node-postgres and its pg-connection-string
306
+ * read one. The driver reads no URL: it is given the parts. (Upstream
307
+ * postgres.js read URLs otherwise: it sent every query parameter it did not
308
+ * know to the server as a setting, which refused the connection over one it
309
+ * did not know either, `sslrootcert` or `uselibpqcompat`; its
310
+ * `sslmode=require` skipped the certificate check, where coffre's URLs, as
311
+ * pg reads them, verify; and it checked an IP address against `localhost`.)
312
+ *
313
+ * TLS is:
314
+ *
315
+ * no sslmode, sslmode=disable none
316
+ * sslmode=prefer, require, verify-ca, the certificate chain and the host verified
317
+ * verify-full; ssl=true or 1
318
+ * sslmode=no-verify TLS, nothing verified
319
+ * uselibpqcompat=true libpq's modes: prefer and require verify nothing
320
+ * (require with a sslrootcert, the chain), verify-ca
321
+ * the chain, verify-full the chain and the host
322
+ * sslrootcert=system Node's trusted CAs; only with verify-full or no sslmode
323
+ * sslrootcert, sslcert, sslkey (files) read from disk, as pg does
324
+ *
325
+ * The host is verified against the URL's own, an IP address included.
326
+ */
327
+ declare function postgresOptions(url: string): Partial<Options> & {
328
+ connection: Record<string, string>;
329
+ };
330
+ /** `name` as a Postgres identifier, quoted, as node-postgres's `escapeIdentifier` writes one. */
331
+ declare function quoteIdentifier(name: string): string;
332
+ /** `text` as a Postgres string literal, as node-postgres's `escapeLiteral` writes one: `E'…'` when it holds a backslash. */
333
+ declare function quoteLiteral(text: string): string;
334
+ //#endregion
335
+ //#region src/prepared.d.ts
336
+ /** The part of a select builder `prepared` reads, once. */
337
+ type Select = PromiseLike<unknown> & {
338
+ toSQL(): Query;
339
+ prepare(...name: never[]): unknown;
340
+ };
341
+ /**
342
+ * A select built once per process, or once per isolate on Workers, and run
343
+ * with new values each time. Drizzle rebuilds a query's SQL from its
344
+ * builder at every run, and that was most of a short query's CPU; this
345
+ * builds it from `build` the first time a database of its dialect asks,
346
+ * then hands the SQL and its columns to that call's own session
347
+ * (`session.prepareQuery`), which binds `values` to the placeholders
348
+ * (`sql.placeholder`) and maps the rows as the builder would.
349
+ *
350
+ * `build` must not depend on anything but the database's dialect, and the
351
+ * values go to the driver as they are, not through a column's encoding:
352
+ * strings, numbers, bigints and bytes.
353
+ *
354
+ * const member = prepared((db) => db.select().from(tablesOf(db).vaultMembers).where(eq(…, sql.placeholder('principal'))));
355
+ * const [row] = await member(db, { principal });
356
+ */
357
+ declare function prepared<Q extends Select>(build: (db: Queryable) => Q): (db: Queryable, values?: Record<string, unknown>) => Promise<Awaited<Q>>;
358
+ //#endregion
359
+ //#region src/database.d.ts
360
+ /** What a hand-written statement answers on Postgres: its rows, with `count` and `command`. */
361
+ interface QueryResult extends PgQueryResultHKT {
362
+ type: RowList<Assume<this['row'], Row>[]>;
363
+ }
364
+ /**
365
+ * A database, typed as Postgres whichever it is; see portable.ts for why
366
+ * that holds. connect.ts opens one of each from a URL.
367
+ */
368
+ type Database = PgDatabase<QueryResult, typeof schema_d_exports, NoRelations>;
369
+ type Transaction = Parameters<Parameters<Database['transaction']>[0]>[0];
370
+ /** Anything a read can run on: the database, or an open transaction. */
371
+ type Queryable = Database | Transaction;
372
+ /**
373
+ * A query made on the database from inside one of its own transactions,
374
+ * rather than through the transaction. With one connection per call, as on
375
+ * Workers, it would wait for the transaction, which waits for it: a call
376
+ * Cloudflare cancels as hung, and nothing says why. So it is refused at
377
+ * once, with this, wherever the database runs.
378
+ */
379
+ declare class QueryOutsideTransaction extends Error {
380
+ constructor();
381
+ }
382
+ /**
383
+ * Coffre runs no relational query (`db.query.*`), and Drizzle's work out of
384
+ * them, `extractTablesRelationalConfig` and a query builder per table for
385
+ * every database, was 4 to 11 ms of a cold isolate's CPU and 0.1 ms of each
386
+ * later call on Workers, where a database is made per call. So the database
387
+ * has none: `db.query` is empty, in type and at run time, and a `db.query.x`
388
+ * fails the typecheck. Only the tables stay, for `tablesOf`.
389
+ */
390
+ type NoRelations = Record<never, never>;
391
+ /**
392
+ * What a database runs on: a postgres.js client (`postgresClient`), or
393
+ * Workers' `HyperdrivePool`, which makes them. Drizzle asks it for
394
+ * statements (`unsafe`) and transactions (`begin`).
395
+ */
396
+ type Client = Pick<PostgresClient, 'unsafe' | 'begin'>;
397
+ declare function createDatabase(client: Client): Database;
398
+ /**
399
+ * The tables of the database's own dialect: the Postgres ones on Postgres,
400
+ * the SQLite ones on SQLite. Every query builds on these.
401
+ */
402
+ declare function tablesOf(db: Queryable): typeof schema_d_exports;
403
+ /**
404
+ * The database's own twin of `table`, which may be another dialect's: the
405
+ * server names tables by importing schema.ts, and the database decides
406
+ * which one that means.
407
+ */
408
+ declare function own<T extends Table>(db: Queryable, table: T): T;
409
+ //#endregion
410
+ export { quoteIdentifier as _, Queryable as a, own as c, ClientOptions as d, PostgresClient as f, postgresSession as g, postgresOptions as h, QueryResult as i, tablesOf as l, postgresClient as m, Database as n, Transaction as o, SessionLost as p, QueryOutsideTransaction as r, createDatabase as s, Client as t, prepared as u, quoteLiteral as v };