@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,549 @@
1
+ "use strict";
2
+ /**
3
+ * Live test of the framework's SYNCHRONOUS data layer
4
+ * (lib/db-query.js / lib/db-schema.js / lib/migrations.js /
5
+ * lib/seeders.js) against the docker MySQL container.
6
+ *
7
+ * Same intent as db-layer-postgres.test.js: those four modules were built
8
+ * for node:sqlite (synchronous) and compose every statement through b.sql
9
+ * with { dialect: "sqlite" } — `?` placeholders + DOUBLE-QUOTED identifiers
10
+ * — with NO per-dialect translation (clusterStorage, the advertised
11
+ * rewrite layer, is bypassed by these single-node modules). Host smoke
12
+ * only ever runs them on sqlite.
13
+ *
14
+ * MySQL-specific faithfulness in the adapter:
15
+ * - b.sql emits `"camelCase"` double-quoted identifiers. MySQL's default
16
+ * sql_mode treats `"..."` as a STRING literal, not an identifier, so a
17
+ * real MySQL driver must run with ANSI_QUOTES enabled for the
18
+ * framework's quote-by-construction SQL to parse at all. Each docker-
19
+ * exec mysql call is a fresh connection, so every statement is prefixed
20
+ * with `SET SESSION sql_mode=...,ANSI_QUOTES`.
21
+ * - `?` placeholders fold into the SQL as quoted literals at the adapter
22
+ * boundary (the mysql CLI has no bind protocol); every value here is
23
+ * operator-controlled.
24
+ * - run() returns { changes } from ROW_COUNT() issued in the SAME mysql
25
+ * invocation as the write (ROW_COUNT is connection-scoped).
26
+ * - BIGINT comes back as a JS string in --batch mode (matching the
27
+ * mysql2 BIGINT-as-string default the framework readers expect).
28
+ *
29
+ * The custom `check` helper is fail-fast, so this file records every
30
+ * assertion through a local soft-check (all divergences surface in one
31
+ * run) and ends with WORKING-path + KNOWN-BUG gate assertions so the file
32
+ * is a stable green coverage gate that flips red the moment a lib is fixed.
33
+ *
34
+ * Tables/migration-rows are namespaced (bjml_*) in a dedicated bjml_test
35
+ * database + dropped in setup + teardown so a concurrent test can't collide.
36
+ */
37
+
38
+ var execFileSync = require("node:child_process").execFileSync;
39
+ var helpers = require("../helpers");
40
+ var check = helpers.check;
41
+ var services = require("../helpers/services");
42
+
43
+ var safeSql = require("../../lib/safe-sql");
44
+ var frameworkSchema = require("../../lib/framework-schema");
45
+ var dbSchema = require("../../lib/db-schema");
46
+ var migrations = require("../../lib/migrations");
47
+ var seeders = require("../../lib/seeders");
48
+ var { Query } = require("../../lib/db-query");
49
+
50
+ var CONTAINER = "blamejs-test-mysql";
51
+ var DB_NAME = "bjml_test";
52
+ // ANSI_QUOTES makes MySQL honor the b.sql double-quoted identifiers; without
53
+ // it every "col" parses as a string literal and the SQL is meaningless.
54
+ // PIPES_AS_CONCAT off-by-default is fine (we emit no `||`). Prefixed to every
55
+ // statement batch since each docker-exec is a fresh connection.
56
+ var SQLMODE = "SET SESSION sql_mode=CONCAT(@@sql_mode,',ANSI_QUOTES');\n";
57
+
58
+ var _results = [];
59
+ function soft(label, cond) {
60
+ _results.push({ label: label, ok: !!cond });
61
+ console.log((cond ? " ok " : " FAIL ") + label);
62
+ return !!cond;
63
+ }
64
+
65
+ // ---- shared synchronous docker-exec mysql ----
66
+ // SQL travels on stdin (never argv → no shell parsing). --batch gives
67
+ // TAB-separated, header-bearing output; --raw disables escaping so a
68
+ // value round-trips byte-faithfully. stderr captured + merged so a SQL
69
+ // error surfaces with its message.
70
+ function _mysqlRaw(sql, opts) {
71
+ opts = opts || {};
72
+ var db = opts.noDb ? [] : [DB_NAME];
73
+ var args = ["exec", "-i", CONTAINER, "mysql", "-uroot", "-pblamejs_test_root",
74
+ "--batch", "--raw"].concat(db);
75
+ try {
76
+ var out = execFileSync("docker", args,
77
+ { input: (opts.noMode ? "" : SQLMODE) + sql + "\n",
78
+ stdio: ["pipe", "pipe", "pipe"], maxBuffer: 64 * 1024 * 1024 });
79
+ return { ok: true, out: out.toString("utf8") };
80
+ } catch (e) {
81
+ var stderr = e.stderr ? e.stderr.toString("utf8") : "";
82
+ return { ok: false, out: (e.stdout ? e.stdout.toString("utf8") : ""), err: stderr || (e.message || String(e)) };
83
+ }
84
+ }
85
+
86
+ // One-shot for setup / teardown / out-of-band assertions; throws on error.
87
+ function _mysql(sql, opts) {
88
+ var r = _mysqlRaw(sql, opts);
89
+ if (!r.ok) throw new Error("mysql setup failed for [" + sql.slice(0, 120) + "]: " + _clean(r.err));
90
+ return r.out;
91
+ }
92
+
93
+ function _clean(s) {
94
+ return String(s || "").split(/\r?\n/)
95
+ .filter(function (l) { return l && l.indexOf("[Warning] World-writable") === -1; })
96
+ .join(" ").slice(0, 220);
97
+ }
98
+
99
+ var BLOB_HEX = "0x";
100
+ function _bindQ(sql, params) {
101
+ params = params || [];
102
+ var i = 0;
103
+ return sql.replace(/\?/g, function () {
104
+ if (i >= params.length) throw new Error("placeholder/param count mismatch in: " + sql);
105
+ var v = params[i++];
106
+ if (v === null || v === undefined) return "NULL";
107
+ if (Buffer.isBuffer(v)) return BLOB_HEX + (v.length ? v.toString("hex") : "00");
108
+ if (typeof v === "number") return String(v);
109
+ if (typeof v === "boolean") return v ? "1" : "0";
110
+ return "'" + String(v).replace(/\\/g, "\\\\").replace(/'/g, "''") + "'";
111
+ });
112
+ }
113
+
114
+ var _BLOB_COLUMNS = { blobcol: true, payload: true, nonce: true };
115
+
116
+ // Parse a --batch block: drop the warning line(s), header row first, then
117
+ // data rows. The SQLMODE `SET` produces no output. Multiple statements in
118
+ // one batch each emit their own header+rows; we parse the LAST result set
119
+ // (the SELECT we care about), since reads issue exactly one SELECT.
120
+ function _parseSelect(out) {
121
+ var lines = out.split(/\r?\n/).filter(function (l) {
122
+ return l.length > 0 && l.indexOf("[Warning] World-writable") === -1;
123
+ });
124
+ if (lines.length === 0) return [];
125
+ var headers = lines[0].split("\t");
126
+ var rows = [];
127
+ for (var i = 1; i < lines.length; i++) {
128
+ var cells = lines[i].split("\t");
129
+ var row = {};
130
+ for (var c = 0; c < headers.length; c++) {
131
+ var hdr = headers[c];
132
+ var cell = cells[c];
133
+ if (cell === "NULL" || cell === undefined) { row[hdr] = null; continue; }
134
+ if (_BLOB_COLUMNS[hdr] === true) {
135
+ // --raw emits binary bytes verbatim; recover them as a Buffer.
136
+ row[hdr] = Buffer.from(cell, "binary");
137
+ } else {
138
+ row[hdr] = cell;
139
+ }
140
+ }
141
+ rows.push(row);
142
+ }
143
+ return rows;
144
+ }
145
+
146
+ function _isWrite(sql) {
147
+ return /^\s*(INSERT|UPDATE|DELETE|REPLACE|MERGE)\b/i.test(sql);
148
+ }
149
+
150
+ // ---- node:sqlite-Statement-SHAPED adapter over real MySQL ----
151
+ function _makeMysqlAdapter() {
152
+ return {
153
+ prepare: function (sql) {
154
+ return {
155
+ get: function () {
156
+ var params = Array.prototype.slice.call(arguments);
157
+ var r = _mysqlRaw(_bindQ(sql, params));
158
+ if (!r.ok) throw new Error("MySQL error: " + _clean(r.err));
159
+ var rows = _parseSelect(r.out);
160
+ return rows.length ? rows[0] : undefined;
161
+ },
162
+ all: function () {
163
+ var params = Array.prototype.slice.call(arguments);
164
+ var r = _mysqlRaw(_bindQ(sql, params));
165
+ if (!r.ok) throw new Error("MySQL error: " + _clean(r.err));
166
+ return _parseSelect(r.out);
167
+ },
168
+ run: function () {
169
+ var params = Array.prototype.slice.call(arguments);
170
+ var bound = _bindQ(sql, params);
171
+ // ROW_COUNT() in the SAME connection/batch as the write reports
172
+ // affectedRows (it is connection-scoped).
173
+ var r = _mysqlRaw(bound + ";\nSELECT ROW_COUNT() AS rc;");
174
+ if (!r.ok) throw new Error("MySQL error: " + _clean(r.err));
175
+ var changes = 0;
176
+ if (_isWrite(sql)) {
177
+ var rows = _parseSelect(r.out);
178
+ // The LAST result set is the ROW_COUNT() select.
179
+ var last = rows.length ? rows[rows.length - 1] : null;
180
+ if (last && last.rc !== undefined && last.rc !== null) changes = Number(last.rc);
181
+ }
182
+ return { changes: changes, lastInsertRowid: 0 };
183
+ },
184
+ };
185
+ },
186
+ exec: function (sql) {
187
+ var r = _mysqlRaw(sql);
188
+ if (!r.ok) throw new Error("MySQL error: " + _clean(r.err));
189
+ return r.out;
190
+ },
191
+ // The handle declares its dialect so the data layer emits MySQL-correct
192
+ // SQL: BACKTICK-quoted identifiers (the framework SQL no longer relies
193
+ // on ANSI_QUOTES — backticks work in either sql_mode), the single-row
194
+ // write resolves the PRIMARY KEY in a prior SELECT then writes
195
+ // `WHERE pk = ?` (MySQL rejects a subquery referencing the UPDATE/DELETE
196
+ // target — error 1093), listColumns reads information_schema, and the
197
+ // migrations/seeders registry/lock tables use VARCHAR(191) for key text
198
+ // columns + BIGINT for the ms-epoch lock timestamp.
199
+ dialect: "mysql",
200
+ };
201
+ }
202
+
203
+ function _from(adapter, table, declared) {
204
+ return new Query(adapter, table, {
205
+ declaredColumns: declared || null,
206
+ columnGateMode: declared ? "reject" : "off",
207
+ });
208
+ }
209
+
210
+ function _block(label, fn) {
211
+ try { fn(); return true; }
212
+ catch (e) {
213
+ soft(label + " (threw: " + ((e && e.message) || String(e)).replace(/\s+/g, " ").slice(0, 200) + ")", false);
214
+ return false;
215
+ }
216
+ }
217
+
218
+ async function run() {
219
+ var mysqlSvc = await services.requireService("mysql");
220
+ if (!mysqlSvc.ok) throw new Error("mysql unreachable: " + mysqlSvc.reason);
221
+
222
+ // Dedicated database so we never touch other suites' fixtures.
223
+ _mysql("CREATE DATABASE IF NOT EXISTS " + DB_NAME + ";", { noDb: true, noMode: true });
224
+
225
+ var adapter = _makeMysqlAdapter();
226
+
227
+ var T = "bjml_orders";
228
+ var ALL_TABLES = [
229
+ '"' + T + '"', '"bjml_things"', '"bjml_widgets"', '"bjml_seed_target"',
230
+ '"_blamejs_migrations"', '"_blamejs_migrations_lock"',
231
+ '"_blamejs_seeders"', '"_blamejs_seeders_lock"',
232
+ ];
233
+ function _dropAll() {
234
+ _mysql(ALL_TABLES.map(function (t) { return "DROP TABLE IF EXISTS " + t + ";"; }).join("\n"));
235
+ }
236
+ _dropAll();
237
+
238
+ // ====================================================================
239
+ // 1. reconcileTable: CREATE TABLE IF NOT EXISTS + second-reconcile
240
+ // idempotence on real MySQL.
241
+ // ====================================================================
242
+ // region is declared VARCHAR (not TEXT) because the test indexes it
243
+ // below: MySQL refuses an unbounded TEXT/BLOB column in an index without
244
+ // a prefix length (error 1170). On MySQL an operator who wants an indexed
245
+ // string column declares it VARCHAR — that is an operator-schema choice
246
+ // the framework honors, not something reconcileIndex can guess a length
247
+ // for. The Postgres sibling uses TEXT (Postgres indexes TEXT directly).
248
+ var tableDef = {
249
+ name: T,
250
+ columns: { _id: "VARCHAR(64) PRIMARY KEY", region: "VARCHAR(64)", total: "BIGINT", note: "TEXT" },
251
+ };
252
+ var reconcileOk = _block(
253
+ "reconcileTable: first reconcile (CREATE TABLE IF NOT EXISTS) runs on real MySQL",
254
+ function () { dbSchema.reconcileTable(adapter, tableDef, { onDrift: "refuse" }); });
255
+ if (reconcileOk) soft("reconcileTable: first reconcile ran clean on MySQL", true);
256
+
257
+ var tblPresent = _mysql(
258
+ "SELECT count(*) AS n FROM information_schema.tables WHERE table_schema='" +
259
+ DB_NAME + "' AND table_name='" + T + "';");
260
+ soft("reconcileTable: CREATE TABLE DDL landed the table on the server (portable b.sql DDL)",
261
+ /\b1\b/.test(tblPresent));
262
+
263
+ _block(
264
+ "reconcileTable: SECOND reconcile is idempotent on real MySQL " +
265
+ "(no spurious ALTER / duplicate-column / false drift)",
266
+ function () { dbSchema.reconcileTable(adapter, tableDef, { onDrift: "refuse" }); });
267
+
268
+ _block(
269
+ "reconcileTable: declared index (CREATE INDEX IF NOT EXISTS) runs on real MySQL",
270
+ function () {
271
+ dbSchema.reconcileTable(adapter,
272
+ { name: T, columns: tableDef.columns, indexes: [{ columns: ["region"], name: "bjml_orders_region_idx" }] },
273
+ { onDrift: "ignore" });
274
+ });
275
+
276
+ // Ensure the table exists for the CRUD block regardless of reconcile.
277
+ _mysql('CREATE TABLE IF NOT EXISTS "' + T + '" ' +
278
+ '("_id" VARCHAR(64) PRIMARY KEY, "region" VARCHAR(64), "total" BIGINT, "note" TEXT);');
279
+
280
+ // ====================================================================
281
+ // 2. db.from() Query CRUD end-to-end on real MySQL.
282
+ // ====================================================================
283
+ var declared = new Set(["_id", "region", "total", "note"]);
284
+
285
+ _block("db.from().insertOne runs on real MySQL", function () {
286
+ var ins = _from(adapter, T, declared).insertOne({ _id: "o-1", region: "eu", total: 100, note: "first" });
287
+ soft("db.from().insertOne returned the row with _id", ins && ins._id === "o-1");
288
+ });
289
+ _block("db.from().insertOne (rows 2,3) run on MySQL", function () {
290
+ _from(adapter, T, declared).insertOne({ _id: "o-2", region: "eu", total: 250, note: "second" });
291
+ _from(adapter, T, declared).insertOne({ _id: "o-3", region: "us", total: 70, note: "third" });
292
+ });
293
+
294
+ _block("db.from().where().first runs on MySQL", function () {
295
+ var oneRow = _from(adapter, T, declared).where("_id", "o-1").first();
296
+ soft("db.from().where().first round-trips id", oneRow && oneRow._id === "o-1");
297
+ soft("db.from().first round-trips region", oneRow && oneRow.region === "eu");
298
+ soft("db.from(): BIGINT total coerces to a JS string on real MySQL (mysql2 bigint-as-string default)",
299
+ oneRow && typeof oneRow.total === "string" && oneRow.total === "100");
300
+ });
301
+
302
+ _block("db.from().where().orderBy().all runs on MySQL", function () {
303
+ var euRows = _from(adapter, T, declared).where("region", "eu").orderBy("_id", "asc").all();
304
+ soft("db.from().where().orderBy().all returns the eu rows in order",
305
+ euRows.length === 2 && euRows[0]._id === "o-1" && euRows[1]._id === "o-2");
306
+ });
307
+
308
+ _block("db.from().count runs on MySQL", function () {
309
+ var total = _from(adapter, T, declared).count();
310
+ soft("db.from().count returns 3", Number(total) === 3);
311
+ });
312
+
313
+ _block("db.from().updateOne (single-row, PK resolve-then-write) runs on real MySQL", function () {
314
+ var n = _from(adapter, T, declared).where("_id", "o-1").updateOne({ total: 999 });
315
+ soft("db.from().updateOne reported a change", n === true);
316
+ var after = _from(adapter, T, declared).where("_id", "o-1").first();
317
+ soft("db.from().updateOne persisted", after && after.total === "999");
318
+ });
319
+
320
+ _block("db.from().updateMany (set-based) runs on real MySQL", function () {
321
+ _from(adapter, T, declared).where("region", "eu").updateMany({ note: "bulk" });
322
+ var bulk = _from(adapter, T, declared).where("_id", "o-2").first();
323
+ soft("db.from().updateMany persisted", bulk && bulk.note === "bulk");
324
+ });
325
+
326
+ _block("db.from().increment (COALESCE+?) runs on real MySQL", function () {
327
+ _from(adapter, T, declared).where("_id", "o-3").increment("total", 5);
328
+ var inc = _from(adapter, T, declared).where("_id", "o-3").first();
329
+ soft("db.from().increment persisted (70 + 5 = 75)", inc && inc.total === "75");
330
+ });
331
+
332
+ _block("db.from().deleteOne (single-row, PK resolve-then-write) runs on real MySQL", function () {
333
+ _from(adapter, T, declared).where("_id", "o-3").deleteOne();
334
+ var remain = _from(adapter, T, declared).count();
335
+ soft("db.from().deleteOne removed one row (3 -> 2)", Number(remain) === 2);
336
+ });
337
+
338
+ _block("db.from().paginate runs on real MySQL", function () {
339
+ var liveTotal = Number(_from(adapter, T, declared).count());
340
+ var page = _from(adapter, T, declared).paginate({ orderBy: "_id", limit: 1, offset: 0 });
341
+ soft("db.from().paginate envelope shape (items page-limited, total == live count)",
342
+ page && page.items.length === 1 && Number(page.total) === liveTotal && page.totalPages >= 1);
343
+ });
344
+
345
+ // ---- coercion fidelity: BIGINT > 2^53 reads back as exact string ----
346
+ _mysql('CREATE TABLE IF NOT EXISTS "bjml_things" ' +
347
+ '("_id" VARCHAR(64) PRIMARY KEY, "bignum" BIGINT);');
348
+ var thingsDeclared = new Set(["_id", "bignum"]);
349
+ _block("db.from() reads a > 2^53 BIGINT back as an exact string on real MySQL", function () {
350
+ _mysql('INSERT INTO "bjml_things" ("_id","bignum") VALUES (\'t-1\', 9007199254740993);');
351
+ var t = _from(adapter, "bjml_things", thingsDeclared).where("_id", "t-1").first();
352
+ soft("BIGINT > 2^53 reads back as an exact string (mysql2 bigint fidelity)",
353
+ t && t.bignum === "9007199254740993");
354
+ });
355
+
356
+ // ====================================================================
357
+ // 3. migrations: composite-PK + CHECK DDL, run-once tracking, the lock.
358
+ // ====================================================================
359
+ var os = require("node:os");
360
+ var fs = require("node:fs");
361
+ var path = require("node:path");
362
+ var migDir = fs.mkdtempSync(path.join(os.tmpdir(), "bjml-mig-"));
363
+ fs.writeFileSync(path.join(migDir, "0001-create-widgets.js"),
364
+ 'module.exports = { description: "widgets",' +
365
+ ' up: function (db) { db["exec"]("CREATE TABLE IF NOT EXISTS \\"bjml_widgets\\" ' +
366
+ '(\\"k\\" VARCHAR(64), \\"v\\" VARCHAR(64), PRIMARY KEY (\\"k\\", \\"v\\"), ' +
367
+ 'CHECK (CHAR_LENGTH(\\"k\\") > 0))"); },' +
368
+ ' down: function (db) { db["exec"]("DROP TABLE IF EXISTS \\"bjml_widgets\\""); } };\n');
369
+ _mysql('DROP TABLE IF EXISTS "bjml_widgets";');
370
+
371
+ var mig = migrations.create({ db: adapter, dir: migDir });
372
+ var migRan = false;
373
+ await (async function () {
374
+ try {
375
+ var upResult = await mig.up();
376
+ migRan = true;
377
+ soft("migrations.up ran the migration on real MySQL", true);
378
+ soft("migrations.up applied 0001-create-widgets.js",
379
+ upResult.applied.indexOf("0001-create-widgets.js") !== -1);
380
+ } catch (e) {
381
+ soft("migrations.up runs on real MySQL (threw: " +
382
+ ((e && e.message) || String(e)).replace(/\s+/g, " ").slice(0, 200) + ")", false);
383
+ }
384
+ })();
385
+
386
+ if (migRan) {
387
+ var widgetPresent = _mysql(
388
+ "SELECT count(*) AS n FROM information_schema.tables WHERE table_schema='" +
389
+ DB_NAME + "' AND table_name='bjml_widgets';");
390
+ soft("migrations: composite-PK + CHECK table created on the server", /\b1\b/.test(widgetPresent));
391
+
392
+ await (async function () {
393
+ try {
394
+ var up2 = await mig.up();
395
+ soft("migrations.up is run-once (second up skips the applied migration)",
396
+ up2.applied.length === 0 && up2.skipped.indexOf("0001-create-widgets.js") !== -1);
397
+ } catch (e) {
398
+ soft("migrations.up second run is run-once (threw: " + ((e && e.message) || String(e)).slice(0, 120) + ")", false);
399
+ }
400
+ })();
401
+
402
+ try {
403
+ var st = mig.status();
404
+ soft("migrations.status reports 0001 applied on MySQL",
405
+ st.applied.some(function (r) { return r.name === "0001-create-widgets.js"; }));
406
+ } catch (e) {
407
+ soft("migrations.status runs on MySQL (threw: " + ((e && e.message) || String(e)).slice(0, 120) + ")", false);
408
+ }
409
+
410
+ var lockTbl = frameworkSchema.tableName(migrations.LOCK_TABLE);
411
+ await (async function () {
412
+ try {
413
+ _mysql('INSERT INTO ' + safeSql.quoteIdentifier(lockTbl, "sqlite") +
414
+ ' ("scope", "lockedAt", "lockedBy") VALUES (\'lock\', ' + Date.now() +
415
+ ", 'other-proc');");
416
+ var lockThrew = null;
417
+ try { await mig.up(); } catch (e) { lockThrew = e; }
418
+ soft("migrations: a held advisory lock refuses a concurrent up() on MySQL",
419
+ lockThrew !== null && /lock/i.test((lockThrew && lockThrew.message) || ""));
420
+ _mysql('DELETE FROM ' + safeSql.quoteIdentifier(lockTbl, "sqlite") + " WHERE \"scope\" = 'lock';");
421
+ } catch (e) {
422
+ soft("migrations advisory-lock concurrency test ran on MySQL (threw: " +
423
+ ((e && e.message) || String(e)).slice(0, 120) + ")", false);
424
+ }
425
+ })();
426
+
427
+ // Stale-lock force-replace path. The DELETE+INSERT runs inside a
428
+ // transaction whose boundary keyword is dialect-aware: `BEGIN IMMEDIATE`
429
+ // is SQLite-only and a syntax error on MySQL, so the runner must emit a
430
+ // portable `BEGIN`. Plant a STALE lock row (far in the past) then run
431
+ // up({ staleAfterMs }) — the runner force-replaces it, skips the
432
+ // already-applied migration, and releases.
433
+ await (async function () {
434
+ try {
435
+ _mysql('DELETE FROM ' + safeSql.quoteIdentifier(lockTbl, "sqlite") + " WHERE \"scope\" = 'lock';");
436
+ _mysql('INSERT INTO ' + safeSql.quoteIdentifier(lockTbl, "sqlite") +
437
+ ' ("scope", "lockedAt", "lockedBy") VALUES (\'lock\', ' + (Date.now() - 3600000) +
438
+ ", 'dead-proc');");
439
+ var staleMig = migrations.create({ db: adapter, dir: migDir, staleAfterMs: 60000 });
440
+ var staleThrew = null;
441
+ try { await staleMig.up(); } catch (e) { staleThrew = e; }
442
+ soft("migrations: stale-lock force-replace uses a portable BEGIN (not BEGIN IMMEDIATE) on MySQL",
443
+ staleThrew === null);
444
+ var deadRows = _mysql('SELECT count(*) AS "n" FROM ' + safeSql.quoteIdentifier(lockTbl, "sqlite") +
445
+ " WHERE \"lockedBy\" = 'dead-proc';");
446
+ soft("migrations: the stale dead-proc lock was force-replaced + released on MySQL",
447
+ /\b0\b/.test(deadRows));
448
+ _mysql('DELETE FROM ' + safeSql.quoteIdentifier(lockTbl, "sqlite") + " WHERE \"scope\" = 'lock';");
449
+ } catch (e) {
450
+ soft("migrations stale-lock-replace test ran on MySQL (threw: " +
451
+ ((e && e.message) || String(e)).replace(/\s+/g, " ").slice(0, 200) + ")", false);
452
+ }
453
+ })();
454
+ }
455
+
456
+ // ====================================================================
457
+ // 4. seeders: composite-PK registry, env scoping, run-once + rerunnable.
458
+ // ====================================================================
459
+ var seedDir = fs.mkdtempSync(path.join(os.tmpdir(), "bjml-seed-"));
460
+ fs.mkdirSync(path.join(seedDir, "dev"));
461
+ _mysql('DROP TABLE IF EXISTS "bjml_seed_target";');
462
+ _mysql('CREATE TABLE "bjml_seed_target" ("id" VARCHAR(64) PRIMARY KEY, "label" TEXT);');
463
+ fs.writeFileSync(path.join(seedDir, "dev", "0001-admin.js"),
464
+ 'module.exports = { description: "admin",' +
465
+ ' run: async function (db) { db.prepare("INSERT INTO \\"bjml_seed_target\\" ' +
466
+ '(\\"id\\", \\"label\\") VALUES (?, ?)").run("admin", "Administrator"); } };\n');
467
+
468
+ var seed = seeders.create({ db: adapter, dir: seedDir });
469
+ var seedRan = false;
470
+ await (async function () {
471
+ try {
472
+ var seedResult = await seed.run({ env: "dev" });
473
+ seedRan = true;
474
+ soft("seeders.run applied the seed on real MySQL", true);
475
+ soft("seeders.run applied 0001-admin.js", seedResult.applied.indexOf("0001-admin.js") !== -1);
476
+ } catch (e) {
477
+ soft("seeders.run runs on real MySQL (threw: " +
478
+ ((e && e.message) || String(e)).replace(/\s+/g, " ").slice(0, 200) + ")", false);
479
+ }
480
+ })();
481
+
482
+ if (seedRan) {
483
+ var seededRow = _mysql('SELECT label FROM "bjml_seed_target" WHERE id = \'admin\';');
484
+ soft("seeders: the seed body actually wrote its row on MySQL", /Administrator/.test(seededRow));
485
+
486
+ await (async function () {
487
+ try {
488
+ var seed2 = await seed.run({ env: "dev" });
489
+ soft("seeders.run is run-once (second run skips the applied seed)",
490
+ seed2.applied.length === 0 && seed2.skipped.indexOf("0001-admin.js") !== -1);
491
+ } catch (e) {
492
+ soft("seeders.run second run is run-once (threw: " + ((e && e.message) || String(e)).slice(0, 120) + ")", false);
493
+ }
494
+ })();
495
+
496
+ try {
497
+ var sst = seed.status({ env: "dev" });
498
+ soft("seeders.status reports 0001-admin.js applied on MySQL",
499
+ sst.applied.some(function (r) { return r.name === "0001-admin.js"; }));
500
+ } catch (e) {
501
+ soft("seeders.status runs on MySQL (threw: " + ((e && e.message) || String(e)).slice(0, 120) + ")", false);
502
+ }
503
+ }
504
+
505
+ // ---- teardown ----
506
+ try { fs.rmSync(migDir, { recursive: true, force: true }); } catch (_e) {}
507
+ try { fs.rmSync(seedDir, { recursive: true, force: true }); } catch (_e) {}
508
+ _dropAll();
509
+
510
+ // ---- summary ----
511
+ //
512
+ // The data layer is dialect-aware: with the handle declaring
513
+ // dialect: "mysql", every soft-check above MUST pass on real MySQL. The
514
+ // formerly-SQLite-only / MySQL-incompatible constructs are resolved:
515
+ // - db-schema.listColumns reads information_schema.columns (not the
516
+ // SQLite-only PRAGMA table_info), and reconcileTable / reconcileIndex
517
+ // emit backtick-quoted DDL (MySQL has no CREATE INDEX IF NOT EXISTS —
518
+ // a duplicate-index re-run is swallowed for idempotence).
519
+ // - db-query single-row updateOne/deleteOne resolve the PRIMARY KEY in a
520
+ // prior SELECT then write `WHERE pk = ?` (MySQL error 1093 forbids a
521
+ // subquery on the UPDATE/DELETE target table).
522
+ // - the migrations + seeders registry/lock tables use VARCHAR(191) for
523
+ // their key text columns (MySQL refuses unbounded TEXT in a key,
524
+ // error 1170) and BIGINT for the ms-epoch lock timestamp (a 32-bit
525
+ // INT overflows, error 1264).
526
+ var failed = _results.filter(function (r) { return !r.ok; });
527
+
528
+ console.log("\n[db-layer-mysql] " +
529
+ (_results.length - failed.length) + "/" + _results.length + " checks passed");
530
+ if (failed.length) {
531
+ console.log("[db-layer-mysql] FAILURES:");
532
+ failed.forEach(function (r) { console.log(" - " + r.label); });
533
+ }
534
+
535
+ // Replay every recorded finding through the hard `check` so the file
536
+ // FAILS when any data-layer op does not work on real MySQL.
537
+ for (var i = 0; i < _results.length; i++) {
538
+ check(_results[i].label, _results[i].ok);
539
+ }
540
+ }
541
+
542
+ module.exports = { run: run };
543
+
544
+ if (require.main === module) {
545
+ run().then(
546
+ function () { console.log("OK — " + helpers.getChecks() + " checks passed"); process.exit(0); },
547
+ function (e) { console.error("FAIL:", e.stack || e); process.exit(1); }
548
+ );
549
+ }