@blamejs/blamejs-shop 0.4.30 → 0.4.32

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/CHANGELOG.md +4 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/checkout.js +8 -0
  4. package/lib/order.js +71 -11
  5. package/lib/vendor/MANIFEST.json +392 -278
  6. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  7. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  8. package/lib/vendor/blamejs/.gitignore +6 -0
  9. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  10. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  11. package/lib/vendor/blamejs/README.md +8 -6
  12. package/lib/vendor/blamejs/SECURITY.md +19 -3
  13. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  14. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  15. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  16. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  17. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  18. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  19. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  20. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  21. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  22. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  23. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  24. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  25. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  26. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  27. package/lib/vendor/blamejs/index.js +4 -0
  28. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  29. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  30. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  31. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  32. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  33. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  34. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  35. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  36. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  37. package/lib/vendor/blamejs/lib/audit.js +259 -123
  38. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -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 +31 -5
  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 +206 -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/crypto-field.js +916 -156
  55. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  56. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  57. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  58. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  59. package/lib/vendor/blamejs/lib/db.js +249 -99
  60. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  61. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  62. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  63. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  64. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  65. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  66. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  67. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  68. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  69. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  70. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  71. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  72. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  73. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  74. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  75. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  76. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  77. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  78. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  79. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  80. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  81. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  82. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  83. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  84. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  85. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  86. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  87. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  88. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  89. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  90. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  91. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  92. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  93. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  94. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  95. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  96. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  97. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  98. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  99. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  100. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  101. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  102. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  103. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  104. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  106. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  107. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  108. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  109. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  110. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  111. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  112. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  113. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  114. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  115. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  116. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  117. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  118. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  119. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  120. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  121. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  122. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  123. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  124. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  125. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  126. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  128. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  129. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  131. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  132. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  133. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  134. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  135. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  136. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  137. package/lib/vendor/blamejs/lib/mail.js +8 -4
  138. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  139. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  140. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  141. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  142. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  143. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  144. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  145. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  146. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  147. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  148. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  149. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  150. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  151. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  152. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  153. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  154. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  155. package/lib/vendor/blamejs/lib/observability.js +124 -0
  156. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  157. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  158. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  159. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  160. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  161. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  162. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  163. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  164. package/lib/vendor/blamejs/lib/queue.js +7 -0
  165. package/lib/vendor/blamejs/lib/redact.js +68 -11
  166. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  167. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  168. package/lib/vendor/blamejs/lib/retention.js +101 -40
  169. package/lib/vendor/blamejs/lib/router.js +212 -5
  170. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  171. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  172. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  173. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  174. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  175. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  176. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  177. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  178. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  179. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  180. package/lib/vendor/blamejs/lib/session.js +175 -77
  181. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  182. package/lib/vendor/blamejs/lib/sse.js +26 -0
  183. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  184. package/lib/vendor/blamejs/lib/static.js +177 -34
  185. package/lib/vendor/blamejs/lib/subject.js +96 -49
  186. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  187. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  188. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  189. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  190. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  191. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  192. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  193. package/lib/vendor/blamejs/package.json +2 -2
  194. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  200. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  201. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  202. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  203. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  204. package/lib/vendor/blamejs/scripts/release.js +398 -38
  205. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  206. package/lib/vendor/blamejs/test/10-state.js +140 -14
  207. package/lib/vendor/blamejs/test/20-db.js +65 -2
  208. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  209. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  210. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  211. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  212. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  213. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  214. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  215. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  220. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  221. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  222. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  223. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  224. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  225. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  226. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  227. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  228. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  229. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  230. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  231. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  232. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  233. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  234. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  235. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  236. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  237. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  238. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  240. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  248. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  249. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  250. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  251. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  256. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  258. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  271. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  272. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  273. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  274. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  275. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  279. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  280. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  284. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  285. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  293. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  302. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  304. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  308. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  310. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  312. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  313. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  314. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  315. package/lib/vendor/blamejs/test/smoke.js +79 -21
  316. package/package.json +1 -1
  317. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  318. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  319. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  320. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  321. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  322. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  323. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  324. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  325. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  326. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  327. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  328. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  329. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  330. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  331. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  332. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  334. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  335. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  336. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  337. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  338. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -50,6 +50,7 @@ var lazyRequire = require("./lazy-require");
50
50
  var numericBounds = require("./numeric-bounds");
51
51
  var safeJson = require("./safe-json");
52
52
  var safeSql = require("./safe-sql");
53
+ var sql = require("./sql");
53
54
  var scheduler = require("./scheduler");
