@ddd-ts-kit/audit 0.0.0-stage → 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.
Files changed (338) hide show
  1. package/README.md +559 -2
  2. package/dist/chain/audit-checkpoint.d.ts +7 -0
  3. package/dist/chain/audit-checkpoint.d.ts.map +1 -0
  4. package/dist/chain/audit-checkpoint.js +2 -0
  5. package/dist/chain/audit-checkpoint.js.map +1 -0
  6. package/dist/chain/canonicalize.d.ts +8 -0
  7. package/dist/chain/canonicalize.d.ts.map +1 -0
  8. package/dist/chain/canonicalize.js +26 -0
  9. package/dist/chain/canonicalize.js.map +1 -0
  10. package/dist/chain/chain-head.d.ts +8 -0
  11. package/dist/chain/chain-head.d.ts.map +1 -0
  12. package/dist/chain/chain-head.js +2 -0
  13. package/dist/chain/chain-head.js.map +1 -0
  14. package/dist/chain/chain-of-tenant.d.ts +9 -0
  15. package/dist/chain/chain-of-tenant.d.ts.map +1 -0
  16. package/dist/chain/chain-of-tenant.js +10 -0
  17. package/dist/chain/chain-of-tenant.js.map +1 -0
  18. package/dist/chain/empty-chain.d.ts +3 -0
  19. package/dist/chain/empty-chain.d.ts.map +1 -0
  20. package/dist/chain/empty-chain.js +5 -0
  21. package/dist/chain/empty-chain.js.map +1 -0
  22. package/dist/chain/genesis-hash.d.ts +3 -0
  23. package/dist/chain/genesis-hash.d.ts.map +1 -0
  24. package/dist/chain/genesis-hash.js +3 -0
  25. package/dist/chain/genesis-hash.js.map +1 -0
  26. package/dist/chain/hash-of.d.ts +5 -0
  27. package/dist/chain/hash-of.d.ts.map +1 -0
  28. package/dist/chain/hash-of.js +8 -0
  29. package/dist/chain/hash-of.js.map +1 -0
  30. package/dist/chain/head-after.d.ts +4 -0
  31. package/dist/chain/head-after.d.ts.map +1 -0
  32. package/dist/chain/head-after.js +4 -0
  33. package/dist/chain/head-after.js.map +1 -0
  34. package/dist/chain/seal-checkpoint.d.ts +4 -0
  35. package/dist/chain/seal-checkpoint.d.ts.map +1 -0
  36. package/dist/chain/seal-checkpoint.js +7 -0
  37. package/dist/chain/seal-checkpoint.js.map +1 -0
  38. package/dist/chain/seal.d.ts +5 -0
  39. package/dist/chain/seal.d.ts.map +1 -0
  40. package/dist/chain/seal.js +13 -0
  41. package/dist/chain/seal.js.map +1 -0
  42. package/dist/chain/sealing-options.d.ts +12 -0
  43. package/dist/chain/sealing-options.d.ts.map +1 -0
  44. package/dist/chain/sealing-options.js +2 -0
  45. package/dist/chain/sealing-options.js.map +1 -0
  46. package/dist/drizzle/audit-chains-table.d.ts +61 -0
  47. package/dist/drizzle/audit-chains-table.d.ts.map +1 -0
  48. package/dist/drizzle/audit-chains-table.js +12 -0
  49. package/dist/drizzle/audit-chains-table.js.map +1 -0
  50. package/dist/drizzle/audit-entries-table.d.ts +424 -0
  51. package/dist/drizzle/audit-entries-table.d.ts.map +1 -0
  52. package/dist/drizzle/audit-entries-table.js +44 -0
  53. package/dist/drizzle/audit-entries-table.js.map +1 -0
  54. package/dist/drizzle/audit-guard-statements.d.ts +7 -0
  55. package/dist/drizzle/audit-guard-statements.d.ts.map +1 -0
  56. package/dist/drizzle/audit-guard-statements.js +10 -0
  57. package/dist/drizzle/audit-guard-statements.js.map +1 -0
  58. package/dist/drizzle/drizzle-audit-context.d.ts +7 -0
  59. package/dist/drizzle/drizzle-audit-context.d.ts.map +1 -0
  60. package/dist/drizzle/drizzle-audit-context.js +2 -0
  61. package/dist/drizzle/drizzle-audit-context.js.map +1 -0
  62. package/dist/drizzle/drizzle-audit-trail.d.ts +17 -0
  63. package/dist/drizzle/drizzle-audit-trail.d.ts.map +1 -0
  64. package/dist/drizzle/drizzle-audit-trail.js +28 -0
  65. package/dist/drizzle/drizzle-audit-trail.js.map +1 -0
  66. package/dist/drizzle/table-in.d.ts +4 -0
  67. package/dist/drizzle/table-in.d.ts.map +1 -0
  68. package/dist/drizzle/table-in.js +6 -0
  69. package/dist/drizzle/table-in.js.map +1 -0
  70. package/dist/drizzle.d.ts +6 -0
  71. package/dist/drizzle.d.ts.map +1 -0
  72. package/dist/drizzle.js +5 -0
  73. package/dist/drizzle.js.map +1 -0
  74. package/dist/index.d.ts +36 -0
  75. package/dist/index.d.ts.map +1 -0
  76. package/dist/index.js +18 -0
  77. package/dist/index.js.map +1 -0
  78. package/dist/knex/create-audit-tables.d.ts +9 -0
  79. package/dist/knex/create-audit-tables.d.ts.map +1 -0
  80. package/dist/knex/create-audit-tables.js +12 -0
  81. package/dist/knex/create-audit-tables.js.map +1 -0
  82. package/dist/knex/drop-audit-tables.d.ts +5 -0
  83. package/dist/knex/drop-audit-tables.d.ts.map +1 -0
  84. package/dist/knex/drop-audit-tables.js +8 -0
  85. package/dist/knex/drop-audit-tables.js.map +1 -0
  86. package/dist/knex/knex-audit-context.d.ts +6 -0
  87. package/dist/knex/knex-audit-context.d.ts.map +1 -0
  88. package/dist/knex/knex-audit-context.js +2 -0
  89. package/dist/knex/knex-audit-context.js.map +1 -0
  90. package/dist/knex/knex-audit-trail.d.ts +14 -0
  91. package/dist/knex/knex-audit-trail.d.ts.map +1 -0
  92. package/dist/knex/knex-audit-trail.js +22 -0
  93. package/dist/knex/knex-audit-trail.js.map +1 -0
  94. package/dist/knex.d.ts +6 -0
  95. package/dist/knex.d.ts.map +1 -0
  96. package/dist/knex.js +4 -0
  97. package/dist/knex.js.map +1 -0
  98. package/dist/redaction/audit-masker.d.ts +8 -0
  99. package/dist/redaction/audit-masker.d.ts.map +1 -0
  100. package/dist/redaction/audit-masker.js +5 -0
  101. package/dist/redaction/audit-masker.js.map +1 -0
  102. package/dist/redaction/audit-projection.d.ts +13 -0
  103. package/dist/redaction/audit-projection.d.ts.map +1 -0
  104. package/dist/redaction/audit-projection.js +2 -0
  105. package/dist/redaction/audit-projection.js.map +1 -0
  106. package/dist/redaction/audited-field.d.ts +3 -0
  107. package/dist/redaction/audited-field.d.ts.map +1 -0
  108. package/dist/redaction/audited-field.js +2 -0
  109. package/dist/redaction/audited-field.js.map +1 -0
  110. package/dist/redaction/audited-fields.d.ts +16 -0
  111. package/dist/redaction/audited-fields.d.ts.map +1 -0
  112. package/dist/redaction/audited-fields.js +24 -0
  113. package/dist/redaction/audited-fields.js.map +1 -0
  114. package/dist/redaction/audited-message.d.ts +9 -0
  115. package/dist/redaction/audited-message.d.ts.map +1 -0
  116. package/dist/redaction/audited-message.js +2 -0
  117. package/dist/redaction/audited-message.js.map +1 -0
  118. package/dist/redaction/audited-projection.d.ts +10 -0
  119. package/dist/redaction/audited-projection.d.ts.map +1 -0
  120. package/dist/redaction/audited-projection.js +9 -0
  121. package/dist/redaction/audited-projection.js.map +1 -0
  122. package/dist/redaction/changes-of.d.ts +11 -0
  123. package/dist/redaction/changes-of.d.ts.map +1 -0
  124. package/dist/redaction/changes-of.js +37 -0
  125. package/dist/redaction/changes-of.js.map +1 -0
  126. package/dist/redaction/hmac-masker.d.ts +12 -0
  127. package/dist/redaction/hmac-masker.d.ts.map +1 -0
  128. package/dist/redaction/hmac-masker.js +14 -0
  129. package/dist/redaction/hmac-masker.js.map +1 -0
  130. package/dist/redaction/masked-field.d.ts +6 -0
  131. package/dist/redaction/masked-field.d.ts.map +1 -0
  132. package/dist/redaction/masked-field.js +2 -0
  133. package/dist/redaction/masked-field.js.map +1 -0
  134. package/dist/redaction/masked.d.ts +3 -0
  135. package/dist/redaction/masked.d.ts.map +1 -0
  136. package/dist/redaction/masked.js +4 -0
  137. package/dist/redaction/masked.js.map +1 -0
  138. package/dist/redaction/masking-subject.d.ts +9 -0
  139. package/dist/redaction/masking-subject.d.ts.map +1 -0
  140. package/dist/redaction/masking-subject.js +2 -0
  141. package/dist/redaction/masking-subject.js.map +1 -0
  142. package/dist/redaction/missing-masker-error.d.ts +5 -0
  143. package/dist/redaction/missing-masker-error.d.ts.map +1 -0
  144. package/dist/redaction/missing-masker-error.js +8 -0
  145. package/dist/redaction/missing-masker-error.js.map +1 -0
  146. package/dist/search/comparing.d.ts +8 -0
  147. package/dist/search/comparing.d.ts.map +1 -0
  148. package/dist/search/comparing.js +23 -0
  149. package/dist/search/comparing.js.map +1 -0
  150. package/dist/search/cursor-position.d.ts +7 -0
  151. package/dist/search/cursor-position.d.ts.map +1 -0
  152. package/dist/search/cursor-position.js +2 -0
  153. package/dist/search/cursor-position.js.map +1 -0
  154. package/dist/search/decode-cursor.d.ts +3 -0
  155. package/dist/search/decode-cursor.d.ts.map +1 -0
  156. package/dist/search/decode-cursor.js +21 -0
  157. package/dist/search/decode-cursor.js.map +1 -0
  158. package/dist/search/encode-cursor.d.ts +3 -0
  159. package/dist/search/encode-cursor.d.ts.map +1 -0
  160. package/dist/search/encode-cursor.js +5 -0
  161. package/dist/search/encode-cursor.js.map +1 -0
  162. package/dist/search/matches.d.ts +5 -0
  163. package/dist/search/matches.d.ts.map +1 -0
  164. package/dist/search/matches.js +34 -0
  165. package/dist/search/matches.js.map +1 -0
  166. package/dist/search/order-of.d.ts +4 -0
  167. package/dist/search/order-of.d.ts.map +1 -0
  168. package/dist/search/order-of.js +5 -0
  169. package/dist/search/order-of.js.map +1 -0
  170. package/dist/search/search-order.d.ts +6 -0
  171. package/dist/search/search-order.d.ts.map +1 -0
  172. package/dist/search/search-order.js +2 -0
  173. package/dist/search/search-order.js.map +1 -0
  174. package/dist/sources/allowed-reads.d.ts +9 -0
  175. package/dist/sources/allowed-reads.d.ts.map +1 -0
  176. package/dist/sources/allowed-reads.js +2 -0
  177. package/dist/sources/allowed-reads.js.map +1 -0
  178. package/dist/sources/audit-decisions.d.ts +19 -0
  179. package/dist/sources/audit-decisions.d.ts.map +1 -0
  180. package/dist/sources/audit-decisions.js +48 -0
  181. package/dist/sources/audit-decisions.js.map +1 -0
  182. package/dist/sources/audit-fact.d.ts +4 -0
  183. package/dist/sources/audit-fact.d.ts.map +1 -0
  184. package/dist/sources/audit-fact.js +2 -0
  185. package/dist/sources/audit-fact.js.map +1 -0
  186. package/dist/sources/audit-integration-events.d.ts +23 -0
  187. package/dist/sources/audit-integration-events.d.ts.map +1 -0
  188. package/dist/sources/audit-integration-events.js +59 -0
  189. package/dist/sources/audit-integration-events.js.map +1 -0
  190. package/dist/sources/audit-middleware.d.ts +33 -0
  191. package/dist/sources/audit-middleware.d.ts.map +1 -0
  192. package/dist/sources/audit-middleware.js +113 -0
  193. package/dist/sources/audit-middleware.js.map +1 -0
  194. package/dist/sources/audit-record-of.d.ts +10 -0
  195. package/dist/sources/audit-record-of.d.ts.map +1 -0
  196. package/dist/sources/audit-record-of.js +10 -0
  197. package/dist/sources/audit-record-of.js.map +1 -0
  198. package/dist/sources/audit-source.d.ts +8 -0
  199. package/dist/sources/audit-source.d.ts.map +1 -0
  200. package/dist/sources/audit-source.js +2 -0
  201. package/dist/sources/audit-source.js.map +1 -0
  202. package/dist/sources/audit-subscription.d.ts +7 -0
  203. package/dist/sources/audit-subscription.d.ts.map +1 -0
  204. package/dist/sources/audit-subscription.js +2 -0
  205. package/dist/sources/audit-subscription.js.map +1 -0
  206. package/dist/sources/audited-events.d.ts +7 -0
  207. package/dist/sources/audited-events.d.ts.map +1 -0
  208. package/dist/sources/audited-events.js +2 -0
  209. package/dist/sources/audited-events.js.map +1 -0
  210. package/dist/sources/authorization-decision.d.ts +21 -0
  211. package/dist/sources/authorization-decision.d.ts.map +1 -0
  212. package/dist/sources/authorization-decision.js +2 -0
  213. package/dist/sources/authorization-decision.js.map +1 -0
  214. package/dist/sources/record-in.d.ts +5 -0
  215. package/dist/sources/record-in.d.ts.map +1 -0
  216. package/dist/sources/record-in.js +19 -0
  217. package/dist/sources/record-in.js.map +1 -0
  218. package/dist/sql/audit-chains-table-name.d.ts +2 -0
  219. package/dist/sql/audit-chains-table-name.d.ts.map +1 -0
  220. package/dist/sql/audit-chains-table-name.js +2 -0
  221. package/dist/sql/audit-chains-table-name.js.map +1 -0
  222. package/dist/sql/audit-entries-table-name.d.ts +2 -0
  223. package/dist/sql/audit-entries-table-name.d.ts.map +1 -0
  224. package/dist/sql/audit-entries-table-name.js +2 -0
  225. package/dist/sql/audit-entries-table-name.js.map +1 -0
  226. package/dist/sql/audit-guard-sql.d.ts +8 -0
  227. package/dist/sql/audit-guard-sql.d.ts.map +1 -0
  228. package/dist/sql/audit-guard-sql.js +17 -0
  229. package/dist/sql/audit-guard-sql.js.map +1 -0
  230. package/dist/sql/audit-tables-options.d.ts +5 -0
  231. package/dist/sql/audit-tables-options.d.ts.map +1 -0
  232. package/dist/sql/audit-tables-options.js +2 -0
  233. package/dist/sql/audit-tables-options.js.map +1 -0
  234. package/dist/sql/audit-tables-sql.d.ts +7 -0
  235. package/dist/sql/audit-tables-sql.d.ts.map +1 -0
  236. package/dist/sql/audit-tables-sql.js +48 -0
  237. package/dist/sql/audit-tables-sql.js.map +1 -0
  238. package/dist/sql/audit-tables.d.ts +8 -0
  239. package/dist/sql/audit-tables.d.ts.map +1 -0
  240. package/dist/sql/audit-tables.js +7 -0
  241. package/dist/sql/audit-tables.js.map +1 -0
  242. package/dist/sql/drop-audit-tables-sql.d.ts +4 -0
  243. package/dist/sql/drop-audit-tables-sql.d.ts.map +1 -0
  244. package/dist/sql/drop-audit-tables-sql.js +12 -0
  245. package/dist/sql/drop-audit-tables-sql.js.map +1 -0
  246. package/dist/sql/entry-of.d.ts +5 -0
  247. package/dist/sql/entry-of.d.ts.map +1 -0
  248. package/dist/sql/entry-of.js +109 -0
  249. package/dist/sql/entry-of.js.map +1 -0
  250. package/dist/sql/insert-of.d.ts +4 -0
  251. package/dist/sql/insert-of.d.ts.map +1 -0
  252. package/dist/sql/insert-of.js +51 -0
  253. package/dist/sql/insert-of.js.map +1 -0
  254. package/dist/sql/named.d.ts +3 -0
  255. package/dist/sql/named.d.ts.map +1 -0
  256. package/dist/sql/named.js +6 -0
  257. package/dist/sql/named.js.map +1 -0
  258. package/dist/sql/postgres-audit-trail.d.ts +25 -0
  259. package/dist/sql/postgres-audit-trail.d.ts.map +1 -0
  260. package/dist/sql/postgres-audit-trail.js +111 -0
  261. package/dist/sql/postgres-audit-trail.js.map +1 -0
  262. package/dist/sql/qualified.d.ts +3 -0
  263. package/dist/sql/qualified.d.ts.map +1 -0
  264. package/dist/sql/qualified.js +5 -0
  265. package/dist/sql/qualified.js.map +1 -0
  266. package/dist/sql/rows-of.d.ts +4 -0
  267. package/dist/sql/rows-of.d.ts.map +1 -0
  268. package/dist/sql/rows-of.js +14 -0
  269. package/dist/sql/rows-of.js.map +1 -0
  270. package/dist/sql/sql-row.d.ts +2 -0
  271. package/dist/sql/sql-row.d.ts.map +1 -0
  272. package/dist/sql/sql-row.js +2 -0
  273. package/dist/sql/sql-row.js.map +1 -0
  274. package/dist/sql/sql-session.d.ts +9 -0
  275. package/dist/sql/sql-session.d.ts.map +1 -0
  276. package/dist/sql/sql-session.js +2 -0
  277. package/dist/sql/sql-session.js.map +1 -0
  278. package/dist/sql/sql.d.ts +12 -0
  279. package/dist/sql/sql.d.ts.map +1 -0
  280. package/dist/sql/sql.js +35 -0
  281. package/dist/sql/sql.js.map +1 -0
  282. package/dist/testing/audit-trail-contract.d.ts +16 -0
  283. package/dist/testing/audit-trail-contract.d.ts.map +1 -0
  284. package/dist/testing/audit-trail-contract.js +208 -0
  285. package/dist/testing/audit-trail-contract.js.map +1 -0
  286. package/dist/testing/audit-trail-under-contract.d.ts +4 -0
  287. package/dist/testing/audit-trail-under-contract.d.ts.map +1 -0
  288. package/dist/testing/audit-trail-under-contract.js +2 -0
  289. package/dist/testing/audit-trail-under-contract.js.map +1 -0
  290. package/dist/testing/records/a-record.d.ts +3 -0
  291. package/dist/testing/records/a-record.d.ts.map +1 -0
  292. package/dist/testing/records/a-record.js +14 -0
  293. package/dist/testing/records/a-record.js.map +1 -0
  294. package/dist/testing/records/full-record.d.ts +3 -0
  295. package/dist/testing/records/full-record.d.ts.map +1 -0
  296. package/dist/testing/records/full-record.js +16 -0
  297. package/dist/testing/records/full-record.js.map +1 -0
  298. package/dist/testing/records/in-tenant.d.ts +3 -0
  299. package/dist/testing/records/in-tenant.d.ts.map +1 -0
  300. package/dist/testing/records/in-tenant.js +5 -0
  301. package/dist/testing/records/in-tenant.js.map +1 -0
  302. package/dist/testing/records/journal.d.ts +4 -0
  303. package/dist/testing/records/journal.d.ts.map +1 -0
  304. package/dist/testing/records/journal.js +32 -0
  305. package/dist/testing/records/journal.js.map +1 -0
  306. package/dist/testing/records/later.d.ts +4 -0
  307. package/dist/testing/records/later.d.ts.map +1 -0
  308. package/dist/testing/records/later.js +6 -0
  309. package/dist/testing/records/later.js.map +1 -0
  310. package/dist/testing.d.ts +3 -0
  311. package/dist/testing.d.ts.map +1 -0
  312. package/dist/testing.js +2 -0
  313. package/dist/testing.js.map +1 -0
  314. package/dist/trail/audit-trail-options.d.ts +8 -0
  315. package/dist/trail/audit-trail-options.d.ts.map +1 -0
  316. package/dist/trail/audit-trail-options.js +2 -0
  317. package/dist/trail/audit-trail-options.js.map +1 -0
  318. package/dist/trail/in-memory-audit-trail.d.ts +16 -0
  319. package/dist/trail/in-memory-audit-trail.d.ts.map +1 -0
  320. package/dist/trail/in-memory-audit-trail.js +48 -0
  321. package/dist/trail/in-memory-audit-trail.js.map +1 -0
  322. package/dist/verify/chain-break-kind.d.ts +8 -0
  323. package/dist/verify/chain-break-kind.d.ts.map +1 -0
  324. package/dist/verify/chain-break-kind.js +2 -0
  325. package/dist/verify/chain-break-kind.js.map +1 -0
  326. package/dist/verify/chain-break.d.ts +12 -0
  327. package/dist/verify/chain-break.d.ts.map +1 -0
  328. package/dist/verify/chain-break.js +2 -0
  329. package/dist/verify/chain-break.js.map +1 -0
  330. package/dist/verify/chain-verification.d.ts +10 -0
  331. package/dist/verify/chain-verification.d.ts.map +1 -0
  332. package/dist/verify/chain-verification.js +2 -0
  333. package/dist/verify/chain-verification.js.map +1 -0
  334. package/dist/verify/verify-chain.d.ts +20 -0
  335. package/dist/verify/verify-chain.d.ts.map +1 -0
  336. package/dist/verify/verify-chain.js +110 -0
  337. package/dist/verify/verify-chain.js.map +1 -0
  338. package/package.json +70 -4
