@coffre/db 0.14.5 → 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 (214) 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 -622
  17. package/dist/log.js +178 -13
  18. package/dist/migrate.d.ts +43 -3
  19. package/dist/migrate.js +149 -29
  20. package/dist/migrations/postgres/0022_log_015.sql +672 -0
  21. package/dist/migrations/postgres/0023_change_path.sql +153 -0
  22. package/dist/migrations/postgres/0024_use_015.sql +556 -0
  23. package/dist/migrations/postgres/0025_app_change.sql +221 -0
  24. package/dist/migrations/postgres/0026_issue_lock.sql +106 -0
  25. package/dist/migrations/postgres/0027_retention.sql +118 -0
  26. package/dist/migrations/postgres/0028_use_stalls.sql +594 -0
  27. package/dist/migrations/postgres/0029_use_objects.sql +887 -0
  28. package/dist/migrations/postgres/0030_unarchive_restores.sql +259 -0
  29. package/dist/migrations/postgres/0031_app_read.sql +65 -0
  30. package/dist/migrations/postgres/0032_secrets_live_index.sql +4 -0
  31. package/dist/migrations/postgres/0033_use_generations.sql +582 -0
  32. package/dist/migrations/postgres/0034_vault_credentials.sql +153 -0
  33. package/dist/migrations/postgres/0035_first_days.sql +3 -0
  34. package/dist/migrations/postgres/0036_vault_issues.sql +91 -0
  35. package/dist/migrations/postgres/0037_vault_bindings.sql +271 -0
  36. package/dist/migrations/postgres/0040_binding_origin.sql +159 -0
  37. package/dist/migrations/postgres/0041_cutover.sql +132 -0
  38. package/dist/migrations/postgres/0042_sign_in_index.sql +7 -0
  39. package/dist/migrations/postgres/0043_issue_revoke_index.sql +4 -0
  40. package/dist/migrations/postgres/0044_use_by_name.sql +705 -0
  41. package/dist/migrations/postgres/0045_decide_first.sql +878 -0
  42. package/dist/migrations/postgres/0046_way_in_uses.sql +1149 -0
  43. package/dist/migrations/postgres/0047_cutover_finish.sql +268 -0
  44. package/dist/migrations/postgres/0048_use_batch.sql +59 -0
  45. package/dist/migrations/postgres/0049_reads.sql +171 -0
  46. package/dist/migrations/postgres/meta/0022_snapshot.json +3831 -0
  47. package/dist/migrations/postgres/meta/0023_snapshot.json +3831 -0
  48. package/dist/migrations/postgres/meta/0024_snapshot.json +3831 -0
  49. package/dist/migrations/postgres/meta/0025_snapshot.json +3831 -0
  50. package/dist/migrations/postgres/meta/0026_snapshot.json +3831 -0
  51. package/dist/migrations/postgres/meta/0027_snapshot.json +3853 -0
  52. package/dist/migrations/postgres/meta/0028_snapshot.json +3853 -0
  53. package/dist/migrations/postgres/meta/0029_snapshot.json +3859 -0
  54. package/dist/migrations/postgres/meta/0030_snapshot.json +3859 -0
  55. package/dist/migrations/postgres/meta/0031_snapshot.json +3859 -0
  56. package/dist/migrations/postgres/meta/0032_snapshot.json +3875 -0
  57. package/dist/migrations/postgres/meta/0033_snapshot.json +3875 -0
  58. package/dist/migrations/postgres/meta/0034_snapshot.json +3875 -0
  59. package/dist/migrations/postgres/meta/0035_snapshot.json +3875 -0
  60. package/dist/migrations/postgres/meta/0036_snapshot.json +3875 -0
  61. package/dist/migrations/postgres/meta/0037_snapshot.json +3875 -0
  62. package/dist/migrations/postgres/meta/0038_snapshot.json +3881 -0
  63. package/dist/migrations/postgres/meta/0039_snapshot.json +3881 -0
  64. package/dist/migrations/postgres/meta/0040_snapshot.json +3931 -0
  65. package/dist/migrations/postgres/meta/0041_snapshot.json +3981 -0
  66. package/dist/migrations/postgres/meta/0042_snapshot.json +3981 -0
  67. package/dist/migrations/postgres/meta/0043_snapshot.json +3981 -0
  68. package/dist/migrations/postgres/meta/0044_snapshot.json +3991 -0
  69. package/dist/migrations/postgres/meta/0045_snapshot.json +3997 -0
  70. package/dist/migrations/postgres/meta/0046_snapshot.json +3997 -0
  71. package/dist/migrations/postgres/meta/0047_snapshot.json +4234 -0
  72. package/dist/migrations/postgres/meta/_journal.json +182 -0
  73. package/dist/migrations/sqlite/0018_log_015.sql +84 -0
  74. package/dist/migrations/sqlite/0019_retention.sql +2 -0
  75. package/dist/migrations/sqlite/0020_ended_references.sql +1 -0
  76. package/dist/migrations/sqlite/0021_secrets_live_index.sql +1 -0
  77. package/dist/migrations/sqlite/0022_binding_origin.sql +1 -0
  78. package/dist/migrations/sqlite/0023_sign_in_index.sql +2 -0
  79. package/dist/migrations/sqlite/0024_issue_revoke_index.sql +2 -0
  80. package/dist/migrations/sqlite/0025_way_in_uses.sql +42 -0
  81. package/dist/migrations/sqlite/0026_cutover_finish.sql +11 -0
  82. package/dist/migrations/sqlite/0027_reads.sql +38 -0
  83. package/dist/migrations/sqlite/meta/0018_snapshot.json +3529 -0
  84. package/dist/migrations/sqlite/meta/0019_snapshot.json +3538 -0
  85. package/dist/migrations/sqlite/meta/0020_snapshot.json +3545 -0
  86. package/dist/migrations/sqlite/meta/0021_snapshot.json +3553 -0
  87. package/dist/migrations/sqlite/meta/0022_snapshot.json +3560 -0
  88. package/dist/migrations/sqlite/meta/0023_snapshot.json +3579 -0
  89. package/dist/migrations/sqlite/meta/0024_snapshot.json +3598 -0
  90. package/dist/migrations/sqlite/meta/0025_snapshot.json +3609 -0
  91. package/dist/migrations/sqlite/meta/0026_snapshot.json +3616 -0
  92. package/dist/migrations/sqlite/meta/0027_snapshot.json +3834 -0
  93. package/dist/migrations/sqlite/meta/_journal.json +70 -0
  94. package/dist/platform-Y3gICK6n.d.ts +58 -0
  95. package/dist/portable.d.ts +2 -2
  96. package/dist/postgres-BI3xTnyw.js +1718 -0
  97. package/dist/postgres-platform-node.d.ts +14 -0
  98. package/dist/postgres-platform-node.js +21 -0
  99. package/dist/postgres-platform-workerd.d.ts +61 -0
  100. package/dist/postgres-platform-workerd.js +163 -0
  101. package/dist/{schema-BfQEBqFv.d.ts → schema-DgoPqqsI.d.ts} +1326 -7
  102. package/dist/schema-sqlite.d.ts +1306 -6
  103. package/dist/schema-sqlite.js +154 -18
  104. package/dist/schema-version.d.ts +1 -1
  105. package/dist/schema-version.js +254 -2
  106. package/dist/schema.d.ts +2 -2
  107. package/dist/schema.js +226 -20
  108. package/package.json +13 -5
  109. package/src/active-subject.ts +9 -0
  110. package/src/change-records.ts +38 -0
  111. package/src/connect.ts +67 -13
  112. package/src/database.ts +67 -51
  113. package/src/dialect.ts +17 -8
  114. package/src/grants.ts +3 -3
  115. package/src/hyperdrive.ts +181 -104
  116. package/src/log.ts +196 -15
  117. package/src/migrate.ts +157 -30
  118. package/src/migrations/postgres/0022_log_015.sql +672 -0
  119. package/src/migrations/postgres/0023_change_path.sql +153 -0
  120. package/src/migrations/postgres/0024_use_015.sql +556 -0
  121. package/src/migrations/postgres/0025_app_change.sql +221 -0
  122. package/src/migrations/postgres/0026_issue_lock.sql +106 -0
  123. package/src/migrations/postgres/0027_retention.sql +118 -0
  124. package/src/migrations/postgres/0028_use_stalls.sql +594 -0
  125. package/src/migrations/postgres/0029_use_objects.sql +887 -0
  126. package/src/migrations/postgres/0030_unarchive_restores.sql +259 -0
  127. package/src/migrations/postgres/0031_app_read.sql +65 -0
  128. package/src/migrations/postgres/0032_secrets_live_index.sql +4 -0
  129. package/src/migrations/postgres/0033_use_generations.sql +582 -0
  130. package/src/migrations/postgres/0034_vault_credentials.sql +153 -0
  131. package/src/migrations/postgres/0035_first_days.sql +3 -0
  132. package/src/migrations/postgres/0036_vault_issues.sql +91 -0
  133. package/src/migrations/postgres/0037_vault_bindings.sql +271 -0
  134. package/src/migrations/postgres/0040_binding_origin.sql +159 -0
  135. package/src/migrations/postgres/0041_cutover.sql +132 -0
  136. package/src/migrations/postgres/0042_sign_in_index.sql +7 -0
  137. package/src/migrations/postgres/0043_issue_revoke_index.sql +4 -0
  138. package/src/migrations/postgres/0044_use_by_name.sql +705 -0
  139. package/src/migrations/postgres/0045_decide_first.sql +878 -0
  140. package/src/migrations/postgres/0046_way_in_uses.sql +1149 -0
  141. package/src/migrations/postgres/0047_cutover_finish.sql +268 -0
  142. package/src/migrations/postgres/0048_use_batch.sql +59 -0
  143. package/src/migrations/postgres/0049_reads.sql +171 -0
  144. package/src/migrations/postgres/meta/0022_snapshot.json +3831 -0
  145. package/src/migrations/postgres/meta/0023_snapshot.json +3831 -0
  146. package/src/migrations/postgres/meta/0024_snapshot.json +3831 -0
  147. package/src/migrations/postgres/meta/0025_snapshot.json +3831 -0
  148. package/src/migrations/postgres/meta/0026_snapshot.json +3831 -0
  149. package/src/migrations/postgres/meta/0027_snapshot.json +3853 -0
  150. package/src/migrations/postgres/meta/0028_snapshot.json +3853 -0
  151. package/src/migrations/postgres/meta/0029_snapshot.json +3859 -0
  152. package/src/migrations/postgres/meta/0030_snapshot.json +3859 -0
  153. package/src/migrations/postgres/meta/0031_snapshot.json +3859 -0
  154. package/src/migrations/postgres/meta/0032_snapshot.json +3875 -0
  155. package/src/migrations/postgres/meta/0033_snapshot.json +3875 -0
  156. package/src/migrations/postgres/meta/0034_snapshot.json +3875 -0
  157. package/src/migrations/postgres/meta/0035_snapshot.json +3875 -0
  158. package/src/migrations/postgres/meta/0036_snapshot.json +3875 -0
  159. package/src/migrations/postgres/meta/0037_snapshot.json +3875 -0
  160. package/src/migrations/postgres/meta/0038_snapshot.json +3881 -0
  161. package/src/migrations/postgres/meta/0039_snapshot.json +3881 -0
  162. package/src/migrations/postgres/meta/0040_snapshot.json +3931 -0
  163. package/src/migrations/postgres/meta/0041_snapshot.json +3981 -0
  164. package/src/migrations/postgres/meta/0042_snapshot.json +3981 -0
  165. package/src/migrations/postgres/meta/0043_snapshot.json +3981 -0
  166. package/src/migrations/postgres/meta/0044_snapshot.json +3991 -0
  167. package/src/migrations/postgres/meta/0045_snapshot.json +3997 -0
  168. package/src/migrations/postgres/meta/0046_snapshot.json +3997 -0
  169. package/src/migrations/postgres/meta/0047_snapshot.json +4234 -0
  170. package/src/migrations/postgres/meta/_journal.json +182 -0
  171. package/src/migrations/sqlite/0018_log_015.sql +84 -0
  172. package/src/migrations/sqlite/0019_retention.sql +2 -0
  173. package/src/migrations/sqlite/0020_ended_references.sql +1 -0
  174. package/src/migrations/sqlite/0021_secrets_live_index.sql +1 -0
  175. package/src/migrations/sqlite/0022_binding_origin.sql +1 -0
  176. package/src/migrations/sqlite/0023_sign_in_index.sql +2 -0
  177. package/src/migrations/sqlite/0024_issue_revoke_index.sql +2 -0
  178. package/src/migrations/sqlite/0025_way_in_uses.sql +42 -0
  179. package/src/migrations/sqlite/0026_cutover_finish.sql +11 -0
  180. package/src/migrations/sqlite/0027_reads.sql +38 -0
  181. package/src/migrations/sqlite/meta/0018_snapshot.json +3529 -0
  182. package/src/migrations/sqlite/meta/0019_snapshot.json +3538 -0
  183. package/src/migrations/sqlite/meta/0020_snapshot.json +3545 -0
  184. package/src/migrations/sqlite/meta/0021_snapshot.json +3553 -0
  185. package/src/migrations/sqlite/meta/0022_snapshot.json +3560 -0
  186. package/src/migrations/sqlite/meta/0023_snapshot.json +3579 -0
  187. package/src/migrations/sqlite/meta/0024_snapshot.json +3598 -0
  188. package/src/migrations/sqlite/meta/0025_snapshot.json +3609 -0
  189. package/src/migrations/sqlite/meta/0026_snapshot.json +3616 -0
  190. package/src/migrations/sqlite/meta/0027_snapshot.json +3834 -0
  191. package/src/migrations/sqlite/meta/_journal.json +70 -0
  192. package/src/postgres-js/README.md +183 -0
  193. package/src/postgres-js/UNLICENSE +24 -0
  194. package/src/postgres-js/bytes.ts +89 -0
  195. package/src/postgres-js/connection.ts +882 -0
  196. package/src/postgres-js/errors.ts +84 -0
  197. package/src/postgres-js/index.ts +516 -0
  198. package/src/postgres-js/platform.node.ts +29 -0
  199. package/src/postgres-js/platform.ts +60 -0
  200. package/src/postgres-js/platform.workerd.ts +225 -0
  201. package/src/postgres-js/query.ts +123 -0
  202. package/src/postgres-js/queue.ts +42 -0
  203. package/src/postgres-js/result.ts +46 -0
  204. package/src/postgres-js/types.ts +52 -0
  205. package/src/postgres.ts +375 -26
  206. package/src/schema-version.ts +2 -2
  207. package/src/schema.sqlite.ts +198 -7
  208. package/src/schema.ts +291 -6
  209. package/src/verify-runtime.ts +18 -29
  210. package/LICENSE +0 -21
  211. package/dist/database-wq1AVRAP.d.ts +0 -73
  212. package/dist/postgres-Bmar8y0q.js +0 -29
  213. package/dist/relations-BfR3JjT1.js +0 -38
  214. package/src/relations.ts +0 -40
