@blamejs/blamejs-shop 0.4.31 → 0.4.33

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 (343) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +1 -1
  3. package/lib/asset-manifest.json +1 -1
  4. package/lib/vendor/MANIFEST.json +400 -282
  5. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  6. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  7. package/lib/vendor/blamejs/.gitignore +6 -0
  8. package/lib/vendor/blamejs/CHANGELOG.md +28 -0
  9. package/lib/vendor/blamejs/MIGRATING.md +55 -0
  10. package/lib/vendor/blamejs/README.md +8 -6
  11. package/lib/vendor/blamejs/SECURITY.md +19 -3
  12. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  13. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  14. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  15. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  16. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  17. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  18. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  19. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  20. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  21. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  22. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  23. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  24. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  25. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  26. package/lib/vendor/blamejs/index.js +4 -0
  27. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  28. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  29. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  30. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  31. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  32. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  33. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  34. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  35. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  36. package/lib/vendor/blamejs/lib/audit.js +259 -123
  37. package/lib/vendor/blamejs/lib/auth/elevation-grant.js +6 -2
  38. package/lib/vendor/blamejs/lib/auth/oauth.js +66 -9
  39. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  40. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  41. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +36 -7
  42. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  43. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  44. package/lib/vendor/blamejs/lib/cache.js +174 -105
  45. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  46. package/lib/vendor/blamejs/lib/cli.js +19 -14
  47. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  48. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  49. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  50. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  51. package/lib/vendor/blamejs/lib/compliance.js +210 -4
  52. package/lib/vendor/blamejs/lib/consent.js +82 -29
  53. package/lib/vendor/blamejs/lib/constants.js +27 -11
  54. package/lib/vendor/blamejs/lib/credential-hash.js +9 -0
  55. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  56. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  57. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  58. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  59. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  60. package/lib/vendor/blamejs/lib/db.js +249 -99
  61. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  62. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  63. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  64. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  65. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  66. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  67. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  68. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  69. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  70. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  71. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  72. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  73. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  74. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  75. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  76. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  77. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  78. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  79. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  80. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  81. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  82. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  83. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  84. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  85. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  86. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  87. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  88. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  89. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  90. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  91. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  92. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  93. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  94. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  95. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  96. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  97. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  98. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  99. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  100. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  101. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  102. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  103. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  104. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  105. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  106. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  107. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  108. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  109. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  110. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  111. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  112. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  113. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  114. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  115. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  116. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  117. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  118. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  119. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  120. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  121. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  122. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  123. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  124. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  125. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  126. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  127. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  128. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  129. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  131. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  132. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  133. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  134. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  135. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  136. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  137. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  138. package/lib/vendor/blamejs/lib/mail.js +8 -4
  139. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  140. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  141. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  142. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  143. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  144. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  145. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  146. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  147. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  148. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  149. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  150. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  151. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  152. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  153. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  154. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  155. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  156. package/lib/vendor/blamejs/lib/observability.js +124 -0
  157. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  158. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  159. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  160. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  161. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  162. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  163. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  164. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  165. package/lib/vendor/blamejs/lib/queue.js +7 -0
  166. package/lib/vendor/blamejs/lib/redact.js +68 -11
  167. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  168. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  169. package/lib/vendor/blamejs/lib/retention.js +117 -42
  170. package/lib/vendor/blamejs/lib/router.js +212 -5
  171. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  172. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  173. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  174. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  175. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  176. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  177. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  178. package/lib/vendor/blamejs/lib/scheduler.js +47 -12
  179. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  180. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  181. package/lib/vendor/blamejs/lib/session.js +175 -77
  182. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  183. package/lib/vendor/blamejs/lib/sse.js +26 -0
  184. package/lib/vendor/blamejs/lib/ssrf-guard.js +169 -4
  185. package/lib/vendor/blamejs/lib/static.js +177 -34
  186. package/lib/vendor/blamejs/lib/subject.js +96 -49
  187. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  188. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  189. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  190. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  191. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  192. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  193. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  194. package/lib/vendor/blamejs/package.json +2 -2
  195. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  200. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  201. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  202. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  203. package/lib/vendor/blamejs/release-notes/v0.15.7.json +43 -0
  204. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  205. package/lib/vendor/blamejs/scripts/gen-migrating.js +67 -0
  206. package/lib/vendor/blamejs/scripts/release.js +398 -38
  207. package/lib/vendor/blamejs/test/00-primitives.js +168 -0
  208. package/lib/vendor/blamejs/test/10-state.js +140 -14
  209. package/lib/vendor/blamejs/test/20-db.js +65 -2
  210. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  211. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  212. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  213. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  214. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  215. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  216. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  217. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  220. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  221. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  222. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  223. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  224. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  225. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  226. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  227. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  228. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  229. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  230. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  231. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  232. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  233. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  234. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  235. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  236. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  237. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  238. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  239. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  240. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  242. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  248. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  249. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  250. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  251. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  252. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1196 -14
  253. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  254. package/lib/vendor/blamejs/test/layer-0-primitives/credential-hash.test.js +18 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  256. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  258. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  259. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  267. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  271. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  272. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  273. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  275. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  276. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  277. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  278. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  282. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  283. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  286. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  287. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  288. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  296. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/retention-floor.test.js +59 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  302. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +362 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/scheduler-watchdog-stale-settle.test.js +71 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  308. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  309. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  310. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  312. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  313. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  314. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  315. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  316. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  317. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  318. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  319. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  320. package/lib/vendor/blamejs/test/smoke.js +79 -21
  321. package/package.json +2 -2
  322. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  323. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  324. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  325. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  326. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  327. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  328. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  329. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  330. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  331. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  332. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  333. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  334. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  335. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  336. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  337. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  338. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  339. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  340. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  341. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  342. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  343. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -53,9 +53,11 @@ var clusterStorage = require("./cluster-storage");
