@blamejs/blamejs-shop 0.4.30 → 0.4.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (338) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/checkout.js +8 -0
  4. package/lib/order.js +71 -11
  5. package/lib/vendor/MANIFEST.json +392 -278
  6. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  7. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  8. package/lib/vendor/blamejs/.gitignore +6 -0
  9. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  10. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  11. package/lib/vendor/blamejs/README.md +8 -6
  12. package/lib/vendor/blamejs/SECURITY.md +19 -3
  13. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  14. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  15. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  16. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  17. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  18. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  19. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  20. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  21. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  22. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  23. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  24. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  25. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  26. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  27. package/lib/vendor/blamejs/index.js +4 -0
  28. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  29. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  30. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  31. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  32. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  33. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  34. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  35. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  36. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  37. package/lib/vendor/blamejs/lib/audit.js +259 -123
  38. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
  39. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  40. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  41. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
  42. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  43. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  44. package/lib/vendor/blamejs/lib/cache.js +174 -105
  45. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  46. package/lib/vendor/blamejs/lib/cli.js +19 -14
  47. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  48. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  49. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  50. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  51. package/lib/vendor/blamejs/lib/compliance.js +206 -4
  52. package/lib/vendor/blamejs/lib/consent.js +82 -29
  53. package/lib/vendor/blamejs/lib/constants.js +27 -11
  54. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  55. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  56. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  57. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  58. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  59. package/lib/vendor/blamejs/lib/db.js +249 -99
  60. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  61. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  62. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  63. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  64. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  65. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  66. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  67. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  68. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  69. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  70. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  71. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  72. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  73. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  74. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  75. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  76. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  77. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  78. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  79. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  80. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  81. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  82. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  83. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  84. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  85. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  86. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  87. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  88. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  89. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  90. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  91. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  92. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  93. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  94. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  95. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  96. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  97. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  98. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  99. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  100. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  101. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  102. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  103. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  104. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  106. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  107. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  108. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  109. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  110. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  111. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  112. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  113. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  114. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  115. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  116. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  117. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  118. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  119. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  120. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  121. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  122. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  123. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  124. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  125. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  126. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  128. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  129. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  131. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  132. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  133. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  134. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  135. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  136. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  137. package/lib/vendor/blamejs/lib/mail.js +8 -4
  138. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  139. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  140. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  141. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  142. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  143. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  144. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  145. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  146. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  147. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  148. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  149. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  150. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  151. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  152. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  153. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  154. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  155. package/lib/vendor/blamejs/lib/observability.js +124 -0
  156. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  157. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  158. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  159. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  160. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  161. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  162. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  163. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  164. package/lib/vendor/blamejs/lib/queue.js +7 -0
  165. package/lib/vendor/blamejs/lib/redact.js +68 -11
  166. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  167. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  168. package/lib/vendor/blamejs/lib/retention.js +101 -40
  169. package/lib/vendor/blamejs/lib/router.js +212 -5
  170. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  171. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  172. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  173. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  174. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  175. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  176. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  177. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  178. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  179. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  180. package/lib/vendor/blamejs/lib/session.js +175 -77
  181. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  182. package/lib/vendor/blamejs/lib/sse.js +26 -0
  183. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  184. package/lib/vendor/blamejs/lib/static.js +177 -34
  185. package/lib/vendor/blamejs/lib/subject.js +96 -49
  186. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  187. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  188. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  189. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  190. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  191. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  192. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  193. package/lib/vendor/blamejs/package.json +2 -2
  194. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  200. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  201. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  202. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  203. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  204. package/lib/vendor/blamejs/scripts/release.js +398 -38
  205. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  206. package/lib/vendor/blamejs/test/10-state.js +140 -14
  207. package/lib/vendor/blamejs/test/20-db.js +65 -2
  208. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  209. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  210. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  211. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  212. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  213. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  214. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  215. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  220. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  221. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  222. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  223. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  224. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  225. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  226. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  227. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  228. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  229. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  230. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  231. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  232. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  233. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  234. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  235. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  236. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  237. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  238. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  240. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  248. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  249. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  250. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  251. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  256. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  258. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  270. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  271. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  272. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  273. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  274. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  275. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  277. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  278. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  279. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  280. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  284. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  285. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  291. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  293. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  302. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  304. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  308. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  310. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  311. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  312. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  313. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  314. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  315. package/lib/vendor/blamejs/test/smoke.js +79 -21
  316. package/package.json +1 -1
  317. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  318. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  319. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  320. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  321. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  322. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  323. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  324. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  325. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  326. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  327. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  328. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  329. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  330. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  331. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  332. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  334. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  335. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  336. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  337. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  338. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -0,0 +1,19 @@
