@blamejs/blamejs-shop 0.4.56 → 0.4.57

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 (397) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +426 -366
  4. package/lib/vendor/blamejs/.github/codeql/codeql-config.yml +25 -0
  5. package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
  6. package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +1 -1
  7. package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +1 -1
  8. package/lib/vendor/blamejs/.github/workflows/ci.yml +13 -13
  9. package/lib/vendor/blamejs/.github/workflows/codeql.yml +8 -7
  10. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +2 -2
  11. package/lib/vendor/blamejs/.github/workflows/release-container.yml +4 -4
  12. package/lib/vendor/blamejs/.github/workflows/scorecard.yml +1 -1
  13. package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
  14. package/lib/vendor/blamejs/CHANGELOG.md +2 -0
  15. package/lib/vendor/blamejs/api-snapshot.json +1381 -4
  16. package/lib/vendor/blamejs/eslint.config.mjs +1 -0
  17. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +4 -1
  18. package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +5 -2
  19. package/lib/vendor/blamejs/examples/wiki/routes/pages.js +4 -1
  20. package/lib/vendor/blamejs/fuzz/guard-text.fuzz.js +20 -0
  21. package/lib/vendor/blamejs/index.js +2 -0
  22. package/lib/vendor/blamejs/lib/a2a-tasks.js +7 -23
  23. package/lib/vendor/blamejs/lib/acme.js +6 -5
  24. package/lib/vendor/blamejs/lib/agent-event-bus.js +5 -4
  25. package/lib/vendor/blamejs/lib/agent-idempotency.js +2 -5
  26. package/lib/vendor/blamejs/lib/agent-orchestrator.js +2 -5
  27. package/lib/vendor/blamejs/lib/agent-saga.js +3 -5
  28. package/lib/vendor/blamejs/lib/agent-tenant.js +2 -5
  29. package/lib/vendor/blamejs/lib/ai-adverse-decision.js +2 -15
  30. package/lib/vendor/blamejs/lib/ai-capability.js +1 -6
  31. package/lib/vendor/blamejs/lib/ai-dp.js +1 -5
  32. package/lib/vendor/blamejs/lib/ai-input.js +2 -2
  33. package/lib/vendor/blamejs/lib/ai-pref.js +3 -8
  34. package/lib/vendor/blamejs/lib/ai-quota.js +3 -14
  35. package/lib/vendor/blamejs/lib/api-key.js +37 -28
  36. package/lib/vendor/blamejs/lib/archive-adapters.js +2 -4
  37. package/lib/vendor/blamejs/lib/archive-entry-policy.js +32 -0
  38. package/lib/vendor/blamejs/lib/archive-read.js +5 -17
  39. package/lib/vendor/blamejs/lib/archive-tar-read.js +5 -16
  40. package/lib/vendor/blamejs/lib/archive.js +2 -10
  41. package/lib/vendor/blamejs/lib/arg-parser.js +7 -6
  42. package/lib/vendor/blamejs/lib/asyncapi-traits.js +2 -6
  43. package/lib/vendor/blamejs/lib/atomic-file.js +108 -31
  44. package/lib/vendor/blamejs/lib/audit-chain.js +133 -53
  45. package/lib/vendor/blamejs/lib/audit-daily-review.js +24 -14
  46. package/lib/vendor/blamejs/lib/audit-emit.js +82 -0
  47. package/lib/vendor/blamejs/lib/audit-sign.js +257 -0
  48. package/lib/vendor/blamejs/lib/audit.js +84 -0
  49. package/lib/vendor/blamejs/lib/auth/access-lock.js +5 -27
  50. package/lib/vendor/blamejs/lib/auth/dpop.js +23 -35
  51. package/lib/vendor/blamejs/lib/auth/fido-mds3.js +9 -15
  52. package/lib/vendor/blamejs/lib/auth/jwt-external.js +26 -8
  53. package/lib/vendor/blamejs/lib/auth/jwt.js +13 -15
  54. package/lib/vendor/blamejs/lib/auth/lockout.js +6 -25
  55. package/lib/vendor/blamejs/lib/auth/oauth.js +67 -45
  56. package/lib/vendor/blamejs/lib/auth/oid4vci.js +55 -32
  57. package/lib/vendor/blamejs/lib/auth/oid4vp.js +3 -2
  58. package/lib/vendor/blamejs/lib/auth/openid-federation.js +6 -6
  59. package/lib/vendor/blamejs/lib/auth/passkey.js +3 -3
  60. package/lib/vendor/blamejs/lib/auth/password.js +7 -1
  61. package/lib/vendor/blamejs/lib/auth/saml.js +37 -27
  62. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +2 -14
  63. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +2 -14
  64. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +1 -1
  65. package/lib/vendor/blamejs/lib/auth/status-list.js +7 -7
  66. package/lib/vendor/blamejs/lib/auth/step-up.js +6 -12
  67. package/lib/vendor/blamejs/lib/auth-bot-challenge.js +6 -37
  68. package/lib/vendor/blamejs/lib/backup/bundle.js +11 -18
  69. package/lib/vendor/blamejs/lib/backup/index.js +14 -47
  70. package/lib/vendor/blamejs/lib/bounded-map.js +112 -1
  71. package/lib/vendor/blamejs/lib/breach-deadline.js +1 -11
  72. package/lib/vendor/blamejs/lib/cache.js +7 -18
  73. package/lib/vendor/blamejs/lib/cbor.js +2 -1
  74. package/lib/vendor/blamejs/lib/cdn-cache-control.js +8 -9
  75. package/lib/vendor/blamejs/lib/cert.js +3 -10
  76. package/lib/vendor/blamejs/lib/chain-writer.js +162 -47
  77. package/lib/vendor/blamejs/lib/cli.js +5 -1
  78. package/lib/vendor/blamejs/lib/client-hints.js +7 -9
  79. package/lib/vendor/blamejs/lib/cloud-events.js +40 -31
  80. package/lib/vendor/blamejs/lib/cluster-storage.js +2 -38
  81. package/lib/vendor/blamejs/lib/cms-codec.js +2 -1
  82. package/lib/vendor/blamejs/lib/codepoint-class.js +67 -1
  83. package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +1 -6
  84. package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +2 -4
  85. package/lib/vendor/blamejs/lib/compliance-eaa.js +1 -11
  86. package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +21 -28
  87. package/lib/vendor/blamejs/lib/compliance-sanctions.js +2 -14
  88. package/lib/vendor/blamejs/lib/compliance.js +2 -9
  89. package/lib/vendor/blamejs/lib/config-drift.js +2 -12
  90. package/lib/vendor/blamejs/lib/content-digest.js +10 -8
  91. package/lib/vendor/blamejs/lib/cookies.js +5 -11
  92. package/lib/vendor/blamejs/lib/cose.js +19 -11
  93. package/lib/vendor/blamejs/lib/cra-report.js +1 -11
  94. package/lib/vendor/blamejs/lib/crypto-field.js +5 -10
  95. package/lib/vendor/blamejs/lib/crypto.js +120 -3
  96. package/lib/vendor/blamejs/lib/csp.js +235 -3
  97. package/lib/vendor/blamejs/lib/daemon.js +42 -41
  98. package/lib/vendor/blamejs/lib/data-act.js +19 -9
  99. package/lib/vendor/blamejs/lib/db-query.js +6 -40
  100. package/lib/vendor/blamejs/lib/db.js +34 -12
  101. package/lib/vendor/blamejs/lib/dbsc.js +5 -6
  102. package/lib/vendor/blamejs/lib/ddl-change-control.js +18 -14
  103. package/lib/vendor/blamejs/lib/deprecate.js +4 -5
  104. package/lib/vendor/blamejs/lib/did.js +6 -2
  105. package/lib/vendor/blamejs/lib/dsr.js +8 -12
  106. package/lib/vendor/blamejs/lib/external-db-migrate.js +21 -22
  107. package/lib/vendor/blamejs/lib/external-db.js +14 -26
  108. package/lib/vendor/blamejs/lib/fda-21cfr11.js +12 -8
  109. package/lib/vendor/blamejs/lib/fdx.js +22 -18
  110. package/lib/vendor/blamejs/lib/file-upload.js +80 -66
  111. package/lib/vendor/blamejs/lib/flag-evaluation-context.js +5 -8
  112. package/lib/vendor/blamejs/lib/framework-error.js +12 -0
  113. package/lib/vendor/blamejs/lib/framework-schema.js +19 -0
  114. package/lib/vendor/blamejs/lib/fsm.js +7 -12
  115. package/lib/vendor/blamejs/lib/gate-contract.js +869 -38
  116. package/lib/vendor/blamejs/lib/gdpr-ropa.js +4 -13
  117. package/lib/vendor/blamejs/lib/graphql-federation.js +1 -1
  118. package/lib/vendor/blamejs/lib/guard-agent-registry.js +2 -1
  119. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  120. package/lib/vendor/blamejs/lib/guard-archive.js +9 -30
  121. package/lib/vendor/blamejs/lib/guard-auth.js +23 -80
  122. package/lib/vendor/blamejs/lib/guard-cidr.js +20 -96
  123. package/lib/vendor/blamejs/lib/guard-csv.js +135 -196
  124. package/lib/vendor/blamejs/lib/guard-domain.js +23 -106
  125. package/lib/vendor/blamejs/lib/guard-dsn.js +16 -13
  126. package/lib/vendor/blamejs/lib/guard-email.js +46 -53
  127. package/lib/vendor/blamejs/lib/guard-envelope.js +1 -1
  128. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +2 -1
  129. package/lib/vendor/blamejs/lib/guard-filename.js +12 -60
  130. package/lib/vendor/blamejs/lib/guard-graphql.js +28 -75
  131. package/lib/vendor/blamejs/lib/guard-html-wcag.js +15 -2
  132. package/lib/vendor/blamejs/lib/guard-html.js +65 -117
  133. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +2 -1
  134. package/lib/vendor/blamejs/lib/guard-image.js +280 -77
  135. package/lib/vendor/blamejs/lib/guard-imap-command.js +8 -9
  136. package/lib/vendor/blamejs/lib/guard-json.js +87 -103
  137. package/lib/vendor/blamejs/lib/guard-jsonpath.js +20 -88
  138. package/lib/vendor/blamejs/lib/guard-jwt.js +32 -114
  139. package/lib/vendor/blamejs/lib/guard-list-id.js +2 -7
  140. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -7
  141. package/lib/vendor/blamejs/lib/guard-mail-compose.js +5 -6
  142. package/lib/vendor/blamejs/lib/guard-mail-move.js +2 -1
  143. package/lib/vendor/blamejs/lib/guard-mail-query.js +5 -3
  144. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +6 -7
  145. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +5 -4
  146. package/lib/vendor/blamejs/lib/guard-markdown.js +76 -110
  147. package/lib/vendor/blamejs/lib/guard-message-id.js +5 -6
  148. package/lib/vendor/blamejs/lib/guard-mime.js +20 -99
  149. package/lib/vendor/blamejs/lib/guard-oauth.js +19 -73
  150. package/lib/vendor/blamejs/lib/guard-pdf.js +65 -72
  151. package/lib/vendor/blamejs/lib/guard-pop3-command.js +12 -13
  152. package/lib/vendor/blamejs/lib/guard-posture-chain.js +2 -1
  153. package/lib/vendor/blamejs/lib/guard-regex.js +24 -99
  154. package/lib/vendor/blamejs/lib/guard-saga-config.js +2 -1
  155. package/lib/vendor/blamejs/lib/guard-shell.js +22 -87
  156. package/lib/vendor/blamejs/lib/guard-smtp-command.js +8 -11
  157. package/lib/vendor/blamejs/lib/guard-sql.js +15 -13
  158. package/lib/vendor/blamejs/lib/guard-stream-args.js +2 -1
  159. package/lib/vendor/blamejs/lib/guard-svg.js +95 -140
  160. package/lib/vendor/blamejs/lib/guard-template.js +23 -80
  161. package/lib/vendor/blamejs/lib/guard-tenant-id.js +2 -1
  162. package/lib/vendor/blamejs/lib/guard-text.js +592 -0
  163. package/lib/vendor/blamejs/lib/guard-time.js +27 -95
  164. package/lib/vendor/blamejs/lib/guard-uuid.js +21 -93
  165. package/lib/vendor/blamejs/lib/guard-xml.js +76 -106
  166. package/lib/vendor/blamejs/lib/guard-yaml.js +24 -60
  167. package/lib/vendor/blamejs/lib/http-client-cache.js +5 -12
  168. package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +2 -4
  169. package/lib/vendor/blamejs/lib/http-client.js +8 -21
  170. package/lib/vendor/blamejs/lib/http-message-signature.js +3 -2
  171. package/lib/vendor/blamejs/lib/i18n-messageformat.js +5 -7
  172. package/lib/vendor/blamejs/lib/i18n.js +83 -26
  173. package/lib/vendor/blamejs/lib/inbox.js +8 -8
  174. package/lib/vendor/blamejs/lib/incident-report.js +3 -21
  175. package/lib/vendor/blamejs/lib/ip-utils.js +49 -6
  176. package/lib/vendor/blamejs/lib/jobs.js +3 -2
  177. package/lib/vendor/blamejs/lib/keychain.js +6 -18
  178. package/lib/vendor/blamejs/lib/legal-hold.js +6 -15
  179. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +44 -112
  180. package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +17 -14
  181. package/lib/vendor/blamejs/lib/log-stream-otlp.js +16 -80
  182. package/lib/vendor/blamejs/lib/log-stream-webhook.js +20 -92
  183. package/lib/vendor/blamejs/lib/mail-arc-sign.js +8 -3
  184. package/lib/vendor/blamejs/lib/mail-arf.js +3 -2
  185. package/lib/vendor/blamejs/lib/mail-auth.js +40 -66
  186. package/lib/vendor/blamejs/lib/mail-bimi.js +19 -39
  187. package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +3 -2
  188. package/lib/vendor/blamejs/lib/mail-dav.js +8 -35
  189. package/lib/vendor/blamejs/lib/mail-deploy.js +6 -9
  190. package/lib/vendor/blamejs/lib/mail-dkim.js +19 -38
  191. package/lib/vendor/blamejs/lib/mail-greylist.js +15 -26
  192. package/lib/vendor/blamejs/lib/mail-helo.js +2 -3
  193. package/lib/vendor/blamejs/lib/mail-journal.js +2 -1
  194. package/lib/vendor/blamejs/lib/mail-mdn.js +4 -3
  195. package/lib/vendor/blamejs/lib/mail-rbl.js +5 -8
  196. package/lib/vendor/blamejs/lib/mail-scan.js +2 -2
  197. package/lib/vendor/blamejs/lib/mail-send-deliver.js +33 -20
  198. package/lib/vendor/blamejs/lib/mail-server-imap.js +32 -87
  199. package/lib/vendor/blamejs/lib/mail-server-jmap.js +35 -51
  200. package/lib/vendor/blamejs/lib/mail-server-managesieve.js +29 -83
  201. package/lib/vendor/blamejs/lib/mail-server-mx.js +33 -74
  202. package/lib/vendor/blamejs/lib/mail-server-net.js +177 -0
  203. package/lib/vendor/blamejs/lib/mail-server-pop3.js +30 -83
  204. package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +30 -6
  205. package/lib/vendor/blamejs/lib/mail-server-submission.js +34 -73
  206. package/lib/vendor/blamejs/lib/mail-server-tls.js +89 -0
  207. package/lib/vendor/blamejs/lib/mail-spam-score.js +7 -8
  208. package/lib/vendor/blamejs/lib/mail-store.js +3 -2
  209. package/lib/vendor/blamejs/lib/mail.js +6 -11
  210. package/lib/vendor/blamejs/lib/markup-escape.js +31 -0
  211. package/lib/vendor/blamejs/lib/markup-tokenizer.js +54 -0
  212. package/lib/vendor/blamejs/lib/mcp-tool-registry.js +26 -23
  213. package/lib/vendor/blamejs/lib/mcp.js +1 -1
  214. package/lib/vendor/blamejs/lib/mdoc.js +11 -12
  215. package/lib/vendor/blamejs/lib/metrics.js +32 -30
  216. package/lib/vendor/blamejs/lib/middleware/age-gate.js +3 -23
  217. package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +11 -22
  218. package/lib/vendor/blamejs/lib/middleware/assetlinks.js +2 -7
  219. package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +2 -1
  220. package/lib/vendor/blamejs/lib/middleware/body-parser.js +31 -48
  221. package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +7 -10
  222. package/lib/vendor/blamejs/lib/middleware/bot-guard.js +2 -10
  223. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +13 -2
  224. package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +6 -26
  225. package/lib/vendor/blamejs/lib/middleware/deny-response.js +19 -1
  226. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +7 -0
  227. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +4 -20
  228. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +20 -28
  229. package/lib/vendor/blamejs/lib/middleware/scim-server.js +3 -2
  230. package/lib/vendor/blamejs/lib/middleware/security-headers.js +9 -1
  231. package/lib/vendor/blamejs/lib/middleware/security-txt.js +2 -6
  232. package/lib/vendor/blamejs/lib/middleware/tus-upload.js +12 -27
  233. package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +2 -7
  234. package/lib/vendor/blamejs/lib/migrations.js +4 -13
  235. package/lib/vendor/blamejs/lib/mime-parse.js +34 -17
  236. package/lib/vendor/blamejs/lib/module-loader.js +44 -0
  237. package/lib/vendor/blamejs/lib/money.js +105 -0
  238. package/lib/vendor/blamejs/lib/mtls-ca.js +116 -36
  239. package/lib/vendor/blamejs/lib/network-byte-quota.js +4 -18
  240. package/lib/vendor/blamejs/lib/network-dane.js +8 -6
  241. package/lib/vendor/blamejs/lib/network-dns-resolver.js +97 -6
  242. package/lib/vendor/blamejs/lib/network-dnssec.js +16 -16
  243. package/lib/vendor/blamejs/lib/network-heartbeat.js +3 -2
  244. package/lib/vendor/blamejs/lib/network-smtp-policy.js +29 -41
  245. package/lib/vendor/blamejs/lib/network-tls.js +40 -42
  246. package/lib/vendor/blamejs/lib/nis2-report.js +1 -11
  247. package/lib/vendor/blamejs/lib/nonce-store.js +81 -3
  248. package/lib/vendor/blamejs/lib/numeric-bounds.js +22 -8
  249. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +2 -6
  250. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +5 -45
  251. package/lib/vendor/blamejs/lib/object-store/gcs.js +8 -71
  252. package/lib/vendor/blamejs/lib/object-store/http-put.js +1 -5
  253. package/lib/vendor/blamejs/lib/object-store/http-request.js +128 -0
  254. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +2 -1
  255. package/lib/vendor/blamejs/lib/object-store/sigv4.js +9 -77
  256. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -25
  257. package/lib/vendor/blamejs/lib/observability.js +95 -0
  258. package/lib/vendor/blamejs/lib/openapi-paths-builder.js +7 -3
  259. package/lib/vendor/blamejs/lib/otel-export.js +7 -10
  260. package/lib/vendor/blamejs/lib/outbox.js +43 -37
  261. package/lib/vendor/blamejs/lib/pagination.js +11 -15
  262. package/lib/vendor/blamejs/lib/parsers/safe-env.js +5 -4
  263. package/lib/vendor/blamejs/lib/parsers/safe-ini.js +10 -4
  264. package/lib/vendor/blamejs/lib/parsers/safe-toml.js +11 -9
  265. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +2 -2
  266. package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +7 -6
  267. package/lib/vendor/blamejs/lib/pick.js +63 -5
  268. package/lib/vendor/blamejs/lib/pipl-cn.js +69 -59
  269. package/lib/vendor/blamejs/lib/privacy-pass.js +8 -6
  270. package/lib/vendor/blamejs/lib/problem-details.js +2 -5
  271. package/lib/vendor/blamejs/lib/pubsub.js +4 -8
  272. package/lib/vendor/blamejs/lib/redact.js +2 -1
  273. package/lib/vendor/blamejs/lib/render.js +4 -2
  274. package/lib/vendor/blamejs/lib/request-helpers.js +133 -6
  275. package/lib/vendor/blamejs/lib/restore.js +5 -22
  276. package/lib/vendor/blamejs/lib/retention.js +3 -5
  277. package/lib/vendor/blamejs/lib/safe-async.js +457 -0
  278. package/lib/vendor/blamejs/lib/safe-buffer.js +137 -6
  279. package/lib/vendor/blamejs/lib/safe-decompress.js +2 -1
  280. package/lib/vendor/blamejs/lib/safe-dns.js +2 -1
  281. package/lib/vendor/blamejs/lib/safe-ical.js +12 -26
  282. package/lib/vendor/blamejs/lib/safe-json.js +7 -8
  283. package/lib/vendor/blamejs/lib/safe-jsonpath.js +6 -5
  284. package/lib/vendor/blamejs/lib/safe-mime.js +25 -29
  285. package/lib/vendor/blamejs/lib/safe-redirect.js +2 -5
  286. package/lib/vendor/blamejs/lib/safe-schema.js +7 -6
  287. package/lib/vendor/blamejs/lib/safe-sql.js +126 -0
  288. package/lib/vendor/blamejs/lib/safe-vcard.js +12 -26
  289. package/lib/vendor/blamejs/lib/sandbox-worker.js +9 -2
  290. package/lib/vendor/blamejs/lib/sandbox.js +3 -2
  291. package/lib/vendor/blamejs/lib/scheduler.js +5 -12
  292. package/lib/vendor/blamejs/lib/sec-cyber.js +82 -37
  293. package/lib/vendor/blamejs/lib/seeders.js +4 -11
  294. package/lib/vendor/blamejs/lib/self-update.js +92 -69
  295. package/lib/vendor/blamejs/lib/session-device-binding.js +112 -66
  296. package/lib/vendor/blamejs/lib/session.js +194 -6
  297. package/lib/vendor/blamejs/lib/sql.js +225 -78
  298. package/lib/vendor/blamejs/lib/sse.js +6 -10
  299. package/lib/vendor/blamejs/lib/static.js +136 -98
  300. package/lib/vendor/blamejs/lib/storage.js +4 -2
  301. package/lib/vendor/blamejs/lib/structured-fields.js +275 -16
  302. package/lib/vendor/blamejs/lib/tenant-quota.js +2 -20
  303. package/lib/vendor/blamejs/lib/tsa.js +11 -15
  304. package/lib/vendor/blamejs/lib/validate-opts.js +154 -8
  305. package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +30 -48
  306. package/lib/vendor/blamejs/lib/vault-aad.js +3 -2
  307. package/lib/vendor/blamejs/lib/vc.js +2 -7
  308. package/lib/vendor/blamejs/lib/vex.js +35 -13
  309. package/lib/vendor/blamejs/lib/web-push-vapid.js +23 -20
  310. package/lib/vendor/blamejs/lib/webhook-dispatcher.js +706 -0
  311. package/lib/vendor/blamejs/lib/webhook.js +43 -18
  312. package/lib/vendor/blamejs/lib/websocket-channels.js +9 -7
  313. package/lib/vendor/blamejs/lib/websocket.js +7 -3
  314. package/lib/vendor/blamejs/lib/worm.js +2 -3
  315. package/lib/vendor/blamejs/lib/ws-client.js +8 -10
  316. package/lib/vendor/blamejs/package.json +1 -1
  317. package/lib/vendor/blamejs/release-notes/v0.15.13.json +81 -0
  318. package/lib/vendor/blamejs/scripts/check-changelog-extract.js +1 -1
  319. package/lib/vendor/blamejs/test/00-primitives.js +136 -7
  320. package/lib/vendor/blamejs/test/10-state.js +9 -3
  321. package/lib/vendor/blamejs/test/30-chain.js +40 -0
  322. package/lib/vendor/blamejs/test/helpers/check.js +18 -0
  323. package/lib/vendor/blamejs/test/helpers/db.js +4 -0
  324. package/lib/vendor/blamejs/test/helpers/index.js +1 -0
  325. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +2 -1
  326. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +2 -1
  327. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +8 -1
  328. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +1 -1
  329. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +2 -1
  330. package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +269 -0
  331. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-fd-read.test.js +149 -0
  332. package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +51 -0
  333. package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +88 -0
  334. package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +55 -1
  335. package/lib/vendor/blamejs/test/layer-0-primitives/backup-object-store-adapter.test.js +2 -2
  336. package/lib/vendor/blamejs/test/layer-0-primitives/bot-guard.test.js +1 -1
  337. package/lib/vendor/blamejs/test/layer-0-primitives/bounded-map.test.js +129 -0
  338. package/lib/vendor/blamejs/test/layer-0-primitives/chain-writer-multichain.test.js +107 -0
  339. package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +12 -0
  340. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +2788 -3214
  341. package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +78 -0
  342. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +63 -0
  343. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +2 -1
  344. package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +50 -0
  345. package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +1 -1
  346. package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +2 -1
  347. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-resolve-opts.test.js +76 -0
  348. package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +9 -0
  349. package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract-content-gate.test.js +290 -0
  350. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +84 -0
  351. package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +78 -0
  352. package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +23 -0
  353. package/lib/vendor/blamejs/test/layer-0-primitives/guard-gate-disposition-coverage.test.js +93 -0
  354. package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +60 -0
  355. package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +184 -0
  356. package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
  357. package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +54 -0
  358. package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +10 -0
  359. package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +45 -0
  360. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +101 -0
  361. package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +18 -0
  362. package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +76 -0
  363. package/lib/vendor/blamejs/test/layer-0-primitives/guard-text.test.js +365 -0
  364. package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +35 -0
  365. package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +36 -0
  366. package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +20 -0
  367. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -0
  368. package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +83 -0
  369. package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +10 -0
  370. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +39 -0
  371. package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +36 -0
  372. package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +17 -0
  373. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +39 -0
  374. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +17 -0
  375. package/lib/vendor/blamejs/test/layer-0-primitives/mime-parse.test.js +106 -0
  376. package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +17 -0
  377. package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-revocation.test.js +98 -0
  378. package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-release.test.js +77 -0
  379. package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +48 -0
  380. package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-memory-getorinsert.test.js +100 -0
  381. package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +88 -0
  382. package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +278 -0
  383. package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +37 -0
  384. package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +14 -0
  385. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +19 -0
  386. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +1 -1
  387. package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +2 -1
  388. package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +18 -0
  389. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +1 -1
  390. package/lib/vendor/blamejs/test/layer-0-primitives/session-valid-from.test.js +73 -0
  391. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +100 -0
  392. package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +80 -0
  393. package/lib/vendor/blamejs/test/layer-0-primitives/validate-opts-shape.test.js +235 -0
  394. package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +374 -0
  395. package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +75 -8
  396. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +3 -3
  397. package/package.json +1 -1