53
53
  var C = require("./constants");
54
54
  var { generateToken, sha3Hash } = require("./crypto");
55
55
  var cryptoField = require("./crypto-field");
56
+ var frameworkSchema = require("./framework-schema");
56
57
  var lazyRequire = require("./lazy-require");
57
58
  var requestHelpers = require("./request-helpers");
58
59
  var safeJson = require("./safe-json");
60
+ var sql = require("./sql");
59
61
  var { SessionError } = require("./framework-error");
60
62
 
61
63
  // vault is initialized at boot before sessions; lazyRequire keeps the
@@ -119,8 +121,33 @@ var SID_NAMESPACE = "bj-session:";
119
121
  // behind the same helper.
120
122
  var SID_BYTES = C.BYTES.bytes(32);
121
123
 
124
+ // Logical session-table name. Two uses, deliberately distinct:
125
+ // - As the cryptoField registry key (sealRow / unsealRow / lookupHash),
126
+ // it stays the LOGICAL name — that is the key db.js registers the
127
+ // sealedFields + derivedHashes under, independent of any table prefix.
128
+ // - As the SQL table name, it is resolved through
129
+ // frameworkSchema.tableName(...) so a configured table prefix
130
+ // (b.frameworkSchema.setTablePrefix) is honored. The name is
131
+ // identity-mapped in LOCAL_TO_EXTERNAL, so clusterStorage's
132
+ // resolveTables leaves it untouched at dispatch.
133
+ var SESSION_TABLE = "_blamejs_sessions"; // allow:hand-rolled-sql — canonical logical table-name + cryptoField registry key
134
+ function _sessionSqlTable() { return frameworkSchema.tableName(SESSION_TABLE); }
135
+
136
+ // b.sql opts for every session statement: thread the ACTIVE backend dialect
137
+ // (clusterStorage.dialect() — "sqlite" single-node, "postgres" | "mysql" in
138
+ // cluster mode) so the emitted identifier quoting and dialect idioms match
139
+ // the backend the SQL dispatches to. b.sql defaults to "sqlite", which works
140
+ // on Postgres only by accident (both double-quote identifiers) and emits the
141
+ // wrong quoting + idioms on MySQL. The default store routes through
142
+ // clusterStorage, and an operator localDbThin store is single-node sqlite —
143
+ // in both single-node cases clusterStorage.dialect() resolves "sqlite", so
144
+ // the opts agree with the store the SQL reaches. clusterStorage.execute (the
145
+ // default store) still rewrites table names + translates `?` placeholders at
146
+ // dispatch; this controls only the builder-side quoting + idiom selection.
147
+ function _sessionSqlOpts() { return { dialect: clusterStorage.dialect() }; }
148
+
122
149
  // Column order used for INSERT — kept as a constant so the placeholders
