@blamejs/core 0.15.12 → 0.15.13

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 (298) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/index.js +2 -0
  3. package/lib/a2a-tasks.js +7 -23
  4. package/lib/acme.js +6 -5
  5. package/lib/agent-event-bus.js +5 -4
  6. package/lib/agent-idempotency.js +2 -5
  7. package/lib/agent-orchestrator.js +2 -5
  8. package/lib/agent-saga.js +3 -5
  9. package/lib/agent-tenant.js +2 -5
  10. package/lib/ai-adverse-decision.js +2 -15
  11. package/lib/ai-capability.js +1 -6
  12. package/lib/ai-dp.js +1 -5
  13. package/lib/ai-input.js +2 -2
  14. package/lib/ai-pref.js +3 -8
  15. package/lib/ai-quota.js +3 -14
  16. package/lib/api-key.js +37 -28
  17. package/lib/archive-adapters.js +2 -4
  18. package/lib/archive-entry-policy.js +32 -0
  19. package/lib/archive-read.js +5 -17
  20. package/lib/archive-tar-read.js +5 -16
  21. package/lib/archive.js +2 -10
  22. package/lib/arg-parser.js +7 -6
  23. package/lib/asyncapi-traits.js +2 -6
  24. package/lib/atomic-file.js +108 -31
  25. package/lib/audit-chain.js +133 -53
  26. package/lib/audit-daily-review.js +24 -14
  27. package/lib/audit-emit.js +82 -0
  28. package/lib/audit-sign.js +257 -0
  29. package/lib/audit.js +84 -0
  30. package/lib/auth/access-lock.js +5 -27
  31. package/lib/auth/dpop.js +23 -35
  32. package/lib/auth/fido-mds3.js +9 -15
  33. package/lib/auth/jwt-external.js +26 -8
  34. package/lib/auth/jwt.js +13 -15
  35. package/lib/auth/lockout.js +6 -25
  36. package/lib/auth/oauth.js +67 -45
  37. package/lib/auth/oid4vci.js +55 -32
  38. package/lib/auth/oid4vp.js +3 -2
  39. package/lib/auth/openid-federation.js +6 -6
  40. package/lib/auth/passkey.js +3 -3
  41. package/lib/auth/password.js +7 -1
  42. package/lib/auth/saml.js +37 -27
  43. package/lib/auth/sd-jwt-vc-holder.js +2 -14
  44. package/lib/auth/sd-jwt-vc-issuer.js +2 -14
  45. package/lib/auth/sd-jwt-vc.js +1 -1
  46. package/lib/auth/status-list.js +7 -7
  47. package/lib/auth/step-up.js +6 -12
  48. package/lib/auth-bot-challenge.js +6 -37
  49. package/lib/backup/bundle.js +11 -18
  50. package/lib/backup/index.js +14 -47
  51. package/lib/bounded-map.js +112 -1
  52. package/lib/breach-deadline.js +1 -11
  53. package/lib/cache.js +7 -18
  54. package/lib/cbor.js +2 -1
  55. package/lib/cdn-cache-control.js +8 -9
  56. package/lib/cert.js +3 -10
  57. package/lib/chain-writer.js +162 -47
  58. package/lib/cli.js +5 -1
  59. package/lib/client-hints.js +7 -9
  60. package/lib/cloud-events.js +40 -31
  61. package/lib/cluster-storage.js +2 -38
  62. package/lib/cms-codec.js +2 -1
  63. package/lib/codepoint-class.js +67 -1
  64. package/lib/compliance-ai-act-logging.js +1 -6
  65. package/lib/compliance-ai-act-transparency.js +2 -4
  66. package/lib/compliance-eaa.js +1 -11
  67. package/lib/compliance-sanctions-fetcher.js +21 -28
  68. package/lib/compliance-sanctions.js +2 -14
  69. package/lib/compliance.js +2 -9
  70. package/lib/config-drift.js +2 -12
  71. package/lib/content-digest.js +10 -8
  72. package/lib/cookies.js +5 -11
  73. package/lib/cose.js +19 -11
  74. package/lib/cra-report.js +1 -11
  75. package/lib/crypto-field.js +5 -10
  76. package/lib/crypto.js +120 -3
  77. package/lib/csp.js +235 -3
  78. package/lib/daemon.js +42 -41
  79. package/lib/data-act.js +19 -9
  80. package/lib/db-query.js +6 -40
  81. package/lib/db.js +34 -12
  82. package/lib/dbsc.js +5 -6
  83. package/lib/ddl-change-control.js +18 -14
  84. package/lib/deprecate.js +4 -5
  85. package/lib/did.js +6 -2
  86. package/lib/dsr.js +8 -12
  87. package/lib/external-db-migrate.js +21 -22
  88. package/lib/external-db.js +14 -26
  89. package/lib/fda-21cfr11.js +12 -8
  90. package/lib/fdx.js +22 -18
  91. package/lib/file-upload.js +80 -66
  92. package/lib/flag-evaluation-context.js +5 -8
  93. package/lib/framework-error.js +12 -0
  94. package/lib/framework-schema.js +19 -0
  95. package/lib/fsm.js +7 -12
  96. package/lib/gate-contract.js +869 -38
  97. package/lib/gdpr-ropa.js +4 -13
  98. package/lib/graphql-federation.js +1 -1
  99. package/lib/guard-agent-registry.js +2 -1
  100. package/lib/guard-all.js +1 -0
  101. package/lib/guard-archive.js +9 -30
  102. package/lib/guard-auth.js +23 -80
  103. package/lib/guard-cidr.js +20 -96
  104. package/lib/guard-csv.js +135 -196
  105. package/lib/guard-domain.js +23 -106
  106. package/lib/guard-dsn.js +16 -13
  107. package/lib/guard-email.js +46 -53
  108. package/lib/guard-envelope.js +1 -1
  109. package/lib/guard-event-bus-topic.js +2 -1
  110. package/lib/guard-filename.js +12 -60
  111. package/lib/guard-graphql.js +28 -75
  112. package/lib/guard-html-wcag.js +15 -2
  113. package/lib/guard-html.js +65 -117
  114. package/lib/guard-idempotency-key.js +2 -1
  115. package/lib/guard-image.js +280 -77
  116. package/lib/guard-imap-command.js +8 -9
  117. package/lib/guard-json.js +87 -103
  118. package/lib/guard-jsonpath.js +20 -88
  119. package/lib/guard-jwt.js +32 -114
  120. package/lib/guard-list-id.js +2 -7
  121. package/lib/guard-list-unsubscribe.js +2 -7
  122. package/lib/guard-mail-compose.js +5 -6
  123. package/lib/guard-mail-move.js +2 -1
  124. package/lib/guard-mail-query.js +5 -3
  125. package/lib/guard-mail-sieve.js +6 -7
  126. package/lib/guard-managesieve-command.js +5 -4
  127. package/lib/guard-markdown.js +76 -110
  128. package/lib/guard-message-id.js +5 -6
  129. package/lib/guard-mime.js +20 -99
  130. package/lib/guard-oauth.js +19 -73
  131. package/lib/guard-pdf.js +65 -72
  132. package/lib/guard-pop3-command.js +12 -13
  133. package/lib/guard-posture-chain.js +2 -1
  134. package/lib/guard-regex.js +24 -99
  135. package/lib/guard-saga-config.js +2 -1
  136. package/lib/guard-shell.js +22 -87
  137. package/lib/guard-smtp-command.js +8 -11
  138. package/lib/guard-sql.js +15 -13
  139. package/lib/guard-stream-args.js +2 -1
  140. package/lib/guard-svg.js +95 -140
  141. package/lib/guard-template.js +23 -80
  142. package/lib/guard-tenant-id.js +2 -1
  143. package/lib/guard-text.js +592 -0
  144. package/lib/guard-time.js +27 -95
  145. package/lib/guard-uuid.js +21 -93
  146. package/lib/guard-xml.js +76 -106
  147. package/lib/guard-yaml.js +24 -60
  148. package/lib/http-client-cache.js +5 -12
  149. package/lib/http-client-cookie-jar.js +2 -4
  150. package/lib/http-client.js +8 -21
  151. package/lib/http-message-signature.js +3 -2
  152. package/lib/i18n-messageformat.js +5 -7
  153. package/lib/i18n.js +83 -26
  154. package/lib/inbox.js +8 -8
  155. package/lib/incident-report.js +3 -21
  156. package/lib/ip-utils.js +49 -6
  157. package/lib/jobs.js +3 -2
  158. package/lib/keychain.js +6 -18
  159. package/lib/legal-hold.js +6 -15
  160. package/lib/log-stream-cloudwatch.js +44 -112
  161. package/lib/log-stream-otlp-grpc.js +17 -14
  162. package/lib/log-stream-otlp.js +16 -80
  163. package/lib/log-stream-webhook.js +20 -92
  164. package/lib/mail-arc-sign.js +8 -3
  165. package/lib/mail-arf.js +3 -2
  166. package/lib/mail-auth.js +40 -66
  167. package/lib/mail-bimi.js +19 -39
  168. package/lib/mail-crypto-pgp.js +3 -2
  169. package/lib/mail-dav.js +8 -35
  170. package/lib/mail-deploy.js +6 -9
  171. package/lib/mail-dkim.js +19 -38
  172. package/lib/mail-greylist.js +15 -26
  173. package/lib/mail-helo.js +2 -3
  174. package/lib/mail-journal.js +2 -1
  175. package/lib/mail-mdn.js +4 -3
  176. package/lib/mail-rbl.js +5 -8
  177. package/lib/mail-scan.js +2 -2
  178. package/lib/mail-send-deliver.js +33 -20
  179. package/lib/mail-server-imap.js +32 -87
  180. package/lib/mail-server-jmap.js +35 -51
  181. package/lib/mail-server-managesieve.js +29 -83
  182. package/lib/mail-server-mx.js +33 -74
  183. package/lib/mail-server-net.js +177 -0
  184. package/lib/mail-server-pop3.js +30 -83
  185. package/lib/mail-server-rate-limit.js +30 -6
  186. package/lib/mail-server-submission.js +34 -73
  187. package/lib/mail-server-tls.js +89 -0
  188. package/lib/mail-spam-score.js +7 -8
  189. package/lib/mail-store.js +3 -2
  190. package/lib/mail.js +6 -11
  191. package/lib/markup-escape.js +31 -0
  192. package/lib/markup-tokenizer.js +54 -0
  193. package/lib/mcp-tool-registry.js +26 -23
  194. package/lib/mcp.js +1 -1
  195. package/lib/mdoc.js +11 -12
  196. package/lib/metrics.js +32 -30
  197. package/lib/middleware/age-gate.js +3 -23
  198. package/lib/middleware/api-encrypt.js +11 -22
  199. package/lib/middleware/assetlinks.js +2 -7
  200. package/lib/middleware/bearer-auth.js +2 -1
  201. package/lib/middleware/body-parser.js +31 -48
  202. package/lib/middleware/bot-disclose.js +7 -10
  203. package/lib/middleware/bot-guard.js +2 -10
  204. package/lib/middleware/csrf-protect.js +13 -2
  205. package/lib/middleware/daily-byte-quota.js +6 -26
  206. package/lib/middleware/deny-response.js +19 -1
  207. package/lib/middleware/fetch-metadata.js +7 -0
  208. package/lib/middleware/idempotency-key.js +4 -20
  209. package/lib/middleware/rate-limit.js +20 -28
  210. package/lib/middleware/scim-server.js +3 -2
  211. package/lib/middleware/security-headers.js +9 -1
  212. package/lib/middleware/security-txt.js +2 -6
  213. package/lib/middleware/tus-upload.js +12 -27
  214. package/lib/middleware/web-app-manifest.js +2 -7
  215. package/lib/migrations.js +4 -13
  216. package/lib/mime-parse.js +34 -17
  217. package/lib/module-loader.js +44 -0
  218. package/lib/money.js +105 -0
  219. package/lib/mtls-ca.js +116 -36
  220. package/lib/network-byte-quota.js +4 -18
  221. package/lib/network-dane.js +8 -6
  222. package/lib/network-dns-resolver.js +97 -6
  223. package/lib/network-dnssec.js +16 -16
  224. package/lib/network-heartbeat.js +3 -2
  225. package/lib/network-smtp-policy.js +29 -41
  226. package/lib/network-tls.js +40 -42
  227. package/lib/nis2-report.js +1 -11
  228. package/lib/nonce-store.js +81 -3
  229. package/lib/numeric-bounds.js +22 -8
  230. package/lib/object-store/azure-blob-bucket-ops.js +2 -6
  231. package/lib/object-store/azure-blob.js +5 -45
  232. package/lib/object-store/gcs.js +8 -71
  233. package/lib/object-store/http-put.js +1 -5
  234. package/lib/object-store/http-request.js +128 -0
  235. package/lib/object-store/sigv4-bucket-ops.js +2 -1
  236. package/lib/object-store/sigv4.js +9 -77
  237. package/lib/observability-otlp-exporter.js +9 -25
  238. package/lib/observability.js +95 -0
  239. package/lib/openapi-paths-builder.js +7 -3
  240. package/lib/otel-export.js +7 -10
  241. package/lib/outbox.js +43 -37
  242. package/lib/pagination.js +11 -15
  243. package/lib/parsers/safe-env.js +5 -4
  244. package/lib/parsers/safe-ini.js +10 -4
  245. package/lib/parsers/safe-toml.js +11 -9
  246. package/lib/parsers/safe-xml.js +2 -2
  247. package/lib/parsers/safe-yaml.js +7 -6
  248. package/lib/pick.js +63 -5
  249. package/lib/pipl-cn.js +69 -59
  250. package/lib/privacy-pass.js +8 -6
  251. package/lib/problem-details.js +2 -5
  252. package/lib/pubsub.js +4 -8
  253. package/lib/redact.js +2 -1
  254. package/lib/render.js +4 -2
  255. package/lib/request-helpers.js +133 -6
  256. package/lib/restore.js +5 -22
  257. package/lib/retention.js +3 -5
  258. package/lib/safe-async.js +457 -0
  259. package/lib/safe-buffer.js +137 -6
  260. package/lib/safe-decompress.js +2 -1
  261. package/lib/safe-dns.js +2 -1
  262. package/lib/safe-ical.js +12 -26
  263. package/lib/safe-json.js +7 -8
  264. package/lib/safe-jsonpath.js +6 -5
  265. package/lib/safe-mime.js +25 -29
  266. package/lib/safe-redirect.js +2 -5
  267. package/lib/safe-schema.js +7 -6
  268. package/lib/safe-sql.js +126 -0
  269. package/lib/safe-vcard.js +12 -26
  270. package/lib/sandbox-worker.js +9 -2
  271. package/lib/sandbox.js +3 -2
  272. package/lib/scheduler.js +5 -12
  273. package/lib/sec-cyber.js +82 -37
  274. package/lib/seeders.js +4 -11
  275. package/lib/self-update.js +92 -69
  276. package/lib/session-device-binding.js +112 -66
  277. package/lib/session.js +194 -6
  278. package/lib/sql.js +225 -78
  279. package/lib/sse.js +6 -10
  280. package/lib/static.js +136 -98
  281. package/lib/storage.js +4 -2
  282. package/lib/structured-fields.js +275 -16
  283. package/lib/tenant-quota.js +2 -20
  284. package/lib/tsa.js +11 -15
  285. package/lib/validate-opts.js +154 -8
  286. package/lib/vault/seal-pem-file.js +30 -48
  287. package/lib/vault-aad.js +3 -2
  288. package/lib/vc.js +2 -7
  289. package/lib/vex.js +35 -13
  290. package/lib/web-push-vapid.js +23 -20
  291. package/lib/webhook-dispatcher.js +706 -0
  292. package/lib/webhook.js +43 -18
  293. package/lib/websocket-channels.js +9 -7
  294. package/lib/websocket.js +7 -3
  295. package/lib/worm.js +2 -3
  296. package/lib/ws-client.js +8 -10
  297. package/package.json +1 -1
  298. package/sbom.cdx.json +6 -6
