@blamejs/blamejs-shop 0.4.31 → 0.4.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (336) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/lib/asset-manifest.json +1 -1
  3. package/lib/vendor/MANIFEST.json +392 -278
  4. package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
  5. package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
  6. package/lib/vendor/blamejs/.gitignore +6 -0
  7. package/lib/vendor/blamejs/CHANGELOG.md +26 -0
  8. package/lib/vendor/blamejs/MIGRATING.md +43 -0
  9. package/lib/vendor/blamejs/README.md +8 -6
  10. package/lib/vendor/blamejs/SECURITY.md +19 -3
  11. package/lib/vendor/blamejs/api-snapshot.json +2190 -664
  12. package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
  13. package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
  14. package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
  15. package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
  16. package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
  17. package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
  18. package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
  19. package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
  20. package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
  21. package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
  22. package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
  23. package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
  24. package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
  25. package/lib/vendor/blamejs/index.js +4 -0
  26. package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
  27. package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
  28. package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
  29. package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
  30. package/lib/vendor/blamejs/lib/api-key.js +158 -77
  31. package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
  32. package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
  33. package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
  34. package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
  35. package/lib/vendor/blamejs/lib/audit.js +259 -123
  36. package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
  37. package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
  38. package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
  39. package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
  40. package/lib/vendor/blamejs/lib/backup/index.js +45 -10
  41. package/lib/vendor/blamejs/lib/break-glass.js +355 -147
  42. package/lib/vendor/blamejs/lib/cache.js +174 -105
  43. package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
  44. package/lib/vendor/blamejs/lib/cli.js +19 -14
  45. package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
  46. package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
  47. package/lib/vendor/blamejs/lib/cluster.js +119 -71
  48. package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
  49. package/lib/vendor/blamejs/lib/compliance.js +206 -4
  50. package/lib/vendor/blamejs/lib/consent.js +82 -29
  51. package/lib/vendor/blamejs/lib/constants.js +27 -11
  52. package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
  53. package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
  54. package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
  55. package/lib/vendor/blamejs/lib/db-query.js +882 -260
  56. package/lib/vendor/blamejs/lib/db-schema.js +228 -44
  57. package/lib/vendor/blamejs/lib/db.js +249 -99
  58. package/lib/vendor/blamejs/lib/dsr.js +385 -55
  59. package/lib/vendor/blamejs/lib/error-page.js +14 -1
  60. package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
  61. package/lib/vendor/blamejs/lib/external-db.js +549 -34
  62. package/lib/vendor/blamejs/lib/file-upload.js +52 -7
  63. package/lib/vendor/blamejs/lib/framework-error.js +20 -1
  64. package/lib/vendor/blamejs/lib/framework-files.js +73 -0
  65. package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
  66. package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
  67. package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
  68. package/lib/vendor/blamejs/lib/guard-all.js +1 -0
  69. package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
  70. package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
  71. package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
  72. package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
  73. package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
  74. package/lib/vendor/blamejs/lib/guard-email.js +47 -69
  75. package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
  76. package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
  77. package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
  78. package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
  79. package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
  80. package/lib/vendor/blamejs/lib/guard-html.js +53 -108
  81. package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
  82. package/lib/vendor/blamejs/lib/guard-image.js +46 -103
  83. package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
  84. package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
  85. package/lib/vendor/blamejs/lib/guard-json.js +38 -108
  86. package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
  87. package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
  88. package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
  89. package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
  90. package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
  91. package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
  92. package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
  93. package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
  94. package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
  95. package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
  96. package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
  97. package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
  98. package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
  99. package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
  100. package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
  101. package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
  102. package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
  103. package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
  104. package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
  105. package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
  106. package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
  107. package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
  108. package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
  109. package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
  110. package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
  111. package/lib/vendor/blamejs/lib/guard-template.js +35 -172
  112. package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
  113. package/lib/vendor/blamejs/lib/guard-time.js +32 -154
  114. package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
  115. package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
  116. package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
  117. package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
  118. package/lib/vendor/blamejs/lib/http-client.js +37 -9
  119. package/lib/vendor/blamejs/lib/inbox.js +120 -107
  120. package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
  121. package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
  122. package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
  123. package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
  124. package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
  125. package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
  126. package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
  127. package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
  128. package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
  129. package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
  130. package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
  131. package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
  132. package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
  133. package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
  134. package/lib/vendor/blamejs/lib/mail-store.js +293 -154
  135. package/lib/vendor/blamejs/lib/mail.js +8 -4
  136. package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
  137. package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
  138. package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
  139. package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
  140. package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
  141. package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
  142. package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
  143. package/lib/vendor/blamejs/lib/migrations.js +108 -66
  144. package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
  145. package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
  146. package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
  147. package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
  148. package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
  149. package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
  150. package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
  151. package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
  152. package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
  153. package/lib/vendor/blamejs/lib/observability.js +124 -0
  154. package/lib/vendor/blamejs/lib/otel-export.js +12 -3
  155. package/lib/vendor/blamejs/lib/outbox.js +184 -83
  156. package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
  157. package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
  158. package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
  159. package/lib/vendor/blamejs/lib/queue-local.js +225 -140
  160. package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
  161. package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
  162. package/lib/vendor/blamejs/lib/queue.js +7 -0
  163. package/lib/vendor/blamejs/lib/redact.js +68 -11
  164. package/lib/vendor/blamejs/lib/redis-client.js +160 -31
  165. package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
  166. package/lib/vendor/blamejs/lib/retention.js +101 -40
  167. package/lib/vendor/blamejs/lib/router.js +212 -5
  168. package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
  169. package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
  170. package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
  171. package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
  172. package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
  173. package/lib/vendor/blamejs/lib/safe-url.js +170 -3
  174. package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
  175. package/lib/vendor/blamejs/lib/scheduler.js +35 -12
  176. package/lib/vendor/blamejs/lib/seeders.js +122 -74
  177. package/lib/vendor/blamejs/lib/session-stores.js +42 -14
  178. package/lib/vendor/blamejs/lib/session.js +175 -77
  179. package/lib/vendor/blamejs/lib/sql.js +3842 -0
  180. package/lib/vendor/blamejs/lib/sse.js +26 -0
  181. package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
  182. package/lib/vendor/blamejs/lib/static.js +177 -34
  183. package/lib/vendor/blamejs/lib/subject.js +96 -49
  184. package/lib/vendor/blamejs/lib/vault/index.js +3 -2
  185. package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
  186. package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
  187. package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
  188. package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
  189. package/lib/vendor/blamejs/lib/websocket.js +35 -5
  190. package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
  191. package/lib/vendor/blamejs/package.json +2 -2
  192. package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
  193. package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
  194. package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
  195. package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
  196. package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
  197. package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
  198. package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
  199. package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
  200. package/lib/vendor/blamejs/scripts/check-services.js +21 -0
  201. package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
  202. package/lib/vendor/blamejs/scripts/release.js +398 -38
  203. package/lib/vendor/blamejs/test/00-primitives.js +117 -0
  204. package/lib/vendor/blamejs/test/10-state.js +140 -14
  205. package/lib/vendor/blamejs/test/20-db.js +65 -2
  206. package/lib/vendor/blamejs/test/helpers/db.js +9 -0
  207. package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
  208. package/lib/vendor/blamejs/test/helpers/services.js +21 -0
  209. package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
  210. package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
  211. package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
  212. package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
  213. package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
  214. package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
  215. package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
  216. package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
  217. package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
  218. package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
  219. package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
  220. package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
  221. package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
  222. package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
  223. package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
  224. package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
  225. package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
  226. package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
  227. package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
  228. package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
  229. package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
  230. package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
  231. package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
  232. package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
  233. package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
  234. package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
  235. package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
  236. package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
  237. package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
  238. package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
  239. package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
  240. package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
  241. package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
  242. package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
  243. package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
  244. package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
  245. package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
  246. package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
  247. package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
  248. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
  249. package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
  250. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
  251. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
  252. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
  253. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
  254. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
  255. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
  256. package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
  257. package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
  258. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
  259. package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
  260. package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
  261. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
  262. package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
  263. package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
  264. package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
  265. package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
  266. package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
  267. package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
  268. package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
  269. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
  270. package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
  271. package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
  272. package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
  273. package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
  274. package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
  275. package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
  276. package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
  277. package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
  278. package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
  279. package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
  280. package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
  281. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
  282. package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
  283. package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
  284. package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
  285. package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
  286. package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
  287. package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
  288. package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
  289. package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
  290. package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
  291. package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
  292. package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
  293. package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
  294. package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
  295. package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
  296. package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
  297. package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
  298. package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
  299. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
  300. package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
  301. package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
  302. package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
  303. package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
  304. package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
  305. package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
  306. package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
  307. package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
  308. package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
  309. package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
  310. package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
  311. package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
  312. package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
  313. package/lib/vendor/blamejs/test/smoke.js +79 -21
  314. package/package.json +1 -1
  315. package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
  316. package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
  317. package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
  318. package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
  319. package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
  320. package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
  321. package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
  322. package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
  323. package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
  324. package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
  325. package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
  326. package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
  327. package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
  328. package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
  329. package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
  330. package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
  331. package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
  332. package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
  333. package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
  334. package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
  335. package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
  336. package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
