@blamejs/blamejs-shop 0.4.31 → 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 (336) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +392 -278
  4. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  5. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  6. package/lib/vendor/blamejs/.gitignore +6 -0
  7. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  8. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  9. package/lib/vendor/blamejs/README.md +8 -6
  10. package/lib/vendor/blamejs/SECURITY.md +19 -3
  11. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  12. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  13. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  14. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  15. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  16. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  17. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  18. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  19. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  20. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  21. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  22. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  23. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  24. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  25. package/lib/vendor/blamejs/index.js +4 -0
  26. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  27. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  28. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  29. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  30. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  31. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  32. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  33. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  34. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  35. package/lib/vendor/blamejs/lib/audit.js +259 -123
  36. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
  37. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  38. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  39. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
  40. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  41. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  42. package/lib/vendor/blamejs/lib/cache.js +174 -105
  43. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  44. package/lib/vendor/blamejs/lib/cli.js +19 -14
  45. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  46. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  47. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  48. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  49. package/lib/vendor/blamejs/lib/compliance.js +206 -4
  50. package/lib/vendor/blamejs/lib/consent.js +82 -29
  51. package/lib/vendor/blamejs/lib/constants.js +27 -11
  52. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  53. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  54. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  55. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  56. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  57. package/lib/vendor/blamejs/lib/db.js +249 -99
  58. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  59. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  60. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  61. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  62. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  63. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  64. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  65. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  66. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  67. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  68. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  69. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  70. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  71. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  72. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  73. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  74. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  75. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  76. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  77. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  78. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  79. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  80. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  81. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  82. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  83. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  84. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  85. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  86. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  87. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  88. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  89. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  90. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  91. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  92. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  93. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  94. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  95. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  96. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  97. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  98. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  99. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  100. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  101. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  102. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  103. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  104. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  106. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  107. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  108. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  109. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  110. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  111. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  112. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  113. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  114. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  115. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  116. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  117. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  118. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  119. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  120. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  121. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  122. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  123. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  124. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  125. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  126. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  128. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  129. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  131. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  132. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  133. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  134. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  135. package/lib/vendor/blamejs/lib/mail.js +8 -4
  136. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  137. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  138. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  139. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  140. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  141. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  142. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  143. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  144. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  145. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  146. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  147. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  148. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  149. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  150. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  151. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  152. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  153. package/lib/vendor/blamejs/lib/observability.js +124 -0
  154. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  155. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  156. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  157. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  158. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  159. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  160. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  161. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  162. package/lib/vendor/blamejs/lib/queue.js +7 -0
  163. package/lib/vendor/blamejs/lib/redact.js +68 -11
  164. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  165. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  166. package/lib/vendor/blamejs/lib/retention.js +101 -40
  167. package/lib/vendor/blamejs/lib/router.js +212 -5
  168. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  169. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  170. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  171. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  172. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  173. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  174. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  175. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  176. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  177. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  178. package/lib/vendor/blamejs/lib/session.js +175 -77
  179. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  180. package/lib/vendor/blamejs/lib/sse.js +26 -0
  181. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  182. package/lib/vendor/blamejs/lib/static.js +177 -34
  183. package/lib/vendor/blamejs/lib/subject.js +96 -49
  184. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  185. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  186. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  187. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  188. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  189. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  190. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  191. package/lib/vendor/blamejs/package.json +2 -2
  192. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  193. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  194. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  200. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  201. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  202. package/lib/vendor/blamejs/scripts/release.js +398 -38
  203. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  204. package/lib/vendor/blamejs/test/10-state.js +140 -14
  205. package/lib/vendor/blamejs/test/20-db.js +65 -2
  206. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  207. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  208. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  209. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  210. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  211. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  212. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  213. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  214. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  215. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  220. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  221. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  222. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  223. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  224. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  225. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  226. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  227. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  228. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  229. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  230. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  231. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  232. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  233. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  234. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  235. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  236. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  237. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  238. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  240. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  248. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  249. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  250. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  251. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  256. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  258. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  270. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  271. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  272. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  273. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  277. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  278. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  291. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  302. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  308. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  310. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  311. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  312. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  313. package/lib/vendor/blamejs/test/smoke.js +79 -21
  314. package/package.json +1 -1
  315. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  316. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  317. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  318. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  319. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  320. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  321. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  322. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  323. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  324. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  325. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  326. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  327. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  328. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  329. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  330. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  331. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  332. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  334. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  335. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  336. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -63,8 +63,20 @@ var bCrypto = require("./crypto");