1
+ # TLS terminator in front of LocalStack. LocalStack has no supported way to
2
+ # present a cert chaining to our test CA on its own :4566 listener, so Caddy
3
+ # terminates TLS with the CA-issued localstack leaf and reverse-proxies to
4
+ # LocalStack over the internal compose network. The framework's AWS clients
5
+ # (CloudWatch Logs, SQS) connect here and verify the cert against the test CA
6
+ # via NODE_EXTRA_CA_CERTS — no rejectUnauthorized:false.
7
+ #
8
+ # LocalStack does not verify SigV4 signatures (it ignores the secret key), so
9
+ # the Host header it receives is irrelevant to auth; reverse_proxy's defaults
10
+ # pass X-Amz-Target / Authorization / Content-Type through verbatim.
11
+
12
+ {
13
+ auto_https off
14
+ }
15
+
16
+ :4566 {
17
+ tls /certs/localstack.crt /certs/localstack.key
18
+ reverse_proxy localstack:4566
19
+ }
@@ -39,7 +39,7 @@ fi
39
39
 
40
40
  # Service list — each gets a leaf cert covering the docker-network
41
41
  # hostname, the host-bind 127.0.0.1 / [::1], and localhost.
42
- SERVICES="redis postgres mysql mongo minio rabbitmq nats syslog mailpit haproxy caddy nginx mitmproxy squid coredns"
42
+ SERVICES="redis postgres mysql mongo minio rabbitmq nats syslog mailpit haproxy caddy nginx mitmproxy squid coredns azurite gcs otel localstack"
43
43
 
44
44
  for SVC in $SERVICES; do
45
45
  if [ -f "$CERT_DIR/$SVC.crt" ]; then