@@ -63,17 +63,69 @@ var auditSign = lazyRequire(function () { return require("./audit-sign"); });
63
63
  var ExternalDbMigrateError = defineClass("ExternalDbMigrateError", { alwaysPermanent: true });
64
64
 
65
65
  // Lazy require — external-db imports back into this module via its
66
- // public `migrate` namespace; load-order would cycle without lazy.
66
+ // public `migrate` namespace; load-order would cycle without lazy. The
67
+ // same cycle (external-db -> external-db-migrate -> cluster-storage ->
68
+ // cluster -> cluster-provider-db -> external-db) means clusterStorage +
69
+ // frameworkSchema must be lazy here too, and the table-name constants
70
+ // resolved on first use rather than at module load (frameworkSchema's
71
+ // tableName export is not yet bound while this module evaluates).
67
72
  var externalDb = lazyRequire(function () { return require("./external-db"); });
73
+ var clusterStorage = lazyRequire(function () { return require("./cluster-storage"); });
74
+ var frameworkSchema = lazyRequire(function () { return require("./framework-schema"); });
75
+ var sql = lazyRequire(function () { return require("./sql"); });
76
+
77
+ // The migration runner's own bookkeeping tables, resolved through
78
+ // frameworkSchema so the configurable framework-table prefix is honored
79
+ // (these names are not in the LOCAL_TO_EXTERNAL map, so the resolve only
80
+ // swaps the leading prefix; default prefix is a no-op). b.sql quotes
81
+ // every identifier by construction in the backend's own dialect
82
+ // (double-quote on Postgres / SQLite, backtick on MySQL), with the
83
+ // placeholder form (`$N` on Postgres, `?` on SQLite / MySQL) selected by
84
+ // the resolved backend dialect — see _backendDialect / _bind below.
85
+ function _trackingTable() { return frameworkSchema().tableName("_blamejs_externaldb_migrations"); } // allow:hand-rolled-sql — single canonical logical-name reference
86
+ function _lockTable() { return frameworkSchema().tableName("_blamejs_externaldb_migrations_lock"); } // allow:hand-rolled-sql — single canonical logical-name reference
87
+ function _historyTable() { return frameworkSchema().tableName("_blamejs_schema_version_history"); } // allow:hand-rolled-sql — single canonical logical-name reference
88
+
89
+ // Resolve the SQL dialect of the backend this migration wave targets.
90
+ // The runner emits Postgres / SQLite / MySQL — they diverge on identifier
91
+ // quoting (double-quote vs backtick), the ON CONFLICT / ON DUPLICATE KEY
92
+ // upsert idiom, and placeholder syntax (`$N` vs `?`). Reading the dialect
93
+ // off the backend itself (set at b.externalDb.init) is what keeps the
94
+ // bookkeeping DDL + tracking statements valid on each. Falls back to
95
+ // "postgres" when the backend can't be resolved (uninitialized externalDb
96
+ // surfaces a clearer error upstream at _resolveBackendName); the bare
97
+ // fallback never reaches a real query.
98
+ function _backendDialect(backendName) {
99
+ var listed;
100
+ try { listed = externalDb().listBackends(); }
101
+ catch (_e) { return "postgres"; }
102
+ for (var i = 0; i < listed.length; i++) {
103
+ if (listed[i].name === backendName) {
104
+ return (listed[i].dialect || "postgres").toLowerCase();
105
+ }
106
+ }
107
+ return "postgres";
108
+ }
109
+
110
+ // b.sql emits `?` placeholders; the externalDb driver receives SQL
111
+ // verbatim, so translate to the Postgres `$N` form on a Postgres backend
112
+ // (placeholderize is a passthrough for SQLite / MySQL, which keep `?`).
113
+ // dialect is the resolved backend dialect so the placeholder form matches
114
+ // the backend the SQL dispatches to.
115
+ function _bind(builder, dialect) {
116
+ var built = builder.toSql();
117
+ return { sql: clusterStorage().placeholderize(built.sql, dialect), params: built.params };
118
+ }
68
119
 