package/lib/webhook.js CHANGED
@@ -59,6 +59,10 @@ var numericChecks = require("./numeric-checks");
59
59
  var requestHelpers = require("./request-helpers");
60
60
  var validateOpts = require("./validate-opts");
61
61
  var { WebhookError } = require("./framework-error");
62
+ // b.webhook.dispatcher — durable signed-webhook delivery store. Lives in its
63
+ // own module (distinct domain: persistence) and lazyRequires this file back,
64
+ // so this top-level require is cycle-safe.
65
+ var webhookDispatcher = require("./webhook-dispatcher");
62
66
 
63
67
  var observability = lazyRequire(function () { return require("./observability"); });
64
68
 
@@ -832,16 +836,28 @@ function _coerceBodyString(body) {
832
836
  * HMAC-SHA-256 over the literal `<t>.<rawBody>` string using the
833
837
  * operator's `whsec_...` secret bytes verbatim (the prefix IS the key).
834
838
  * Refuses signatures older than the tolerance window (default 5 min,
835
- * minimum 30 s). When `nonceStore` is supplied the verifier records
836
- * the accepted v1 signature so a replay within the tolerance window
837
- * is refused. Constant-time compare via `b.crypto.timingSafeEqual`.
839
+ * minimum 30 s). When `nonceStore` is supplied the verifier atomically
840
+ * records the accepted v1 signature so a replay within the tolerance window
841
+ * is refused; the store speaks the same `checkAndInsert(nonce, expireAt) →
842
+ * bool` contract as `b.webhook.verifier` and `b.nonceStore.create`, so the
843
+ * framework's own replay store plugs in directly and concurrent redeliveries
844
+ * cannot race. Constant-time compare via `b.crypto.timingSafeEqual`.
845
+ *
846
+ * @opts
847
+ * alg: "hmac-sha256-stripe",
848
+ * secret: string | Buffer, // whsec_... bytes verbatim
849
+ * header: string, // Stripe-Signature value
850
+ * body: string | Buffer, // raw request body
851
+ * toleranceMs: number, // default 5 min, min 30 s
852
+ * nonceStore: { checkAndInsert(nonce, expireAt) }, // optional atomic replay defense
838
853
  *