@@ -0,0 +1,111 @@
1
+ import { pageOf, } from '@ddd-ts-kit/kernel';
2
+ import { chainOfTenant } from '../chain/chain-of-tenant.js';
3
+ import { GENESIS_HASH } from '../chain/genesis-hash.js';
4
+ import { seal } from '../chain/seal.js';
5
+ import { sealCheckpoint } from '../chain/seal-checkpoint.js';
6
+ import { decodeCursor } from '../search/decode-cursor.js';
7
+ import { encodeCursor } from '../search/encode-cursor.js';
8
+ import { orderOf } from '../search/order-of.js';
9
+ import { entryOf } from './entry-of.js';
10
+ import { insertOf } from './insert-of.js';
11
+ import { joined, sql } from './sql.js';
12
+ /**
13
+ * The trail in PostgreSQL, whatever the query builder: the adapters give it a session, which
14
+ * is the transaction of the unit of work in progress when there is one.
15
+ *
16
+ * An append locks the head row of its chain (`SELECT ... FOR UPDATE`) until its transaction
17
+ * ends, so two appends to one chain never read the same head and the chain cannot fork. Under
18
+ * REPEATABLE READ or SERIALIZABLE the second one fails with a serialization error instead of
19
+ * waiting: the caller retries its unit of work, as for any other statement.
20
+ */
21
+ export class PostgresAuditTrail {
22
+ session;
23
+ tables;
24
+ options;
25
+ constructor(session, tables, options = {}) {
26
+ this.session = session;
27
+ this.tables = tables;
28
+ this.options = options;
29
+ }
30
+ async record(record) {
31
+ const chain = (this.options.chainOf ?? chainOfTenant)(record);
32
+ await this.session().transaction(async (transaction) => {
33
+ const entry = seal(record, await this.lockHead(transaction, chain));
34
+ await transaction.query(insertOf(this.tables.entries, entry));
35
+ await transaction.query(sql `update ${this.tables.chains} set "sequence" = ${entry.sequence}, "hash" = ${entry.hash} where "chain" = ${chain}`);
36
+ await sealCheckpoint(entry, this.options.sealing);
37
+ });
38
+ }
39
+ async search(filter, page) {
40
+ const order = orderOf(page);
41
+ const matching = conditionsOf(filter);
42
+ if (page.kind === 'offset') {
43
+ const rows = await this.select(matching, order, sql `limit ${page.limit} offset ${page.offset}`);
44
+ return pageOf(rows, { total: await this.count(matching) });
45
+ }
46
+ const resumed = page.cursor === undefined ? matching : [...matching, afterCursor(page.cursor, order)];
47
+ const rows = await this.select(resumed, order, sql `limit ${page.limit + 1}`);
48
+ const items = rows.slice(0, page.limit);
49
+ const last = items.at(-1);
50
+ return pageOf(items, rows.length > items.length && last !== undefined ? { nextCursor: encodeCursor(last) } : {});
51
+ }
52
+ async lockHead(transaction, chain) {
53
+ const { chains } = this.tables;
54
+ await transaction.query(sql `insert into ${chains} ("chain", "sequence", "hash") values (${chain}, 0, ${GENESIS_HASH}) on conflict ("chain") do nothing`);
55
+ const [head] = await transaction.query(sql `select "sequence", "hash" from ${chains} where "chain" = ${chain} for update`);
56
+ const hash = head?.['hash'];
57
+ if (typeof hash !== 'string') {
58
+ throw new TypeError(`The head of audit chain "${chain}" could not be read`);
59
+ }
60
+ return { chain, sequence: Number(head?.['sequence']), hash };
61
+ }
62
+ async select(conditions, order, limit) {
63
+ const statement = sql `select * from ${this.tables.entries} ${where(conditions)} order by ${orderBy(order)} ${limit}`;
64
+ return (await this.session().query(statement)).map(entryOf);
65
+ }
66
+ async count(conditions) {
67
+ const [row] = await this.session().query(sql `select count(*) as "total" from ${this.tables.entries} ${where(conditions)}`);
68
+ return Number(row?.['total']);
69
+ }
70
+ }
71
+ function conditionsOf(filter) {
72
+ const equalities = [
73
+ [sql `"chain"`, filter.chain],
74
+ [sql `"tenant_id"`, filter.tenantId],
75
+ [sql `"actor_id"`, filter.actorId],
76
+ [sql `"resource_type"`, filter.resource?.type],
77
+ [sql `"resource_id"`, filter.resource?.id],
78
+ [sql `"action"`, filter.action],
79
+ [sql `"category"`, filter.category],
80
+ [sql `"outcome"`, filter.outcome],
81
+ [sql `"correlation_id"`, filter.correlationId],
82
+ ];
83
+ const equal = equalities.flatMap(([column, value]) => (value === undefined ? [] : [sql `${column} = ${value}`]));
84
+ return [...equal, ...rangesOf(filter)];
85
+ }
86
+ function rangesOf({ from, to, fromSequence, toSequence }) {
87
+ return [
88
+ ...(from === undefined ? [] : [sql `"occurred_at" >= ${from.toISOString()}::timestamptz`]),
89
+ ...(to === undefined ? [] : [sql `"occurred_at" < ${to.toISOString()}::timestamptz`]),
90
+ ...(fromSequence === undefined ? [] : [sql `"sequence" >= ${fromSequence}`]),
91
+ ...(toSequence === undefined ? [] : [sql `"sequence" <= ${toSequence}`]),
92
+ ];
93
+ }
94
+ /** A row comparison: the three columns move together, in the direction of the order. */
95
+ function afterCursor(cursor, order) {
96
+ const { occurredAt, chain, sequence } = decodeCursor(cursor);
97
+ const beyond = order.direction === 'asc' ? sql `>` : sql `<`;
98
+ if (order.field === 'sequence') {
99
+ return sql `("chain", "sequence") ${beyond} (${chain}, ${sequence}::bigint)`;
100
+ }
101
+ return sql `("occurred_at", "chain", "sequence") ${beyond} (${occurredAt.toISOString()}::timestamptz, ${chain}, ${sequence}::bigint)`;
102
+ }
103
+ function where(conditions) {
104
+ return conditions.length === 0 ? sql `` : sql `where ${joined(conditions, ' and ')}`;
105
+ }
106
+ function orderBy(order) {
107
+ const direction = order.direction === 'asc' ? sql `asc` : sql `desc`;
108
+ const columns = order.field === 'sequence' ? [sql `"chain"`, sql `"sequence"`] : [sql `"occurred_at"`, sql `"chain"`, sql `"sequence"`];
109
+ return joined(columns.map((column) => sql `${column} ${direction}`), ', ');
110
+ }
111
+ //# sourceMappingURL=postgres-audit-trail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-audit-trail.js","sourceRoot":"","sources":["../../src/sql/postgres-audit-trail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type Sql } from './sql.js';
2
+ export declare function qualified(schema: string | undefined, name: string): Sql;
3
+ //# sourceMappingURL=qualified.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qualified.d.ts","sourceRoot":"","sources":["../../src/sql/qualified.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,GAAG,EAAE,MAAM,UAAU,CAAC;AAEhD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAEvE"}
@@ -0,0 +1,5 @@
1
+ import { identifier } from './sql.js';
2
+ export function qualified(schema, name) {
3
+ return schema === undefined ? identifier(name) : identifier(schema, name);
4
+ }
5
+ //# sourceMappingURL=qualified.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qualified.js","sourceRoot":"","sources":["../../src/sql/qualified.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAY,MAAM,UAAU,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,MAA0B,EAAE,IAAY;IAChE,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { SqlRow } from './sql-row.js';
2
+ /** The rows of a driver result: an array (postgres-js) or an object holding `rows` (node-postgres, PGlite). */
3
+ export declare function rowsOf(result: unknown): readonly SqlRow[];
4
+ //# sourceMappingURL=rows-of.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows-of.d.ts","sourceRoot":"","sources":["../../src/sql/rows-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,+GAA+G;AAC/G,wBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,MAAM,EAAE,CAUzD"}
@@ -0,0 +1,14 @@
1
+ /** The rows of a driver result: an array (postgres-js) or an object holding `rows` (node-postgres, PGlite). */
2
+ export function rowsOf(result) {
3
+ if (Array.isArray(result)) {
4
+ return result.filter(isRow);
5
+ }
6
+ if (typeof result === 'object' && result !== null && 'rows' in result) {
7
+ return rowsOf(result.rows);
8
+ }
9
+ return [];
10
+ }
11
+ function isRow(value) {
12
+ return typeof value === 'object' && value !== null;
13
+ }
14
+ //# sourceMappingURL=rows-of.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows-of.js","sourceRoot":"","sources":["../../src/sql/rows-of.ts"],"names":[],"mappings":"AAEA,+GAA+G;AAC/G,MAAM,UAAU,MAAM,CAAC,MAAe;IACpC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QACtE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,KAAK,CAAC,KAAc;IAC3B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export type SqlRow = Readonly<Record<string, unknown>>;
2
+ //# sourceMappingURL=sql-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-row.d.ts","sourceRoot":"","sources":["../../src/sql/sql-row.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sql-row.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-row.js","sourceRoot":"","sources":["../../src/sql/sql-row.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { SqlRow } from './sql-row.js';
2
+ import type { Sql } from './sql.js';
3
+ /** Where a store runs its statements: the ambient transaction, or the database itself. */
4
+ export interface SqlSession {
5
+ query(statement: Sql): Promise<readonly SqlRow[]>;
6
+ /** A transaction of its own, or a savepoint when the session is already one. */
7
+ transaction<T>(work: (session: SqlSession) => Promise<T>): Promise<T>;
8
+ }
9
+ //# sourceMappingURL=sql-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-session.d.ts","sourceRoot":"","sources":["../../src/sql/sql-session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,0FAA0F;AAC1F,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAElD,gFAAgF;IAChF,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACvE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sql-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-session.js","sourceRoot":"","sources":["../../src/sql/sql-session.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ /** A statement as its literal parts and the values that go between them, in order. */
2
+ export declare class Sql {
3
+ readonly strings: readonly string[];
4
+ readonly values: readonly unknown[];
5
+ constructor(strings: readonly string[], values: readonly unknown[]);
6
+ }
7
+ /** `sql\`select ${value}\``: a value becomes a parameter, a nested `Sql` is spliced in. */
8
+ export declare function sql(strings: TemplateStringsArray, ...parts: readonly unknown[]): Sql;
9
+ /** A quoted identifier, or a qualified one: `identifier('audit', 'audit_entries')`. */
10
+ export declare function identifier(...names: readonly string[]): Sql;
11
+ export declare function joined(parts: readonly Sql[], separator: string): Sql;
12
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/sql/sql.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,qBAAa,GAAG;IAEZ,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE;IACnC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE;IAFrC,YACW,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,MAAM,EAAE,SAAS,OAAO,EAAE,EACjC;CACL;AAED,2FAA2F;AAC3F,wBAAgB,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,GAAG,CASpF;AAgBD,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,GAAG,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,GAAG,CAE3D;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,GAAG,CAIpE"}
@@ -0,0 +1,35 @@
1
+ /** A statement as its literal parts and the values that go between them, in order. */
2
+ export class Sql {
3
+ strings;
4
+ values;
5
+ constructor(strings, values) {
6
+ this.strings = strings;
7
+ this.values = values;
8
+ }
9
+ }
10
+ /** `sql\`select ${value}\``: a value becomes a parameter, a nested `Sql` is spliced in. */
11
+ export function sql(strings, ...parts) {
12
+ return parts.reduce((statement, part, index) => {
13
+ const following = text(strings[index + 1] ?? '');
14
+ return part instanceof Sql ? concat(concat(statement, part), following) : withValue(statement, part, following);
15
+ }, text(strings[0] ?? ''));
16
+ }
17
+ function text(literal) {
18
+ return new Sql([literal], []);
19
+ }
20
+ function concat(left, right) {
21
+ const joint = `${left.strings.at(-1) ?? ''}${right.strings[0] ?? ''}`;
22
+ return new Sql([...left.strings.slice(0, -1), joint, ...right.strings.slice(1)], [...left.values, ...right.values]);
23
+ }
24
+ function withValue(statement, value, following) {
25
+ return concat(new Sql([...statement.strings, ''], [...statement.values, value]), following);
26
+ }
27
+ /** A quoted identifier, or a qualified one: `identifier('audit', 'audit_entries')`. */
28
+ export function identifier(...names) {
29
+ return text(names.map((name) => `"${name.replaceAll('"', '""')}"`).join('.'));
30
+ }
31
+ export function joined(parts, separator) {
32
+ const [first, ...rest] = parts;
33
+ return rest.reduce((all, part) => concat(concat(all, text(separator)), part), first ?? text(''));
34
+ }
35
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/sql/sql.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,MAAM,OAAO,GAAG;IAEH,OAAO;IACP,MAAM;IAFjB,YACW,OAA0B,EAC1B,MAA0B;uBAD1B,OAAO;sBACP,MAAM;IACd,CAAC;CACL;AAED,2FAA2F;AAC3F,MAAM,UAAU,GAAG,CAAC,OAA6B,EAAE,GAAG,KAAyB;IAC7E,OAAO,KAAK,CAAC,MAAM,CACjB,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAEjD,OAAO,IAAI,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAClH,CAAC,EACD,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CACvB,CAAC;AACJ,CAAC;AAED,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,MAAM,CAAC,IAAS,EAAE,KAAU;IACnC,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;IAEtE,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;AACtH,CAAC;AAED,SAAS,SAAS,CAAC,SAAc,EAAE,KAAc,EAAE,SAAc;IAC/D,OAAO,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAC9F,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,UAAU,CAAC,GAAG,KAAwB;IACpD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAqB,EAAE,SAAiB;IAC7D,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;IAE/B,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACnG,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type AuditEntry } from '@ddd-ts-kit/kernel';
2
+ import { type Awaitable, type ContractRunner } from '@ddd-ts-kit/testing/contracts';
3
+ import type { AuditTrailUnderContract } from './audit-trail-under-contract.js';
4
+ export interface AuditTrailContractOptions {
5
+ readonly name: string;
6
+ /** A fresh, empty trail with the default chains (one per tenant, `global` otherwise); called before each test. */
7
+ createTrail(): Awaitable<AuditTrailUnderContract>;
8
+ /**
9
+ * Rewrites the stored `action` of this entry behind the back of the trail, the way somebody
10
+ * with access to the storage would. When absent, tampering is only checked on what was read.
11
+ */
12
+ readonly tamper?: (entry: AuditEntry, action: string) => Awaitable<void>;
13
+ }
14
+ /** What every audit trail, fake or real, guarantees to the sources and to the reader. */
15
+ export declare function auditTrailContract(runner: ContractRunner, options: AuditTrailContractOptions): void;
16
+ //# sourceMappingURL=audit-trail-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-trail-contract.d.ts","sourceRoot":"","sources":["../../src/testing/audit-trail-contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EAKhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAInG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAO/E,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kHAAkH;IAClH,WAAW,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC;CAC1E;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,yBAAyB,GAAG,IAAI,CAEnG"}
@@ -0,0 +1,208 @@
1
+ import { cursorPage, offsetPage, } from '@ddd-ts-kit/kernel';
2
+ import { ContractSuite } from '@ddd-ts-kit/testing/contracts';
3
+ import { GENESIS_HASH } from '../chain/genesis-hash.js';
4
+ import { hashOf } from '../chain/hash-of.js';
5
+ import { verifyChain } from '../verify/verify-chain.js';
6
+ import { aRecord } from './records/a-record.js';
7
+ import { fullRecord } from './records/full-record.js';
8
+ import { inTenant } from './records/in-tenant.js';
9
+ import { JOURNAL } from './records/journal.js';
10
+ import { later } from './records/later.js';
11
+ /** What every audit trail, fake or real, guarantees to the sources and to the reader. */
12
+ export function auditTrailContract(runner, options) {
13
+ new AuditTrailSuite(runner, options).describe(`${options.name} (audit trail contract)`);
14
+ }
15
+ const ALPHA = 'tenant:alpha';
16
+ const BY_SEQUENCE = [{ field: 'sequence', direction: 'asc' }];
17
+ class AuditTrailSuite extends ContractSuite {
18
+ options;
19
+ constructor(runner, options) {
20
+ super(runner, () => options.createTrail());
21
+ this.options = options;
22
+ }
23
+ tests() {
24
+ this.appends();
25
+ this.numbersEachChain();
26
+ this.chainsTheEntries();
27
+ this.detectsTampering();
28
+ this.neverForks();
29
+ this.filters();
30
+ this.paginates();
31
+ }
32
+ appends() {
33
+ this.it('starts empty', async () => {
34
+ this.expect(await this.subject.search({}, offsetPage())).toEqual({ items: [], total: 0 });
35
+ });
36
+ this.it('gives back what was recorded, sealed as the first entry of its chain', async () => {
37
+ const record = fullRecord('entry-1');
38
+ await this.subject.record(record);
39
+ const [entry] = await this.all();
40
+ this.expect(entry).toEqual({
41
+ ...record,
42
+ chain: ALPHA,
43
+ sequence: 1,
44
+ previousHash: GENESIS_HASH,
45
+ hash: entry?.hash,
46
+ });
47
+ this.expect(entry === undefined ? undefined : hashOf(entry)).toBe(entry?.hash);
48
+ });
49
+ this.it('leaves out what a record does not carry', async () => {
50
+ await this.subject.record(aRecord('entry-1'));
51
+ const [entry] = await this.all();
52
+ this.expect(entry).toEqual({
53
+ ...aRecord('entry-1'),
54
+ extensions: {},
55
+ chain: 'global',
56
+ sequence: 1,
57
+ previousHash: GENESIS_HASH,
58
+ hash: entry?.hash,
59
+ });
60
+ });
61
+ }
62
+ numbersEachChain() {
63
+ this.it('numbers the entries of each chain from 1, without a gap', async () => {
64
+ await this.recordAll([
65
+ inTenant('a-1', 'alpha'),
66
+ inTenant('b-1', 'beta'),
67
+ inTenant('a-2', 'alpha'),
68
+ aRecord('g-1'),
69
+ inTenant('a-3', 'alpha'),
70
+ ]);
71
+ this.expect(await this.sequencesOf(ALPHA)).toEqual([1, 2, 3]);
72
+ this.expect(await this.sequencesOf('tenant:beta')).toEqual([1]);
73
+ this.expect(await this.sequencesOf('global')).toEqual([1]);
74
+ });
75
+ }
76
+ chainsTheEntries() {
77
+ this.it('links each entry to the hash of the one before it', async () => {
78
+ await this.recordAll([inTenant('a-1', 'alpha'), inTenant('a-2', 'alpha'), inTenant('a-3', 'alpha')]);
79
+ const entries = await this.entriesOf(ALPHA);
80
+ this.expect(entries.map((entry) => entry.previousHash)).toEqual([
81
+ GENESIS_HASH,
82
+ entries[0]?.hash,
83
+ entries[1]?.hash,
84
+ ]);
85
+ this.expect(await verifyChain(this.subject, { chain: ALPHA })).toEqual({ valid: true, checked: 3 });
86
+ this.expect(await verifyChain(entries)).toEqual({ valid: true, checked: 3 });
87
+ });
88
+ this.it('verifies a range of a chain read page by page', async () => {
89
+ await this.recordAll(Array.from({ length: 7 }, (_, index) => inTenant(`a-${index}`, 'alpha')));
90
+ this.expect(await verifyChain(this.subject, { chain: ALPHA, from: 3, to: 6 })).toEqual({
91
+ valid: true,
92
+ checked: 4,
93
+ });
94
+ const beyond = await verifyChain(this.subject, { chain: ALPHA, to: 9 });
95
+ this.expect(beyond).toEqual({
96
+ valid: false,
97
+ checked: 7,
98
+ break: { kind: 'missing-entry', chain: ALPHA, position: 7, sequence: 8 },
99
+ });
100
+ });
101
+ }
102
+ detectsTampering() {
103
+ this.it('shows an entry whose content was changed after it was read', async () => {
104
+ await this.recordAll([inTenant('a-1', 'alpha'), inTenant('a-2', 'alpha'), inTenant('a-3', 'alpha')]);
105
+ const entries = await this.entriesOf(ALPHA);
106
+ const altered = entries.map((entry) => entry.sequence === 2 ? { ...entry, outcome: 'failed' } : entry);
107
+ const altering = { kind: 'altered-content', chain: ALPHA, position: 1, sequence: 2, entryId: 'a-2' };
108
+ this.expect(await verifyChain(altered)).toEqual({ valid: false, checked: 1, break: altering });
109
+ });
110
+ const { tamper } = this.options;
111
+ if (tamper === undefined) {
112
+ return;
113
+ }
114
+ this.it('shows an entry rewritten in the storage itself', async () => {
115
+ await this.recordAll([inTenant('a-1', 'alpha'), inTenant('a-2', 'alpha'), inTenant('a-3', 'alpha')]);
116
+ const [, second] = await this.entriesOf(ALPHA);
117
+ if (second === undefined) {
118
+ throw new Error('The second entry of the chain was not listed');
119
+ }
120
+ await tamper(second, 'contract.thing.forged');
121
+ const altering = { kind: 'altered-content', chain: ALPHA, position: 1, sequence: 2, entryId: 'a-2' };
122
+ this.expect(await verifyChain(this.subject, { chain: ALPHA })).toEqual({
123
+ valid: false,
124
+ checked: 1,
125
+ break: altering,
126
+ });
127
+ });
128
+ }
129
+ neverForks() {
130
+ this.it('gives concurrent appends to one chain a position each', async () => {
131
+ const records = Array.from({ length: 12 }, (_, index) => inTenant(`a-${index}`, 'alpha'));
132
+ await Promise.all([...records, inTenant('b-1', 'beta')].map((record) => this.subject.record(record)));
133
+ this.expect(await this.sequencesOf(ALPHA)).toEqual(records.map((_, index) => index + 1));
134
+ this.expect(await verifyChain(this.subject, { chain: ALPHA })).toEqual({ valid: true, checked: 12 });
135
+ this.expect(await verifyChain(this.subject, { chain: 'tenant:beta' })).toEqual({ valid: true, checked: 1 });
136
+ });
137
+ }
138
+ filters() {
139
+ const cases = [
140
+ ['actor', { actorId: 'grace' }, ['e-2', 'e-4']],
141
+ ['resource', { resource: { type: 'appointment', id: 'apt-1' } }, ['e-1', 'e-4']],
142
+ ['resource type', { resource: { type: 'appointment' } }, ['e-1', 'e-3', 'e-4']],
143
+ ['action', { action: 'scheduling:appointment.read' }, ['e-2']],
144
+ ['category', { category: 'authorization' }, ['e-2', 'e-3']],
145
+ ['outcome', { outcome: 'denied' }, ['e-3']],
146
+ ['period', { from: later(1), to: later(3) }, ['e-2', 'e-3']],
147
+ ['correlation id', { correlationId: 'correlation-2' }, ['e-3', 'e-4']],
148
+ ['tenant', { tenantId: 'beta' }, ['e-4']],
149
+ ['chain and positions', { chain: ALPHA, fromSequence: 2, toSequence: 3 }, ['e-2', 'e-3']],
150
+ ['several criteria at once', { actorId: 'ada', category: 'authorization' }, ['e-3']],
151
+ ];
152
+ for (const [criterion, filter, expected] of cases) {
153
+ this.it(`searches by ${criterion}`, async () => {
154
+ await this.recordAll(JOURNAL);
155
+ const page = await this.subject.search(filter, offsetPage());
156
+ this.expect(page.items.map((entry) => entry.id)).toEqual(expected);
157
+ this.expect(page.total).toBe(expected.length);
158
+ });
159
+ }
160
+ }
161
+ paginates() {
162
+ this.it('cuts an offset page out of the whole and counts the whole', async () => {
163
+ await this.recordAll(JOURNAL);
164
+ const page = await this.subject.search({}, offsetPage({ offset: 1, limit: 2 }));
165
+ this.expect(page.items.map((entry) => entry.id)).toEqual(['e-2', 'e-3']);
166
+ this.expect(page.total).toBe(4);
167
+ });
168
+ this.it('walks every entry once by cursor, oldest first, then says there is no more', async () => {
169
+ await this.recordAll(JOURNAL);
170
+ this.expect(await this.walk([])).toEqual(['e-1', 'e-2', 'e-3', 'e-4']);
171
+ });
172
+ this.it('walks newest first when asked', async () => {
173
+ await this.recordAll(JOURNAL);
174
+ this.expect(await this.walk([{ field: 'occurredAt', direction: 'desc' }])).toEqual(['e-4', 'e-3', 'e-2', 'e-1']);
175
+ });
176
+ this.it('walks chain by chain when sorted by sequence', async () => {
177
+ await this.recordAll(JOURNAL);
178
+ const ids = await this.walk(BY_SEQUENCE);
179
+ this.expect(ids.filter((id) => id !== 'e-4')).toEqual(['e-1', 'e-2', 'e-3']);
180
+ this.expect(ids.length).toBe(4);
181
+ });
182
+ }
183
+ async recordAll(records) {
184
+ for (const record of records) {
185
+ await this.subject.record(record);
186
+ }
187
+ }
188
+ async all() {
189
+ return (await this.subject.search({}, offsetPage({ limit: 100 }))).items;
190
+ }
191
+ async entriesOf(chain) {
192
+ return (await this.subject.search({ chain }, offsetPage({ limit: 100, sort: BY_SEQUENCE }))).items;
193
+ }
194
+ async sequencesOf(chain) {
195
+ return (await this.entriesOf(chain)).map((entry) => entry.sequence);
196
+ }
197
+ async walk(sort) {
198
+ const ids = [];
199
+ let cursor;
200
+ do {
201
+ const page = await this.subject.search({}, cursorPage({ limit: 3, sort, ...(cursor === undefined ? {} : { cursor }) }));
202
+ ids.push(...page.items.map((entry) => entry.id));
203
+ cursor = page.nextCursor;
204
+ } while (cursor !== undefined);
205
+ return ids;
206
+ }
207
+ }
208
+ //# sourceMappingURL=audit-trail-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-trail-contract.js","sourceRoot":"","sources":["../../src/testing/audit-trail-contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { AuditReader, AuditTrail } from '@ddd-ts-kit/kernel';
2
+ export interface AuditTrailUnderContract extends AuditTrail, AuditReader {
3
+ }
4
+ //# sourceMappingURL=audit-trail-under-contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-trail-under-contract.d.ts","sourceRoot":"","sources":["../../src/testing/audit-trail-under-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAElE,MAAM,WAAW,uBAAwB,SAAQ,UAAU,EAAE,WAAW;CAAG"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit-trail-under-contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-trail-under-contract.js","sourceRoot":"","sources":["../../src/testing/audit-trail-under-contract.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { AuditRecord } from '@ddd-ts-kit/kernel';
2
+ export declare function aRecord(id: string): AuditRecord;
3
+ //# sourceMappingURL=a-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a-record.d.ts","sourceRoot":"","sources":["../../../src/testing/records/a-record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,CAW/C"}
@@ -0,0 +1,14 @@
1
+ import { NOW } from './later.js';
2
+ export function aRecord(id) {
3
+ return {
4
+ id,
5
+ occurredAt: NOW,
6
+ category: 'command',
7
+ action: 'ContractThingCommand',
8
+ outcome: 'succeeded',
9
+ actor: { id: 'ada', type: 'user' },
10
+ correlationId: 'correlation-1',
11
+ origin: 'http',
12
+ };
13
+ }
14
+ //# sourceMappingURL=a-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a-record.js","sourceRoot":"","sources":["../../../src/testing/records/a-record.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEjC,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,OAAO;QACL,EAAE;QACF,UAAU,EAAE,GAAG;QACf,QAAQ,EAAE,SAAS;QACnB,MAAM,EAAE,sBAAsB;QAC9B,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE;QAClC,aAAa,EAAE,eAAe;QAC9B,MAAM,EAAE,MAAM;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AuditRecord } from '@ddd-ts-kit/kernel';
2
+ export declare function fullRecord(id: string): AuditRecord;
3
+ //# sourceMappingURL=full-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full-record.d.ts","sourceRoot":"","sources":["../../../src/testing/records/full-record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,CAalD"}
@@ -0,0 +1,16 @@
1
+ import { inTenant } from './in-tenant.js';
2
+ export function fullRecord(id) {
3
+ return {
4
+ ...inTenant(id, 'alpha'),
5
+ outcome: 'failed',
6
+ reason: 'APPOINTMENT_ALREADY_CANCELLED',
7
+ impersonatedBy: 'support-7',
8
+ sessionId: 'session-1',
9
+ resource: { type: 'appointment', id: 'apt-1' },
10
+ context: 'scheduling',
11
+ causationId: 'request-1',
12
+ changes: { status: 'cancelled', seats: 2, urgent: false, note: null, email: { masked: 'k1:9f2c' } },
13
+ extensions: {},
14
+ };
15
+ }
16
+ //# sourceMappingURL=full-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full-record.js","sourceRoot":"","sources":["../../../src/testing/records/full-record.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO;QACL,GAAG,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;QACxB,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,+BAA+B;QACvC,cAAc,EAAE,WAAW;QAC3B,SAAS,EAAE,WAAW;QACtB,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,OAAO,EAAE;QAC9C,OAAO,EAAE,YAAY;QACrB,WAAW,EAAE,WAAW;QACxB,OAAO,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;QACnG,UAAU,EAAE,EAAE;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AuditRecord } from '@ddd-ts-kit/kernel';
2
+ export declare function inTenant(id: string, tenantId: string): AuditRecord;
3
+ //# sourceMappingURL=in-tenant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-tenant.d.ts","sourceRoot":"","sources":["../../../src/testing/records/in-tenant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAElE"}
@@ -0,0 +1,5 @@
1
+ import { aRecord } from './a-record.js';
2
+ export function inTenant(id, tenantId) {
3
+ return { ...aRecord(id), actor: { id: 'ada', type: 'user', tenantId }, tenantId };
4
+ }
5
+ //# sourceMappingURL=in-tenant.js.map