69
- var TRACKING_TABLE = "_blamejs_externaldb_migrations";
70
- var LOCK_TABLE = "_blamejs_externaldb_migrations_lock";
71
- var HISTORY_TABLE = "_blamejs_schema_version_history";
72
- // Identifiers wrapped in `"..."` per project convention so a reserved-word
73
- // or whitespace-bearing name resolves correctly.
74
- var Q_TRACKING = '"' + TRACKING_TABLE + '"';
75
- var Q_LOCK = '"' + LOCK_TABLE + '"';
76
- var Q_HISTORY = '"' + HISTORY_TABLE + '"';
120
+ // The migration tracking / history / lock tables hold framework
121
+ // bookkeeping ("migration X ran at time T"), not region-bound personal
122
+ // data, so their writes carry the residency-neutral "unrestricted" tag
123
+ // the per-row residency write gate (b.externalDb.query) refuses DML
124
+ // to a residency-tagged backend under a cross-border regulated posture
125
+ // unless a compatible rowResidencyTag is supplied. Operator migration
126
+ // DML (mod.up) stays subject to the gate; only these internal writes
127
+ // are exempt. Passed as the per-statement opts override on the txClient.
128
+ var FRAMEWORK_METADATA_OPTS = Object.freeze({ rowResidencyTag: "unrestricted" });
77
129
 
78
130
  // Bytes that get signed for one history row. Stable forever — changing
79
131
  // it invalidates every prior signature.