63
63
  var lazyRequire = require("./lazy-require");
64
64
  var safeJson = require("./safe-json");
65
65
  var validateOpts = require("./validate-opts");
66
+ var sql = require("./sql");
67
+ var cryptoField = require("./crypto-field");
66
68
  var { defineClass } = require("./framework-error");
67
69
 
70
+ // Local-SQLite framework table names. These run against the b.db() handle
71
+ // directly (single-node legal-hold registry + the audit_log read), so the
72
+ // b.sql builders carry { quoteName: true } to emit the quoted local name
73
+ // (no clusterStorage prefix rewrite on this path) and bind every value as a
74
+ // placeholder. The names are passed as literals here for the same reason
75
+ // db.js declares them as literals — they ARE the canonical local table
76
+ // identifiers.
77
+ var HOLD_TABLE = "_blamejs_legal_hold"; // allow:hand-rolled-sql — canonical local table-name; passed to b.sql with quoteName
78
+ var AUDIT_TABLE = "audit_log";
79
+
68
80
  var audit = lazyRequire(function () { return require("./audit"); });
69
81
 
70
82
  var LegalHoldError = defineClass("LegalHoldError", { alwaysPermanent: true });
@@ -99,6 +111,24 @@ function _hashSubject(subjectId) {
99
111
  return bCrypto.sha3Hash("bj-legal-hold:" + subjectId);
100
112
  }
101
113
 