@@ -0,0 +1,42 @@
1
+ # Test-only OpenTelemetry Collector (contrib). Receives the framework's
2
+ # OTLP/HTTP log export over TLS (the stack's test CA) and writes every
3
+ # received batch to a host-readable NDJSON file so a test can read it back
4
+ # and assert that secrets / PII were redacted before egress.
5
+ #
6
+ # The framework posts to <base>:4318/v1/logs (OTLP HTTP, JSON). With only
7
+ # cert_file/key_file set (no client_ca_file) the receiver does server-side
8
+ # TLS, not mTLS — the client just needs to trust the CA via
9
+ # NODE_EXTRA_CA_CERTS, with no rejectUnauthorized:false.
10
+
11
+ extensions:
12
+ health_check:
13
+ endpoint: 0.0.0.0:13133
14
+
15
+ receivers:
16
+ otlp:
17
+ protocols:
18
+ http:
19
+ endpoint: 0.0.0.0:4318
20
+ tls:
21
+ cert_file: /certs/otel.crt
22
+ key_file: /certs/otel.key
23
+
24
+ exporters:
25
+ # One OTLP ExportLogsServiceRequest as JSON per line (NDJSON). append:false
26
+ # is the default, so the file is truncated on start — each stack run gets a
27
+ # clean file. create_directory makes the collector materialize the path
28
+ # inside the mounted volume.
29
+ file:
30
+ path: /export/otlp-logs.json
31
+ format: json
32
+ create_directory: true
33
+ # Mirror to stderr at full fidelity for interactive debugging.
34
+ debug:
35
+ verbosity: detailed
36
+
37
+ service:
38
+ extensions: [health_check]
39
+ pipelines:
40
+ logs:
41
+ receivers: [otlp]
42
+ exporters: [file, debug]
File without changes
@@ -0,0 +1,15 @@
1
+ #!/bin/sh
2
+ # Primary-side initdb hook. Allows streaming replication and client
3
+ # connections from the docker bridge subnets so the standby can base-back-up
4
+ # and stream, and so integration tests reach the server over the compose
5
+ # network. Appended during initdb; the real server starts afterward and reads
6
+ # the full file (no reload needed). Test-only: the network is loopback-isolated
7
+ # (host ports bound to 127.0.0.1 / ::1), so trust is acceptable for the fixture.
8
+ cat >> "$PGDATA/pg_hba.conf" <<'EOF'
9
+
10
+ # --- blamejs test stack: replication + bridge-network access ---
11
+ host replication all 172.30.0.0/16 trust
12
+ host replication all fd00:dead:beef::/48 trust
13
+ host all all 172.30.0.0/16 trust
14
+ host all all fd00:dead:beef::/48 trust
15
+ EOF
@@ -0,0 +1,38 @@
1
+ #!/bin/sh
2
+ # Postgres hot-standby replica. On first boot (empty data dir) base-back-up
3
+ # from the primary with -R (writes standby.signal + primary_conninfo);
4
+ # thereafter just start and stream. Serves TLS with the same test-CA leaf as
5
+ # the primary so the framework's read-replica client verifies it against the
6
+ # CA with no rejectUnauthorized:false.
7
+
8
+ set -eu
9
+
10
+ # Certs into a postgres-owned location with the strict perms the server wants
11
+ # (same shape as the primary's init-tls.sh).
12
+ mkdir -p /var/lib/postgresql/certs
13
+ cp /certs/postgres.crt /var/lib/postgresql/certs/server.crt
14
+ cp /certs/postgres.key /var/lib/postgresql/certs/server.key
15
+ cp /certs/ca.crt /var/lib/postgresql/certs/root.crt
16
+ chown -R postgres:postgres /var/lib/postgresql/certs
17
+ chmod 600 /var/lib/postgresql/certs/server.key
18
+ chmod 644 /var/lib/postgresql/certs/server.crt /var/lib/postgresql/certs/root.crt
19
+
20
+ PGDATA="${PGDATA:-/var/lib/postgresql/18/docker}"
21
+
22
+ if [ ! -s "$PGDATA/PG_VERSION" ]; then
23
+ echo "[replica] empty data dir — waiting for primary, then base-backing up..."
24
+ mkdir -p "$PGDATA"
25
+ until pg_isready -h postgres -p 5432 -U blamejs >/dev/null 2>&1; do
26
+ echo "[replica] primary not ready yet..."
27
+ sleep 2
28
+ done
29
+ # Replication is trust-authed from the bridge subnet (initdb hook), so no
30
+ # password is needed. -R writes standby.signal + primary_conninfo; -Xs
31
+ # streams WAL during the backup so the standby is consistent on start.
32
+ pg_basebackup -h postgres -p 5432 -U blamejs -D "$PGDATA" -Fp -Xs -R -P
33
+ chown -R postgres:postgres "$PGDATA"
34
+ chmod 700 "$PGDATA"
35
+ echo "[replica] base backup complete — starting as hot standby."
36
+ fi
37
+
38
+ exec docker-entrypoint.sh postgres -c config_file=/etc/postgresql/postgresql.conf
@@ -0,0 +1,14 @@
1
+ [
2
+ {
3
+ "name": "redis",
4
+ "listen": "[::]:16379",
5
+ "upstream": "redis:6379",
6
+ "enabled": true
7
+ },
8
+ {
9
+ "name": "postgres",
10
+ "listen": "[::]:15432",
11
+ "upstream": "postgres:5432",
12
+ "enabled": true
13
+ }
14
+ ]
@@ -79,6 +79,7 @@ services:
79
79
  - certs:/certs:ro