@@ -0,0 +1,592 @@
1
+ "use strict";
2
+ /**
3
+ * @module b.guardText
4
+ * @nav Guards
5
+ * @title Guard Text
6
+ *
7
+ * @intro
8
+ * General-purpose UTF-8 free-text content-safety guard — the screen for
9
+ * unconstrained human text (a comment, a note, a review body, a gift
10
+ * message, a display name) where the legitimate content is "arbitrary
11
+ * letters in any writing system" but the dangerous content is a hidden
12
+ * codepoint that renders as nothing yet changes meaning.
13
+ *
14
+ * Unlike the format-specific members of the guard family (csv / html / svg /
15
+ * json / yaml / xml / markdown), this guard imposes NO grammar on its input.
16
+ * Cyrillic, Han, Arabic, emoji, combining marks — all pass. What it screens
17
+ * is the codepoint threat catalog shared across the family:
18
+ *
19
+ * - Unicode bidi overrides (CVE-2021-42574 Trojan Source — U+202A..U+202E,
20
+ * U+2066..U+2069, U+200E/F, U+061C). Visible text reads one way; the
21
+ * logical order is reversed.
22
+ * - C0 control characters (minus tab / lf / cr, which are legitimate in
23
+ * free text) — terminal-escape and log-injection vectors.
24
+ * - Null bytes — truncation / C-string-boundary attacks downstream.
25
+ * - Zero-width / invisible formatting chars (ZWSP / ZWNJ / ZWJ / WJ / SHY /
26
+ * BOM) — payload-hiding and watermark channels.
27
+ * - Unicode Tags block (U+E0000..U+E007F) — "ASCII smuggling": an invisible
28
+ * copy of an ASCII instruction an LLM tokenizer reads verbatim
29
+ * (prompt-injection over a comment field).
30
+ * - Mixed-script confusables (UTS #39) — a Cyrillic letter inside an
31
+ * otherwise-Latin word. Audit severity by default (legitimate
32
+ * multilingual text mixes scripts); promoted to refuse under the strict
33
+ * profile and the regulated postures.
34
+ *
35
+ * Three profiles ship — `strict` / `balanced` / `permissive` — plus four
36
+ * compliance postures (`hipaa` / `pci-dss` / `gdpr` / `soc2`). `strict`
37
+ * rejects bidi / control / null; `balanced` strips them and serves the
38
+ * cleaned text; `permissive` strips the invisibles and only audits the rest.
39
+ * Sanitize is a SHRINKING operation by contract — stripping invisible
40
+ * codepoints never grows the string; an amplification past
41
+ * `sanitizeAmplificationCap` (default 1.5x) is refused.
42
+ *
43
+ * `b.guardText.gate(opts)` plugs into `b.fileUpload` / `b.staticServe` /
44
+ * `b.mail` / `b.objectStore` / `b.guardAll` like every other content guard.
45
+ *
46
+ * Threat-detection regex literals are composed from the numeric codepoint
47
+ * tables in `b.codepointClass`. The source file never embeds the attack
48
+ * characters themselves (the family ASCII-purity invariant).
49
+ *
50
+ * @card
51
+ * General-purpose UTF-8 free-text guard — allows arbitrary letters in any script, screens bidi / control / null / zero-width / Unicode-Tags / confusable codepoints.
52
+ */
53
+
54
+ var codepointClass = require("./codepoint-class");
55
+ var C = require("./constants");
56
+ var numericBounds = require("./numeric-bounds");
57
+ var gateContract = require("./gate-contract");
58
+ var { GuardTextError } = require("./framework-error");
59
+
60
+ var _err = GuardTextError.factory;
61
+ var HEX_RADIX = 16; // base-16 radix, not byte size
62
+
63
+ // ---- Shared codepoint catalog (composed from lib/codepoint-class) ----
64
+ // Pre-compiled regexes pulled from the shared catalog; this guard adds no
65
+ // codepoint table of its own.
66
+ var TAG_RE = codepointClass.TAG_RE;
67
+
68
+ // ---- Profile presets ----
69
+ // policy axis vocabulary mirrors the codepoint-class opt names so
70
+ // detectCharThreats / assertNoCharThreats / applyCharStripPolicies read them
71
+ // directly: bidiPolicy / controlPolicy / nullBytePolicy / zeroWidthPolicy /
72
+ // tagsPolicy each in "reject" | "strip" | "audit" | "allow". confusablePolicy
73
+ // ("reject" | "audit" | "allow") is text-specific — no strip, because you
74
+ // cannot repair a confusable without guessing the intended script.
75
+ var PROFILES = Object.freeze({
76
+ "strict": {
77
+ ...gateContract.CHAR_THREATS_REJECT_ALL,
78
+ tagsPolicy: "reject",
79
+ confusablePolicy: "reject",
80
+ allowedScripts: null,
81
+ maxBytes: C.BYTES.mib(1),
82
+ },
83
+ "balanced": {
84
+ bidiPolicy: "strip",
85
+ controlPolicy: "strip",
86
+ nullBytePolicy: "strip",
87
+ zeroWidthPolicy: "strip",
88
+ tagsPolicy: "strip",
89
+ confusablePolicy: "audit",
90
+ allowedScripts: null,
91
+ maxBytes: C.BYTES.mib(4),
92
+ },
93
+ "permissive": {
94
+ bidiPolicy: "audit",
95
+ controlPolicy: "strip",
96
+ nullBytePolicy: "strip",
97
+ zeroWidthPolicy: "strip",
98
+ tagsPolicy: "strip",
99
+ confusablePolicy: "allow",
100
+ allowedScripts: null,
101
+ maxBytes: C.BYTES.mib(16),
102
+ encodingPolicy: "audit",
103
+ },
104
+ });
105
+
106
+ var DEFAULTS = gateContract.strictDefaults(PROFILES, {
107
+ // Encoding/keyspace axis (byte→codepoint layer + codepoint range), distinct
108
+ // from the bad-codepoint regexes. encodingPolicy: reject malformed UTF-8 by
109
+ // default; asciiOnly / maxCodepoint are opt-in keyspace ceilings.
110
+ encodingPolicy: "reject", // "reject" | "audit" | "allow"
111
+ asciiOnly: false,
112
+ maxCodepoint: null,
113
+ sanitizeAmplificationCap: 1.5,
114
+ forensicSnippetBytes: 0,
115
+ maxRuntimeMs: C.TIME.seconds(30),
116
+ });
117
+
118
+ var COMPLIANCE_POSTURES = gateContract.compliancePostures(PROFILES, { base: 256 });
119
+
120
+ // ---- Internal helpers ----
121
+
122
+ function _resolveOpts(opts) {
123
+ return gateContract.resolveProfileAndPosture(opts, {
124
+ profiles: PROFILES,
125
+ compliancePostures: COMPLIANCE_POSTURES,
126
+ defaults: DEFAULTS,
127
+ errorClass: GuardTextError,
128
+ errCodePrefix: "text",
129
+ });
130
+ }
131
+
132
+ function _firstMatch(text, re) {
133
+ if (typeof text !== "string") return null;
134
+ var m = text.match(re);
135
+ if (!m) return null;
136
+ return { index: m.index, char: m[0] };
137
+ }
138
+
139
+ // _STRICT_UTF8 — fatal-mode decoder: an overlong encoding, an invalid
140
+ // continuation byte, or a truncated multibyte sequence THROWS instead of
141
+ // lossily substituting U+FFFD. A guard that only `toString("utf8")`s its bytes
142
+ // silently launders an overlong-encoded "/" or NUL into U+FFFD, defeating a
143
+ // downstream filter (the classic UTF-8 overlong filter-bypass). Validating the
144
+ // ENCODING (the byte→codepoint layer) is distinct from the codepoint regexes.
145
+ var _STRICT_UTF8 = new TextDecoder("utf-8", { fatal: true });
146
+ // Unpaired UTF-16 surrogate in an already-decoded JS string (malformed Unicode
147
+ // that a Buffer round-trip can't represent).
148
+ var _LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]/;
149
+
150
+ // _strictText — decode `input` to a JS string AND report a malformed encoding.
151
+ // Buffer → strict UTF-8 (fatal); string → unpaired-surrogate check. Returns
152
+ // { text, encodingError } where encodingError is null for well-formed input.
153
+ function _strictText(input) {
154
+ if (Buffer.isBuffer(input)) {
155
+ try { return { text: _STRICT_UTF8.decode(input), encodingError: null }; }
156
+ catch (_e) {
157
+ return { text: input.toString("utf8"),
158
+ encodingError: "malformed UTF-8 (overlong / invalid continuation / truncated multibyte)" };
159
+ }
160
+ }
161
+ if (typeof input === "string") {
162
+ return { text: input,
163
+ // allow:regex-no-length-cap — _LONE_SURROGATE_RE is a single-pass char-class
164
+ // alternation (no quantifier, no backtracking); O(n) on any input length.
165
+ encodingError: _LONE_SURROGATE_RE.test(input) ? "unpaired UTF-16 surrogate" : null };
166
+ }
167
+ return { text: null, encodingError: null };
168
+ }
169
+
170
+ // _firstCodepointAbove — first codepoint exceeding `max` (keyspace ceiling),
171
+ // iterating by codepoint so an astral char counts once. Returns { index, cp }.
172
+ function _firstCodepointAbove(text, max) {
173
+ for (var i = 0; i < text.length; ) {
174
+ var cp = text.codePointAt(i);
175
+ if (cp > max) return { index: i, cp: cp };
176
+ i += cp > 0xFFFF ? 2 : 1;
177
+ }
178
+ return null;
179
+ }
180
+
181
+ // _detectIssues — pure inspection; never mutates / throws. Emits at most one
182
+ // issue per class (the codepoint catalog classes + the text-specific
183
+ // confusable class). An "allow" policy suppresses the class entirely;
184
+ // everything else surfaces the issue and the gate/sanitize layer decides
185
+ // serve / strip / refuse.
186
+ function _detectIssues(text, opts) {
187
+ var issues = [];
188
+ if (typeof text !== "string") return issues;
189
+
190
+ // bidi / null-byte / control / zero-width — delegate to the shared catalog
191
+ // detector so the per-class match-and-push block lives in exactly one place.
192
+ // Invisible chars spoof displayed text (homoglyph), so zero-width is `high`.
193
+ issues.push.apply(issues, codepointClass.detectCharThreats(text, opts, "text", "high"));
194
+
195
+ if (opts.tagsPolicy !== "allow") {
196
+ // TAG_RE uses the `u` flag (astral block U+E0000..U+E007F); index is the
197
+ // UTF-16 offset of the first tag codepoint.
198
+ var tagMatch = text.match(TAG_RE);
199
+ if (tagMatch) {
200
+ issues.push({
201
+ kind: "unicode-tags", severity: "critical", ruleId: "text.unicode-tags",
202
+ location: tagMatch.index,
203
+ snippet: "Unicode Tags block char (ASCII-smuggling / prompt-injection) at offset " +
204
+ tagMatch.index,
205
+ });
206
+ }
207
+ }
208
+
209
+ if (opts.confusablePolicy !== "allow") {
210
+ var scripts = codepointClass.detectMixedScripts(text, opts.allowedScripts || null);
211
+ if (scripts) {
212
+ // Mixed-script is an audit signal by default (legitimate multilingual
213
+ // text mixes scripts); strict / regulated postures set confusablePolicy
214
+ // "reject", which promotes the severity below so the gate refuses.
215
+ issues.push({
216
+ kind: "mixed-script-confusable",
217
+ severity: opts.confusablePolicy === "reject" ? "high" : "warn",
218
+ ruleId: "text.confusable",
219
+ location: 0,
220
+ snippet: "mixed-script text (UTS #39 confusable risk): " + scripts.join(", "),
221
+ });
222
+ }
223
+ }
224
+
225
+ // Keyspace bounds — restrict the allowed codepoint range. asciiOnly pins the
226
+ // keyspace to US-ASCII (cp <= 0x7F); maxCodepoint sets an arbitrary ceiling.
227
+ // Distinct from the script/confusable axis: this is the raw codepoint range,
228
+ // not which writing systems mix.
229
+ if (opts.asciiOnly) {
230
+ var na = _firstCodepointAbove(text, 0x7F);
231
+ if (na) {
232
+ issues.push({
233
+ kind: "non-ascii", severity: "high", ruleId: "text.non-ascii",
234
+ location: na.index,
235
+ snippet: "non-ASCII codepoint U+" + na.cp.toString(HEX_RADIX) +
236
+ " at offset " + na.index + " (asciiOnly keyspace)",
237
+ });
238
+ }
239
+ }
240
+ if (typeof opts.maxCodepoint === "number") {
241
+ var oor = _firstCodepointAbove(text, opts.maxCodepoint);
242
+ if (oor) {
243
+ issues.push({
244
+ kind: "codepoint-out-of-range", severity: "high", ruleId: "text.codepoint-range",
245
+ location: oor.index,
246
+ snippet: "codepoint U+" + oor.cp.toString(HEX_RADIX) + " at offset " +
247
+ oor.index + " exceeds maxCodepoint U+" + opts.maxCodepoint.toString(HEX_RADIX),
248
+ });
249
+ }
250
+ }
251
+
252
+ return issues;
253
+ }
254
+
255
+ // _STRIPPABLE — issue kinds whose codepoints the sanitizer can physically
256
+ // remove. A confusable / too-large / operator-rule hit is NOT in this set:
257
+ // there is no safe automated repair, so its disposition can only be serve /
258
+ // audit / refuse — never sanitize.
259
+ var _STRIPPABLE = Object.freeze({
260
+ "bidi-override": true, "control-char": true, "null-byte": true,
261
+ "zero-width": true, "unicode-tags": true,
262
+ });
263
+
264
+ // _dispositionFor — map a fired issue to the operator's chosen disposition
265
+ // for its class, drawn from the resolved policy axis (not a generic severity
266
+ // threshold). This is what makes the profile semantics honest: under
267
+ // `permissive`, bidiPolicy "audit" means report-and-serve, while controlPolicy
268
+ // "strip" means remove-and-serve. Returns "reject" | "strip" | "audit" |
269
+ // "serve". A non-strippable class that an operator marked dangerous (a
270
+ // confusable under "reject", an oversized input, a high/critical operator
271
+ // rule) resolves to "reject" — never "strip" — so the gate refuses rather than
272
+ // serving a file it cannot actually clean.
273
+ function _dispositionFor(issue, opts) {
274
+ switch (issue.kind) {
275
+ case "bidi-override": return opts.bidiPolicy;
276
+ case "control-char": return opts.controlPolicy;
277
+ case "null-byte": return opts.nullBytePolicy;
278
+ case "zero-width": return opts.zeroWidthPolicy;
279
+ case "unicode-tags": return opts.tagsPolicy;
280
+ case "mixed-script-confusable":
281
+ // No "strip" — a confusable cannot be repaired without guessing the
282
+ // intended script. reject → refuse; anything else → audit-and-serve.
283
+ return opts.confusablePolicy === "reject" ? "reject" : "audit";
284
+ case "invalid-encoding":
285
+ // Malformed UTF-8 is not repairable by stripping. reject → refuse;
286
+ // audit → serve-with-note. ("allow" never produces this issue.)
287
+ return opts.encodingPolicy === "reject" ? "reject" : "audit";
288
+ case "non-ascii":
289
+ case "codepoint-out-of-range":
290
+ // A keyspace violation under an operator-set ceiling — not strippable
291
+ // (can't drop arbitrary letters), so refuse.
292
+ return "reject";
293
+ case "too-large":
294
+ case "bad-input":
295
+ return "reject";
296
+ default:
297
+ // Operator rule (or any custom kind): a high/critical hit blocks; a
298
+ // warn rides along as an audit note. Operator rules are never strippable.
299
+ return (issue.severity === "high" || issue.severity === "critical")
300
+ ? "reject" : "audit";
301
+ }
302
+ }
303
+
304
+ // _stripIssues — sanitize path. Removes only the invisible / dangerous
305
+ // codepoints whose policy is "strip"; never touches legitimate letters, never
306
+ // repairs a confusable (no safe automated repair). Delegates the bidi /
307
+ // control / null / zero-width / tags strips to the shared catalog helper so
308
+ // the replace() sequence lives once.
309
+ function _stripIssues(text, opts) {
310
+ if (typeof text !== "string") return text;
311
+ return codepointClass.applyCharStripPolicies(text, opts);
312
+ }
313
+
314
+ // ---- Public surface ----
315
+
316
+ /**
317
+ * @primitive b.guardText.validate
318
+ * @signature b.guardText.validate(input, opts?)
319
+ * @since 0.15.13
320
+ * @status stable
321
+ * @compliance hipaa, pci-dss, gdpr, soc2
322
+ * @related b.guardText.sanitize, b.guardText.gate, b.guardAll.gate
323
+ *
324
+ * Inspect `input` (string or Buffer of UTF-8 text) and return `{ ok, issues }`.
325
+ * Each issue carries `{ kind, severity, ruleId, location, snippet }` with
326
+ * severity in `"warn"|"high"|"critical"`. Three validation axes: (1) ENCODING —
327
+ * a Buffer is decoded as STRICT UTF-8, so a malformed / overlong / truncated
328
+ * sequence is flagged `invalid-encoding` rather than silently lossily decoded
329
+ * to U+FFFD (the overlong-encoding filter-bypass); a JS string is checked for
330
+ * unpaired surrogates. (2) KEYSPACE — `asciiOnly` pins the allowed codepoint
331
+ * range to US-ASCII and `maxCodepoint` sets a ceiling (distinct from the script
332
+ * axis: the raw codepoint range, not which writing systems mix). (3) CODEPOINT
333
+ * THREATS — Unicode bidi override (CVE-2021-42574 Trojan Source), C0 control
334
+ * char, null byte, zero-width / invisible char, Unicode Tags block char (ASCII
335
+ * smuggling), and mixed-script confusable. Arbitrary letters in any single
336
+ * script are NOT issues — this guard imposes no grammar. `ok` is `false` only
337
+ * when at least one issue is `high` or `critical`. Pure inspection — never
338
+ * mutates input or throws (other than the `maxBytes` positive-finite-integer
339
+ * opt check). The `maxBytes` limit is measured in UTF-8 BYTES. Passing
340
+ * `Infinity` for `maxBytes` throws.
341
+ *
342
+ * @opts
343
+ * profile: "strict"|"balanced"|"permissive",
344
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
345
+ * bidiPolicy: "reject"|"strip"|"audit"|"allow",
346
+ * controlPolicy: "reject"|"strip"|"allow",
347
+ * nullBytePolicy: "reject"|"strip"|"allow",
348
+ * zeroWidthPolicy: "reject"|"strip"|"allow",
349
+ * tagsPolicy: "reject"|"strip"|"allow",
350
+ * confusablePolicy: "reject"|"audit"|"allow",
351
+ * encodingPolicy: "reject"|"audit"|"allow", // malformed UTF-8 (default reject)
352
+ * asciiOnly: boolean, // keyspace = US-ASCII only (default false)
353
+ * maxCodepoint: number, // keyspace ceiling (e.g. 0xFFFF for BMP-only)
354
+ * allowedScripts: Array, // confusable allowlist (e.g. ["latin","han"])
355
+ * maxBytes: number, // default 1 MiB, measured in UTF-8 bytes
356
+ *
357
+ * @example
358
+ * var rv = b.guardText.validate("hello world", { profile: "strict" });
359
+ * rv.ok; // → true
360
+ * // Build the hostile input programmatically so the source stays ASCII.
361
+ * var RLO = String.fromCharCode(0x202E);
362
+ * var bad = b.guardText.validate("review " + RLO + "txt.exe", { profile: "strict" });
363
+ * bad.ok; // → false
364
+ * bad.issues[0].kind; // → "bidi-override"
365
+ */
366
+ function validate(input, opts) {
367
+ opts = _resolveOpts(opts);
368
+ numericBounds.requireAllPositiveFiniteIntIfPresent(opts,
369
+ ["maxBytes"], "guardText.validate", GuardTextError, "text.bad-opt");
370
+
371
+ var decoded = _strictText(input);
372
+ if (decoded.text == null) {
373
+ return gateContract.runIssueValidator(input, opts, _detectIssues);
374
+ }
375
+ // Encoding-validity is the byte→codepoint layer, checked before the codepoint
376
+ // regexes — a malformed/overlong sequence is a critical refuse-or-audit issue
377
+ // depending on encodingPolicy (default reject).
378
+ var encIssue = (decoded.encodingError && opts.encodingPolicy !== "allow")
379
+ ? { kind: "invalid-encoding",
380
+ severity: opts.encodingPolicy === "reject" ? "critical" : "warn",
381
+ ruleId: "text.invalid-encoding", snippet: decoded.encodingError }
382
+ : null;
383
+ var byteLen = Buffer.byteLength(decoded.text, "utf8");
384
+ if (byteLen > opts.maxBytes) {
385
+ var big = [{ kind: "too-large", severity: "high", ruleId: "text.too-large",
386
+ snippet: "input " + byteLen + " bytes exceeds maxBytes " + opts.maxBytes }];
387
+ if (encIssue) big.unshift(encIssue);
388
+ return { ok: false, issues: big };
389
+ }
390
+ var rv = gateContract.runIssueValidator(decoded.text, opts, _detectIssues);
391
+ if (!encIssue) return rv;
392
+ var issues = [encIssue].concat(rv.issues);
393
+ var ok = issues.every(function (i) { return i.severity !== "critical" && i.severity !== "high"; });
394
+ return { ok: ok, issues: issues };
395
+ }
396
+
397
+ /**
398
+ * @primitive b.guardText.sanitize
399
+ * @signature b.guardText.sanitize(input, opts?)
400
+ * @since 0.15.13
401
+ * @status stable
402
+ * @related b.guardText.validate, b.guardText.gate
403
+ *
404
+ * Best-effort cleanup of `input` (string or Buffer): strips bidi overrides
405
+ * (when `bidiPolicy: "strip"`), C0 control chars (`controlPolicy: "strip"`),
406
+ * null bytes (`nullBytePolicy: "strip"`), zero-width / invisible chars
407
+ * (`zeroWidthPolicy: "strip"`), and Unicode Tags block chars (`tagsPolicy:
408
+ * "strip"`). Legitimate letters in any script are preserved; a mixed-script
409
+ * confusable is NEVER auto-repaired (there is no safe automated repair — the
410
+ * gate refuses it instead). Sanitize is a SHRINKING operation by contract:
411
+ * when the output exceeds `sanitizeAmplificationCap` (default 1.5x) the
412
+ * function throws `GuardTextError("text.sanitize-amplified")`.
413
+ *
414
+ * @opts
415
+ * profile: "strict"|"balanced"|"permissive",
416
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
417
+ * bidiPolicy: "reject"|"strip"|"audit"|"allow",
418
+ * controlPolicy: "reject"|"strip"|"allow",
419
+ * nullBytePolicy: "reject"|"strip"|"allow",
420
+ * zeroWidthPolicy: "reject"|"strip"|"allow",
421
+ * tagsPolicy: "reject"|"strip"|"allow",
422
+ * sanitizeAmplificationCap: number, // default 1.5
423
+ *
424
+ * @example
425
+ * var ZWSP = String.fromCharCode(0x200B);
426
+ * var clean = b.guardText.sanitize("nice" + ZWSP + "review", { profile: "balanced" });
427
+ * clean.indexOf(ZWSP) === -1; // → true
428
+ * clean; // → "nicereview"
429
+ */
430
+ function sanitize(input, opts) {
431
+ opts = _resolveOpts(opts);
432
+ var decoded = _strictText(input);
433
+ if (decoded.text == null) {
434
+ throw _err("text.bad-input", "sanitize requires string or Buffer input");
435
+ }
436
+ // Malformed UTF-8 is not safely repairable by stripping codepoints; under the
437
+ // default reject policy, refuse rather than serve a lossily-decoded string.
438
+ if (decoded.encodingError && opts.encodingPolicy === "reject") {
439
+ throw _err("text.invalid-encoding",
440
+ "cannot sanitize input with " + decoded.encodingError + " (not repairable)");
441
+ }
442
+ var text = decoded.text;
443
+ var byteLen = Buffer.byteLength(text, "utf8");
444
+ if (byteLen > opts.maxBytes) {
445
+ throw _err("text.too-large",
446
+ "input " + byteLen + " bytes exceeds maxBytes " + opts.maxBytes);
447
+ }
448
+ var sanitized = _stripIssues(text, opts);
449
+ var amplification = sanitized.length / Math.max(text.length, 1);
450
+ if (amplification > opts.sanitizeAmplificationCap) {
451
+ throw _err("text.sanitize-amplified",
452
+ "sanitize grew output " + amplification.toFixed(2) +
453
+ "x; cap " + opts.sanitizeAmplificationCap);
454
+ }
455
+ return sanitized;
456
+ }
457
+
458
+ /**
459
+ * @primitive b.guardText.gate
460
+ * @signature b.guardText.gate(opts?)
461
+ * @since 0.15.13
462
+ * @status stable
463
+ * @compliance hipaa, pci-dss, gdpr, soc2
464
+ * @related b.guardText.validate, b.guardText.sanitize, b.fileUpload.create, b.staticServe.create
465
+ *
466
+ * Build a `b.gateContract` gate suitable for plugging into
467
+ * `b.fileUpload({ contentSafety: { "text/plain": gate } })`,
468
+ * `b.staticServe({ contentSafety: { ".txt": gate } })`, `b.mail`, or
469
+ * `b.objectStore`. Action chain on inspection: `serve` (no issues) →
470
+ * `audit-only` (warn-only issues — e.g. a mixed-script confusable under
471
+ * `confusablePolicy: "audit"`) → `sanitize` (critical/high but no `reject`
472
+ * policy active — strips the invisible codepoints and serves the cleaned text)
473
+ * → `refuse` (critical/high under any `reject` policy, a confusable under
474
+ * `confusablePolicy: "reject"`, or when sanitize fails / amplifies past cap).
475
+ *
476
+ * Operator extensibility: pass `operatorRules: [{ id, severity, detect:
477
+ * fn(ctx)->boolean, reason }]` to inject custom detectors alongside the
478
+ * built-in catalog. Rules run best-effort — a throwing detector is skipped
479
+ * (the framework cannot crash a request because an operator rule mishandled
480
+ * bytes).
481
+ *
482
+ * @opts
483
+ * profile: "strict"|"balanced"|"permissive",
484
+ * compliancePosture: "hipaa"|"pci-dss"|"gdpr"|"soc2",
485
+ * name: string, // gate identity for audit / observability
486
+ * operatorRules: Array, // [{ id, severity, detect: function, reason }]
487
+ *
488
+ * @example
489
+ * var textGate = b.guardText.gate({ profile: "strict" });
490
+ * var upload = b.fileUpload.create({ contentSafety: { "text/plain": textGate } });
491
+ * var RLO = String.fromCharCode(0x202E);
492
+ * var hostile = Buffer.from("ok " + RLO + "danger", "utf8");
493
+ * var verdict = await textGate.check({ bytes: hostile });
494
+ * verdict.action; // → "refuse"
495
+ */
496
+ function gate(opts) {
497
+ opts = _resolveOpts(opts);
498
+ return gateContract.buildGuardGate(
499
+ opts.name || "guardText:" + (opts.profile || "default"),
500
+ opts,
501
+ async function (ctx) {
502
+ var text = gateContract.extractBytesAsText(ctx);
503
+ if (!text) return { ok: true, action: "serve" };
504
+ // Validate the RAW bytes when present so strict UTF-8 decoding can catch a
505
+ // malformed / overlong sequence (extractBytesAsText already lossily
506
+ // decoded it to a string).
507
+ var rawInput = (ctx && Buffer.isBuffer(ctx.bytes)) ? ctx.bytes : text;
508
+ var rv = validate(rawInput, opts);
509
+
510
+ var operatorIssues = [];
511
+ if (Array.isArray(opts.operatorRules)) {
512
+ for (var ri = 0; ri < opts.operatorRules.length; ri += 1) {
513
+ var rule = opts.operatorRules[ri];
514
+ try {
515
+ if (rule.detect && rule.detect({ bytes: text, ctx: ctx })) {
516
+ operatorIssues.push({
517
+ kind: rule.id, severity: rule.severity || "warn",
518
+ ruleId: rule.id, snippet: rule.reason || rule.id,
519
+ });
520
+ }
521
+ } catch (_e) { /* operator rule best-effort — never crash the request */ }
522
+ }
523
+ }
524
+ var allIssues = rv.issues.concat(operatorIssues);
525
+ if (allIssues.length === 0) return { ok: true, action: "serve" };
526
+
527
+ // Resolve the strongest disposition across every fired issue, driven by
528
+ // the per-class policy (reject > strip > audit > serve). One "reject"
529
+ // refuses; otherwise a "strip" sanitizes the strippable codepoints and
530
+ // serves the cleaned text; otherwise the issues are audit-only.
531
+ var dispositions = allIssues.map(function (i) { return _dispositionFor(i, opts); });
532
+ if (dispositions.indexOf("reject") !== -1) {
533
+ return { ok: false, action: "refuse", issues: allIssues };
534
+ }
535
+ if (dispositions.indexOf("strip") !== -1) {
536
+ // Fail-closed invariant: every issue we're about to "sanitize away"
537
+ // must be a codepoint class the stripper can physically remove. If a
538
+ // future kind ever resolves to "strip" without being strippable,
539
+ // refuse rather than serve a file we only claimed to clean.
540
+ var stripUnrepairable = allIssues.some(function (i, idx) {
541
+ return dispositions[idx] === "strip" && !_STRIPPABLE[i.kind];
542
+ });
543
+ if (stripUnrepairable) {
544
+ return { ok: false, action: "refuse", issues: allIssues };
545
+ }
546
+ // Amplify-past-cap / bad-input refuses instead.
547
+ try {
548
+ var clean = sanitize(text, opts);
549
+ return {
550
+ ok: true, action: "sanitize",
551
+ sanitized: Buffer.from(clean, "utf8"),
552
+ issues: allIssues,
553
+ };
554
+ } catch (_e) {
555
+ return { ok: false, action: "refuse", issues: allIssues };
556
+ }
557
+ }
558
+ return { ok: true, action: "audit-only", issues: allIssues };
559
+ });
560
+ }
561
+
562
+ // ---- adaptive integration-test fixtures (consumed by layer-5 host harness) ----
563
+ var INTEGRATION_FIXTURES = Object.freeze({
564
+ kind: "content",
565
+ contentType: "text/plain",
566
+ extension: ".txt",
567
+ benignBytes: Buffer.from("a perfectly ordinary review of the product", "utf8"),
568
+ // Hostile: a bidi override (U+202E RTLO) embedded mid-string — strict
569
+ // profile refuses; CVE-2021-42574 Trojan Source. Built from a numeric
570
+ // codepoint so this source stays pure ASCII.
571
+ hostileBytes: Buffer.from("ok " + String.fromCharCode(0x202E) + "danger", "utf8"),
572
+ });
573
+
574
+ // Assembled from the gate-contract guard factory: error class, registry
575
+ // exports (NAME / KIND / MIME_TYPES / EXTENSIONS / INTEGRATION_FIXTURES),
576
+ // buildProfile / compliancePosture / loadRulePack wiring, plus the per-guard
577
+ // inspection surface (validate / sanitize / gate). The bespoke `gate` carries
578
+ // the text sanitize-then-refuse chain (confusables are non-repairable).
579
+ module.exports = gateContract.defineGuard({
580
+ name: "text",
581
+ kind: "content",
582
+ errorClass: GuardTextError,
583
+ profiles: PROFILES,
584
+ defaults: DEFAULTS,
585
+ postures: COMPLIANCE_POSTURES,
586
+ mimeTypes: ["text/plain"],
587
+ extensions: [".txt"],
588
+ integrationFixtures: INTEGRATION_FIXTURES,
589
+ validate: validate,
590
+ sanitize: sanitize,
591
+ gate: gate,
592
+ });