54
55
  var { QueueError } = require("./framework-error");
55
56
 
@@ -59,10 +60,16 @@ var _err = QueueError.factory;
59
60
  // COLUMN→seal map registered in db.js's FRAMEWORK_SCHEMA, NOT the
60
61
  // physical table the SQL writes to. An operator who points the backend
61
62
  // at their own table still seals payload + lastError through this map,
62
- // so a bring-your-own table inherits the same at-rest protection.
63
+ // so a bring-your-own table inherits the same at-rest protection. The KEY
64
+ // must stay byte-identical to db.js's registerTable literal.
65
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not a SQL table.
63
66
  var SEAL_TABLE = "_blamejs_jobs";
64
67
 
65
- // Default physical table for the local backend.
68
+ // Default LOGICAL table for the local backend. Passed BARE to b.sql so
69
+ // clusterStorage.resolveTables rewrites it to the configured cluster name
70
+ // (applying the configurable prefix); a custom config.table is quoted at
71
+ // build time instead. b.sql owns the quoting; this is the logical name.
72
+ // allow:hand-rolled-sql — framework logical jobs-table name handed to b.sql, not a SQL literal.
66
73
  var DEFAULT_TABLE = "_blamejs_jobs";
67
74
 
68
75
  // vault is lazy-required because some flows (sealed lastError) only
@@ -70,6 +77,22 @@ var DEFAULT_TABLE = "_blamejs_jobs";
70
77
  // (queue-local → vault → db → audit → cluster) tolerates the late bind.
71
78
  var vault = lazyRequire(function () { return require("./vault"); });
72
79
 
80
+ // Self-register the _blamejs_jobs sealed-column declaration with
81
+ // cryptoField so payload + lastError seal at rest even when db.init never
82
+ // ran in this process. cryptoField.sealRow is a SILENT pass-through for an
83
+ // unregistered table — a standalone redis/sqs queue node (no db.init) would
84
+ // otherwise write job payloads (webhook bodies, credentials, PII) in
85
+ // cleartext. db.init registers the same shape from its FRAMEWORK_SCHEMA;
86
+ // registerTable is idempotent, and probing getSchema (rather than a module
87
+ // boolean) keeps this reset-safe — db._resetForTest() clears the cryptoField
88
+ // registry between tests, and a boolean cache would then leave seal a no-op.
89
+ function _ensureSealTable() {
90
+ if (cryptoField.getSchema(SEAL_TABLE)) return;
91
+ cryptoField.registerTable(SEAL_TABLE, {
92
+ sealedFields: ["payload", "lastError"],
93
+ });
94
+ }
95
+
73
96
  // Column order kept as a constant so the placeholders + values lists
74
97
  // stay in sync. Mirrors db.js's FRAMEWORK_SCHEMA for _blamejs_jobs.