123
- // list and the values list stay in sync. Must match _blamejs_sessions's
150
+ // list and the values list stay in sync. Must match the session table's
124
151
  // schema in db.js (single-node) and framework-schema.js (cluster mode).
125
152
  var SESSION_COLS = ["sidHash", "userId", "userIdHash", "data", "createdAt", "expiresAt", "lastActivity"];
126
153
 
@@ -167,7 +194,7 @@ function _unsealCookieToken(token) {
167
194
  // where not set). The cryptoField.sealRow call seals userId/data and
168
195
  // produces userIdHash from userId.
169
196
  function _sealForInsert(row) {
170
- var sealed = cryptoField.sealRow("_blamejs_sessions", row);
197
+ var sealed = cryptoField.sealRow(SESSION_TABLE, row);
171
198
  for (var i = 0; i < SESSION_COLS.length; i++) {
172
199
  if (!(SESSION_COLS[i] in sealed)) sealed[SESSION_COLS[i]] = null;
173
200
  }
@@ -433,13 +460,13 @@ async function create(opts) {
433
460
  expiresAt: expiresAt,
434
461
  lastActivity: nowMs,
435
462
  });
436
- var values = SESSION_COLS.map(function (c) { return sealed[c]; });
437
- var placeholders = SESSION_COLS.map(function () { return "?"; }).join(", ");
438
- var quoted = SESSION_COLS.map(function (c) { return '"' + c + '"'; }).join(", ");
439
- await _currentStore().execute(
440
- "INSERT INTO _blamejs_sessions (" + quoted + ") VALUES (" + placeholders + ")",
441
- values
442
- );
463
+ var insertRow = {};
464
+ for (var ci = 0; ci < SESSION_COLS.length; ci++) insertRow[SESSION_COLS[ci]] = sealed[SESSION_COLS[ci]];
465
+ var built = sql.insert(_sessionSqlTable(), _sessionSqlOpts())
466
+ .columns(SESSION_COLS)
467
+ .values(insertRow)
468
+ .toSql();
469
+ await _currentStore().execute(built.sql, built.params);
443
470
 
444
471
  return { token: _sealCookieToken(sid), expiresAt: expiresAt };
445
472
  }