@@ -0,0 +1,722 @@
1
+ import { a as Queryable, o as Transaction } from "./database-CVteLhp1.js";
2
+ import { Placeholder, SQL, SQLWrapper } from "drizzle-orm";
3
+ import { LogKey, StoredEntry } from "@coffre/core/audit";
4
+ import { PreparedChange } from "@coffre/core/vault";
5
+ //#region src/change-records.d.ts
6
+ /**
7
+ * What a change of 0.15's log records besides its op, which the audit pages
8
+ * list where 0.14's entry stood (D147): a sign-in through a trust binding
9
+ * (`signIn`, T156); a token the vault issued (`issue`); a credential it
10
+ * revoked by request, or that signed itself out (a revoke's `reason`,
11
+ * T164). Each is known by text its payload holds (`holds`), and by how the
12
+ * payload starts (`starts`): the vault writes it canonical, its keys in
13
+ * order, so an issue's is `{"caller":…` and a revoke's
14
+ * `{"op":"credential.revoke",…`. A string the payload holds has its quotes
15
+ * escaped, but an object's keys need not be the vault's own (a role's
16
+ * name, in the roles' change: review r1), so where the text alone could be
17
+ * one, the start says whose payload it is. The partial indexes of
18
+ * `log_changes` hold each set, and a read that is to use one repeats its
19
+ * condition (`recorded`), word for word and with no parameter.
20
+ */
21
+ declare const RECORDS: {
22
+ readonly signIn: {
23
+ readonly holds: "\"signIn\":{";
24
+ };
25
+ readonly issue: {
26
+ readonly starts: "{\"caller\":\"";
27
+ readonly holds: "\"issue\":{\"by\":\"";
28
+ };
29
+ readonly revoke: {
30
+ readonly starts: "{\"op\":\"credential.revoke\",";
31
+ readonly holds: "\"reason\":\"revoke\"";
32
+ };
33
+ readonly signOut: {
34
+ readonly starts: "{\"op\":\"credential.revoke\",";
35
+ readonly holds: "\"reason\":\"sign_out\"";
36
+ };
37
+ };
38
+ type ChangeRecord = keyof typeof RECORDS;
39
+ /** Whether `payload` holds one of `records`, on Postgres or SQLite: an index's condition, and the reads' that use it. */
40
+ declare function recorded(engine: 'postgres' | 'sqlite', payload: SQLWrapper, ...records: ChangeRecord[]): SQL;
41
+ //#endregion
42
+ //#region src/log.d.ts
43
+ /**
44
+ * Appending to the audit log, the one table both the app and the vault
45
+ * write, each under its own key (@coffre/core/audit says what an entry's MAC
46
+ * and hash cover).
47
+ *
48
+ * Every append locks the log's head first, `audit_chain_head`, so entries
49
+ * from any process take their numbers in one order. It then reads the
50
+ * database clock, after the lock, and the log's last entry, which the head
51
+ * must name: a head that does not was moved, or entries were deleted behind
52
+ * it, and the append refuses. The same statement says whether the log has
53
+ * moved on from the key it appends under (`KeyRetired`).
54
+ *
55
+ * This is deliberately not a queue and not best-effort: the entries go in
56
+ * the caller's transaction, so if the append fails, what it records does
57
+ * not happen either.
58
+ */
59
+ /** An entry to append: what it says. The append numbers, dates, signs and chains it. */
60
+ type NewEntry = {
61
+ actor: string;
62
+ action: string;
63
+ decision: 'allow' | 'deny';
64
+ code?: string | null;
65
+ subjectPrincipal?: string | null;
66
+ projectId?: string | null;
67
+ environmentId?: string | null;
68
+ secretId?: string | null;
69
+ secretVersionId?: string | null;
70
+ operationId?: string | null;
71
+ requestId?: string | null;
72
+ sourceIp?: string | null;
73
+ relatedSeq?: bigint | null;
74
+ /** JSON text. */
75
+ metadata?: string;
76
+ };
77
+ type Appended = {
78
+ /** The first entry's number, and the next number after the last. */
79
+ seqStart: bigint;
80
+ nextSeq: bigint;
81
+ headHash: Buffer;
82
+ /** Milliseconds since the epoch, the database's, shared by the batch. */
83
+ occurredAt: number;
84
+ };
85
+ /** The log's head does not name its last entry: something moved it, or cut the log behind it. */
86
+ declare class LogHeadMismatch extends Error {
87
+ constructor(message: string);
88
+ }
89
+ /**
90
+ * As many transactions as may already wait for the log's head do
91
+ * (`lockLogHeadQueued`): this one waits for nothing, and holds nothing.
92
+ * Its code is Postgres's for a lock not available, so every caller already
93
+ * answers it as one that gave up waiting: unavailable, ask again shortly.
94
+ */
95
+ declare class HeadBusy extends Error {
96
+ readonly code = "55P03";
97
+ constructor();
98
+ }
99
+ /**
100
+ * The log's head is behind one this process wrote: the database was rolled
101
+ * back, or entries were cut off its end. That cannot be told from a restore,
102
+ * so the append refuses and someone has to look.
103
+ */
104
+ declare class LogRewound extends Error {
105
+ constructor(message: string);
106
+ }
107
+ /**
108
+ * An append under a key the log has moved on from: an entry of its
109
+ * author's, `key.reseal` or `key.rotate`, names it as the key it moves
110
+ * from (`MOVES_FROM`), and a key moved from writes no more.
111
+ */
112
+ declare class KeyRetired extends Error {
113
+ constructor(message: string);
114
+ }
115
+ /**
116
+ * The actions by which an author moves to a new key, each under the new one
117
+ * and naming the key it moves from as its subject: from the first, that key
118
+ * writes no more (`KeyRetired`). The app's key rotation writes them
119
+ * (packages/server/src/key-rotation.ts).
120
+ */
121
+ declare const MOVES_FROM: readonly ["key.reseal", "key.rotate"];
122
+ /**
123
+ * Forget every head written so far. For tests that empty the database
124
+ * between cases, which is exactly what the check above refuses.
125
+ */
126
+ declare function forgetLogHeads(): void;
127
+ /**
128
+ * Lock the log's head, and read it. A transaction that appends takes this
129
+ * before any other row, so the lock order is the same everywhere; taking it
130
+ * again in the same transaction is free.
131
+ */
132
+ declare function lockLogHead(tx: Transaction): Promise<{
133
+ nextSeq: bigint;
134
+ headHash: Buffer;
135
+ }>;
136
+ /**
137
+ * Take the issue lock exclusive (migration 0026's, `1668244070, 1`): every
138
+ * issue in flight, a sign-in or a token's, ends first, and none starts
139
+ * until this transaction does. A write that moves what an issue's policy
140
+ * check compares (`issue_token`: the policy, a protected environment's
141
+ * slug) takes it, after its own rows and before the fence its append's
142
+ * trigger takes, as the checkpointer's barrier does: so the issue is
143
+ * ordered against it, and no use waits behind an issue (formal/Lifecycle.tla's
144
+ * IssuePolicyHeld, Migration015.tla's PolicyIssueFirst; T149, review r3).
145
+ * SQLite's transactions hold the whole file.
146
+ */
147
+ declare function holdIssues(tx: Transaction): Promise<void>;
148
+ /**
149
+ * The issue lock shared, then 0.15's fence exclusive (`1668244070, 0`), as
150
+ * 0.14's trigger takes them for an entry that changes access: what 0.15's
151
+ * cutover holds, its member rows and 0.14's head taken first, so that its
152
+ * own 0.14 entry's trigger waits on nothing (formal/Migration015.tla,
153
+ * CutoverIssueFirst; T132). Every use and every change waits for its
154
+ * commit; the checkpointer's barrier, which takes the issue lock exclusive
155
+ * first, too. SQLite's transactions hold the whole file.
156
+ */
157
+ declare function holdFence(tx: Transaction): Promise<void>;
158
+ /**
159
+ * Lock the log's head if no one holds it, without waiting: whether it is
160
+ * held now. For work any caller may do, of which one at a time is enough,
161
+ * which a request that finds the head taken leaves to the one that has it.
162
+ * SQLite's transactions hold the whole file, so the head is always free.
163
+ */
164
+ declare function lockLogHeadIfFree(tx: Transaction): Promise<boolean>;
165
+ /**
166
+ * Lock the log's head, waiting for it as `lockLogHead` does, if fewer than
167
+ * `waiters` other transactions hold one of its places in line; otherwise
168
+ * refuse at once (`HeadBusy`), having waited for nothing. A place is an
169
+ * advisory lock, tried, never waited for, and held to the end of the
170
+ * transaction, which holds the head by then: so at most `waiters`
171
+ * connections wait for the head, or hold it, through here, and a burst
172
+ * beyond them answers in one round trip rather than seconds later, holding
173
+ * a connection all the while. One statement: the place, then, only if one
174
+ * was free, the head; refused, one more says whether the head is there at
175
+ * all. SQLite's transactions hold the whole file.
176
+ */
177
+ declare function lockLogHeadQueued(tx: Transaction, waiters: number): Promise<{
178
+ nextSeq: bigint;
179
+ headHash: Buffer;
180
+ }>;
181
+ /**
182
+ * Append `entries` under `key`. `check`, when given, runs once the head is
183
+ * locked and before anything is written: a writer's own condition on the
184
+ * log as it stands, which no other append can change until this one
185
+ * commits. It throws to refuse.
186
+ */
187
+ declare function appendEntries(tx: Transaction, key: LogKey, entries: readonly NewEntry[], check?: (tx: Transaction) => Promise<void>,
188
+ /**
189
+ * The head as a statement of the caller's locked it, with the log's last
190
+ * entry and the clock as that statement read them once it held the lock:
191
+ * nothing to read again.
192
+ */
193
+ locked?: HeldHead,
194
+ /**
195
+ * 0.15's changes of the app's write these entries record (`appChanges`):
196
+ * on Postgres, made in the append's own statement, one round trip less
197
+ * under the head, which every sign-in waits for (T123). Their numbers
198
+ * come back as `changes`.
199
+ */
200
+ changes?: readonly PreparedChange[],
201
+ /**
202
+ * Whether the writer runs under 0.15's log: its entries carry `log015`,
203
+ * which no MAC covers and 0.14's code never sets. Once the log is cut
204
+ * over, migration 0047's trigger refuses a write's entry without it.
205
+ */
206
+ log015?: boolean): Promise<Appended & {
207
+ changes: (bigint | null)[];
208
+ }>;
209
+ /** A head locked by a statement of the caller's, and what it read under the lock (`appendEntries`). */
210
+ type HeldHead = {
211
+ head: {
212
+ nextSeq: bigint;
213
+ headHash: Buffer;
214
+ };
215
+ last: {
216
+ seq: bigint;
217
+ hash: Buffer;
218
+ } | null;
219
+ at: number;
220
+ };
221
+ /** An entry's columns, as the chain's codec reads them (`StoredEntry`). */
222
+ declare function entryColumns(db: Queryable): {
223
+ seq: import("drizzle-orm/pg-core").PgColumn<{
224
+ name: "seq";
225
+ tableName: "audit_log";
226
+ dataType: "bigint";
227
+ columnType: "PgBigInt64";
228
+ data: bigint;
229
+ driverParam: string;
230
+ notNull: true;
231
+ hasDefault: false;
232
+ isPrimaryKey: true;
233
+ isAutoincrement: false;
234
+ hasRuntimeDefault: false;
235
+ enumValues: undefined;
236
+ baseColumn: never;
237
+ identity: undefined;
238
+ generated: undefined;
239
+ }, {}, {}>;
240
+ author: import("drizzle-orm/pg-core").PgColumn<{
241
+ name: "author";
242
+ tableName: "audit_log";
243
+ dataType: "string";
244
+ columnType: "PgText";
245
+ data: string;
246
+ driverParam: string;
247
+ notNull: true;
248
+ hasDefault: false;
249
+ isPrimaryKey: false;
250
+ isAutoincrement: false;
251
+ hasRuntimeDefault: false;
252
+ enumValues: [string, ...string[]];
253
+ baseColumn: never;
254
+ identity: undefined;
255
+ generated: undefined;
256
+ }, {}, {}>;
257
+ keyId: import("drizzle-orm/pg-core").PgColumn<{
258
+ name: "key_id";
259
+ tableName: "audit_log";
260
+ dataType: "string";
261
+ columnType: "PgText";
262
+ data: string;
263
+ driverParam: string;
264
+ notNull: true;
265
+ hasDefault: false;
266
+ isPrimaryKey: false;
267
+ isAutoincrement: false;
268
+ hasRuntimeDefault: false;
269
+ enumValues: [string, ...string[]];
270
+ baseColumn: never;
271
+ identity: undefined;
272
+ generated: undefined;
273
+ }, {}, {}>;
274
+ occurredAt: import("drizzle-orm/pg-core").PgColumn<{
275
+ name: "occurred_at";
276
+ tableName: "audit_log";
277
+ dataType: "number";
278
+ columnType: "PgBigInt53";
279
+ data: number;
280
+ driverParam: string | number;
281
+ notNull: true;
282
+ hasDefault: false;
283
+ isPrimaryKey: false;
284
+ isAutoincrement: false;
285
+ hasRuntimeDefault: false;
286
+ enumValues: undefined;
287
+ baseColumn: never;
288
+ identity: undefined;
289
+ generated: undefined;
290
+ }, {}, {}>;
291
+ actor: import("drizzle-orm/pg-core").PgColumn<{
292
+ name: "actor";
293
+ tableName: "audit_log";
294
+ dataType: "string";
295
+ columnType: "PgText";
296
+ data: string;
297
+ driverParam: string;
298
+ notNull: true;
299
+ hasDefault: false;
300
+ isPrimaryKey: false;
301
+ isAutoincrement: false;
302
+ hasRuntimeDefault: false;
303
+ enumValues: [string, ...string[]];
304
+ baseColumn: never;
305
+ identity: undefined;
306
+ generated: undefined;
307
+ }, {}, {}>;
308
+ action: import("drizzle-orm/pg-core").PgColumn<{
309
+ name: "action";
310
+ tableName: "audit_log";
311
+ dataType: "string";
312
+ columnType: "PgText";
313
+ data: string;
314
+ driverParam: string;
315
+ notNull: true;
316
+ hasDefault: false;
317
+ isPrimaryKey: false;
318
+ isAutoincrement: false;
319
+ hasRuntimeDefault: false;
320
+ enumValues: [string, ...string[]];
321
+ baseColumn: never;
322
+ identity: undefined;
323
+ generated: undefined;
324
+ }, {}, {}>;
325
+ decision: import("drizzle-orm/pg-core").PgColumn<{
326
+ name: "decision";
327
+ tableName: "audit_log";
328
+ dataType: "string";
329
+ columnType: "PgText";
330
+ data: string;
331
+ driverParam: string;
332
+ notNull: true;
333
+ hasDefault: false;
334
+ isPrimaryKey: false;
335
+ isAutoincrement: false;
336
+ hasRuntimeDefault: false;
337
+ enumValues: [string, ...string[]];
338
+ baseColumn: never;
339
+ identity: undefined;
340
+ generated: undefined;
341
+ }, {}, {}>;
342
+ code: import("drizzle-orm/pg-core").PgColumn<{
343
+ name: "code";
344
+ tableName: "audit_log";
345
+ dataType: "string";
346
+ columnType: "PgText";
347
+ data: string;
348
+ driverParam: string;
349
+ notNull: false;
350
+ hasDefault: false;
351
+ isPrimaryKey: false;
352
+ isAutoincrement: false;
353
+ hasRuntimeDefault: false;
354
+ enumValues: [string, ...string[]];
355
+ baseColumn: never;
356
+ identity: undefined;
357
+ generated: undefined;
358
+ }, {}, {}>;
359
+ subjectPrincipal: import("drizzle-orm/pg-core").PgColumn<{
360
+ name: "subject_principal";
361
+ tableName: "audit_log";
362
+ dataType: "string";
363
+ columnType: "PgText";
364
+ data: string;
365
+ driverParam: string;
366
+ notNull: false;
367
+ hasDefault: false;
368
+ isPrimaryKey: false;
369
+ isAutoincrement: false;
370
+ hasRuntimeDefault: false;
371
+ enumValues: [string, ...string[]];
372
+ baseColumn: never;
373
+ identity: undefined;
374
+ generated: undefined;
375
+ }, {}, {}>;
376
+ projectId: import("drizzle-orm/pg-core").PgColumn<{
377
+ name: "project_id";
378
+ tableName: "audit_log";
379
+ dataType: "string";
380
+ columnType: "PgUUID";
381
+ data: string;
382
+ driverParam: string;
383
+ notNull: false;
384
+ hasDefault: false;
385
+ isPrimaryKey: false;
386
+ isAutoincrement: false;
387
+ hasRuntimeDefault: false;
388
+ enumValues: undefined;
389
+ baseColumn: never;
390
+ identity: undefined;
391
+ generated: undefined;
392
+ }, {}, {}>;
393
+ environmentId: import("drizzle-orm/pg-core").PgColumn<{
394
+ name: "environment_id";
395
+ tableName: "audit_log";
396
+ dataType: "string";
397
+ columnType: "PgUUID";
398
+ data: string;
399
+ driverParam: string;
400
+ notNull: false;
401
+ hasDefault: false;
402
+ isPrimaryKey: false;
403
+ isAutoincrement: false;
404
+ hasRuntimeDefault: false;
405
+ enumValues: undefined;
406
+ baseColumn: never;
407
+ identity: undefined;
408
+ generated: undefined;
409
+ }, {}, {}>;
410
+ secretId: import("drizzle-orm/pg-core").PgColumn<{
411
+ name: "secret_id";
412
+ tableName: "audit_log";
413
+ dataType: "string";
414
+ columnType: "PgUUID";
415
+ data: string;
416
+ driverParam: string;
417
+ notNull: false;
418
+ hasDefault: false;
419
+ isPrimaryKey: false;
420
+ isAutoincrement: false;
421
+ hasRuntimeDefault: false;
422
+ enumValues: undefined;
423
+ baseColumn: never;
424
+ identity: undefined;
425
+ generated: undefined;
426
+ }, {}, {}>;
427
+ secretVersionId: import("drizzle-orm/pg-core").PgColumn<{
428
+ name: "secret_version_id";
429
+ tableName: "audit_log";
430
+ dataType: "string";
431
+ columnType: "PgUUID";
432
+ data: string;
433
+ driverParam: string;
434
+ notNull: false;
435
+ hasDefault: false;
436
+ isPrimaryKey: false;
437
+ isAutoincrement: false;
438
+ hasRuntimeDefault: false;
439
+ enumValues: undefined;
440
+ baseColumn: never;
441
+ identity: undefined;
442
+ generated: undefined;
443
+ }, {}, {}>;
444
+ operationId: import("drizzle-orm/pg-core").PgColumn<{
445
+ name: "operation_id";
446
+ tableName: "audit_log";
447
+ dataType: "string";
448
+ columnType: "PgUUID";
449
+ data: string;
450
+ driverParam: string;
451
+ notNull: false;
452
+ hasDefault: false;
453
+ isPrimaryKey: false;
454
+ isAutoincrement: false;
455
+ hasRuntimeDefault: false;
456
+ enumValues: undefined;
457
+ baseColumn: never;
458
+ identity: undefined;
459
+ generated: undefined;
460
+ }, {}, {}>;
461
+ requestId: import("drizzle-orm/pg-core").PgColumn<{
462
+ name: "request_id";
463
+ tableName: "audit_log";
464
+ dataType: "string";
465
+ columnType: "PgText";
466
+ data: string;
467
+ driverParam: string;
468
+ notNull: false;
469
+ hasDefault: false;
470
+ isPrimaryKey: false;
471
+ isAutoincrement: false;
472
+ hasRuntimeDefault: false;
473
+ enumValues: [string, ...string[]];
474
+ baseColumn: never;
475
+ identity: undefined;
476
+ generated: undefined;
477
+ }, {}, {}>;
478
+ sourceIp: import("drizzle-orm/pg-core").PgColumn<{
479
+ name: "source_ip";
480
+ tableName: "audit_log";
481
+ dataType: "string";
482
+ columnType: "PgText";
483
+ data: string;
484
+ driverParam: string;
485
+ notNull: false;
486
+ hasDefault: false;
487
+ isPrimaryKey: false;
488
+ isAutoincrement: false;
489
+ hasRuntimeDefault: false;
490
+ enumValues: [string, ...string[]];
491
+ baseColumn: never;
492
+ identity: undefined;
493
+ generated: undefined;
494
+ }, {}, {}>;
495
+ relatedSeq: import("drizzle-orm/pg-core").PgColumn<{
496
+ name: "related_seq";
497
+ tableName: "audit_log";
498
+ dataType: "bigint";
499
+ columnType: "PgBigInt64";
500
+ data: bigint;
501
+ driverParam: string;
502
+ notNull: false;
503
+ hasDefault: false;
504
+ isPrimaryKey: false;
505
+ isAutoincrement: false;
506
+ hasRuntimeDefault: false;
507
+ enumValues: undefined;
508
+ baseColumn: never;
509
+ identity: undefined;
510
+ generated: undefined;
511
+ }, {}, {}>;
512
+ metadata: import("drizzle-orm/pg-core").PgColumn<{
513
+ name: "metadata";
514
+ tableName: "audit_log";
515
+ dataType: "string";
516
+ columnType: "PgText";
517
+ data: string;
518
+ driverParam: string;
519
+ notNull: true;
520
+ hasDefault: true;
521
+ isPrimaryKey: false;
522
+ isAutoincrement: false;
523
+ hasRuntimeDefault: false;
524
+ enumValues: [string, ...string[]];
525
+ baseColumn: never;
526
+ identity: undefined;
527
+ generated: undefined;
528
+ }, {}, {}>;
529
+ prevHash: import("drizzle-orm/pg-core").PgColumn<{
530
+ name: "prev_hash";
531
+ tableName: "audit_log";
532
+ dataType: "custom";
533
+ columnType: "PgCustomColumn";
534
+ data: Buffer<ArrayBufferLike>;
535
+ driverParam: unknown;
536
+ notNull: true;
537
+ hasDefault: false;
538
+ isPrimaryKey: false;
539
+ isAutoincrement: false;
540
+ hasRuntimeDefault: false;
541
+ enumValues: undefined;
542
+ baseColumn: never;
543
+ identity: undefined;
544
+ generated: undefined;
545
+ }, {}, {
546
+ pgColumnBuilderBrand: "PgCustomColumnBuilderBrand";
547
+ }>;
548
+ mac: import("drizzle-orm/pg-core").PgColumn<{
549
+ name: "mac";
550
+ tableName: "audit_log";
551
+ dataType: "custom";
552
+ columnType: "PgCustomColumn";
553
+ data: Buffer<ArrayBufferLike>;
554
+ driverParam: unknown;
555
+ notNull: true;
556
+ hasDefault: false;
557
+ isPrimaryKey: false;
558
+ isAutoincrement: false;
559
+ hasRuntimeDefault: false;
560
+ enumValues: undefined;
561
+ baseColumn: never;
562
+ identity: undefined;
563
+ generated: undefined;
564
+ }, {}, {
565
+ pgColumnBuilderBrand: "PgCustomColumnBuilderBrand";
566
+ }>;
567
+ hash: import("drizzle-orm/pg-core").PgColumn<{
568
+ name: "hash";
569
+ tableName: "audit_log";
570
+ dataType: "custom";
571
+ columnType: "PgCustomColumn";
572
+ data: Buffer<ArrayBufferLike>;
573
+ driverParam: unknown;
574
+ notNull: true;
575
+ hasDefault: false;
576
+ isPrimaryKey: false;
577
+ isAutoincrement: false;
578
+ hasRuntimeDefault: false;
579
+ enumValues: undefined;
580
+ baseColumn: never;
581
+ identity: undefined;
582
+ generated: undefined;
583
+ }, {}, {
584
+ pgColumnBuilderBrand: "PgCustomColumnBuilderBrand";
585
+ }>;
586
+ };
587
+ /**
588
+ * Metadata a reader of many entries holds at once, at most: an entry about
589
+ * a read of several secrets lists them, a thousand some 150 kilobytes, so a
590
+ * count of entries alone does not bound a batch's or a page's memory within
591
+ * a Worker's 128 megabytes.
592
+ */
593
+ declare const BATCH_BYTES: number;
594
+ /**
595
+ * Of the entries `where` matches, in `order` of seq, the first `limit` or
596
+ * fewer that hold no more than `BATCH_BYTES` of metadata between them, but
597
+ * always the first: the seqs they run from and to, and whether the bytes
598
+ * cut the run short of `limit`. Null when none matches. A reader asks this
599
+ * first, then reads `where` between the two.
600
+ */
601
+ declare function withinBytes(db: Queryable, where: SQL | undefined, limit: number, order?: 'asc' | 'desc'): Promise<{
602
+ from: bigint;
603
+ to: bigint;
604
+ cut: boolean;
605
+ count: number;
606
+ } | null>;
607
+ /**
608
+ * The first entry missing from the log up to `seq`, and the one found in
609
+ * its place, or null when every one is there. Seqs are the primary key, so
610
+ * a stretch is whole exactly when its count is its length: one pass over
611
+ * the key's index, never the entries. Only a log with a gap pays for more,
612
+ * a count per halving to find where.
613
+ *
614
+ * entries 0..9, 4 cut: { expected: 4n, found: 5n }
615
+ */
616
+ declare function missingEntry(db: Queryable, seq: bigint): Promise<{
617
+ expected: bigint;
618
+ found: bigint | null;
619
+ } | null>;
620
+ /**
621
+ * How a reader tells the vault's own entries from those forged in its name:
622
+ * by their MAC, which only the vault holds the key to check. Each it finds
623
+ * forged goes to `forged`.
624
+ */
625
+ type Authenticity = {
626
+ authentic: (entry: StoredEntry) => boolean;
627
+ forged: (entry: StoredEntry) => void;
628
+ };
629
+ /** Up to `limit` of the entries in the vault's name, allowed, of one `action`, before `before` (the newest when undefined), newest first. */
630
+ declare function newestVaultEntries(db: Queryable, action: string, limit: number, before?: bigint): Promise<StoredEntry[]>;
631
+ /**
632
+ * The number of the newest entry in the vault's name, allowed, of one
633
+ * `action`, or null for none: whether one was appended since, and nothing
634
+ * of what it says, so its MAC is not checked. One indexed read.
635
+ */
636
+ declare function newestVaultSeq(db: Queryable, action: string): Promise<bigint | null>;
637
+ /**
638
+ * `newestVaultSeq`'s query, to run or to read inside another, as a
639
+ * credential's read takes the newest `policy.change` with it: one rule for
640
+ * what the newest is, wherever it is read.
641
+ */
642
+ declare function newestSeqQuery(db: Queryable, action: string | Placeholder): Omit<import("drizzle-orm/pg-core").PgSelectBase<"audit_log", {
643
+ seq: import("drizzle-orm/pg-core").PgColumn<{
644
+ name: "seq";
645
+ tableName: "audit_log";
646
+ dataType: "bigint";
647
+ columnType: "PgBigInt64";
648
+ data: bigint;
649
+ driverParam: string;
650
+ notNull: true;
651
+ hasDefault: false;
652
+ isPrimaryKey: true;
653
+ isAutoincrement: false;
654
+ hasRuntimeDefault: false;
655
+ enumValues: undefined;
656
+ baseColumn: never;
657
+ identity: undefined;
658
+ generated: undefined;
659
+ }, {}, {}>;
660
+ }, "partial", Record<"audit_log", "not-null">, false, "where" | "orderBy" | "limit", {
661
+ seq: bigint;
662
+ }[], {
663
+ seq: import("drizzle-orm/pg-core").PgColumn<{
664
+ name: "seq";
665
+ tableName: "audit_log";
666
+ dataType: "bigint";
667
+ columnType: "PgBigInt64";
668
+ data: bigint;
669
+ driverParam: string;
670
+ notNull: true;
671
+ hasDefault: false;
672
+ isPrimaryKey: true;
673
+ isAutoincrement: false;
674
+ hasRuntimeDefault: false;
675
+ enumValues: undefined;
676
+ baseColumn: never;
677
+ identity: undefined;
678
+ generated: undefined;
679
+ }, {}, {}>;
680
+ }>, "where" | "orderBy" | "limit">;
681
+ /** How many entries in its name the vault reads back, a page at a time, for its own newest of a kind (`newestAuthentic`). */
682
+ declare const LOOK_BACK: {
683
+ page: number;
684
+ pages: number;
685
+ };
686
+ /** What `newestAuthentic` finds: the entry, or why there is none. */
687
+ type Newest = StoredEntry | 'none' | 'forged' | 'unreached';
688
+ /**
689
+ * The newest of the entries `page` reads, newest first and before a seq,
690
+ * that `check` finds authentic: the newest alone first, which it is unless
691
+ * entries were forged in the vault's name since, then back a page at a
692
+ * time. 'none' when there are none at all, 'forged' when every one is in
693
+ * the vault's name but not its own, and 'unreached' once it has read
694
+ * LOOK_BACK such entries (1024), whether or not more are left.
695
+ */
696
+ declare function newestAuthentic(page: (limit: number, before: bigint | undefined) => Promise<StoredEntry[]>, check: Authenticity): Promise<Newest>;
697
+ /**
698
+ * The app's changes to the objects its rows hold, as the vault sealed them
699
+ * (`Vault.prepare`), each `app_change` (migrations 0025, 0026 and 0030), in its
700
+ * transaction, once its rows and 0.14 entries are written: in order, in one
701
+ * round trip, or in the append's own (`appendEntries`). Each entry's number;
702
+ * 0 for a row of 0.14's, which logs nothing; null where a row's seal moved
703
+ * since the app read it, and nothing was done (ChangeCAS: read again). A row
704
+ * that is not its object's newest change's fails the call (`isStaleChange`),
705
+ * and its transaction with it.
706
+ *
707
+ * On SQLite, which has no functions, the same steps in the transaction,
708
+ * which holds the database's one write lock: the fence is implicit there
709
+ * (0.15's plan, "Postgres serves; SQLite is for tests").
710
+ */
711
+ declare function appChanges(tx: Transaction, calls: readonly PreparedChange[]): Promise<(bigint | null)[]>;
712
+ /**
713
+ * An object's key in 0.15's log, `log_changes.object`: the first 16 bytes
714
+ * of SHA-256 over its kind and id, as a uuid (`log_object` in SQL). The
715
+ * vault's (`objectKey`), and the app's, which finds a credential's sign-in
716
+ * by it.
717
+ */
718
+ declare function logObject(kind: string, id: string): string;
719
+ /** Whether `error` is `app_change`'s refusal of a row that is not its object's newest change's: Postgres's `data_corrupted`. */
720
+ declare function isStaleChange(error: unknown): boolean;
721
+ //#endregion
722
+ export { ChangeRecord as A, logObject as C, newestVaultEntries as D, newestSeqQuery as E, recorded as M, newestVaultSeq as O, lockLogHeadQueued as S, newestAuthentic as T, holdFence as _, HeldHead as a, lockLogHead as b, LogHeadMismatch as c, NewEntry as d, Newest as f, forgetLogHeads as g, entryColumns as h, HeadBusy as i, RECORDS as j, withinBytes as k, LogRewound as l, appendEntries as m, Authenticity as n, KeyRetired as o, appChanges as p, BATCH_BYTES as r, LOOK_BACK as s, Appended as t, MOVES_FROM as u, holdIssues as v, missingEntry as w, lockLogHeadIfFree as x, isStaleChange as y };