75
98
  var JOB_COLS = [
@@ -95,14 +118,6 @@ var LEASE_RETURN_COLS = [
95
118
  "repeatCron", "repeatTimezone", "flowId", "flowChildName",
96
119
  ];
97
120
 
98
- function _quotedList(cols) {
99
- return cols.map(function (c) { return '"' + c + '"'; }).join(", ");
100
- }
101
-
102
- function _placeholders(cols) {
103
- return cols.map(function () { return "?"; }).join(", ");
104
- }
105
-
106
121
  function _shapeLeasedRow(raw) {
107
122
  // raw is a row coming back from RETURNING — payload is sealed if
108
123
  // present. Run through cryptoField's unseal pipeline so the caller
@@ -146,12 +161,19 @@ function _resolveStore(handle) {
146
161
  return handle;
147
162
  }
148
163
 
149
- // Compose the physical table reference from config.table + config.schema,
150
- // quoting each identifier through b.safeSql so an operator-supplied name
151
- // cannot interpolate SQL through the identifier slot (CWE-89). Returns
152
- // the bare default name unquoted when no custom table/schema is given so
153
- // the framework's cluster-mode table rewrite (resolveTables) still fires
154
- // on the default jobs table; any custom name is fully validated + quoted.
164
+ // Resolve the b.sql table-builder options from config.table + config.schema.
165
+ // Every SQL statement is composed through b.sql, which quotes identifiers
166
+ // through b.safeSql so an operator-supplied name cannot interpolate SQL
167
+ // through the identifier slot (CWE-89). The DEFAULT logical table is passed
168
+ // BARE (quoteName off) so the framework's cluster-mode rewrite
169
+ // (clusterStorage.resolveTables) still fires on the jobs table and applies
170
+ // the configurable prefix; any custom table/schema is validated + quoted at
171
+ // build time instead (no rewrite — it is the operator's own table).
172
+ //
173
+ // Returns { name, opts } where `opts` is spread into every b.sql verb call:
174
+ // default → { dialect: "sqlite" } (bare name, rewritten)
175
+ // custom → { dialect: "sqlite", quoteName: true } (quoted, no rewrite)
176
+ // custom+schema → adds { schema } (b.sql emits the quoted schema.table form)
155
177
  function _resolveTableRef(config) {
156
178
  var table = config.table !== undefined && config.table !== null
157
179
  ? config.table : DEFAULT_TABLE;
@@ -167,23 +189,33 @@ function _resolveTableRef(config) {
167
189
  var usingDefault = (table === DEFAULT_TABLE) &&
168
190
  (schema === undefined || schema === null);
169
191
  if (usingDefault) {
170
- // Byte-identical default SQL unquoted bare name so cluster-mode
171
- // resolveTables continues to recognize and rewrite the jobs table.
172
- return DEFAULT_TABLE;
192
+ // Bare default — b.sql leaves it unquoted so cluster-mode resolveTables
193
+ // recognizes + rewrites the jobs table (and applies the prefix).
194
+ return { name: DEFAULT_TABLE, opts: { dialect: "sqlite" } };
173
195
  }
174
- // Any custom table/schema is validated + dialect-quoted. validateIdentifier
175
- // / quoteQualified THROW (SafeSqlError) on a bad identifier; surface that
176
- // as the queue's config-time error so the operator catches the typo at
177
- // boot rather than on first enqueue.
196
+ // Any custom table/schema is validated + dialect-quoted by b.sql at build
197
+ // time. validateIdentifier (run inside b.sql's TableRef) THROWs
198
+ // (SqlBuilderError / SafeSqlError) on a bad identifier; surface that as the
199
+ // queue's config-time error so the operator catches the typo at boot rather
200
+ // than on first enqueue.
201
+ var opts = { dialect: "sqlite", quoteName: true };
202
+ if (schema !== undefined && schema !== null && schema !== "") opts.schema = schema;
178
203
  try {
179
- if (schema !== undefined && schema !== null && schema !== "") {
180
- return safeSql.quoteQualified([schema, table]);
181
- }
182
- return safeSql.quoteIdentifier(table);
204
+ // Validate the custom identifier(s) at config time with the STRICTER
205
+ // policy (allowReserved off — a reserved word like `select` is refused
206
+ // for a bring-your-own queue table, matching the prior
207
+ // quoteIdentifier / quoteQualified contract). b.sql then quotes the
208
+ // already-validated name at build time. validateIdentifier THROWs
209
+ // (SafeSqlError) on a bad shape / reserved word / injection-shaped
210
+ // schema, surfaced here as the queue's config-time error so the
211
+ // operator catches the typo at boot rather than on first enqueue.
212
+ safeSql.validateIdentifier(table);
213
+ if (opts.schema) safeSql.validateIdentifier(opts.schema);
183
214
  } catch (e) {
184
215
  throw _err("INVALID_TABLE",
185
216
  "queue local table/schema failed identifier validation: " + e.message, true);
186
217
  }
218
+ return { name: table, opts: opts };
187
219
  }
188
220
 
189
221
  function create(config) {
@@ -192,11 +224,20 @@ function create(config) {
192
224
  // exactly: cluster-storage dispatch to the framework's main DB
193
225
  // (single-node) / external-db (cluster), table "_blamejs_jobs".
194
226
  var store = _resolveStore(config.db);
195
- // qTable holds the physical table reference already validated +
196
- // dialect-quoted by _resolveTableRef (via safeSql.quoteIdentifier /
197
- // quoteQualified, or the framework's bare default name). The `q` prefix
198
- // marks it as a safe-to-interpolate identifier so it is never re-quoted.
199
- var qTable = _resolveTableRef(config);
227
+ // ref = { name, opts } for every b.sql verb call — the bare default
228
+ // jobs table (clusterStorage rewrites it + applies the configurable
229
+ // prefix) or a validated + quoted custom table/schema. Small helpers
230
+ // open each verb builder pre-bound to this table so the table reference
231
+ // is resolved in exactly one place.
232
+ var ref = _resolveTableRef(config);
233
+ function _select() { return sql.select(ref.name, ref.opts); }
234
+ function _insert() { return sql.insert(ref.name, ref.opts); }
235
+ function _update() { return sql.update(ref.name, ref.opts); }
236
+ function _delete() { return sql.delete(ref.name, ref.opts); }
237
+ // Quoted column expression for a setRaw RHS that references the column's
238
+ // own pre-update value (attempts/availableAt). dialect-sqlite quoting is
239
+ // the double-quote form clusterStorage's Postgres path keeps.
240
+ function _qc(col) { return safeSql.quoteIdentifier(col, "sqlite", { allowReserved: true }); }
200
241
 
201
242
  async function enqueue(queueName, payload, opts) {
202
243
  cluster.requireLeader();
@@ -264,13 +305,16 @@ function create(config) {
264
305
  dependsOn: dependsOn,
265
306
  };
266
307
  var sealed = cryptoField.sealRow(SEAL_TABLE, row);
267
- var values = JOB_COLS.map(function (c) { return c in sealed ? sealed[c] : null; });
268
-
269
- await store.execute(
270
- "INSERT INTO " + qTable + " (" + _quotedList(JOB_COLS) + ") " +
271
- "VALUES (" + _placeholders(JOB_COLS) + ")",
272
- values
273
- );
308
+ // Build the full column→value map in JOB_COLS order (a missing sealed
309
+ // column binds NULL, matching the prior positional-values shape). b.sql
310
+ // quotes every column + binds every value as a placeholder.
311
+ var insertRow = {};
312
+ for (var ci = 0; ci < JOB_COLS.length; ci++) {
313
+ var col = JOB_COLS[ci];
314
+ insertRow[col] = col in sealed ? sealed[col] : null;
315
+ }
316
+ var insertBuilt = _insert().columns(JOB_COLS).values(insertRow).toSql();
317
+ await store.execute(insertBuilt.sql, insertBuilt.params);
274
318
  return {
275
319
  jobId: row._id,
276
320
  queueName: queueName,
@@ -291,21 +335,28 @@ function create(config) {
291
335
  // rows that still match status='pending' after the lock acquires
292
336
  // (Postgres EvalPlanQual; SQLite is single-writer so the same row
293
337
  // can't be picked twice). RETURNING hands back the leased columns
294
- // so we don't need a separate SELECT after the UPDATE.
295
- var sql =
296
- "UPDATE " + qTable + " " +
297
- "SET status = 'inflight', leasedAt = ?, leaseExpiresAt = ?, attempts = attempts + 1 " +
298
- "WHERE _id IN (" +
299
- " SELECT _id FROM " + qTable + " " +
300
- " WHERE queueName = ? AND status = 'pending' AND availableAt <= ? " +
301
- " ORDER BY priority DESC, availableAt ASC, enqueuedAt ASC " +
302
- " LIMIT ?" +
303
- ") " +
304
- "RETURNING " + _quotedList(LEASE_RETURN_COLS);
305
- var result = await store.execute(
306
- sql,
307
- [nowMs, leaseExpiresAt, queueName, nowMs, maxRows]
308
- );
338
+ // so we don't need a separate SELECT after the UPDATE. maxRows is a
339
+ // framework-computed integer emitted inline via b.sql's .limit() (a
340
+ // bound LIMIT param has no portable form across the subquery path);
341
+ // attempts = attempts + 1 is a setRaw over the column's own value.
342
+ var leaseInner = _select()
343
+ .columns(["_id"])
344
+ .where("queueName", queueName)
345
+ .where("status", "pending")
346
+ .whereOp("availableAt", "<=", nowMs)
347
+ .orderBy("priority", "desc")
348
+ .orderBy("availableAt", "asc")
349
+ .orderBy("enqueuedAt", "asc")
350
+ .limit(maxRows);
351
+ var leaseBuilt = _update()
352
+ .set("status", "inflight")
353
+ .set("leasedAt", nowMs)
354
+ .set("leaseExpiresAt", leaseExpiresAt)
355
+ .setRaw("attempts", _qc("attempts") + " + 1", [])
356
+ .whereIn("_id", leaseInner)
357
+ .returning(LEASE_RETURN_COLS)
358
+ .toSql();
359
+ var result = await store.execute(leaseBuilt.sql, leaseBuilt.params);
309
360
  var leased = [];
310
361
  for (var i = 0; i < result.rows.length; i++) {
311
362
  leased.push(_shapeLeasedRow(result.rows[i]));
@@ -324,11 +375,12 @@ function create(config) {
324
375
  "extendLease: additionalMs must be a positive number", true);
325
376
  }
326
377
  var newExpiry = Date.now() + additionalMs;
327
- var result = await store.execute(
328
- "UPDATE " + qTable + " SET leaseExpiresAt = ? " +
329
- "WHERE _id = ? AND status = 'inflight'",
330
- [newExpiry, jobId]
331
- );
378
+ var built = _update()
379
+ .set("leaseExpiresAt", newExpiry)
380
+ .where("_id", jobId)
381
+ .where("status", "inflight")
382
+ .toSql();
383
+ var result = await store.execute(built.sql, built.params);
332
384
  return (result.rowCount || 0) > 0;
333
385
  }
334
386
 
@@ -339,19 +391,22 @@ function create(config) {
339
391
  // the status flip. Single SELECT + UPDATE pair under the same
340
392
  // jobId — race-free under SQLite (single-writer); cluster-storage
341
393
  // dispatches both calls to the same backend.
342
- var rowRes = await store.execute(
343
- "SELECT _id, queueName, payload, repeatCron, repeatTimezone, " +
344
- " flowId, flowChildName, priority, classification, traceId " +
345
- "FROM " + qTable + " WHERE _id = ?",
346
- [jobId]
347
- );
394
+ var rowBuilt = _select()
395
+ .columns(["_id", "queueName", "payload", "repeatCron", "repeatTimezone",
396
+ "flowId", "flowChildName", "priority", "classification", "traceId"])
397
+ .where("_id", jobId)
398
+ .toSql();
399
+ var rowRes = await store.execute(rowBuilt.sql, rowBuilt.params);
348
400
  var row = (rowRes && rowRes.rows && rowRes.rows[0]) || null;
349
401
 
350
- await store.execute(
351
- "UPDATE " + qTable + " SET status = 'done', finishedAt = ?, leaseExpiresAt = NULL " +
352
- "WHERE _id = ? AND status = 'inflight'",
353
- [nowMs, jobId]
354
- );
402
+ var doneBuilt = _update()
403
+ .set("status", "done")
404
+ .set("finishedAt", nowMs)
405
+ .set("leaseExpiresAt", null)
406
+ .where("_id", jobId)
407
+ .where("status", "inflight")
408
+ .toSql();
409
+ await store.execute(doneBuilt.sql, doneBuilt.params);
355
410
 
356
411
  // Repeat-in-queue: cron-recurring job re-enqueues itself for the
357
412
  // next firing time. Failures (which take the fail() path) don't
@@ -388,11 +443,13 @@ function create(config) {
388
443
  }
389
444
 
390
445
  async function _maybeReleaseFlowChildren(flowId, completedJobId, completedChildName, nowMs) {
391
- var siblingsRes = await store.execute(
392
- "SELECT _id, dependsOn, flowChildName, status, availableAt FROM " + qTable + " " +
393
- "WHERE flowId = ? AND status = 'pending' AND availableAt > ?",
394
- [flowId, nowMs]
395
- );
446
+ var siblingsBuilt = _select()
447
+ .columns(["_id", "dependsOn", "flowChildName", "status", "availableAt"])
448
+ .where("flowId", flowId)
449
+ .where("status", "pending")
450
+ .whereOp("availableAt", ">", nowMs)
451
+ .toSql();
452
+ var siblingsRes = await store.execute(siblingsBuilt.sql, siblingsBuilt.params);
396
453
  var siblings = (siblingsRes && siblingsRes.rows) || [];
397
454
  for (var i = 0; i < siblings.length; i++) {
398
455
  var sib = siblings[i];
@@ -408,19 +465,25 @@ function create(config) {
408
465
  var dep = deps[d];
409
466
  // Quick path: just-completed job matches by id or child name.
410
467
  if (dep === completedJobId || (completedChildName && dep === completedChildName)) continue;
411
- // Otherwise SELECT to confirm done.
412
- var depRes = await store.execute(
413
- "SELECT 1 FROM " + qTable + " WHERE flowId = ? AND status = 'done' AND " +
414
- " (_id = ? OR flowChildName = ?) LIMIT 1",
415
- [flowId, dep, dep]
416
- );
468
+ // Otherwise SELECT to confirm done. The (_id = ? OR flowChildName = ?)
469
+ // disjunction is a whereGroup so it AND-composes at one precedence
470
+ // level with the flowId + status equalities.
471
+ var depBuilt = _select()
472
+ .columns(["_id"])
473
+ .where("flowId", flowId)
474
+ .where("status", "done")
475
+ .whereGroup(function (g) { g.where("_id", dep).orWhere("flowChildName", dep); })
476
+ .limit(1)
477
+ .toSql();
478
+ var depRes = await store.execute(depBuilt.sql, depBuilt.params);
417
479
  if (!depRes || !depRes.rows || depRes.rows.length === 0) { allDone = false; break; }
418
480
  }
419
481
  if (allDone) {
420
- await store.execute(
421
- "UPDATE " + qTable + " SET availableAt = ? WHERE _id = ?",
422
- [nowMs, sib._id]
423
- );
482
+ var releaseBuilt = _update()
483
+ .set("availableAt", nowMs)
484
+ .where("_id", sib._id)
485
+ .toSql();
486
+ await store.execute(releaseBuilt.sql, releaseBuilt.params);
424
487
  }
425
488
  }
426
489
  }
@@ -436,36 +499,46 @@ function create(config) {
436
499
  // row's current attempts/maxAttempts. CASE expressions split the
437
500
  // status / availableAt / finishedAt updates per branch — same
438
501
  // semantics as the previous SELECT-then-UPDATE-in-transaction
439
- // path, but no cross-dialect transaction primitive needed.
440
- await store.execute(
441
- "UPDATE " + qTable + " SET " +
442
- " status = CASE WHEN attempts < maxAttempts THEN 'pending' ELSE 'failed' END, " +
443
- " lastError = ?, " +
444
- " leaseExpiresAt = NULL, " +
445
- " availableAt = CASE WHEN attempts < maxAttempts THEN ? ELSE availableAt END, " +
446
- " finishedAt = CASE WHEN attempts < maxAttempts THEN NULL ELSE ? END " +
447
- "WHERE _id = ?",
448
- [sealedErr, nowMs + retryDelayMs, nowMs, jobId]
449
- );
502
+ // path, but no cross-dialect transaction primitive needed. Each CASE
503
+ // is a b.sql setRaw value-expression (guarded by b.guardSql) over the
504
+ // row's own columns; the branch values bind as `?` placeholders (the
505
+ // prior 'pending'/'failed' SQL literals now bind, which keeps the raw
506
+ // fragment literal-free).
507
+ var attemptsLt = _qc("attempts") + " < " + _qc("maxAttempts");
508
+ var failBuilt = _update()
509
+ .setRaw("status", "CASE WHEN " + attemptsLt + " THEN ? ELSE ? END", ["pending", "failed"])
510
+ .set("lastError", sealedErr)
511
+ .set("leaseExpiresAt", null)
512
+ .setRaw("availableAt", "CASE WHEN " + attemptsLt + " THEN ? ELSE " + _qc("availableAt") + " END",
513
+ [nowMs + retryDelayMs])
514
+ .setRaw("finishedAt", "CASE WHEN " + attemptsLt + " THEN NULL ELSE ? END", [nowMs])
515
+ .where("_id", jobId)
516
+ .toSql();
517
+ await store.execute(failBuilt.sql, failBuilt.params);
450
518
  return true;
451
519
  }
452
520
 
453
521
  async function sweepExpired() {
454
522
  cluster.requireLeader();
455
- var result = await store.execute(
456
- "UPDATE " + qTable + " SET status = 'pending', leaseExpiresAt = NULL " +
457
- "WHERE status = 'inflight' AND leaseExpiresAt < ?",
458
- [Date.now()]
459
- );
523
+ var built = _update()
524
+ .set("status", "pending")
525
+ .set("leaseExpiresAt", null)
526
+ .where("status", "inflight")
527
+ .whereOp("leaseExpiresAt", "<", Date.now())
528
+ .toSql();
529
+ var result = await store.execute(built.sql, built.params);
460
530
  return result.rowCount || 0;
461
531
  }
462
532
 
463
533
  async function size(queueName) {
464
- var row = await store.executeOne(
465
- "SELECT COUNT(*) AS n FROM " + qTable + " " +
466
- "WHERE queueName = ? AND (status = 'pending' OR status = 'inflight')",
467
- [queueName]
468
- );
534
+ // (status = 'pending' OR status = 'inflight') is an IN-list over the two
535
+ // active states b.sql expands it to (?, ?) bound placeholders.
536
+ var built = _select()
537
+ .count("*", "n")
538
+ .where("queueName", queueName)
539
+ .whereIn("status", ["pending", "inflight"])
540
+ .toSql();
541
+ var row = await store.executeOne(built.sql, built.params);
469
542
  return row ? Number(row.n) : 0;
470
543
  }
471
544
 
@@ -487,14 +560,15 @@ function create(config) {
487
560
  }
488
561
  limit = opts.limit;
489
562
  }
490
- var rows = await store.executeAll(
491
- "SELECT _id, queueName, payload, status, enqueuedAt, finishedAt, " +
492
- " attempts, maxAttempts, lastError, traceId, classification " +
493
- "FROM " + qTable + " " +
494
- "WHERE queueName = ? AND status = 'failed' " +
495
- "ORDER BY finishedAt DESC LIMIT ?",
496
- [queueName, limit]
497
- );
563
+ var built = _select()
564
+ .columns(["_id", "queueName", "payload", "status", "enqueuedAt", "finishedAt",
565
+ "attempts", "maxAttempts", "lastError", "traceId", "classification"])
566
+ .where("queueName", queueName)
567
+ .where("status", "failed")
568
+ .orderBy("finishedAt", "desc")
569
+ .limit(limit)
570
+ .toSql();
571
+ var rows = await store.executeAll(built.sql, built.params);
498
572
  return rows.map(function (row) {
499
573
  var unsealed = cryptoField.unsealRow(SEAL_TABLE, row);
500
574
  return {
@@ -516,36 +590,39 @@ function create(config) {
516
590
  async function dlqRetry(jobId) {
517
591
  cluster.requireLeader();
518
592
  var nowMs = Date.now();
519
- var result = await store.execute(
520
- "UPDATE " + qTable + " SET " +
521
- " status = 'pending', " +
522
- " attempts = 0, " +
523
- " availableAt = ?, " +
524
- " finishedAt = NULL, " +
525
- " leasedAt = NULL, " +
526
- " leaseExpiresAt = NULL, " +
527
- " lastError = NULL " +
528
- "WHERE _id = ? AND status = 'failed'",
529
- [nowMs, jobId]
530
- );
593
+ // NULL resets bind as null params (the prior SQL-literal NULLs); the
594
+ // string-literal statuses bind too.
595
+ var built = _update()
596
+ .set({
597
+ status: "pending",
598
+ attempts: 0,
599
+ availableAt: nowMs,
600
+ finishedAt: null,
601
+ leasedAt: null,
602
+ leaseExpiresAt: null,
603
+ lastError: null,
604
+ })
605
+ .where("_id", jobId)
606
+ .where("status", "failed")
607
+ .toSql();
608
+ var result = await store.execute(built.sql, built.params);
531
609
  return (result.rowCount || 0) > 0;
532
610
  }
533
611
 
534
612
  async function dlqSize(queueName) {
535
- var row = await store.executeOne(
536
- "SELECT COUNT(*) AS n FROM " + qTable + " " +
537
- "WHERE queueName = ? AND status = 'failed'",
538
- [queueName]
539
- );
613
+ var built = _select()
614
+ .count("*", "n")
615
+ .where("queueName", queueName)
616
+ .where("status", "failed")
617
+ .toSql();
618
+ var row = await store.executeOne(built.sql, built.params);
540
619
  return row ? Number(row.n) : 0;
541
620
  }
542
621
 
543
622
  async function purge(queueName) {
544
623
  cluster.requireLeader();
545
- var result = await store.execute(
546
- "DELETE FROM " + qTable + " WHERE queueName = ?",
547
- [queueName]
548
- );
624
+ var built = _delete().where("queueName", queueName).toSql();
625
+ var result = await store.execute(built.sql, built.params);
549
626
  return result.rowCount || 0;
550
627
  }
551
628
 
@@ -559,10 +636,12 @@ function create(config) {
559
636
  // to JSON for the dependsOn column.
560
637
  async function patchFlowDeps(jobId, depIds) {
561
638
  cluster.requireLeader();
562
- var result = await store.execute(
563
- "UPDATE " + qTable + " SET dependsOn = ?, availableAt = ? WHERE _id = ?",
564
- [JSON.stringify(depIds), FLOW_BLOCKED_AVAILABLE_AT, jobId]
565
- );
639
+ var built = _update()
640
+ .set("dependsOn", JSON.stringify(depIds))
641
+ .set("availableAt", FLOW_BLOCKED_AVAILABLE_AT)
642
+ .where("_id", jobId)
643
+ .toSql();
644
+ var result = await store.execute(built.sql, built.params);
566
645
  return (result.rowCount || 0) > 0;
567
646
  }
568
647
 
@@ -583,4 +662,10 @@ function create(config) {
583
662
  };
584
663
  }
585
664
 
586
- module.exports = { create: create };
665
+ module.exports = {
666
+ create: create,
667
+ // Idempotent, reset-safe self-registration of the _blamejs_jobs sealed-
668
+ // column declaration. queue.init calls this so seal-at-rest engages on a
669
+ // standalone queue node that never ran db.init.
670
+ _ensureSealTable: _ensureSealTable,
671
+ };
@@ -310,7 +310,10 @@ function create(opts) {
310
310
  // contract queue-local returns from _shapeLeasedRow.
311
311
  function _shapeLeasedRow(jobId, raw) {
312
312
  if (!raw) return null;
313
- // Pretend it's a "_blamejs_jobs" row so cryptoField unseals correctly.
313
+ // The cryptoField seal-table registry KEY (matches db.js's registerTable
314
+ // literal), not a SQL table name; this adapter holds no SQL (Redis
315
+ // ZSET/HASH ops). Keep it byte-identical so payload + lastError unseal.
316
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not SQL.
314
317
  var unsealed = cryptoField.unsealRow("_blamejs_jobs", raw);
315
318
  return {
316
319
  jobId: jobId,
@@ -368,6 +371,9 @@ function create(opts) {
368
371
  dependsOn: Array.isArray(opts2.dependsOn) && opts2.dependsOn.length > 0
369
372
  ? JSON.stringify(opts2.dependsOn) : null,
370
373
  };
374
+ // cryptoField seal-table registry KEY (db.js registers payload + lastError
375
+ // under this literal), not a SQL table; this Redis adapter holds no SQL.
376
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not SQL.
371
377
  var sealed = cryptoField.sealRow("_blamejs_jobs", row);
372
378
 
373
379
  // Pipeline: HSET job + ZADD ready + SADD queues + (if flowId)
@@ -466,6 +472,7 @@ function create(opts) {
466
472
 
467
473
  if (raw.repeatCron) {
468
474
  try {
475
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not SQL.
469
476
  var unsealed = cryptoField.unsealRow("_blamejs_jobs", raw);
470
477
  var cron = scheduler.parseCron(unsealed.repeatCron);
471
478
  var nextMs = scheduler.nextCronFire(
@@ -689,6 +696,7 @@ function create(opts) {
689
696
  for (var i = 0; i < idStrs.length; i++) {
690
697
  var raw = _decodeHash(hashes[i]);
691
698
  if (!raw) continue;
699
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not SQL.
692
700
  var unsealed = cryptoField.unsealRow("_blamejs_jobs", raw);
693
701
  out.push({
694
702
  jobId: idStrs[i],
@@ -175,6 +175,11 @@ function create(opts) {
175
175
  enqueueOpts = enqueueOpts || {};
176
176
  var queueUrl = queueUrlResolver(queueName);
177
177
  var jobId = generateToken(C.BYTES.bytes(16));
178
+ // The cryptoField seal-table registry KEY (matches db.js's registerTable
179
+ // literal), not a SQL table name; this SQS adapter holds no SQL
180
+ // (AWSJsonProtocol over HTTPS). Keep it byte-identical so the sealed
181
+ // message body unseals under the same schema on receive.
182
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not SQL.
178
183
  var sealed = cryptoField.sealRow("_blamejs_jobs", {
179
184
  _id: jobId,
180
185
  queueName: queueName,
@@ -222,6 +227,7 @@ function create(opts) {
222
227
  var sealed;
223
228
  try { sealed = safeJson.parse(m.Body); }
224
229
  catch (_e) { continue; }
230
+ // allow:hand-rolled-sql — cryptoField seal-table registry KEY, not SQL.
225
231
  var unsealed = cryptoField.unsealRow("_blamejs_jobs", sealed);
226
232
  var payload;
227
233
  try {
@@ -152,6 +152,13 @@ function init(opts) {
152
152
  throw _err("INVALID_CONFIG", "queue.init({ backends }) is required", true);
153
153
  }
154
154
 
155
+ // Self-register the _blamejs_jobs sealed-column declaration so payload +
156
+ // lastError seal at rest even when this process never ran db.init (a
157
+ // standalone redis/sqs queue node). cryptoField.sealRow silently passes
158
+ // through for an unregistered table, so without this a queue node would
159
+ // write job payloads to Redis/SQS in cleartext. Idempotent + reset-safe.
160
+ localProto._ensureSealTable();
161
+
155
162
  backends = {};
156
163
  // IIFE per-iteration so each backend's wrappers close over its own
157
164
  // raw / breaker / cfg. With `var` (function-scoped) those bindings