80
80
  - ./docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro
81
81
  - ./docker/postgres/init-tls.sh:/init-tls.sh:ro
82
+ - ./docker/postgres/initdb/10-replication.sh:/docker-entrypoint-initdb.d/10-replication.sh:ro
82
83
  - blamejs_test_pgdata:/var/lib/postgresql
83
84
  entrypoint:
84
85
  - "/bin/sh"
@@ -534,9 +535,217 @@ services:
534
535
  start_period: 60s
535
536
  restart: unless-stopped
536
537
 
538
+ # Azure Blob Storage emulator (blob service only), HTTPS via the test CA.
539
+ # Path-style account placement: blob URLs are
540
+ # https://<host>:10000/<account>/<container>/<blob> with the account in the
541
+ # PATH, not the host (unlike production <account>.blob.core.windows.net).
542
+ # The client uses endpoint=https://127.0.0.1:10000 with account
543
+ # devstoreaccount1 + the well-known emulator key. node:alpine image has no
544
+ # wget/curl and busybox sh lacks /dev/tcp, so the host-side checker probes
545
+ # :10000 (Azurite answers 400 on an unauthenticated GET, which is "up").
546
+ azurite:
547
+ image: mcr.microsoft.com/azure-storage/azurite:3.35.0
548
+ container_name: blamejs-test-azurite
549
+ ports:
550
+ - "127.0.0.1:10000:10000"
551
+ - "[::1]:10000:10000"
552
+ volumes:
553
+ - certs:/certs:ro
554
+ - blamejs_test_azuritedata:/data
555
+ command:
556
+ - "azurite-blob"
557
+ # Bind dual-stack (::) so both the IPv4 and IPv6 host-port mappings
558
+ # reach a listening socket — 0.0.0.0 is IPv4-only and the network's
559
+ # IPv6 publish path resets.
560
+ - "--blobHost"
561
+ - "::"
562
+ - "--blobPort"
563
+ - "10000"
564
+ - "--location"
565
+ - "/data"
566
+ - "--cert"
567
+ - "/certs/azurite.crt"
568
+ - "--key"
569
+ - "/certs/azurite.key"
570
+ - "--skipApiVersionCheck"
571
+ depends_on:
572
+ pki-init:
573
+ condition: service_completed_successfully
574
+ healthcheck:
575
+ disable: true
576
+ restart: unless-stopped
577
+
578
+ # Google Cloud Storage emulator, HTTPS via the test CA (loads our leaf via
579
+ # -cert-location/-private-key-location). In-memory backend; tests create
580
+ # buckets at setup. public-host must equal the client's connect authority
581
+ # so the XML/V4 routes match. fake-gcs-server does NOT verify the bearer
582
+ # token or V4 signature — the live test proves wire/URL/marshalling +
583
+ # TLS-trust, not signature correctness (that stays a unit-vector concern).
584
+ # scratch image (no shell) → host-side probe of /_internal/healthcheck.
585
+ fake-gcs:
586
+ image: fsouza/fake-gcs-server:1.54.0
587
+ container_name: blamejs-test-gcs
588
+ ports:
589
+ - "127.0.0.1:4443:4443"
590
+ - "[::1]:4443:4443"
591
+ volumes:
592
+ - certs:/certs:ro
593
+ command:
594
+ - "-scheme=https"
595
+ - "-host=0.0.0.0"
596
+ - "-port=4443"
597
+ - "-cert-location=/certs/gcs.crt"
598
+ - "-private-key-location=/certs/gcs.key"
599
+ - "-public-host=127.0.0.1:4443"
600
+ - "-external-url=https://127.0.0.1:4443"
601
+ - "-backend=memory"
602
+ depends_on:
603
+ pki-init:
604
+ condition: service_completed_successfully
605
+ healthcheck:
606
+ disable: true
607
+ restart: unless-stopped
608
+
609
+ # OpenTelemetry Collector (contrib) — receives OTLP/HTTP logs over TLS (test
610
+ # CA) on :4318/v1/logs and writes each received batch as NDJSON to
611
+ # ./docker/otel/export/otlp-logs.json so a test can read it back and assert
612
+ # secrets/PII were redacted before egress. scratch image (no shell) →
613
+ # host-side probe of the health_check extension on :13133.
614
+ otel-collector:
615
+ image: otel/opentelemetry-collector-contrib:0.153.0
616
+ container_name: blamejs-test-otel-collector
617
+ ports:
618
+ - "127.0.0.1:4318:4318"
619
+ - "[::1]:4318:4318"
620
+ - "127.0.0.1:13133:13133"
621
+ - "[::1]:13133:13133"
622
+ command: ["--config=/etc/otel/config.yaml"]
623
+ volumes:
624
+ - certs:/certs:ro
625
+ - ./docker/otel/config.yaml:/etc/otel/config.yaml:ro
626
+ - ./docker/otel/export:/export
627
+ depends_on:
628
+ pki-init:
629
+ condition: service_completed_successfully
630
+ healthcheck:
631
+ disable: true
632
+ restart: unless-stopped
633
+
634
+ # AWS emulator (CloudWatch Logs + SQS) for the cloudwatch log sink and the
635
+ # SQS queue backend. LocalStack stays plain HTTP on the internal network;
636
+ # the localstack-tls sidecar terminates TLS with the test CA so the client
637
+ # verifies the cert with no rejectUnauthorized:false. LocalStack does NOT
638
+ # verify SigV4 signatures (it ignores the secret key) — the live test proves
639
+ # request shape + sequence-token flow + read-back + redaction, not signature
640
+ # correctness. Image ships curl, so the readiness check is in-container.
641
+ localstack:
642
+ # Pinned to the last pre-unification semver. From 2026.03 (CalVer) the
643
+ # unified localstack/localstack image is Pro-gated and exits without a
644
+ # license token even with ACTIVATE_PRO=0; 4.14.0 is the community line and
645
+ # boots free. CloudWatch Logs + SQS are stable community services.
646
+ image: localstack/localstack:4.14.0
647
+ container_name: blamejs-test-localstack
648
+ environment:
649
+ ACTIVATE_PRO: "0"
650
+ SERVICES: "logs,sqs"
651
+ EAGER_SERVICE_LOADING: "1"
652
+ GATEWAY_LISTEN: "0.0.0.0:4566"
653
+ expose:
654
+ - "4566"
655
+ healthcheck:
656
+ test: ["CMD-SHELL", "curl -fsS http://localhost:4566/_localstack/health | grep -q '\"logs\"'"]
657
+ interval: 5s
658
+ timeout: 5s
659
+ retries: 30
660
+ start_period: 40s
661
+ restart: unless-stopped
662
+
663
+ localstack-tls:
664
+ image: caddy:2-alpine
665
+ container_name: blamejs-test-localstack-tls
666
+ ports:
667
+ - "127.0.0.1:4566:4566"
668
+ - "[::1]:4566:4566"
669
+ volumes:
670
+ - certs:/certs:ro
671
+ - ./docker/caddy/localstack.Caddyfile:/etc/caddy/Caddyfile:ro
672
+ depends_on:
673
+ pki-init:
674
+ condition: service_completed_successfully
675
+ localstack:
676
+ condition: service_healthy
677
+ healthcheck:
678
+ disable: true
679
+ restart: unless-stopped
680
+
681
+ # Postgres hot-standby streaming replica of the primary, so tests can prove
682
+ # read-replica routing (b.externalDb.read.query) against a real standby and
683
+ # that crypto-shred residual ciphertext is gone from the replica too. First
684
+ # boot base-backs-up from the primary (replica-entrypoint.sh); serves TLS on
685
+ # 5433 with the same test-CA leaf as the primary.
686
+ postgres-replica:
687
+ image: postgres:18-alpine
688
+ container_name: blamejs-test-postgres-replica
689
+ ports:
690
+ - "127.0.0.1:5433:5432"
691
+ - "[::1]:5433:5432"
692
+ environment:
693
+ POSTGRES_USER: blamejs
694
+ POSTGRES_PASSWORD: blamejs_test
695
+ POSTGRES_DB: blamejs_test
696
+ PGDATA: /var/lib/postgresql/18/docker
697
+ volumes:
698
+ - certs:/certs:ro
699
+ - ./docker/postgres/postgresql.conf:/etc/postgresql/postgresql.conf:ro
700
+ - ./docker/postgres/replica-entrypoint.sh:/replica-entrypoint.sh:ro
701
+ - blamejs_test_pgreplicadata:/var/lib/postgresql
702
+ entrypoint: ["/bin/sh", "/replica-entrypoint.sh"]
703
+ depends_on:
704
+ pki-init:
705
+ condition: service_completed_successfully
706
+ postgres:
707
+ condition: service_healthy
708
+ healthcheck:
709
+ test: ["CMD-SHELL", "pg_isready -U blamejs -d blamejs_test"]
710
+ interval: 5s
711
+ timeout: 3s
712
+ retries: 20
713
+ start_period: 25s
714
+ restart: unless-stopped
715
+
716
+ # TCP fault-injection proxy in front of redis + postgres so tests can prove
717
+ # the framework's reconnect / failover behavior against a real backend that
718
+ # is made to drop, reset, or slow mid-connection (via the toxiproxy API on
719
+ # :8474). Transparent passthrough until a toxic is added, so the proxied
720
+ # ports speak the backend protocol verbatim. scratch image (no shell) →
721
+ # host-side probe. Bound dual-stack so both loopback families reach it.
722
+ toxiproxy:
723
+ image: ghcr.io/shopify/toxiproxy:2.12.0
724
+ container_name: blamejs-test-toxiproxy
725
+ command: ["-host=::", "-config=/config/toxiproxy.json"]
726
+ ports:
727
+ - "127.0.0.1:8474:8474"
728
+ - "[::1]:8474:8474"
729
+ - "127.0.0.1:16379:16379"
730
+ - "[::1]:16379:16379"
731
+ - "127.0.0.1:15432:15432"
732
+ - "[::1]:15432:15432"
733
+ volumes:
734
+ - ./docker/toxiproxy/toxiproxy.json:/config/toxiproxy.json:ro
735
+ depends_on:
736
+ redis:
737
+ condition: service_healthy
738
+ postgres:
739
+ condition: service_healthy
740
+ healthcheck:
741
+ disable: true
742
+ restart: unless-stopped
743
+
537
744
  volumes:
538
745
  certs:
746
+ blamejs_test_azuritedata:
539
747
  blamejs_test_pgdata:
748
+ blamejs_test_pgreplicadata:
540
749
  blamejs_test_mysqldata:
541
750
  blamejs_test_mongodata:
542
751
  blamejs_test_miniodata:
@@ -236,6 +236,85 @@ function _renderPrimitive(prim, resolveRelated) {
236
236
  });
237
237
  }
238
238
 
239
+ // Resolve the @since to stamp on a factory namespace's synthesized ABI
240
+ // sections: the guard's @module @since wins; else the earliest @since
241
+ // across the file's real @primitive blocks; else "0.7.5" (the
242
+ // gate-contract guard family's introduction version) so the validator's
243
+ // semver gate is satisfied.
244
+ function _factorySince(rec) {
245
+ if (rec.module && rec.module.tags && rec.module.tags.since) {
246
+ return rec.module.tags.since;
247
+ }
248
+ var earliest = null;
249
+ (rec.primitives || []).forEach(function (p) {
250
+ var s = p.tags && p.tags.since;
251
+ if (s && (!earliest || _semverLt(s, earliest))) earliest = s;
252
+ });
253
+ return earliest || "0.7.5";
254
+ }
255
+
256
+ // Numeric-segment semver compare (a < b). Pre-release suffixes are
257
+ // ignored — the @since values in lib/ are release versions.
258
+ function _semverLt(a, b) {
259
+ var pa = String(a).split("-")[0].split(".").map(function (n) { return parseInt(n, 10) || 0; });
260
+ var pb = String(b).split("-")[0].split(".").map(function (n) { return parseInt(n, 10) || 0; });
261
+ for (var i = 0; i < 3; i++) {
262
+ var da = pa[i] || 0, db = pb[i] || 0;
263
+ if (da !== db) return da < db;
264
+ }
265
+ return false;
266
+ }
267
+
268
+ // Substitute the ABI template placeholders in a single string:
269
+ // {NS} → the guard namespace (e.g. guardCsv)
270
+ // {ERR} → its error class (e.g. GuardCsvError)
271
+ // {CODE} → its error-code prefix (e.g. csv) — the stem in thrown codes
272
+ // ("csv.bad-posture"), which differs from the namespace.
273
+ // {ERR} / {CODE} fall back to honest phrasing when the parser couldn't
274
+ // resolve them (rather than emitting a literal "{ERR}" / "{CODE}").
275
+ function _subAbi(text, ns, errClass, codePrefix) {
276
+ if (text == null) return text;
277
+ var err = errClass || "the guard's error class";
278
+ var code = codePrefix || ns;
279
+ return String(text)
280
+ .replace(/\{NS\}/g, ns)
281
+ .replace(/\{ERR\}/g, err)
282
+ .replace(/\{CODE\}/g, code);
283
+ }
284
+
285
+ // Turn an @abiTemplate record into a synthetic primitive record shaped
286
+ // exactly like parseBlock's output, so it flows through _renderPrimitive
287
+ // + the per-namespace ordering unchanged. {NS} -> ns, {ERR} -> error
288
+ // class, {CODE} -> error-code prefix, @since filled from the owning guard.
289
+ function _instantiateAbiTemplate(tpl, ns, errClass, codePrefix, since) {
290
+ var tags = tpl.tags || {};
291
+ var method = tags.method;
292
+ var newTags = {
293
+ primitive: "b." + ns + "." + method,
294
+ signature: _subAbi(tags.signature, ns, errClass, codePrefix),
295
+ since: since,
296
+ status: tags.status || "stable",
297
+ };
298
+ if (tags.compliance) newTags.compliance = tags.compliance;
299
+ if (tags.related) newTags.related = _subAbi(tags.related, ns, errClass, codePrefix);
300
+ if (tags.opts != null) newTags.opts = _subAbi(tags.opts, ns, errClass, codePrefix);
301
+ if (Array.isArray(tags.examples)) {
302
+ newTags.examples = tags.examples.map(function (ex) { return _subAbi(ex, ns, errClass, codePrefix); });
303
+ }
304
+ return {
305
+ kind: "primitive",
306
+ tags: newTags,
307
+ prose: _subAbi(tpl.prose, ns, errClass, codePrefix),
308
+ // Synthetic blocks are well-formed by construction; carry the same
309
+ // ordering/mixed-kind flags parseBlock sets on a clean block.
310
+ proseAfterMultiLine: false,
311
+ mixedKind: null,
312
+ // Marker so downstream tooling can distinguish a synthesized ABI
313
+ // section from a hand-authored @primitive block.
314
+ abiSynthesized: true,
315
+ };
316
+ }
317
+
239
318
  // Build a generated page object.