839
854
  * @example
840
- * b.webhook.verify({
841
- * alg: "hmac-sha256-stripe",
842
- * secret: "whsec_abc...",
843
- * header: req.headers["stripe-signature"],
844
- * body: rawBodyBuffer,
855
+ * await b.webhook.verify({
856
+ * alg: "hmac-sha256-stripe",
857
+ * secret: "whsec_abc...",
858
+ * header: req.headers["stripe-signature"],
859
+ * body: rawBodyBuffer,
860
+ * nonceStore: b.nonceStore.create({ backend: "memory" }),
845
861
  * });
846
862
  * // → { ok: true, timestamp: 1700000000, scheme: "v1" }
847
863
  */
@@ -889,24 +905,30 @@ async function verify(input) {
889
905
  "verify: no v1 signature matched HMAC-SHA-256 of <t>.<body>");
890
906
  }
891
907
 
892
- // Optional replay defense — the nonceStore is operator-supplied
893
- // (e.g. `b.kv` or a Redis-shaped { has, set, expire }) so the
894
- // primitive doesn't own retention. `has` / `set` MAY return a
895
- // Promise we always `await` them so async backends (Redis, KV,
896
- // DynamoDB) work without falsely flagging a Promise as truthy.
908
+ // Optional replay defense — the nonceStore speaks the SAME atomic
909
+ // `checkAndInsert(nonce, expireAt) bool` contract as b.webhook.verifier
910
+ // and b.nonceStore.create, so the framework's own replay store drops in
911
+ // with no adapter. The check + insert is one atomic step: a non-atomic
912
+ // check-then-set would race two concurrent redeliveries of the same event
913
+ // (both observe "unseen", both proceed) — the exact failure replay defense
914
+ // exists to prevent. checkAndInsert MAY return a Promise (Redis / KV /
915
+ // cluster SQL); we always await it. `expireAt` is the absolute epoch-ms at
916
+ // which the signature itself falls outside the tolerance window, so a stored
917
+ // nonce is retained exactly as long as a replay of it could still be fresh.
897
918
  if (input.nonceStore) {
898
919
  var ns = input.nonceStore;
899
- if (typeof ns.has !== "function" || typeof ns.set !== "function") {
920
+ if (typeof ns.checkAndInsert !== "function") {
900
921
  throw new WebhookError("webhook/bad-nonce-store",
901
- "verify: nonceStore must expose { has(key), set(key, ttlMs) }");
922
+ "verify: nonceStore must expose checkAndInsert(nonce, expireAt) — the " +
923
+ "b.nonceStore contract shared with b.webhook.verifier");
902
924
  }
903
925
  var nonceKey = "stripe:" + parsed.timestamp + ":" + expectedHex;
904
- var seen = await ns.has(nonceKey);
905
- if (seen) {
926
+ var expireAt = C.TIME.seconds(parsed.timestamp) + tolerance;
927
+ var fresh = await ns.checkAndInsert(nonceKey, expireAt);
928
+ if (!fresh) {
906
929
  throw new WebhookError("webhook/replay",
907
930
  "verify: signature already seen within tolerance window (replay)");
908
931
  }
909
- await ns.set(nonceKey, tolerance);
910
932
  }
911
933
 
912
934
  return { ok: true, timestamp: parsed.timestamp, scheme: "v1" };
@@ -974,4 +996,7 @@ module.exports = {
974
996
  // v0.11.25 — Stripe-shaped inbound HMAC-SHA-256 verifier + signer.
975
997
  verify: verify,
976
998
  sign: sign,
999
+ // Durable signed-webhook delivery store (sign + persist + deliver + retry +
1000
+ // dead-letter + operator replay). Defined in lib/webhook-dispatcher.js.
1001
+ dispatcher: webhookDispatcher.dispatcher,
977
1002
  };
@@ -60,6 +60,7 @@
60
60
 
61
61
  var lazyRequire = require("./lazy-require");
62
62
  var pubsub = require("./pubsub");
63
+ var boundedMap = require("./bounded-map");
63
64
  var validateOpts = require("./validate-opts");
64
65
  var { defineClass } = require("./framework-error");
65
66
 
@@ -187,17 +188,18 @@ function create(opts) {
187
188
  if (typeof channel !== "string" || channel.length === 0) {
188
189
  throw _err("INVALID_CHANNEL", "subscribe: channel must be a non-empty string");
189
190
  }
190
- if (!connToChannels.has(conn)) {
191
+ boundedMap.requirePresent(connToChannels, conn, function () {
191
192
  throw _err("NOT_ATTACHED", "subscribe: connection must be attach()-ed first");
192
- }
193
- if (!channelToConns.has(channel)) {
194
- channelToConns.set(channel, new Set());
193
+ });
194
+ var subs = boundedMap.getOrInsert(channelToConns, channel, function () {
195
195
  // First local listener for this channel — open a pubsub
196
- // subscription so cross-node fan-out reaches us.
196
+ // subscription so cross-node fan-out reaches us, recording the
197
+ // token under the same key the new Set is stored at.
197
198
  var token = ps.subscribe(channel, _onPubsubMessage);
198
199
  channelToToken.set(channel, token);
199
- }
200
- channelToConns.get(channel).add(conn);
200
+ return new Set();
201
+ });
202
+ subs.add(conn);
201
203
  connToChannels.get(conn).add(channel);
202
204
  }
203
205
 
package/lib/websocket.js CHANGED
@@ -82,6 +82,7 @@ var C = require("./constants");
82
82
  var requestHelpers = require("./request-helpers");
83
83
  var safeAsync = require("./safe-async");
84
84
  var safeBuffer = require("./safe-buffer");
85
+ var pick = require("./pick");
85
86
  var structuredFields = require("./structured-fields");
86
87
  var { FrameworkError } = require("./framework-error");
87
88
  var { boot } = require("./log");
@@ -543,7 +544,7 @@ function _parseExtensionHeader(header) {
543
544
  var kv = parts[j].split("=");
544
545
  var k = kv[0].trim().toLowerCase();
545
546
  if (!k) continue;
546
- if (k === "__proto__" || k === "constructor" || k === "prototype") continue;
547
+ if (pick.isPoisonedKey(k)) continue;
547
548
  var v = kv.length > 1 ? kv.slice(1).join("=").trim() : true;
548
549
  // Strip surrounding quotes per the token-or-quoted-string grammar.
549
550
  if (typeof v === "string") {
@@ -1128,7 +1129,7 @@ class WebSocketConnection extends EventEmitter {
1128
1129
  return this._abort(CLOSE_INVALID_PAYLOAD,
1129
1130
  "permessage-deflate inflate failed: " + ((e && e.message) || String(e)));
1130
1131
  }
1131
- if (data.length > this.maxMessageBytes) {
1132
+ if (safeBuffer.byteLengthOf(data) > this.maxMessageBytes) {
1132
1133
  return this._abort(CLOSE_MESSAGE_TOO_BIG,
1133
1134
  "decompressed message exceeds maxMessageBytes");
1134
1135
  }
@@ -1241,8 +1242,11 @@ class WebSocketConnection extends EventEmitter {
1241
1242
  } else if (Buffer.isBuffer(data)) {
1242
1243
  this._sendDataFrame(OPCODE_BINARY, data);
1243
1244
  } else {
1245
+ // WebSocketError's constructor is (code, message, closeCode) — code
1246
+ // first — so the (message, code) errorClass path would swap the two.
1247
+ // errorFactory hands toBuffer a (code, message) constructor instead.
1244
1248
  data = safeBuffer.toBuffer(data, {
1245
- errorClass: WebSocketError,
1249
+ errorFactory: function (code, message) { return new WebSocketError(code, message); },
1246
1250
  typeCode: "ws/invalid-payload",
1247
1251
  typeMessage: "send() requires Buffer, Uint8Array, or string",
1248
1252
  });
package/lib/worm.js CHANGED
@@ -113,10 +113,9 @@ function create(opts) {
113
113
  throw new WormError("worm/bad-opt", "worm.create: defaultRetentionMs must be a non-negative finite number");
114
114
  }
115
115
 
116
+ var _baseAudit = audit().namespaced("worm");
116
117
  function _emit(action, outcome, id, metadata) {
117
- try {
118
- audit().safeEmit({ action: "worm." + action, actor: { type: "system" }, outcome: outcome, metadata: Object.assign({ id: id, mode: mode }, metadata || {}) });
119
- } catch (_e) { /* audit is drop-silent by design */ }
118
+ _baseAudit(action, outcome, Object.assign({ id: id, mode: mode }, metadata || {}), { actor: { type: "system" } });
120
119
  }
121
120
 
122
121
  function _resolveRetainUntil(now, putOpts) {
package/lib/ws-client.js CHANGED
@@ -60,6 +60,7 @@ var audit = lazyRequire(function () { return require("./audit"); });
60
60
  var networkTls = lazyRequire(function () { return require("./network-tls"); });
61
61
  var safeJson = lazyRequire(function () { return require("./safe-json"); });
62
62
  var ssrfGuard = require("./ssrf-guard");
63
+ var structuredFields = require("./structured-fields");
63
64
  var C = require("./constants");
64
65
  var { defineClass } = require("./framework-error");
65
66
 
@@ -492,7 +493,7 @@ class WsClient extends EventEmitter {
492
493
  this._handshakeBuf = Buffer.concat([this._handshakeBuf, chunk]);
493
494
  var headerEnd = this._handshakeBuf.indexOf("\r\n\r\n");
494
495
  if (headerEnd === -1) {
495
- if (this._handshakeBuf.length > C.BYTES.kib(64)) {
496
+ if (safeBuffer.byteLengthOf(this._handshakeBuf) > C.BYTES.kib(64)) {
496
497
  this._handleSocketError(new WsClientError("ws-client/handshake-too-large",
497
498
  "handshake response exceeded 64 KiB before CRLFCRLF"));
498
499
  }
@@ -526,13 +527,10 @@ class WsClient extends EventEmitter {
526
527
  }
527
528
 
528
529
  var headers = Object.create(null);
529
- for (var i = 1; i < lines.length; i += 1) {
530
- var idx = lines[i].indexOf(":");
531
- if (idx === -1) continue;
532
- var hkey = lines[i].slice(0, idx).trim().toLowerCase();
533
- var hval = lines[i].slice(idx + 1).trim();
534
- headers[hkey] = hval;
535
- }
530
+ var hkvps = structuredFields.parseKeyValuePieces(lines, 1, ":");
531
+ structuredFields.forEachKeyValue(hkvps, function (key, value) {
532
+ headers[key] = value;
533
+ });
536
534
 
537
535
  if ((headers["upgrade"] || "").toLowerCase() !== "websocket" ||
538
536
  (headers["connection"] || "").toLowerCase().indexOf("upgrade") === -1) {
@@ -698,7 +696,7 @@ class WsClient extends EventEmitter {
698
696
  }
699
697
  if (frame.fin) {
700
698
  var fullPayload = Buffer.concat(this._fragmentChunks); // allow:handrolled-buffer-collect — bounded by maxMessageBytes below
701
- if (fullPayload.length > this._opts.maxMessageBytes) {
699
+ if (safeBuffer.byteLengthOf(fullPayload) > this._opts.maxMessageBytes) {
702
700
  this._handleSocketError(new WsClientError("ws-client/message-too-big",
703
701
  "incoming message exceeds maxMessageBytes (" + this._opts.maxMessageBytes + ")"));
704
702
  return;
@@ -797,7 +795,7 @@ class WsClient extends EventEmitter {
797
795
  } else {
798
796
  payload = Buffer.from(JSON.stringify(data), "utf8");
799
797
  }
800
- if (payload.length > this._opts.maxMessageBytes) {
798
+ if (safeBuffer.byteLengthOf(payload) > this._opts.maxMessageBytes) {
801
799
  throw new WsClientError("ws-client/payload-too-big",
802
800
  "send: payload exceeds maxMessageBytes (" + this._opts.maxMessageBytes + ")");
803
801
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.15.12",
3
+ "version": "0.15.13",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:caf34b84-1358-4d28-a517-e360819dc35a",
5
+ "serialNumber": "urn:uuid:4df0908b-006e-466d-b6f7-6426f710546e",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-06-14T16:52:10.733Z",
8
+ "timestamp": "2026-06-20T02:02:17.152Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.15.12",
22
+ "bom-ref": "@blamejs/core@0.15.13",
23
23
  "type": "application",
24
24
  "name": "blamejs",
25
- "version": "0.15.12",
25
+ "version": "0.15.13",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.15.12",
29
+ "purl": "pkg:npm/%40blamejs/core@0.15.13",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.15.12",
57
+ "ref": "@blamejs/core@0.15.13",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]