114
+ // Resolve the b.sql dialect for the operator-supplied handle. The framework's
115
+ // local b.db handle is always node:sqlite (db.js pins { dialect: "sqlite",
116
+ // quoteName: true }) and exposes no .dialect, so this defaults to "sqlite" —
117
+ // the registry + the audit_log read both run against that local handle via
118
+ // .prepare(). An operator handle that DOES advertise a dialect (string or
119
+ // () -> string) has it threaded through so the emitted identifier quoting +
120
+ // idioms match the backend the handle dispatches to. quoteName stays on for
121
+ // every legal-hold statement: these are canonical local table names quoted by
122
+ // construction (no clusterStorage prefix rewrite on this path).
123
+ function _handleDialect(db) {
124
+ if (db && typeof db.dialect === "function") {
125
+ try { var d = db.dialect(); return typeof d === "string" ? d : "sqlite"; }
126
+ catch (_e) { return "sqlite"; }
127
+ }
128
+ if (db && typeof db.dialect === "string") return db.dialect;
129
+ return "sqlite";
130
+ }
131
+
102
132
  function create(opts) {
103
133
  opts = opts || {};
104
134
  validateOpts(opts, ["db", "audit", "signWith"], "legalHold");
@@ -106,6 +136,11 @@ function create(opts) {
106
136
  throw _err("BAD_OPT", "create: opts.db is required (a b.db handle)");
107
137
  }
108
138
  var db = opts.db;
139
+ // b.sql opts for every legal-hold statement built against this handle. The
140
+ // dialect tracks the handle (sqlite for the framework's local b.db); the
141
+ // local table names are quoted by construction (quoteName) with no
142
+ // clusterStorage prefix rewrite on this path.
143
+ var SQL_OPTS = { dialect: _handleDialect(db), quoteName: true };
109
144
  var auditOn = opts.audit !== false && opts.audit != null;
110
145
  var auditInstance = (opts.audit && opts.audit !== true) ? opts.audit : null;
111
146
  // signWith is reserved for future per-event detached signatures;
@@ -135,19 +170,31 @@ function create(opts) {
135
170
  // table via FRAMEWORK_SCHEMA at boot; this guard is for the
136
171
  // external-db / cluster path where schema migrations are operator-
137
172
  // driven. Either way the IF NOT EXISTS shape is safe to re-run.
173
+ // DDL built through b.sql.createTable so every identifier is quoted by
174
+ // construction (quoteName) and the type tokens come from the framework
175
+ // type map.
138
176
  var fn = db.runSql || db.execRaw;
139
177
  if (typeof fn === "function") {
140
- fn(
141
- 'CREATE TABLE IF NOT EXISTS "_blamejs_legal_hold" (' +
142
- '"subjectIdHash" TEXT PRIMARY KEY,' +
143
- '"placedAt" INTEGER NOT NULL,' +
144
- '"placedBy" TEXT,' +
145
- '"reason" TEXT NOT NULL,' +
146
- '"custodian" TEXT,' +
147
- '"citation" TEXT,' +
148
- '"retainUntil" INTEGER' +
149
- ')'
150
- );
178
+ var ddl = sql.createTable(HOLD_TABLE, [
179
+ { name: "subjectIdHash", type: "text", primaryKey: true },
180
+ { name: "placedAt", type: "int", notNull: true },
181
+ { name: "placedBy", type: "text" },
182
+ { name: "reason", type: "text", notNull: true },
183
+ { name: "custodian", type: "text" },
184
+ { name: "citation", type: "text" },
185
+ { name: "retainUntil", type: "int" },
186
+ ], SQL_OPTS);
187
+ fn(ddl.sql);
188
+ }
189
+ // Register the table's PII columns for at-rest sealing. The framework
190
+ // SQLite path also registers this via db.init() FRAMEWORK_SCHEMA, but the
191
+ // external-db / cluster path and a post-_resetForTest registry need this
192
+ // idempotent guard so sealRow/unsealRow below are never no-ops (which would
193
+ // store the legal-basis / custodian / citation free text in clear).
194
+ if (!cryptoField.getSchema(HOLD_TABLE)) {
195
+ cryptoField.registerTable(HOLD_TABLE, {
196
+ sealedFields: ["reason", "placedBy", "custodian", "citation"],
197
+ });
151
198
  }
152
199
  }
153
200
 
@@ -171,9 +218,12 @@ function create(opts) {
171
218
  }
172
219
  _ensureSchema();
173
220
  var hash = _hashSubject(sid);
174
- var existing = db.prepare(
175
- 'SELECT placedAt FROM "_blamejs_legal_hold" WHERE subjectIdHash = ?'
176
- ).get(hash);
221
+ var placeSelBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
222
+ .columns(["placedAt"])
223
+ .where("subjectIdHash", hash)
224
+ .toSql();
225
+ var placeSelStmt = db.prepare(placeSelBuilt.sql);
226
+ var existing = placeSelStmt.get.apply(placeSelStmt, placeSelBuilt.params);
177
227
  if (existing) {
178
228
  _emit("legalhold.place_rejected",
179
229
  { subjectId: sid, reason: "already-held",
@@ -182,18 +232,19 @@ function create(opts) {
182
232
  return { error: "already-held", placedAt: existing.placedAt };
183
233
  }
184
234
  var nowMs = Date.now();
185
- db.prepare(
186
- 'INSERT INTO "_blamejs_legal_hold" ' +
187
- '(subjectIdHash, placedAt, placedBy, reason, custodian, citation, retainUntil) ' +
188
- 'VALUES (?, ?, ?, ?, ?, ?, ?)'
189
- ).run(
190
- hash, nowMs,
191
- args.placedBy || null,
192
- args.reason,
193
- args.custodian || null,
194
- args.citation || null,
195
- args.retainUntil || null
196
- );
235
+ var placeInsBuilt = sql.insert(HOLD_TABLE, SQL_OPTS)
236
+ .values(cryptoField.sealRow(HOLD_TABLE, {
237
+ subjectIdHash: hash,
238
+ placedAt: nowMs,
239
+ placedBy: args.placedBy || null,
240
+ reason: args.reason,
241
+ custodian: args.custodian || null,
242
+ citation: args.citation || null,
243
+ retainUntil: args.retainUntil || null,
244
+ }))
245
+ .toSql();
246
+ var placeInsStmt = db.prepare(placeInsBuilt.sql);
247
+ placeInsStmt.run.apply(placeInsStmt, placeInsBuilt.params);
197
248
  _emit("legalhold.placed",
198
249
  { subjectId: sid, reason: args.reason,
199
250
  custodian: args.custodian || null,
@@ -216,18 +267,24 @@ function create(opts) {
216
267
  }
217
268
  _ensureSchema();
218
269
  var hash = _hashSubject(sid);
219
- var existing = db.prepare(
220
- 'SELECT placedAt, reason FROM "_blamejs_legal_hold" WHERE subjectIdHash = ?'
221
- ).get(hash);
270
+ var relSelBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
271
+ .columns(["placedAt", "reason"])
272
+ .where("subjectIdHash", hash)
273
+ .toSql();
274
+ var relSelStmt = db.prepare(relSelBuilt.sql);
275
+ var existing = relSelStmt.get.apply(relSelStmt, relSelBuilt.params);
222
276
  if (!existing) {
223
277
  _emit("legalhold.release_rejected",
224
278
  { subjectId: sid, reason: "not-held" },
225
279
  "denied");
226
280
  return { error: "not-held" };
227
281
  }
228
- db.prepare(
229
- 'DELETE FROM "_blamejs_legal_hold" WHERE subjectIdHash = ?'
230
- ).run(hash);
282
+ existing = cryptoField.unsealRow(HOLD_TABLE, existing);
283
+ var relDelBuilt = sql.delete(HOLD_TABLE, SQL_OPTS)
284
+ .where("subjectIdHash", hash)
285
+ .toSql();
286
+ var relDelStmt = db.prepare(relDelBuilt.sql);
287
+ relDelStmt.run.apply(relDelStmt, relDelBuilt.params);
231
288
  _emit("legalhold.released",
232
289
  { subjectId: sid, reason: args.reason,
233
290
  approver: args.approver,
@@ -241,9 +298,12 @@ function create(opts) {
241
298
  var sid = _subjectIdString(subjectId);
242
299
  _ensureSchema();
243
300
  var hash = _hashSubject(sid);
244
- var row = db.prepare(
245
- 'SELECT retainUntil FROM "_blamejs_legal_hold" WHERE subjectIdHash = ?'
246
- ).get(hash);
301
+ var heldBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
302
+ .columns(["retainUntil"])
303
+ .where("subjectIdHash", hash)
304
+ .toSql();
305
+ var heldStmt = db.prepare(heldBuilt.sql);
306
+ var row = heldStmt.get.apply(heldStmt, heldBuilt.params);
247
307
  if (!row) return false;
248
308
  // retainUntil expiry — when the operator pinned a sunset and it
249
309
  // has passed, the hold has lapsed and isHeld returns false. The
@@ -257,11 +317,14 @@ function create(opts) {
257
317
  var sid = _subjectIdString(subjectId);
258
318
  _ensureSchema();
259
319
  var hash = _hashSubject(sid);
260
- var row = db.prepare(
261
- 'SELECT subjectIdHash, placedAt, placedBy, reason, custodian, citation, retainUntil ' +
262
- 'FROM "_blamejs_legal_hold" WHERE subjectIdHash = ?'
263
- ).get(hash);
320
+ var getBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
321
+ .columns(["subjectIdHash", "placedAt", "placedBy", "reason", "custodian", "citation", "retainUntil"])
322
+ .where("subjectIdHash", hash)
323
+ .toSql();
324
+ var getStmt = db.prepare(getBuilt.sql);
325
+ var row = getStmt.get.apply(getStmt, getBuilt.params);
264
326
  if (!row) return null;
327
+ row = cryptoField.unsealRow(HOLD_TABLE, row);
265
328
  return {
266
329
  subjectId: sid,
267
330
  placedAt: row.placedAt,
@@ -276,12 +339,15 @@ function create(opts) {
276
339
 
277
340
  function list() {
278
341
  _ensureSchema();
279
- var rows = db.prepare(
280
- 'SELECT subjectIdHash, placedAt, placedBy, reason, custodian, citation, retainUntil ' +
281
- 'FROM "_blamejs_legal_hold" ORDER BY placedAt'
282
- ).all();
342
+ var listBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
343
+ .columns(["subjectIdHash", "placedAt", "placedBy", "reason", "custodian", "citation", "retainUntil"])
344
+ .orderBy("placedAt", "asc")
345
+ .toSql();
346
+ var listStmt = db.prepare(listBuilt.sql);
347
+ var rows = listStmt.all.apply(listStmt, listBuilt.params);
283
348
  var nowMs = Date.now();
284
349
  return rows.map(function (r) {
350
+ r = cryptoField.unsealRow(HOLD_TABLE, r);
285
351
  return {
286
352
  subjectIdHash: r.subjectIdHash,
287
353
  placedAt: r.placedAt,
@@ -302,15 +368,20 @@ function create(opts) {
302
368
  var sid = _subjectIdString(subjectId);
303
369
  var rows = [];
304
370
  try {
305
- var auditQuery = db.prepare(
306
- 'SELECT recordedAt, action, metadata, outcome ' +
307
- 'FROM audit_log ' +
308
- 'WHERE action LIKE ? AND resourceKind = ? ' +
309
- 'ORDER BY recordedAt'
310
- );
371
+ // `action LIKE 'legalhold.%'` is a prefix match — b.sql's whereLike
372
+ // in prefix mode emits `"action" LIKE ? ESCAPE '~'` with the live
373
+ // trailing wildcard while escaping the term's own metacharacters
374
+ // (none here), so the wildcard stays builder-controlled.
375
+ var histBuilt = sql.select(AUDIT_TABLE, SQL_OPTS)
376
+ .columns(["recordedAt", "action", "metadata", "outcome"])
377
+ .whereLike("action", "legalhold.", "prefix")
378
+ .where("resourceKind", "legal-hold")
379
+ .orderBy("recordedAt", "asc")
380
+ .toSql();
381
+ var auditQuery = db.prepare(histBuilt.sql);
311
382
  // resourceId is sealed, so match on resourceKind + post-filter
312
383
  // by parsed metadata.
313
- var raw = auditQuery.all("legalhold.%", "legal-hold");
384
+ var raw = auditQuery.all.apply(auditQuery, histBuilt.params);
314
385
  for (var i = 0; i < raw.length; i++) {
315
386
  var meta = null;
316
387
  try { meta = safeJson.parse(raw[i].metadata || "{}"); } catch (_e) { meta = null; }
@@ -205,6 +205,10 @@ function create(config) {
205
205
  var inFlight = false;
206
206
  var closed = false;
207
207
  var sequenceToken = null;
208
+ // Captures the in-flight drain (the IIFE inside _flush) so close() can await
209
+ // the actual run before flipping `closed` — otherwise the _flush while-loop's
210
+ // `&& !closed` bails and buffered records are stranded at shutdown.
211
+ var inFlightPromise = null;
208
212
  var flushScheduler = safeAsync.makeScheduledFlush(cfg.maxBatchAgeMs, function () { return _flush(); });
209
213
 
210
214
  function _takeBatch() {
@@ -236,40 +240,44 @@ function create(config) {
236
240
  }
237
241
 
238
242
  async function _flush() {
239
- if (inFlight) return;
243
+ if (inFlight) return inFlightPromise;
240
244
  if (buffer.length === 0) return;
241
245
  inFlight = true;
242
- try {
243
- try { await _ensureAutoCreated(); }
244
- catch (acErr) {
245
- // autoCreate failure is permanent — every subsequent batch
246
- // would hit the same error. Drop the queue with the
247
- // operator-supplied onDrop callback so they see exactly which
248
- // events were lost AND why, then bail.
249
- var allBuffered = buffer.splice(0, buffer.length);
250
- dropCount += allBuffered.length;
251
- _emitDrop("autocreate-failed", allBuffered, acErr);
252
- return;
253
- }
254
- while (buffer.length > 0 && !closed) {
255
- var batch = _takeBatch();
256
- if (batch.length === 0) break;
257
- try {
258
- await retryHelper.withRetry(function () {
259
- return _send(batch);
260
- }, Object.assign({
261
- isPermanent: _isPermanentAwsError,
262
- }, cfg.retry || {}));
263
- } catch (e) {
264
- dropCount += batch.length;
265
- _emitDrop("retry-exhausted", batch, e);
266
- break;
246
+ inFlightPromise = (async function () {
247
+ try {
248
+ try { await _ensureAutoCreated(); }
249
+ catch (acErr) {
250
+ // autoCreate failure is permanent every subsequent batch
251
+ // would hit the same error. Drop the queue with the
252
+ // operator-supplied onDrop callback so they see exactly which
253
+ // events were lost AND why, then bail.
254
+ var allBuffered = buffer.splice(0, buffer.length);
255
+ dropCount += allBuffered.length;
256
+ _emitDrop("autocreate-failed", allBuffered, acErr);
257
+ return;
258
+ }
259
+ while (buffer.length > 0 && !closed) {
260
+ var batch = _takeBatch();
261
+ if (batch.length === 0) break;
262
+ try {
263
+ await retryHelper.withRetry(function () {
264
+ return _send(batch);
265
+ }, Object.assign({
266
+ isPermanent: _isPermanentAwsError,
267
+ }, cfg.retry || {}));
268
+ } catch (e) {
269
+ dropCount += batch.length;
270
+ _emitDrop("retry-exhausted", batch, e);
271
+ break;
272
+ }
267
273
  }
274
+ } finally {
275
+ inFlight = false;
276
+ inFlightPromise = null;
277
+ if (buffer.length > 0) flushScheduler.schedule();
268
278
  }
269
- } finally {
270
- inFlight = false;
271
- if (buffer.length > 0) flushScheduler.schedule();
272
- }
279
+ })();
280
+ return inFlightPromise;
273
281
  }
274
282
 
275
283
  async function _send(batch) {
@@ -333,9 +341,17 @@ function create(config) {
333
341
  }
334
342
 
335
343
  async function close() {
336
- closed = true;
344
+ // Drain BEFORE flipping closed=true — _flush()'s `while (... && !closed)`
345
+ // loop bails on !closed, so flipping the flag first strands the records the
346
+ // operator queued just before shutdown (the b.logStream drain contract).
347
+ // Stop the timer, await any in-flight drain, drain the remainder, THEN
348
+ // refuse new enqueues. Mirrors the webhook sink.
337
349
  flushScheduler.cancel();
350
+ if (inFlightPromise) {
351
+ try { await inFlightPromise; } catch (_e) { /* surfaced via onDrop */ }
352
+ }
338
353
  await _flush();
354
+ closed = true;
339
355
  }
340
356
 
341
357
  function stats() {
@@ -210,30 +210,38 @@ function create(config) {
210
210
  var dropCount = 0;
211
211
  var inFlight = false;
212
212
  var closed = false;
213
+ // Captures the in-flight drain so close() awaits the real run before flipping
214
+ // `closed` (the _flush while-loop bails on !closed → flipping first strands
215
+ // buffered records at shutdown).
216
+ var inFlightPromise = null;
213
217
  var flushScheduler = safeAsync.makeScheduledFlush(cfg.maxBatchAgeMs, function () { return _flush(); });
214
218
 
215
219
  async function _flush() {
216
- if (inFlight) return;
220
+ if (inFlight) return inFlightPromise;
217
221
  if (buffer.length === 0) return;
218
222
  inFlight = true;
219
- try {
220
- while (buffer.length > 0 && !closed) {
221
- var batch = buffer.splice(0, cfg.batchSize);
222
- var body = _serializeBatch(batch, cfg, scopeVersion);
223
- try {
224
- await retryHelper.withRetry(function () {
225
- return _post(resolvedUrl, body, headers, cfg.timeoutMs, cfg.allowedProtocols, cfg.allowInternal);
226
- }, cfg.retry);
227
- } catch (e) {
228
- dropCount += batch.length;
229
- _emitDrop("retry-exhausted", batch, e);
230
- break;
223
+ inFlightPromise = (async function () {
224
+ try {
225
+ while (buffer.length > 0 && !closed) {
226
+ var batch = buffer.splice(0, cfg.batchSize);
227
+ var body = _serializeBatch(batch, cfg, scopeVersion);
228
+ try {
229
+ await retryHelper.withRetry(function () {
230
+ return _post(resolvedUrl, body, headers, cfg.timeoutMs, cfg.allowedProtocols, cfg.allowInternal);
231
+ }, cfg.retry);
232
+ } catch (e) {
233
+ dropCount += batch.length;
234
+ _emitDrop("retry-exhausted", batch, e);
235
+ break;
236
+ }
231
237
  }
238
+ } finally {
239
+ inFlight = false;
240
+ inFlightPromise = null;
241
+ if (buffer.length > 0) flushScheduler.schedule();
232
242
  }
233
- } finally {
234
- inFlight = false;
235
- if (buffer.length > 0) flushScheduler.schedule();
236
- }
243
+ })();
244
+ return inFlightPromise;
237
245
  }
238
246
 
239
247
  function emit(record) {
@@ -253,9 +261,15 @@ function create(config) {
253
261
  }
254
262
 
255
263
  async function close() {
256
- closed = true;
264
+ // Drain BEFORE flipping closed=true (see _flush's `&& !closed` guard) so
265
+ // records queued just before shutdown reach the wire. Mirrors the webhook
266
+ // + cloudwatch sinks.
257
267
  flushScheduler.cancel();
268
+ if (inFlightPromise) {
269
+ try { await inFlightPromise; } catch (_e) { /* surfaced via onDrop */ }
270
+ }
258
271
  await _flush();
272
+ closed = true;
259
273
  }
260
274
 
261
275
  function stats() {