@@ -496,11 +523,11 @@ async function verify(token, verifyOpts) {
496
523
  if (sid === null) return null;
497
524
  var sidHash = _hashSid(sid);
498
525
 
499
- var row = await _currentStore().executeOne(
500
- "SELECT sidHash, userId, userIdHash, data, createdAt, expiresAt, lastActivity " +
501
- "FROM _blamejs_sessions WHERE sidHash = ?",
502
- [sidHash]
503
- );
526
+ var selBuilt = sql.select(_sessionSqlTable(), _sessionSqlOpts())
527
+ .columns(["sidHash", "userId", "userIdHash", "data", "createdAt", "expiresAt", "lastActivity"])
528
+ .where("sidHash", sidHash)
529
+ .toSql();
530
+ var row = await _currentStore().executeOne(selBuilt.sql, selBuilt.params);
504
531
  if (!row) return null;
505
532
  var nowMs = Date.now();
506
533
  if (Number(row.expiresAt) < nowMs) {
@@ -554,7 +581,7 @@ async function verify(token, verifyOpts) {
554
581
  // Unseal sealed columns (userId, data) using the cryptoField pipeline
555
582
  // so we return cleartext to the caller — same shape as the previous
556
583
  // db().from(...).first() path delivered.
557
- var unsealed = cryptoField.unsealRow("_blamejs_sessions", row);
584
+ var unsealed = cryptoField.unsealRow(SESSION_TABLE, row);
558
585
  var data = null;
559
586
  var storedFingerprint = null;
560
587
  if (unsealed.data) {
@@ -679,10 +706,10 @@ async function destroy(token) {
679
706
  }
680
707
 
681
708
  async function _deleteBySidHash(sidHash) {
682
- var result = await _currentStore().execute(
683
- "DELETE FROM _blamejs_sessions WHERE sidHash = ?",
684
- [sidHash]
685
- );
709
+ var built = sql.delete(_sessionSqlTable(), _sessionSqlOpts())
710
+ .where("sidHash", sidHash)
711
+ .toSql();
712
+ var result = await _currentStore().execute(built.sql, built.params);
686
713
  return (result.rowCount || 0) > 0;
687
714
  }
688
715
 
@@ -718,16 +745,23 @@ async function destroyAllForUser(userId) {
718
745
  true);
719
746
  }
720
747
  // userId is sealed; look up via derived userIdHash.
721
- var lookup = cryptoField.lookupHash("_blamejs_sessions", "userId", userId);
748
+ var lookup = cryptoField.lookupHash(SESSION_TABLE, "userId", userId);
722
749
  if (!lookup) {
723
750
  throw _err("MISCONFIGURED",
724
- "_blamejs_sessions schema is missing the userIdHash derived hash — framework misconfigured",
751
+ "the session table schema is missing the userIdHash derived hash — framework misconfigured",
725
752
  true);
726
753
  }
727
- var result = await _currentStore().execute(
728
- "DELETE FROM _blamejs_sessions WHERE userIdHash = ?",
729
- [lookup.value]
730
- );
754
+ // Dual-read across the keyed-MAC flip: a pre-v0.15.0 session row carries
755
+ // the legacy salted-sha3 userIdHash, so destroy must match both digests
756
+ // or it leaves un-migrated sessions for the user un-revoked.
757
+ var userHashes = [lookup.value];
758
+ if (lookup.legacyValue != null && lookup.legacyValue !== lookup.value) {
759
+ userHashes.push(lookup.legacyValue);
760
+ }
761
+ var built = sql.delete(_sessionSqlTable(), _sessionSqlOpts())
762
+ .whereIn("userIdHash", userHashes)
763
+ .toSql();
764
+ var result = await _currentStore().execute(built.sql, built.params);
731
765
  return result.rowCount || 0;
732
766
  }
733
767
 
@@ -776,18 +810,20 @@ async function touch(token, opts) {
776
810
  if (opts.extendBy !== undefined && opts.extendBy !== null) {
777
811
  _validateTtl(opts.extendBy, "session.touch");
778
812
  var newExpires = nowMs + opts.extendBy;
779
- var result = await _currentStore().execute(
780
- "UPDATE _blamejs_sessions SET lastActivity = ?, expiresAt = ? " +
781
- "WHERE sidHash = ? AND expiresAt >= ?",
782
- [nowMs, newExpires, sidHash, nowMs]
783
- );
813
+ var built = sql.update(_sessionSqlTable(), _sessionSqlOpts())
814
+ .set({ lastActivity: nowMs, expiresAt: newExpires })
815
+ .where("sidHash", sidHash)
816
+ .where("expiresAt", ">=", nowMs)
817
+ .toSql();
818
+ var result = await _currentStore().execute(built.sql, built.params);
784
819
  return (result.rowCount || 0) > 0;
785
820
  }
786
- var result2 = await _currentStore().execute(
787
- "UPDATE _blamejs_sessions SET lastActivity = ? " +
788
- "WHERE sidHash = ? AND expiresAt >= ?",
789
- [nowMs, sidHash, nowMs]
790
- );
821
+ var built2 = sql.update(_sessionSqlTable(), _sessionSqlOpts())
822
+ .set({ lastActivity: nowMs })
823
+ .where("sidHash", sidHash)
824
+ .where("expiresAt", ">=", nowMs)
825
+ .toSql();
826
+ var result2 = await _currentStore().execute(built2.sql, built2.params);
791
827
  return (result2.rowCount || 0) > 0;
792
828
  }
793
829
 
@@ -810,11 +846,20 @@ async function touch(token, opts) {
810
846
  * the new token verifies. Audit event `auth.session.rotate` fires
811
847
  * best-effort with `metadata.reason`.
812
848
  *
849
+ * Device binding: when the session was created with `{ req, fingerprintFields }`
850
+ * the bound fingerprint is keyed to the sid, so rotation re-keys it to the new
851
+ * sid from the live request. Pass the same `{ req, fingerprintFields }` to
852
+ * `rotate` — a fingerprint-bound session rotated without `req` throws, because
853
+ * the binding cannot follow the sid otherwise (it would silently break or make
854
+ * the next `verify` falsely report drift).
855
+ *
813
856
  * @opts
814
857
  * {
815
- * data?: object, // replacement session data (re-sealed)
816
- * ttlMs?: number, // new TTL; if absent, existing expiresAt preserved
817
- * reason?: string, // audit metadata ("login", "mfa", "role-change")
858
+ * data?: object, // replacement session data (re-sealed)
859
+ * ttlMs?: number, // new TTL; if absent, existing expiresAt preserved
860
+ * reason?: string, // audit metadata ("login", "mfa", "role-change")
861
+ * req?: IncomingMessage, // re-key the device fingerprint to the new sid
862
+ * fingerprintFields?: Array<string|fn>, // default ["clientIp","userAgent","acceptLanguage"]
818
863
  * }
819
864
  *
820
865
  * @example
@@ -844,31 +889,76 @@ async function rotate(oldToken, opts) {
844
889
  newExpires = nowMs + opts.ttlMs;
845
890
  }
846
891
 
847
- var setParts = ['"sidHash" = ?', '"lastActivity" = ?'];
848
- var setParams = [newSidHash, nowMs];
892
+ var setCols = { sidHash: newSidHash, lastActivity: nowMs };
893
+
894
+ // Re-key the device binding to the NEW sid. __bj_fingerprint is sid-keyed
895
+ // (_hashFingerprint(sid, inputs), so a stolen DB can't replay it); a rotated
896
+ // session that kept the old-sid hash would make verify(newToken, sameReq)
897
+ // recompute against the new sid and mismatch — a false fingerprintDrift
898
+ // (strict operators destroy the session on every rotation) or a silently
899
+ // broken binding. Read the live row to learn whether the session was bound
900
+ // and to carry its payload forward when opts.data is not supplied.
901
+ var fpFields = Array.isArray(opts.fingerprintFields) && opts.fingerprintFields.length > 0
902
+ ? opts.fingerprintFields : DEFAULT_FINGERPRINT_FIELDS;
903
+ var existingData = null;
904
+ var rotSelBuilt = sql.select(_sessionSqlTable(), _sessionSqlOpts())
905
+ .columns(["data"])
906
+ .where("sidHash", oldSidHash)
907
+ .where("expiresAt", ">=", nowMs)
908
+ .toSql();
909
+ var existingRow = await _currentStore().executeOne(rotSelBuilt.sql, rotSelBuilt.params);
910
+ if (!existingRow) return null; // unknown / expired old session
911
+ try {
912
+ var unsealedExisting = cryptoField.unsealRow(SESSION_TABLE, existingRow);
913
+ if (unsealedExisting.data) existingData = safeJson.parse(unsealedExisting.data);
914
+ } catch (_e) { existingData = null; }
915
+ var wasBound = existingData && typeof existingData === "object" &&
916
+ typeof existingData.__bj_fingerprint === "string";
917
+
918
+ if (opts.data !== undefined || wasBound) {
919
+ // opts.data REPLACES the payload (documented rotate semantics); otherwise
920
+ // carry the existing payload forward. The reserved __bj_fingerprint is
921
+ // never copied verbatim (it is old-sid-keyed) — it is recomputed below.
922
+ var newDataObj;
923
+ if (opts.data !== undefined) {
924
+ newDataObj = (opts.data && typeof opts.data === "object") ? Object.assign({}, opts.data) : null;
925
+ } else {
926
+ newDataObj = (existingData && typeof existingData === "object") ? Object.assign({}, existingData) : null;
927
+ }
928
+ if (newDataObj) delete newDataObj.__bj_fingerprint;
929
+
930
+ if (wasBound) {
931
+ if (!opts.req) {
932
+ throw _err("ROTATE_FINGERPRINT_REQ_REQUIRED",
933
+ "session.rotate: this session is fingerprint-bound; pass { req, fingerprintFields } " +
934
+ "so the device binding can be re-keyed to the new session id", true);
935
+ }
936
+ if (!newDataObj) newDataObj = {};
937
+ newDataObj.__bj_fingerprint = _hashFingerprint(newSid, _buildFingerprintInputs(opts.req, fpFields));
938
+ }
849
939
 
850
- if (opts.data !== undefined) {
851
- var dataJson = opts.data ? JSON.stringify(opts.data) : null;
852
- var sealedRow = cryptoField.sealRow("_blamejs_sessions", { data: dataJson });
853
- setParts.push('"data" = ?');
854
- setParams.push(sealedRow.data);
940
+ var dataJson = newDataObj ? JSON.stringify(newDataObj) : null;
941
+ var sealedRow = cryptoField.sealRow(SESSION_TABLE, { data: dataJson });
942
+ setCols.data = sealedRow.data;
855
943
  }
856
944
  if (newExpires !== null) {
857
- setParts.push('"expiresAt" = ?');
858
- setParams.push(newExpires);
945
+ setCols.expiresAt = newExpires;
859
946
  }
860
947
 
861
- var sql = "UPDATE _blamejs_sessions SET " + setParts.join(", ") +
862
- " WHERE sidHash = ? AND expiresAt >= ?";
863
- var params = setParams.concat([oldSidHash, nowMs]);
864
- var result = await _currentStore().execute(sql, params);
948
+ var updBuilt = sql.update(_sessionSqlTable(), _sessionSqlOpts())
949
+ .set(setCols)
950
+ .where("sidHash", oldSidHash)
951
+ .where("expiresAt", ">=", nowMs)
952
+ .toSql();
953
+ var result = await _currentStore().execute(updBuilt.sql, updBuilt.params);
865
954
  if ((result.rowCount || 0) === 0) return null;
866
955
 
867
956
  // Read the row's effective expiresAt to return — single source of truth.
868
- var row = await _currentStore().executeOne(
869
- 'SELECT "expiresAt" FROM _blamejs_sessions WHERE sidHash = ?',
870
- [newSidHash]
871
- );
957
+ var rowBuilt = sql.select(_sessionSqlTable(), _sessionSqlOpts())
958
+ .columns(["expiresAt"])
959
+ .where("sidHash", newSidHash)
960
+ .toSql();
961
+ var row = await _currentStore().executeOne(rowBuilt.sql, rowBuilt.params);
872
962
  var expiresAt = row ? Number(row.expiresAt) : null;
873
963
 
874
964
  // Audit emit — best-effort. The framework's audit chain logs the
@@ -949,17 +1039,18 @@ async function updateData(token, data, opts) {
949
1039
  // wins on the same sid, which is the right shape for cart-style
950
1040
  // writes; operators needing strict serialization wrap with
951
1041
  // b.resourceAccessLock.
952
- var row = await _currentStore().executeOne(
953
- 'SELECT "userId", "userIdHash", "data", "createdAt", "expiresAt", "lastActivity" ' +
954
- 'FROM _blamejs_sessions WHERE sidHash = ? AND expiresAt >= ?',
955
- [sidHash, nowMs]
956
- );
1042
+ var selBuilt = sql.select(_sessionSqlTable(), _sessionSqlOpts())
1043
+ .columns(["userId", "userIdHash", "data", "createdAt", "expiresAt", "lastActivity"])
1044
+ .where("sidHash", sidHash)
1045
+ .where("expiresAt", ">=", nowMs)
1046
+ .toSql();
1047
+ var row = await _currentStore().executeOne(selBuilt.sql, selBuilt.params);
957
1048
  if (!row) return false;
958
1049
 
959
1050
  // Recover the existing data + reserved fingerprint key (vault-
960
1051
  // sealed at rest). Operators that want a fresh fingerprint also
961
1052
  // call b.session.rotate; updateData preserves the binding.
962
- var unsealed = cryptoField.unsealRow("_blamejs_sessions", row);
1053
+ var unsealed = cryptoField.unsealRow(SESSION_TABLE, row);
963
1054
  var existing = null;
964
1055
  var storedFingerprint = null;
965
1056
  if (unsealed.data) {
@@ -998,19 +1089,20 @@ async function updateData(token, data, opts) {
998
1089
 
999
1090
  // Re-seal the data column. cryptoField.sealRow handles the AAD
1000
1091
  // binding + sealedFields registration automatically.
1001
- var sealedRow = cryptoField.sealRow("_blamejs_sessions", {
1092
+ var sealedRow = cryptoField.sealRow(SESSION_TABLE, {
1002
1093
  data: next ? JSON.stringify(next) : null,
1003
1094
  });
1004
1095
 
1005
- var setParts = ['"data" = ?'];
1006
- var setParams = [sealedRow.data];
1096
+ var setCols = { data: sealedRow.data };
1007
1097
  if (opts.touchLastActivity !== false) {
1008
- setParts.push('"lastActivity" = ?');
1009
- setParams.push(nowMs);
1098
+ setCols.lastActivity = nowMs;
1010
1099
  }
1011
- var sql = "UPDATE _blamejs_sessions SET " + setParts.join(", ") +
1012
- " WHERE sidHash = ? AND expiresAt >= ?";
1013
- var result = await _currentStore().execute(sql, setParams.concat([sidHash, nowMs]));
1100
+ var updBuilt = sql.update(_sessionSqlTable(), _sessionSqlOpts())
1101
+ .set(setCols)
1102
+ .where("sidHash", sidHash)
1103
+ .where("expiresAt", ">=", nowMs)
1104
+ .toSql();
1105
+ var result = await _currentStore().execute(updBuilt.sql, updBuilt.params);
1014
1106
  return (result.rowCount || 0) > 0;
1015
1107
  }
1016
1108
 
@@ -1040,10 +1132,10 @@ async function updateData(token, data, opts) {
1040
1132
  */
1041
1133
  async function purgeExpired() {
1042
1134
  cluster.requireLeader();
1043
- var result = await _currentStore().execute(
1044
- "DELETE FROM _blamejs_sessions WHERE expiresAt < ?",
1045
- [Date.now()]
1046
- );
1135
+ var built = sql.delete(_sessionSqlTable(), _sessionSqlOpts())
1136
+ .where("expiresAt", "<", Date.now())
1137
+ .toSql();
1138
+ var result = await _currentStore().execute(built.sql, built.params);
1047
1139
  return result.rowCount || 0;
1048
1140
  }
1049
1141
 
@@ -1066,10 +1158,16 @@ async function purgeExpired() {
1066
1158
  * // → 482
1067
1159
  */
1068
1160
  async function count() {
1069
- var row = await _currentStore().executeOne(
1070
- "SELECT COUNT(*) AS c FROM _blamejs_sessions WHERE expiresAt >= ?",
1071
- [Date.now()]
1072
- );
1161
+ var built = sql.select(_sessionSqlTable(), _sessionSqlOpts())
1162
+ .count("*", "c")
1163
+ .where("expiresAt", ">=", Date.now())
1164
+ .toSql();
1165
+ var row = await _currentStore().executeOne(built.sql, built.params);
1166
+ // COUNT(*) aliased to `c` is not a framework-schema column, so
1167
+ // clusterStorage.coerceRows does not touch it; node-postgres / mysql2
1168
+ // hand a BIGINT count back as a decimal STRING. Number() at the read
1169
+ // boundary keeps single-node sqlite (native number) and the cluster
1170
+ // backends returning the same JS number.
1073
1171
  return row ? Number(row.c) : 0;
1074
1172
  }
1075
1173