@@ -100,12 +152,11 @@ function _historyPayload(row) {
100
152
  // default introspect just returns the migration name list as a JSON
101
153
  // array, which is enough to detect "someone manually altered the
102
154
  // migrations table."
103
- async function _defaultSchemaIntrospect(xdb) {
104
- var res = await xdb.query(
105
- "SELECT name, appliedAt FROM " + Q_TRACKING +
106
- " ORDER BY appliedAt ASC, name ASC",
107
- []
108
- );
155
+ async function _defaultSchemaIntrospect(xdb, dialect) {
156
+ var q = _bind(sql().select(_trackingTable(), { dialect: dialect })
157
+ .columns(["name", "appliedAt"])
158
+ .orderBy("appliedAt", "asc").orderBy("name", "asc"), dialect);
159
+ var res = await xdb.query(q.sql, q.params);
109
160
  var rows = (res && res.rows) || [];
110
161
  return sha3Hash(Buffer.from(canonicalJson.stringify(rows), "utf8"));
111
162
  }
@@ -139,74 +190,73 @@ function _lockHolderId() {
139
190
  (require("node:os").hostname() || "unknown") + "@" + _BOOT_TOKEN;
140
191
  }
141
192
 
142
- async function _ensureTrackingTable(xdb) {
193
+ async function _ensureTrackingTable(xdb, dialect) {
143
194
  // Tracking table holds the migration history. ISO-8601 timestamp
144
- // strings (TEXT) keep the framework's tracking table portable across
145
- // Postgres/SQLite without dialect-specific type juggling — operators
146
- // who want strict TIMESTAMPTZ for their own ad-hoc queries against
147
- // the table ALTER it post-creation.
148
- await xdb.query(
149
- "CREATE TABLE IF NOT EXISTS " + Q_TRACKING + " (" +
150
- " name TEXT PRIMARY KEY," +
151
- " description TEXT," +
152
- " appliedAt TEXT NOT NULL" +
153
- ")",
154
- []
155
- );
195
+ // strings keep the framework's tracking table portable across
196
+ // Postgres/SQLite/MySQL without dialect-specific type juggling —
197
+ // operators who want strict TIMESTAMPTZ for their own ad-hoc queries
198
+ // against the table ALTER it post-creation. The `name` PK is a bounded
199
+ // VARCHAR, not TEXT: MySQL refuses an unbounded TEXT/BLOB in a key
200
+ // (ER 1170), and a migration filename is length-capped at FILE_NAME_MAX
201
+ // so 255 covers every valid value. Postgres / SQLite treat VARCHAR(255)
202
+ // identically to TEXT for storage.
203
+ await xdb.query(sql().createTable(_trackingTable(), [
204
+ { name: "name", type: "VARCHAR(255)", primaryKey: true },
205
+ { name: "description", type: "TEXT" },
206
+ { name: "appliedAt", type: "TEXT", notNull: true },
207
+ ], { dialect: dialect }).sql, []);
156
208
  }
157
209
 
158
- async function _ensureHistoryTable(xdb) {
210
+ async function _ensureHistoryTable(xdb, dialect) {
159
211
  // Schema-version history table: append-only record of every migrate.up
160
212
  // wave + signature over (version, ranAt, ranBy, schemaIntrospectionHash).
161
213
  // Signature uses ML-DSA-87 / SLH-DSA-SHAKE-256f via b.auditSign — an
162
214
  // attacker tampering with rows after-the-fact cannot forge a matching
163
- // signature without the audit-signing private key.
164
- await xdb.query(
165
- "CREATE TABLE IF NOT EXISTS " + Q_HISTORY + " (" +
166
- " version TEXT NOT NULL," +
167
- " ranAt TEXT NOT NULL," +
168
- " ranBy TEXT NOT NULL," +
169
- " schemaIntrospectionHash TEXT NOT NULL," +
170
- " signature TEXT," +
171
- " publicKeyFingerprint TEXT," +
172
- " PRIMARY KEY (version, ranAt)" +
173
- ")",
174
- []
175
- );
215
+ // signature without the audit-signing private key. version + ranAt form
216
+ // the composite PK, so both are bounded VARCHARs (MySQL refuses an
217
+ // unbounded TEXT/BLOB in a key, ER 1170); version is a filename
218
+ // (length-capped) and ranAt an ISO-8601 string, both within bound.
219
+ await xdb.query(sql().createTable(_historyTable(), [
220
+ { name: "version", type: "VARCHAR(255)", notNull: true },
221
+ { name: "ranAt", type: "VARCHAR(64)", notNull: true },
222
+ { name: "ranBy", type: "TEXT", notNull: true },
223
+ { name: "schemaIntrospectionHash", type: "TEXT", notNull: true },
224
+ { name: "signature", type: "TEXT" },
225
+ { name: "publicKeyFingerprint", type: "TEXT" },
226
+ ], { dialect: dialect, primaryKey: ["version", "ranAt"] }).sql, []);
176
227
  }
177
228
 
178
- async function _writeHistoryRow(xdb, row) {
179
- await xdb.query(
180
- "INSERT INTO " + Q_HISTORY +
181
- " (version, ranAt, ranBy, schemaIntrospectionHash, signature, publicKeyFingerprint) " +
182
- " VALUES ($1, $2, $3, $4, $5, $6)",
183
- [
184
- row.version,
185
- row.ranAt,
186
- row.ranBy,
187
- row.schemaIntrospectionHash,
188
- row.signature,
189
- row.publicKeyFingerprint,
190
- ]
191
- );
229
+ async function _writeHistoryRow(xdb, row, dialect) {
230
+ var q = _bind(sql().insert(_historyTable(), { dialect: dialect }).values({
231
+ version: row.version,
232
+ ranAt: row.ranAt,
233
+ ranBy: row.ranBy,
234
+ schemaIntrospectionHash: row.schemaIntrospectionHash,
235
+ signature: row.signature,
236
+ publicKeyFingerprint: row.publicKeyFingerprint,
237
+ }), dialect);
238
+ await xdb.query(q.sql, q.params, FRAMEWORK_METADATA_OPTS);
192
239
  }
193
240
 
194
- async function _ensureLockTable(xdb) {
195
- await xdb.query(
196
- "CREATE TABLE IF NOT EXISTS " + Q_LOCK + " (" +
197
- " scope TEXT PRIMARY KEY," +
198
- " lockedAt INTEGER NOT NULL," +
199
- " lockedBy TEXT NOT NULL," +
200
- " CHECK (scope = 'lock')" +
201
- ")",
202
- []
203
- );
241
+ async function _ensureLockTable(xdb, dialect) {
242
+ // The scope CHECK is a static operator-controlled literal, carried as
243
+ // the last column's verbatim constraint (b.sql guards it via
244
+ // allowLiterals). lockedAt holds a ms-epoch value, so the framework INT
245
+ // type (BIGINT on Postgres/MySQL) is required — a 32-bit INTEGER
246
+ // overflows. The scope PK is a bounded VARCHAR (only ever 'lock'): MySQL
247
+ // refuses an unbounded TEXT/BLOB in a key (ER 1170).
248
+ await xdb.query(sql().createTable(_lockTable(), [
249
+ { name: "scope", type: "VARCHAR(64)", primaryKey: true },
250
+ { name: "lockedAt", type: "INTEGER", notNull: true },
251
+ { name: "lockedBy", type: "TEXT", notNull: true,
252
+ constraints: ", CHECK (scope = 'lock')" }, // allow:hand-rolled-sql — static DDL CHECK literal
253
+ ], { dialect: dialect }).sql, []);
204
254
  }
205
255
 
206
256
  // ---- Lock acquire / release ----
207
257
 
208
- async function _acquireLock(xdb, opts) {
209
- await _ensureLockTable(xdb);
258
+ async function _acquireLock(xdb, opts, dialect) {
259
+ await _ensureLockTable(xdb, dialect);
210
260
  var holder = _lockHolderId();
211
261
  var nowMs = Date.now();
212
262
  // See migrations.acquireLock for the same fix — Infinity was
@@ -218,27 +268,67 @@ async function _acquireLock(xdb, opts) {
218
268
  ExternalDbMigrateError, "externalDb-migrate/bad-opt");
219
269
  if (opts.staleAfterMs !== undefined) staleAfterMs = opts.staleAfterMs;
220
270
  }
271
+ // Conflict-safe lock acquire. The INSERT runs inside
272
+ // externalDb.transaction(_acquireLock); on Postgres a plain INSERT that
273
+ // hits the PRIMARY KEY conflict raises SQLSTATE 23505 which ABORTS the
274
+ // surrounding transaction (every later statement then fails with 25P02,
275
+ // "current transaction is aborted"), so the holder-naming SELECT could
276
+ // not run and the operator got a raw aborted-transaction error instead of
277
+ // the documented "migration lock is held by <holder>" message. Emitting
278
+ // `INSERT ... ON CONFLICT (scope) DO NOTHING` (Postgres/SQLite) /
279
+ // `INSERT ... ON DUPLICATE KEY UPDATE scope=scope` (MySQL — a no-op)
280
+ // turns the conflict into a 0-row result rather than a transaction-
281
+ // aborting error, so the inspect SELECT below runs cleanly and names the
282
+ // holder. rowCount === 1 means we won the lock; 0 means it is held.
283
+ function _insertLock() {
284
+ return _bind(sql().upsert(_lockTable(), { dialect: dialect })
285
+ .values({ scope: "lock", lockedAt: nowMs, lockedBy: holder })
286
+ .onConflict(["scope"]).doNothing(), dialect);
287
+ }
288
+ var insRes;
221
289
  try {
222
- await xdb.query(
223
- "INSERT INTO " + Q_LOCK + " (scope, lockedAt, lockedBy) VALUES ('lock', $1, $2)",
224
- [nowMs, holder]
225
- );
290
+ var ins = _insertLock();
291
+ insRes = await xdb.query(ins.sql, ins.params, FRAMEWORK_METADATA_OPTS);
292
+ } catch (e0) {
293
+ // A genuine driver/connection fault (not a conflict — the conflict is now
294
+ // a 0-row no-op, never a throw). Surface as lock-busy.
295
+ throw _err("externaldb-migrate/lock-busy",
296
+ "could not acquire migration lock: " + ((e0 && e0.message) || String(e0)));
297
+ }
298
+ if (insRes && insRes.rowCount >= 1) {
226
299
  return { holder: holder, takeoverFrom: null, takeoverAgeMs: 0 };
227
- } catch (_e) {
228
- // PRIMARY KEY conflict → existing lock. Inspect it.
229
- var existingRes = await xdb.query(
230
- "SELECT lockedAt, lockedBy FROM " + Q_LOCK + " WHERE scope = 'lock'",
231
- []
232
- );
300
+ }
301
+ {
302
+ // 0 rows inserted → the lock IS held. Inspect it to name the holder. The
303
+ // conflict was a clean no-op (DO NOTHING), so the transaction is NOT
304
+ // aborted and this SELECT runs.
305
+ var selExisting = _bind(sql().select(_lockTable(), { dialect: dialect })
306
+ .columns(["lockedAt", "lockedBy"]).where("scope", "lock"), dialect);
307
+ var existingRes;
308
+ try {
309
+ existingRes = await xdb.query(selExisting.sql, selExisting.params);
310
+ } catch (_inspectErr) {
311
+ throw _err("externaldb-migrate/lock-held",
312
+ "migration lock is held — another process is running migrations " +
313
+ "(the lock row could not be inspected). Wait for it to finish, or " +
314
+ "pass staleAfterMs to force-replace stale locks.");
315
+ }
233
316
  var existing = existingRes && existingRes.rows && existingRes.rows[0];
234
317
  if (!existing) {
318
+ // Lock row vanished between the no-op insert and the inspect (the
319
+ // holder released concurrently). Retry the acquire once.
235
320
  try {
236
- await xdb.query(
237
- "INSERT INTO " + Q_LOCK + " (scope, lockedAt, lockedBy) VALUES ('lock', $1, $2)",
238
- [nowMs, holder]
239
- );
240
- return { holder: holder, takeoverFrom: null, takeoverAgeMs: 0 };
321
+ var insRetry = _insertLock();
322
+ var retryRes = await xdb.query(insRetry.sql, insRetry.params, FRAMEWORK_METADATA_OPTS);
323
+ if (retryRes && retryRes.rowCount >= 1) {
324
+ return { holder: holder, takeoverFrom: null, takeoverAgeMs: 0 };
325
+ }
326
+ throw _err("externaldb-migrate/lock-held",
327
+ "migration lock is held — another process re-acquired it during " +
328
+ "the acquire race. Wait for it to finish, or pass staleAfterMs to " +
329
+ "force-replace stale locks.");
241
330
  } catch (e2) {
331
+ if (e2 && e2.isExternalDbMigrateError) throw e2;
242
332
  throw _err("externaldb-migrate/lock-busy",
243
333
  "could not acquire migration lock: " + ((e2 && e2.message) || String(e2)));
244
334
  }
@@ -248,14 +338,19 @@ async function _acquireLock(xdb, opts) {
248
338
  // Force-replace the stale lock atomically. Stale-takeover is a
249
339
  // SOC2 evidence event — caller emits an audit row.
250
340
  var prevHolder = existing.lockedby || existing.lockedBy;
251
- await xdb.query(
252
- "DELETE FROM " + Q_LOCK + " WHERE scope = 'lock' AND lockedAt = $1",
253
- [Number(existing.lockedat || existing.lockedAt)]
254
- );
255
- await xdb.query(
256
- "INSERT INTO " + Q_LOCK + " (scope, lockedAt, lockedBy) VALUES ('lock', $1, $2)",
257
- [nowMs, holder]
258
- );
341
+ var delStale = _bind(sql().delete(_lockTable(), { dialect: dialect })
342
+ .where("scope", "lock")
343
+ .where("lockedAt", Number(existing.lockedat || existing.lockedAt)), dialect);
344
+ await xdb.query(delStale.sql, delStale.params, FRAMEWORK_METADATA_OPTS);
345
+ var insTakeover = _insertLock();
346
+ var takeoverRes = await xdb.query(insTakeover.sql, insTakeover.params, FRAMEWORK_METADATA_OPTS);
347
+ if (!takeoverRes || takeoverRes.rowCount < 1) {
348
+ // Another process slipped a fresh lock in between our DELETE and
349
+ // INSERT (the conflict is a DO NOTHING no-op, so 0 rows = lost race).
350
+ throw _err("externaldb-migrate/lock-held",
351
+ "migration lock was re-acquired by another process during the " +
352
+ "stale-lock takeover. Wait for it to finish, or retry.");
353
+ }
259
354
  return { holder: holder, takeoverFrom: prevHolder, takeoverAgeMs: ageMs };
260
355
  }
261
356
  throw _err("externaldb-migrate/lock-held",
@@ -265,12 +360,11 @@ async function _acquireLock(xdb, opts) {
265
360
  }
266
361
  }
267
362
 
268
- async function _releaseLock(xdb, holder) {
363
+ async function _releaseLock(xdb, holder, dialect) {
269
364
  try {
270
- await xdb.query(
271
- "DELETE FROM " + Q_LOCK + " WHERE scope = 'lock' AND lockedBy = $1",
272
- [holder]
273
- );
365
+ var del = _bind(sql().delete(_lockTable(), { dialect: dialect })
366
+ .where("scope", "lock").where("lockedBy", holder), dialect);
367
+ await xdb.query(del.sql, del.params, FRAMEWORK_METADATA_OPTS);
274
368
  } catch (_e) {
275
369
  // best-effort release; operator can DELETE manually.
276
370
  }
@@ -370,13 +464,13 @@ function create(opts) {
370
464
 
371
465
  async function status() {
372
466
  var backendName = _resolveBackendName(opts);
467
+ var dialect = _backendDialect(backendName);
373
468
  return await externalDb().transaction(async function (xdb) {
374
- await _ensureTrackingTable(xdb);
375
- var res = await xdb.query(
376
- "SELECT name, description, appliedAt FROM " + Q_TRACKING +
377
- " ORDER BY appliedAt ASC, name ASC",
378
- []
379
- );
469
+ await _ensureTrackingTable(xdb, dialect);
470
+ var q = _bind(sql().select(_trackingTable(), { dialect: dialect })
471
+ .columns(["name", "description", "appliedAt"])
472
+ .orderBy("appliedAt", "asc").orderBy("name", "asc"), dialect);
473
+ var res = await xdb.query(q.sql, q.params);
380
474
  var applied = (res && res.rows) || [];
381
475
  var appliedNames = new Set(applied.map(function (r) { return r.name; }));
382
476
  var files = _list(dir);
@@ -392,12 +486,13 @@ function create(opts) {
392
486
 
393
487
  async function up() {
394
488
  var backendName = _resolveBackendName(opts);
489
+ var dialect = _backendDialect(backendName);
395
490
  var ctx = _ctx(backendName);
396
491
 
397
492
  return await externalDb().transaction(async function (xdb) {
398
- await _ensureTrackingTable(xdb);
399
- await _ensureLockTable(xdb);
400
- await _ensureHistoryTable(xdb);
493
+ await _ensureTrackingTable(xdb, dialect);
494
+ await _ensureLockTable(xdb, dialect);
495
+ await _ensureHistoryTable(xdb, dialect);
401
496
  }, { backend: backendName }).then(async function () {
402
497
  // Acquire the lock OUTSIDE the per-migration transaction so the
403
498
  // lock survives across migration boundaries. We use a separate
@@ -405,7 +500,7 @@ function create(opts) {
405
500
  // serializes apply order, so this single-connection lock is
406
501
  // sufficient.
407
502
  var lockResult = await externalDb().transaction(async function (xdb) {
408
- return await _acquireLock(xdb, opts);
503
+ return await _acquireLock(xdb, opts, dialect);
409
504
  }, { backend: backendName });
410
505
  var lockHolder = lockResult.holder;
411
506
 
@@ -421,9 +516,9 @@ function create(opts) {
421
516
  }
422
517
 
423
518
  try {
424
- var appliedRes = await externalDb().query(
425
- "SELECT name FROM " + Q_TRACKING, [], { backend: backendName }
426
- );
519
+ var appliedQ = _bind(sql().select(_trackingTable(), { dialect: dialect })
520
+ .columns(["name"]), dialect);
521
+ var appliedRes = await externalDb().query(appliedQ.sql, appliedQ.params, { backend: backendName });
427
522
  var appliedSet = new Set(((appliedRes && appliedRes.rows) || []).map(function (r) { return r.name; }));
428
523
  var files = _list(dir);
429
524
  var applied = [];
@@ -438,11 +533,9 @@ function create(opts) {
438
533
  await externalDb().transaction(async function (xdb) {
439
534
  await mod.up(xdb, ctx);
440
535
  var ranAt = new Date().toISOString();
441
- await xdb.query(
442
- "INSERT INTO " + Q_TRACKING +
443
- " (name, description, appliedAt) VALUES ($1, $2, $3)",
444
- [file, mod.description || "", ranAt]
445
- );
536
+ var insTrack = _bind(sql().insert(_trackingTable(), { dialect: dialect })
537
+ .values({ name: file, description: mod.description || "", appliedAt: ranAt }), dialect);
538
+ await xdb.query(insTrack.sql, insTrack.params, FRAMEWORK_METADATA_OPTS);
446
539
  // Schema-version history with signature. Sign post-INSERT
447
540
  // so the introspection hash reflects the row that just
448
541
  // landed. Sign-failure is non-fatal for the migration but
@@ -451,7 +544,7 @@ function create(opts) {
451
544
  version: file,
452
545
  ranAt: ranAt,
453
546
  ranBy: ranBy,
454
- schemaIntrospectionHash: await schemaIntrospect(xdb),
547
+ schemaIntrospectionHash: await schemaIntrospect(xdb, dialect),
455
548
  signature: null,
456
549
  publicKeyFingerprint: null,
457
550
  };
@@ -467,7 +560,7 @@ function create(opts) {
467
560
  (sigErr && sigErr.message) || String(sigErr));
468
561
  }
469
562
  }
470
- await _writeHistoryRow(xdb, historyRow);
563
+ await _writeHistoryRow(xdb, historyRow, dialect);
471
564
  _emit(audit, "migrations.history.appended", "success", {
472
565
  migration: file,
473
566
  schemaIntrospectionHash: historyRow.schemaIntrospectionHash,
@@ -490,7 +583,7 @@ function create(opts) {
490
583
  } finally {
491
584
  try {
492
585
  await externalDb().transaction(async function (xdb) {
493
- await _releaseLock(xdb, lockHolder);
586
+ await _releaseLock(xdb, lockHolder, dialect);
494
587
  }, { backend: backendName });
495
588
  _emit(audit, "externaldb.migrate.lock.released", "success",
496
589
  { holder: lockHolder, backend: backendName }, null);
@@ -507,15 +600,16 @@ function create(opts) {
507
600
  var steps = (typeof downOpts.steps === "number" && downOpts.steps > 0)
508
601
  ? Math.floor(downOpts.steps) : 1;
509
602
  var backendName = _resolveBackendName(opts);
603
+ var dialect = _backendDialect(backendName);
510
604
  var ctx = _ctx(backendName);
511
605
 
512
606
  await externalDb().transaction(async function (xdb) {
513
- await _ensureTrackingTable(xdb);
514
- await _ensureLockTable(xdb);
607
+ await _ensureTrackingTable(xdb, dialect);
608
+ await _ensureLockTable(xdb, dialect);
515
609
  }, { backend: backendName });
516
610
 
517
611
  var lockResultDown = await externalDb().transaction(async function (xdb) {
518
- return await _acquireLock(xdb, opts);
612
+ return await _acquireLock(xdb, opts, dialect);
519
613
  }, { backend: backendName });
520
614
  var lockHolder = lockResultDown.holder;
521
615
 
@@ -528,10 +622,10 @@ function create(opts) {
528
622
  }
529
623
 
530
624
  try {
531
- var appliedRes = await externalDb().query(
532
- "SELECT name FROM " + Q_TRACKING + " ORDER BY appliedAt DESC, name DESC LIMIT $1",
533
- [steps], { backend: backendName }
534
- );
625
+ var downQ = _bind(sql().select(_trackingTable(), { dialect: dialect })
626
+ .columns(["name"])
627
+ .orderBy("appliedAt", "desc").orderBy("name", "desc").limit(steps), dialect);
628
+ var appliedRes = await externalDb().query(downQ.sql, downQ.params, { backend: backendName });
535
629
  var rows = (appliedRes && appliedRes.rows) || [];
536
630
  var reverted = [];
537
631
  for (var i = 0; i < rows.length; i++) {
@@ -545,10 +639,9 @@ function create(opts) {
545
639
  try {
546
640
  await externalDb().transaction(async function (xdb) {
547
641
  await mod.down(xdb, ctx);
548
- await xdb.query(
549
- "DELETE FROM " + Q_TRACKING + " WHERE name = $1",
550
- [file]
551
- );
642
+ var delTrack = _bind(sql().delete(_trackingTable(), { dialect: dialect })
643
+ .where("name", file), dialect);
644
+ await xdb.query(delTrack.sql, delTrack.params);
552
645
  }, { backend: backendName });
553
646
  _emit(audit, "externaldb.migrate.down", "success",
554
647
  { migration: file, durationMs: Date.now() - t0, backend: backendName }, null);
@@ -565,7 +658,7 @@ function create(opts) {
565
658
  } finally {
566
659
  try {
567
660
  await externalDb().transaction(async function (xdb) {
568
- await _releaseLock(xdb, lockHolder);
661
+ await _releaseLock(xdb, lockHolder, dialect);
569
662
  }, { backend: backendName });
570
663
  _emit(audit, "externaldb.migrate.lock.released", "success",
571
664
  { holder: lockHolder, backend: backendName }, null);
@@ -588,13 +681,13 @@ function create(opts) {
588
681
  async function history(historyOpts) {
589
682
  historyOpts = historyOpts || {};
590
683
  var backendName = _resolveBackendName(opts);
684
+ var dialect = _backendDialect(backendName);
591
685
  return await externalDb().transaction(async function (xdb) {
592
- await _ensureHistoryTable(xdb);
593
- var res = await xdb.query(
594
- "SELECT version, ranAt, ranBy, schemaIntrospectionHash, signature, publicKeyFingerprint " +
595
- "FROM " + Q_HISTORY + " ORDER BY ranAt ASC, version ASC",
596
- []
597
- );
686
+ await _ensureHistoryTable(xdb, dialect);
687
+ var histQ = _bind(sql().select(_historyTable(), { dialect: dialect })
688
+ .columns(["version", "ranAt", "ranBy", "schemaIntrospectionHash", "signature", "publicKeyFingerprint"])
689
+ .orderBy("ranAt", "asc").orderBy("version", "asc"), dialect);
690
+ var res = await xdb.query(histQ.sql, histQ.params);
598
691
  var out = [];
599
692
  var rows = (res && res.rows) || [];
600
693
  for (var i = 0; i < rows.length; i++) {
@@ -653,7 +746,16 @@ function create(opts) {
653
746
  module.exports = {
654
747
  create: create,
655
748
  ExternalDbMigrateError: ExternalDbMigrateError,
656
- TRACKING_TABLE: TRACKING_TABLE,
657
- HISTORY_TABLE: HISTORY_TABLE,
658
749
  HISTORY_SIGNATURE_FORMAT: HISTORY_SIGNATURE_FORMAT,
659
750
  };
751
+
752
+ // The resolved table names are exposed as lazy getters: frameworkSchema's
753
+ // tableName export is not bound while this module evaluates (the
754
+ // external-db require cycle), so resolving at access time gives the
755
+ // configurable-prefix-aware concrete name without a load-order trap.
756
+ Object.defineProperty(module.exports, "TRACKING_TABLE", {
757
+ enumerable: true, get: function () { return _trackingTable(); },
758
+ });
759
+ Object.defineProperty(module.exports, "HISTORY_TABLE", {
760
+ enumerable: true, get: function () { return _historyTable(); },
761
+ });