240
319
  //
241
320
  // pageSpec: {
@@ -261,12 +340,33 @@ function generatePage(pageSpec, docsByPath, resolveRelated) {
261
340
  // Group primitives by namespace, drop hidden ones.
262
341
  var byNs = {};
263
342
  var moduleByNs = {};
343
+ // Map ns → owning factory record + the @since to stamp on synthetic
344
+ // ABI-method sections. The factory lives on the file record; ns is the
345
+ // file's @module namespace.
346
+ var factoryByNs = {};
264
347
  var paths = Object.keys(docsByPath);
265
348
  for (var p = 0; p < paths.length; p++) {
266
349
  var rec = docsByPath[paths[p]];
350
+ var fileNs = null;
267
351
  if (rec.module && rec.module.tags && rec.module.tags.module) {
268
352
  var modSig = rec.module.tags.module.replace(/^\s*b\./, "");
269
353
  moduleByNs[modSig] = rec.module;
354
+ fileNs = modSig;
355
+ }
356
+ if (rec.factory) {
357
+ // Resolve the @since once per factory namespace: the guard's
358
+ // @module @since wins; else the earliest primitive's @since; else
359
+ // a conservative fallback the validator accepts.
360
+ var nsForFactory = fileNs;
361
+ if (!nsForFactory && rec.primitives.length > 0) {
362
+ nsForFactory = _nsOf((rec.primitives[0].tags && rec.primitives[0].tags.primitive) || "");
363
+ }
364
+ if (nsForFactory) {
365
+ factoryByNs[nsForFactory] = {
366
+ factory: rec.factory,
367
+ since: _factorySince(rec),
368
+ };
369
+ }
270
370
  }
271
371
  for (var i = 0; i < rec.primitives.length; i++) {
272
372
  var prim = rec.primitives[i];
@@ -282,6 +382,38 @@ function generatePage(pageSpec, docsByPath, resolveRelated) {
282
382
  }
283
383
  }
284
384
 
385
+ // ---- Synthesize per-guard ABI-method sections from @abiTemplate ----
386
+ // For each namespace whose owning file is a defineGuard / defineParser
387
+ // factory call, instantiate the matching factory's ABI doc templates —
388
+ // substituting the namespace + error class + @since — and append them
389
+ // to byNs[ns]. The de-duplication is SOURCE-only: the prose lives once
390
+ // (in gate-contract.js's @abiTemplate blocks), but every guard's page
391
+ // still lists every ABI method it exposes. A method already documented
392
+ // by a real per-guard @primitive block (a bespoke gate, or a guard that
393
+ // kept its own compliancePosture) is skipped so the real block wins.
394
+ var templates = parser.factoryTemplates(docsByPath);
395
+ Object.keys(byNs).forEach(function (ns) {
396
+ var fb = factoryByNs[ns];
397
+ if (!fb) return;
398
+ var kindTemplates = templates[fb.factory.kind] || [];
399
+ // Methods already documented by a real per-guard block on this page.
400
+ var documented = {};
401
+ byNs[ns].forEach(function (pr) {
402
+ var sig = (pr.tags && pr.tags.primitive) || "";
403
+ var method = String(sig).replace(/^b\./, "").split(".").pop();
404
+ if (method) documented[method] = true;
405
+ });
406
+ kindTemplates.forEach(function (tpl) {
407
+ var method = tpl.tags && tpl.tags.method;
408
+ if (!method) return;
409
+ if (documented[method]) return; // real block wins; skip template
410
+ if (hiddenSet["b." + ns + "." + method]) return;
411
+ var synth = _instantiateAbiTemplate(tpl, ns, fb.factory.errorClass, fb.factory.codePrefix, fb.since);
412
+ byNs[ns].push(synth);
413
+ documented[method] = true; // guard against duplicate templates
414
+ });
415
+ });
416
+
285
417
  // Order primitives within each namespace: explicit `order` first, then
286
418
  // the rest in source order.
287
419
  var orderIdx = {};