@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.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +392 -278
- package/lib/vendor/blamejs/.github/workflows/ci.yml +34 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +21 -4
- package/lib/vendor/blamejs/.gitignore +6 -0
- package/lib/vendor/blamejs/CHANGELOG.md +26 -0
- package/lib/vendor/blamejs/MIGRATING.md +43 -0
- package/lib/vendor/blamejs/README.md +8 -6
- package/lib/vendor/blamejs/SECURITY.md +19 -3
- package/lib/vendor/blamejs/api-snapshot.json +2190 -664
- package/lib/vendor/blamejs/docker/caddy/localstack.Caddyfile +19 -0
- package/lib/vendor/blamejs/docker/init/generate-certs.sh +1 -1
- package/lib/vendor/blamejs/docker/otel/config.yaml +42 -0
- package/lib/vendor/blamejs/docker/otel/export/.gitkeep +0 -0
- package/lib/vendor/blamejs/docker/postgres/initdb/10-replication.sh +15 -0
- package/lib/vendor/blamejs/docker/postgres/replica-entrypoint.sh +38 -0
- package/lib/vendor/blamejs/docker/toxiproxy/toxiproxy.json +14 -0
- package/lib/vendor/blamejs/docker-compose.test.yml +209 -0
- package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +132 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +221 -61
- package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +144 -9
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +99 -0
- package/lib/vendor/blamejs/fuzz/guard-sql.fuzz.js +36 -0
- package/lib/vendor/blamejs/index.js +4 -0
- package/lib/vendor/blamejs/lib/agent-envelope-mac.js +104 -0
- package/lib/vendor/blamejs/lib/agent-event-bus.js +105 -4
- package/lib/vendor/blamejs/lib/agent-posture-chain.js +8 -42
- package/lib/vendor/blamejs/lib/ai-content-detect.js +9 -10
- package/lib/vendor/blamejs/lib/api-key.js +158 -77
- package/lib/vendor/blamejs/lib/atomic-file.js +62 -4
- package/lib/vendor/blamejs/lib/audit-chain.js +47 -11
- package/lib/vendor/blamejs/lib/audit-sign.js +77 -2
- package/lib/vendor/blamejs/lib/audit-tools.js +79 -51
- package/lib/vendor/blamejs/lib/audit.js +259 -123
- package/lib/vendor/blamejs/lib/auth/oauth.js +53 -9
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +108 -47
- package/lib/vendor/blamejs/lib/auth/saml.js +6 -8
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +31 -5
- package/lib/vendor/blamejs/lib/backup/index.js +45 -10
- package/lib/vendor/blamejs/lib/break-glass.js +355 -147
- package/lib/vendor/blamejs/lib/cache.js +174 -105
- package/lib/vendor/blamejs/lib/chain-writer.js +38 -16
- package/lib/vendor/blamejs/lib/cli.js +19 -14
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +130 -104
- package/lib/vendor/blamejs/lib/cluster-storage.js +119 -22
- package/lib/vendor/blamejs/lib/cluster.js +119 -71
- package/lib/vendor/blamejs/lib/codepoint-class.js +23 -0
- package/lib/vendor/blamejs/lib/compliance.js +206 -4
- package/lib/vendor/blamejs/lib/consent.js +82 -29
- package/lib/vendor/blamejs/lib/constants.js +27 -11
- package/lib/vendor/blamejs/lib/crypto-field.js +916 -156
- package/lib/vendor/blamejs/lib/db-declare-row-policy.js +35 -22
- package/lib/vendor/blamejs/lib/db-file-lifecycle.js +3 -2
- package/lib/vendor/blamejs/lib/db-query.js +882 -260
- package/lib/vendor/blamejs/lib/db-schema.js +228 -44
- package/lib/vendor/blamejs/lib/db.js +249 -99
- package/lib/vendor/blamejs/lib/dsr.js +385 -55
- package/lib/vendor/blamejs/lib/error-page.js +14 -1
- package/lib/vendor/blamejs/lib/external-db-migrate.js +239 -137
- package/lib/vendor/blamejs/lib/external-db.js +549 -34
- package/lib/vendor/blamejs/lib/file-upload.js +52 -7
- package/lib/vendor/blamejs/lib/framework-error.js +20 -1
- package/lib/vendor/blamejs/lib/framework-files.js +73 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +695 -394
- package/lib/vendor/blamejs/lib/gate-contract.js +659 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +26 -44
- package/lib/vendor/blamejs/lib/guard-all.js +1 -0
- package/lib/vendor/blamejs/lib/guard-auth.js +42 -112
- package/lib/vendor/blamejs/lib/guard-cidr.js +33 -154
- package/lib/vendor/blamejs/lib/guard-csv.js +46 -113
- package/lib/vendor/blamejs/lib/guard-domain.js +34 -157
- package/lib/vendor/blamejs/lib/guard-dsn.js +27 -43
- package/lib/vendor/blamejs/lib/guard-email.js +47 -69
- package/lib/vendor/blamejs/lib/guard-envelope.js +19 -32
- package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +24 -42
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +25 -43
- package/lib/vendor/blamejs/lib/guard-filename.js +42 -106
- package/lib/vendor/blamejs/lib/guard-graphql.js +42 -123
- package/lib/vendor/blamejs/lib/guard-html.js +53 -108
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +24 -42
- package/lib/vendor/blamejs/lib/guard-image.js +46 -103
- package/lib/vendor/blamejs/lib/guard-imap-command.js +18 -32
- package/lib/vendor/blamejs/lib/guard-jmap.js +16 -30
- package/lib/vendor/blamejs/lib/guard-json.js +38 -108
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +38 -171
- package/lib/vendor/blamejs/lib/guard-jwt.js +49 -179
- package/lib/vendor/blamejs/lib/guard-list-id.js +25 -41
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +27 -43
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-move.js +26 -44
- package/lib/vendor/blamejs/lib/guard-mail-query.js +28 -46
- package/lib/vendor/blamejs/lib/guard-mail-reply.js +24 -42
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +24 -42
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +17 -31
- package/lib/vendor/blamejs/lib/guard-markdown.js +37 -104
- package/lib/vendor/blamejs/lib/guard-message-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-mime.js +39 -151
- package/lib/vendor/blamejs/lib/guard-oauth.js +54 -135
- package/lib/vendor/blamejs/lib/guard-pdf.js +45 -101
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +21 -31
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +24 -42
- package/lib/vendor/blamejs/lib/guard-regex.js +33 -107
- package/lib/vendor/blamejs/lib/guard-saga-config.js +24 -42
- package/lib/vendor/blamejs/lib/guard-shell.js +42 -172
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +48 -54
- package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +24 -42
- package/lib/vendor/blamejs/lib/guard-sql.js +1491 -0
- package/lib/vendor/blamejs/lib/guard-stream-args.js +24 -43
- package/lib/vendor/blamejs/lib/guard-svg.js +47 -65
- package/lib/vendor/blamejs/lib/guard-template.js +35 -172
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +26 -45
- package/lib/vendor/blamejs/lib/guard-time.js +32 -154
- package/lib/vendor/blamejs/lib/guard-trace-context.js +25 -44
- package/lib/vendor/blamejs/lib/guard-uuid.js +32 -153
- package/lib/vendor/blamejs/lib/guard-xml.js +38 -113
- package/lib/vendor/blamejs/lib/guard-yaml.js +51 -163
- package/lib/vendor/blamejs/lib/http-client.js +37 -9
- package/lib/vendor/blamejs/lib/inbox.js +120 -107
- package/lib/vendor/blamejs/lib/legal-hold.js +121 -50
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +47 -31
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +32 -18
- package/lib/vendor/blamejs/lib/mail-auth.js +236 -0
- package/lib/vendor/blamejs/lib/mail-crypto-smime.js +2 -6
- package/lib/vendor/blamejs/lib/mail-dkim.js +1 -0
- package/lib/vendor/blamejs/lib/mail-greylist.js +2 -6
- package/lib/vendor/blamejs/lib/mail-helo.js +2 -6
- package/lib/vendor/blamejs/lib/mail-journal.js +85 -64
- package/lib/vendor/blamejs/lib/mail-rbl.js +2 -6
- package/lib/vendor/blamejs/lib/mail-scan.js +2 -6
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +117 -12
- package/lib/vendor/blamejs/lib/mail-server-mx.js +276 -7
- package/lib/vendor/blamejs/lib/mail-spam-score.js +2 -6
- package/lib/vendor/blamejs/lib/mail-store.js +293 -154
- package/lib/vendor/blamejs/lib/mail.js +8 -4
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +71 -25
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +19 -8
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -1
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +17 -7
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +75 -51
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +102 -32
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +21 -5
- package/lib/vendor/blamejs/lib/migrations.js +108 -66
- package/lib/vendor/blamejs/lib/network-heartbeat.js +7 -0
- package/lib/vendor/blamejs/lib/network-proxy.js +24 -1
- package/lib/vendor/blamejs/lib/nonce-store.js +31 -9
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +9 -4
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +57 -3
- package/lib/vendor/blamejs/lib/object-store/gcs.js +4 -1
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +5 -2
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +38 -6
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +9 -1
- package/lib/vendor/blamejs/lib/observability.js +124 -0
- package/lib/vendor/blamejs/lib/otel-export.js +12 -3
- package/lib/vendor/blamejs/lib/outbox.js +184 -83
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +47 -7
- package/lib/vendor/blamejs/lib/pqc-agent.js +44 -0
- package/lib/vendor/blamejs/lib/pubsub-cluster.js +42 -20
- package/lib/vendor/blamejs/lib/queue-local.js +225 -140
- package/lib/vendor/blamejs/lib/queue-redis.js +9 -1
- package/lib/vendor/blamejs/lib/queue-sqs.js +6 -0
- package/lib/vendor/blamejs/lib/queue.js +7 -0
- package/lib/vendor/blamejs/lib/redact.js +68 -11
- package/lib/vendor/blamejs/lib/redis-client.js +160 -31
- package/lib/vendor/blamejs/lib/request-helpers.js +7 -0
- package/lib/vendor/blamejs/lib/retention.js +101 -40
- package/lib/vendor/blamejs/lib/router.js +212 -5
- package/lib/vendor/blamejs/lib/safe-dns.js +29 -45
- package/lib/vendor/blamejs/lib/safe-ical.js +18 -33
- package/lib/vendor/blamejs/lib/safe-icap.js +27 -43
- package/lib/vendor/blamejs/lib/safe-sieve.js +21 -40
- package/lib/vendor/blamejs/lib/safe-sql.js +212 -3
- package/lib/vendor/blamejs/lib/safe-url.js +170 -3
- package/lib/vendor/blamejs/lib/safe-vcard.js +18 -33
- package/lib/vendor/blamejs/lib/scheduler.js +35 -12
- package/lib/vendor/blamejs/lib/seeders.js +122 -74
- package/lib/vendor/blamejs/lib/session-stores.js +42 -14
- package/lib/vendor/blamejs/lib/session.js +175 -77
- package/lib/vendor/blamejs/lib/sql.js +3842 -0
- package/lib/vendor/blamejs/lib/sse.js +26 -0
- package/lib/vendor/blamejs/lib/ssrf-guard.js +151 -4
- package/lib/vendor/blamejs/lib/static.js +177 -34
- package/lib/vendor/blamejs/lib/subject.js +96 -49
- package/lib/vendor/blamejs/lib/vault/index.js +3 -2
- package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +3 -2
- package/lib/vendor/blamejs/lib/vault/rotate.js +168 -108
- package/lib/vendor/blamejs/lib/vault-aad.js +6 -0
- package/lib/vendor/blamejs/lib/vendor-data.js +2 -0
- package/lib/vendor/blamejs/lib/websocket.js +35 -5
- package/lib/vendor/blamejs/lib/worker-pool.js +11 -0
- package/lib/vendor/blamejs/package.json +2 -2
- package/lib/vendor/blamejs/release-notes/v0.14.x.json +1503 -0
- package/lib/vendor/blamejs/release-notes/v0.15.0.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.15.1.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.2.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.3.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.4.json +39 -0
- package/lib/vendor/blamejs/release-notes/v0.15.5.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.15.6.json +59 -0
- package/lib/vendor/blamejs/scripts/check-services.js +21 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +51 -0
- package/lib/vendor/blamejs/scripts/release.js +398 -38
- package/lib/vendor/blamejs/test/00-primitives.js +117 -0
- package/lib/vendor/blamejs/test/10-state.js +140 -14
- package/lib/vendor/blamejs/test/20-db.js +65 -2
- package/lib/vendor/blamejs/test/helpers/db.js +9 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +27 -15
- package/lib/vendor/blamejs/test/helpers/services.js +21 -0
- package/lib/vendor/blamejs/test/integration/audit-actor-binding-pg.test.js +246 -0
- package/lib/vendor/blamejs/test/integration/audit-chain-external-db.test.js +517 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +639 -0
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +832 -0
- package/lib/vendor/blamejs/test/integration/backup-restore-objectstore.test.js +453 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-mysql.test.js +649 -0
- package/lib/vendor/blamejs/test/integration/data-layer-cluster-pg.test.js +770 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql-privacy.test.js +630 -0
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +610 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +577 -0
- package/lib/vendor/blamejs/test/integration/data-layer-postgres.test.js +771 -0
- package/lib/vendor/blamejs/test/integration/db-layer-mysql.test.js +549 -0
- package/lib/vendor/blamejs/test/integration/db-layer-postgres.test.js +598 -0
- package/lib/vendor/blamejs/test/integration/distributed-scheduler-fencing-pg.test.js +602 -0
- package/lib/vendor/blamejs/test/integration/external-db-postgres.test.js +576 -0
- package/lib/vendor/blamejs/test/integration/framework-schema-mysql.test.js +353 -0
- package/lib/vendor/blamejs/test/integration/log-stream-cloudwatch.test.js +224 -0
- package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +142 -17
- package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +25 -10
- package/lib/vendor/blamejs/test/integration/object-store-azure.test.js +101 -0
- package/lib/vendor/blamejs/test/integration/object-store-gcs.test.js +239 -0
- package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +35 -16
- package/lib/vendor/blamejs/test/integration/object-store-worm-lock.test.js +291 -0
- package/lib/vendor/blamejs/test/integration/pubsub.test.js +14 -0
- package/lib/vendor/blamejs/test/integration/queue-sqs.test.js +322 -0
- package/lib/vendor/blamejs/test/integration/redis-reconnect-toxiproxy.test.js +300 -0
- package/lib/vendor/blamejs/test/integration/sql-fts5-catalog-sqlite.test.js +154 -0
- package/lib/vendor/blamejs/test/integration/tls-classical-downgrade-audit.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +175 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-exclusive-temp.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-checkpoint-false-rollback.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-query-self-log.test.js +126 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-safeemit-redacts-secrets.test.js +196 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-signing-key-rotation.test.js +197 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-verifybundle-tamper.test.js +209 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-key-encoding.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-residency-posture.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-scheduletest-drill.test.js +318 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +233 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +1120 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +24 -7
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-dual-read-migrate.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-per-row-key.test.js +350 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-unseal-rate-cap.test.js +27 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-upgrade-dialect.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-interop-oracles.test.js +392 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csrf-protect.test.js +159 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-column-gate.test.js +180 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +5 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-sealed-field-in.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-drift.test.js +38 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/db-schema-reconcile-emittable.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-stream-and-payload-shape.test.js +267 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/defineguard-default-gate-posture-caps.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-replaystore-required.test.js +46 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +218 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/erase-posture-vacuum.test.js +210 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +4 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +48 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +237 -5
- package/lib/vendor/blamejs/test/layer-0-primitives/fetch-metadata.test.js +20 -9
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +193 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +90 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +10 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +15 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +189 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +3 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +123 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +207 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +43 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otlp-attr-redaction.test.js +101 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox-inflight-reaper.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey-real-vectors.test.js +429 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +21 -11
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-byo-db.test.js +40 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention-dryrun-no-vacuum.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-use-path-scope.test.js +255 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-canonicalize.test.js +309 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-xml.test.js +143 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/saml-subjectconfirmation-notonorafter.test.js +287 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc-ecdsa-p1363.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +31 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +49 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +595 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sse-backpressure.test.js +91 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +194 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket-extension-header.test.js +88 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool-recycle-race.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-5-integration/external-db-residency.test.js +638 -0
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +21 -0
- package/lib/vendor/blamejs/test/smoke.js +79 -21
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.14.0.json +0 -43
- package/lib/vendor/blamejs/release-notes/v0.14.1.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.10.json +0 -54
- package/lib/vendor/blamejs/release-notes/v0.14.11.json +0 -72
- package/lib/vendor/blamejs/release-notes/v0.14.12.json +0 -95
- package/lib/vendor/blamejs/release-notes/v0.14.13.json +0 -52
- package/lib/vendor/blamejs/release-notes/v0.14.14.json +0 -31
- package/lib/vendor/blamejs/release-notes/v0.14.16.json +0 -45
- package/lib/vendor/blamejs/release-notes/v0.14.17.json +0 -57
- package/lib/vendor/blamejs/release-notes/v0.14.18.json +0 -127
- package/lib/vendor/blamejs/release-notes/v0.14.19.json +0 -61
- package/lib/vendor/blamejs/release-notes/v0.14.2.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.20.json +0 -73
- package/lib/vendor/blamejs/release-notes/v0.14.21.json +0 -98
- package/lib/vendor/blamejs/release-notes/v0.14.22.json +0 -91
- package/lib/vendor/blamejs/release-notes/v0.14.3.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.4.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.5.json +0 -18
- package/lib/vendor/blamejs/release-notes/v0.14.6.json +0 -60
- package/lib/vendor/blamejs/release-notes/v0.14.7.json +0 -77
- package/lib/vendor/blamejs/release-notes/v0.14.8.json +0 -27
- package/lib/vendor/blamejs/release-notes/v0.14.9.json +0 -40
|
@@ -63,8 +63,20 @@ var bCrypto = require("./crypto");
|
|
|
63
63
|
var lazyRequire = require("./lazy-require");
|
|
64
64
|
var safeJson = require("./safe-json");
|
|
65
65
|
var validateOpts = require("./validate-opts");
|
|
66
|
+
var sql = require("./sql");
|
|
67
|
+
var cryptoField = require("./crypto-field");
|
|
66
68
|
var { defineClass } = require("./framework-error");
|
|
67
69
|
|
|
70
|
+
// Local-SQLite framework table names. These run against the b.db() handle
|
|
71
|
+
// directly (single-node legal-hold registry + the audit_log read), so the
|
|
72
|
+
// b.sql builders carry { quoteName: true } to emit the quoted local name
|
|
73
|
+
// (no clusterStorage prefix rewrite on this path) and bind every value as a
|
|
74
|
+
// placeholder. The names are passed as literals here for the same reason
|
|
75
|
+
// db.js declares them as literals — they ARE the canonical local table
|
|
76
|
+
// identifiers.
|
|
77
|
+
var HOLD_TABLE = "_blamejs_legal_hold"; // allow:hand-rolled-sql — canonical local table-name; passed to b.sql with quoteName
|
|
78
|
+
var AUDIT_TABLE = "audit_log";
|
|
79
|
+
|
|
68
80
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
69
81
|
|
|
70
82
|
var LegalHoldError = defineClass("LegalHoldError", { alwaysPermanent: true });
|
|
@@ -99,6 +111,24 @@ function _hashSubject(subjectId) {
|
|
|
99
111
|
return bCrypto.sha3Hash("bj-legal-hold:" + subjectId);
|
|
100
112
|
}
|
|
101
113
|
|
|
114
|
+
// Resolve the b.sql dialect for the operator-supplied handle. The framework's
|
|
115
|
+
// local b.db handle is always node:sqlite (db.js pins { dialect: "sqlite",
|
|
116
|
+
// quoteName: true }) and exposes no .dialect, so this defaults to "sqlite" —
|
|
117
|
+
// the registry + the audit_log read both run against that local handle via
|
|
118
|
+
// .prepare(). An operator handle that DOES advertise a dialect (string or
|
|
119
|
+
// () -> string) has it threaded through so the emitted identifier quoting +
|
|
120
|
+
// idioms match the backend the handle dispatches to. quoteName stays on for
|
|
121
|
+
// every legal-hold statement: these are canonical local table names quoted by
|
|
122
|
+
// construction (no clusterStorage prefix rewrite on this path).
|
|
123
|
+
function _handleDialect(db) {
|
|
124
|
+
if (db && typeof db.dialect === "function") {
|
|
125
|
+
try { var d = db.dialect(); return typeof d === "string" ? d : "sqlite"; }
|
|
126
|
+
catch (_e) { return "sqlite"; }
|
|
127
|
+
}
|
|
128
|
+
if (db && typeof db.dialect === "string") return db.dialect;
|
|
129
|
+
return "sqlite";
|
|
130
|
+
}
|
|
131
|
+
|
|
102
132
|
function create(opts) {
|
|
103
133
|
opts = opts || {};
|
|
104
134
|
validateOpts(opts, ["db", "audit", "signWith"], "legalHold");
|
|
@@ -106,6 +136,11 @@ function create(opts) {
|
|
|
106
136
|
throw _err("BAD_OPT", "create: opts.db is required (a b.db handle)");
|
|
107
137
|
}
|
|
108
138
|
var db = opts.db;
|
|
139
|
+
// b.sql opts for every legal-hold statement built against this handle. The
|
|
140
|
+
// dialect tracks the handle (sqlite for the framework's local b.db); the
|
|
141
|
+
// local table names are quoted by construction (quoteName) with no
|
|
142
|
+
// clusterStorage prefix rewrite on this path.
|
|
143
|
+
var SQL_OPTS = { dialect: _handleDialect(db), quoteName: true };
|
|
109
144
|
var auditOn = opts.audit !== false && opts.audit != null;
|
|
110
145
|
var auditInstance = (opts.audit && opts.audit !== true) ? opts.audit : null;
|
|
111
146
|
// signWith is reserved for future per-event detached signatures;
|
|
@@ -135,19 +170,31 @@ function create(opts) {
|
|
|
135
170
|
// table via FRAMEWORK_SCHEMA at boot; this guard is for the
|
|
136
171
|
// external-db / cluster path where schema migrations are operator-
|
|
137
172
|
// driven. Either way the IF NOT EXISTS shape is safe to re-run.
|
|
173
|
+
// DDL built through b.sql.createTable so every identifier is quoted by
|
|
174
|
+
// construction (quoteName) and the type tokens come from the framework
|
|
175
|
+
// type map.
|
|
138
176
|
var fn = db.runSql || db.execRaw;
|
|
139
177
|
if (typeof fn === "function") {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
178
|
+
var ddl = sql.createTable(HOLD_TABLE, [
|
|
179
|
+
{ name: "subjectIdHash", type: "text", primaryKey: true },
|
|
180
|
+
{ name: "placedAt", type: "int", notNull: true },
|
|
181
|
+
{ name: "placedBy", type: "text" },
|
|
182
|
+
{ name: "reason", type: "text", notNull: true },
|
|
183
|
+
{ name: "custodian", type: "text" },
|
|
184
|
+
{ name: "citation", type: "text" },
|
|
185
|
+
{ name: "retainUntil", type: "int" },
|
|
186
|
+
], SQL_OPTS);
|
|
187
|
+
fn(ddl.sql);
|
|
188
|
+
}
|
|
189
|
+
// Register the table's PII columns for at-rest sealing. The framework
|
|
190
|
+
// SQLite path also registers this via db.init() FRAMEWORK_SCHEMA, but the
|
|
191
|
+
// external-db / cluster path and a post-_resetForTest registry need this
|
|
192
|
+
// idempotent guard so sealRow/unsealRow below are never no-ops (which would
|
|
193
|
+
// store the legal-basis / custodian / citation free text in clear).
|
|
194
|
+
if (!cryptoField.getSchema(HOLD_TABLE)) {
|
|
195
|
+
cryptoField.registerTable(HOLD_TABLE, {
|
|
196
|
+
sealedFields: ["reason", "placedBy", "custodian", "citation"],
|
|
197
|
+
});
|
|
151
198
|
}
|
|
152
199
|
}
|
|
153
200
|
|
|
@@ -171,9 +218,12 @@ function create(opts) {
|
|
|
171
218
|
}
|
|
172
219
|
_ensureSchema();
|
|
173
220
|
var hash = _hashSubject(sid);
|
|
174
|
-
var
|
|
175
|
-
|
|
176
|
-
|
|
221
|
+
var placeSelBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
|
|
222
|
+
.columns(["placedAt"])
|
|
223
|
+
.where("subjectIdHash", hash)
|
|
224
|
+
.toSql();
|
|
225
|
+
var placeSelStmt = db.prepare(placeSelBuilt.sql);
|
|
226
|
+
var existing = placeSelStmt.get.apply(placeSelStmt, placeSelBuilt.params);
|
|
177
227
|
if (existing) {
|
|
178
228
|
_emit("legalhold.place_rejected",
|
|
179
229
|
{ subjectId: sid, reason: "already-held",
|
|
@@ -182,18 +232,19 @@ function create(opts) {
|
|
|
182
232
|
return { error: "already-held", placedAt: existing.placedAt };
|
|
183
233
|
}
|
|
184
234
|
var nowMs = Date.now();
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
args.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
);
|
|
235
|
+
var placeInsBuilt = sql.insert(HOLD_TABLE, SQL_OPTS)
|
|
236
|
+
.values(cryptoField.sealRow(HOLD_TABLE, {
|
|
237
|
+
subjectIdHash: hash,
|
|
238
|
+
placedAt: nowMs,
|
|
239
|
+
placedBy: args.placedBy || null,
|
|
240
|
+
reason: args.reason,
|
|
241
|
+
custodian: args.custodian || null,
|
|
242
|
+
citation: args.citation || null,
|
|
243
|
+
retainUntil: args.retainUntil || null,
|
|
244
|
+
}))
|
|
245
|
+
.toSql();
|
|
246
|
+
var placeInsStmt = db.prepare(placeInsBuilt.sql);
|
|
247
|
+
placeInsStmt.run.apply(placeInsStmt, placeInsBuilt.params);
|
|
197
248
|
_emit("legalhold.placed",
|
|
198
249
|
{ subjectId: sid, reason: args.reason,
|
|
199
250
|
custodian: args.custodian || null,
|
|
@@ -216,18 +267,24 @@ function create(opts) {
|
|
|
216
267
|
}
|
|
217
268
|
_ensureSchema();
|
|
218
269
|
var hash = _hashSubject(sid);
|
|
219
|
-
var
|
|
220
|
-
|
|
221
|
-
|
|
270
|
+
var relSelBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
|
|
271
|
+
.columns(["placedAt", "reason"])
|
|
272
|
+
.where("subjectIdHash", hash)
|
|
273
|
+
.toSql();
|
|
274
|
+
var relSelStmt = db.prepare(relSelBuilt.sql);
|
|
275
|
+
var existing = relSelStmt.get.apply(relSelStmt, relSelBuilt.params);
|
|
222
276
|
if (!existing) {
|
|
223
277
|
_emit("legalhold.release_rejected",
|
|
224
278
|
{ subjectId: sid, reason: "not-held" },
|
|
225
279
|
"denied");
|
|
226
280
|
return { error: "not-held" };
|
|
227
281
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
282
|
+
existing = cryptoField.unsealRow(HOLD_TABLE, existing);
|
|
283
|
+
var relDelBuilt = sql.delete(HOLD_TABLE, SQL_OPTS)
|
|
284
|
+
.where("subjectIdHash", hash)
|
|
285
|
+
.toSql();
|
|
286
|
+
var relDelStmt = db.prepare(relDelBuilt.sql);
|
|
287
|
+
relDelStmt.run.apply(relDelStmt, relDelBuilt.params);
|
|
231
288
|
_emit("legalhold.released",
|
|
232
289
|
{ subjectId: sid, reason: args.reason,
|
|
233
290
|
approver: args.approver,
|
|
@@ -241,9 +298,12 @@ function create(opts) {
|
|
|
241
298
|
var sid = _subjectIdString(subjectId);
|
|
242
299
|
_ensureSchema();
|
|
243
300
|
var hash = _hashSubject(sid);
|
|
244
|
-
var
|
|
245
|
-
|
|
246
|
-
|
|
301
|
+
var heldBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
|
|
302
|
+
.columns(["retainUntil"])
|
|
303
|
+
.where("subjectIdHash", hash)
|
|
304
|
+
.toSql();
|
|
305
|
+
var heldStmt = db.prepare(heldBuilt.sql);
|
|
306
|
+
var row = heldStmt.get.apply(heldStmt, heldBuilt.params);
|
|
247
307
|
if (!row) return false;
|
|
248
308
|
// retainUntil expiry — when the operator pinned a sunset and it
|
|
249
309
|
// has passed, the hold has lapsed and isHeld returns false. The
|
|
@@ -257,11 +317,14 @@ function create(opts) {
|
|
|
257
317
|
var sid = _subjectIdString(subjectId);
|
|
258
318
|
_ensureSchema();
|
|
259
319
|
var hash = _hashSubject(sid);
|
|
260
|
-
var
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
320
|
+
var getBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
|
|
321
|
+
.columns(["subjectIdHash", "placedAt", "placedBy", "reason", "custodian", "citation", "retainUntil"])
|
|
322
|
+
.where("subjectIdHash", hash)
|
|
323
|
+
.toSql();
|
|
324
|
+
var getStmt = db.prepare(getBuilt.sql);
|
|
325
|
+
var row = getStmt.get.apply(getStmt, getBuilt.params);
|
|
264
326
|
if (!row) return null;
|
|
327
|
+
row = cryptoField.unsealRow(HOLD_TABLE, row);
|
|
265
328
|
return {
|
|
266
329
|
subjectId: sid,
|
|
267
330
|
placedAt: row.placedAt,
|
|
@@ -276,12 +339,15 @@ function create(opts) {
|
|
|
276
339
|
|
|
277
340
|
function list() {
|
|
278
341
|
_ensureSchema();
|
|
279
|
-
var
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
342
|
+
var listBuilt = sql.select(HOLD_TABLE, SQL_OPTS)
|
|
343
|
+
.columns(["subjectIdHash", "placedAt", "placedBy", "reason", "custodian", "citation", "retainUntil"])
|
|
344
|
+
.orderBy("placedAt", "asc")
|
|
345
|
+
.toSql();
|
|
346
|
+
var listStmt = db.prepare(listBuilt.sql);
|
|
347
|
+
var rows = listStmt.all.apply(listStmt, listBuilt.params);
|
|
283
348
|
var nowMs = Date.now();
|
|
284
349
|
return rows.map(function (r) {
|
|
350
|
+
r = cryptoField.unsealRow(HOLD_TABLE, r);
|
|
285
351
|
return {
|
|
286
352
|
subjectIdHash: r.subjectIdHash,
|
|
287
353
|
placedAt: r.placedAt,
|
|
@@ -302,15 +368,20 @@ function create(opts) {
|
|
|
302
368
|
var sid = _subjectIdString(subjectId);
|
|
303
369
|
var rows = [];
|
|
304
370
|
try {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
371
|
+
// `action LIKE 'legalhold.%'` is a prefix match — b.sql's whereLike
|
|
372
|
+
// in prefix mode emits `"action" LIKE ? ESCAPE '~'` with the live
|
|
373
|
+
// trailing wildcard while escaping the term's own metacharacters
|
|
374
|
+
// (none here), so the wildcard stays builder-controlled.
|
|
375
|
+
var histBuilt = sql.select(AUDIT_TABLE, SQL_OPTS)
|
|
376
|
+
.columns(["recordedAt", "action", "metadata", "outcome"])
|
|
377
|
+
.whereLike("action", "legalhold.", "prefix")
|
|
378
|
+
.where("resourceKind", "legal-hold")
|
|
379
|
+
.orderBy("recordedAt", "asc")
|
|
380
|
+
.toSql();
|
|
381
|
+
var auditQuery = db.prepare(histBuilt.sql);
|
|
311
382
|
// resourceId is sealed, so match on resourceKind + post-filter
|
|
312
383
|
// by parsed metadata.
|
|
313
|
-
var raw = auditQuery.all(
|
|
384
|
+
var raw = auditQuery.all.apply(auditQuery, histBuilt.params);
|
|
314
385
|
for (var i = 0; i < raw.length; i++) {
|
|
315
386
|
var meta = null;
|
|
316
387
|
try { meta = safeJson.parse(raw[i].metadata || "{}"); } catch (_e) { meta = null; }
|
|
@@ -205,6 +205,10 @@ function create(config) {
|
|
|
205
205
|
var inFlight = false;
|
|
206
206
|
var closed = false;
|
|
207
207
|
var sequenceToken = null;
|
|
208
|
+
// Captures the in-flight drain (the IIFE inside _flush) so close() can await
|
|
209
|
+
// the actual run before flipping `closed` — otherwise the _flush while-loop's
|
|
210
|
+
// `&& !closed` bails and buffered records are stranded at shutdown.
|
|
211
|
+
var inFlightPromise = null;
|
|
208
212
|
var flushScheduler = safeAsync.makeScheduledFlush(cfg.maxBatchAgeMs, function () { return _flush(); });
|
|
209
213
|
|
|
210
214
|
function _takeBatch() {
|
|
@@ -236,40 +240,44 @@ function create(config) {
|
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
async function _flush() {
|
|
239
|
-
if (inFlight) return;
|
|
243
|
+
if (inFlight) return inFlightPromise;
|
|
240
244
|
if (buffer.length === 0) return;
|
|
241
245
|
inFlight = true;
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
246
|
+
inFlightPromise = (async function () {
|
|
247
|
+
try {
|
|
248
|
+
try { await _ensureAutoCreated(); }
|
|
249
|
+
catch (acErr) {
|
|
250
|
+
// autoCreate failure is permanent — every subsequent batch
|
|
251
|
+
// would hit the same error. Drop the queue with the
|
|
252
|
+
// operator-supplied onDrop callback so they see exactly which
|
|
253
|
+
// events were lost AND why, then bail.
|
|
254
|
+
var allBuffered = buffer.splice(0, buffer.length);
|
|
255
|
+
dropCount += allBuffered.length;
|
|
256
|
+
_emitDrop("autocreate-failed", allBuffered, acErr);
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
while (buffer.length > 0 && !closed) {
|
|
260
|
+
var batch = _takeBatch();
|
|
261
|
+
if (batch.length === 0) break;
|
|
262
|
+
try {
|
|
263
|
+
await retryHelper.withRetry(function () {
|
|
264
|
+
return _send(batch);
|
|
265
|
+
}, Object.assign({
|
|
266
|
+
isPermanent: _isPermanentAwsError,
|
|
267
|
+
}, cfg.retry || {}));
|
|
268
|
+
} catch (e) {
|
|
269
|
+
dropCount += batch.length;
|
|
270
|
+
_emitDrop("retry-exhausted", batch, e);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
267
273
|
}
|
|
274
|
+
} finally {
|
|
275
|
+
inFlight = false;
|
|
276
|
+
inFlightPromise = null;
|
|
277
|
+
if (buffer.length > 0) flushScheduler.schedule();
|
|
268
278
|
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
if (buffer.length > 0) flushScheduler.schedule();
|
|
272
|
-
}
|
|
279
|
+
})();
|
|
280
|
+
return inFlightPromise;
|
|
273
281
|
}
|
|
274
282
|
|
|
275
283
|
async function _send(batch) {
|
|
@@ -333,9 +341,17 @@ function create(config) {
|
|
|
333
341
|
}
|
|
334
342
|
|
|
335
343
|
async function close() {
|
|
336
|
-
closed
|
|
344
|
+
// Drain BEFORE flipping closed=true — _flush()'s `while (... && !closed)`
|
|
345
|
+
// loop bails on !closed, so flipping the flag first strands the records the
|
|
346
|
+
// operator queued just before shutdown (the b.logStream drain contract).
|
|
347
|
+
// Stop the timer, await any in-flight drain, drain the remainder, THEN
|
|
348
|
+
// refuse new enqueues. Mirrors the webhook sink.
|
|
337
349
|
flushScheduler.cancel();
|
|
350
|
+
if (inFlightPromise) {
|
|
351
|
+
try { await inFlightPromise; } catch (_e) { /* surfaced via onDrop */ }
|
|
352
|
+
}
|
|
338
353
|
await _flush();
|
|
354
|
+
closed = true;
|
|
339
355
|
}
|
|
340
356
|
|
|
341
357
|
function stats() {
|
|
@@ -210,30 +210,38 @@ function create(config) {
|
|
|
210
210
|
var dropCount = 0;
|
|
211
211
|
var inFlight = false;
|
|
212
212
|
var closed = false;
|
|
213
|
+
// Captures the in-flight drain so close() awaits the real run before flipping
|
|
214
|
+
// `closed` (the _flush while-loop bails on !closed → flipping first strands
|
|
215
|
+
// buffered records at shutdown).
|
|
216
|
+
var inFlightPromise = null;
|
|
213
217
|
var flushScheduler = safeAsync.makeScheduledFlush(cfg.maxBatchAgeMs, function () { return _flush(); });
|
|
214
218
|
|
|
215
219
|
async function _flush() {
|
|
216
|
-
if (inFlight) return;
|
|
220
|
+
if (inFlight) return inFlightPromise;
|
|
217
221
|
if (buffer.length === 0) return;
|
|
218
222
|
inFlight = true;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
223
|
+
inFlightPromise = (async function () {
|
|
224
|
+
try {
|
|
225
|
+
while (buffer.length > 0 && !closed) {
|
|
226
|
+
var batch = buffer.splice(0, cfg.batchSize);
|
|
227
|
+
var body = _serializeBatch(batch, cfg, scopeVersion);
|
|
228
|
+
try {
|
|
229
|
+
await retryHelper.withRetry(function () {
|
|
230
|
+
return _post(resolvedUrl, body, headers, cfg.timeoutMs, cfg.allowedProtocols, cfg.allowInternal);
|
|
231
|
+
}, cfg.retry);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
dropCount += batch.length;
|
|
234
|
+
_emitDrop("retry-exhausted", batch, e);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
231
237
|
}
|
|
238
|
+
} finally {
|
|
239
|
+
inFlight = false;
|
|
240
|
+
inFlightPromise = null;
|
|
241
|
+
if (buffer.length > 0) flushScheduler.schedule();
|
|
232
242
|
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (buffer.length > 0) flushScheduler.schedule();
|
|
236
|
-
}
|
|
243
|
+
})();
|
|
244
|
+
return inFlightPromise;
|
|
237
245
|
}
|
|
238
246
|
|
|
239
247
|
function emit(record) {
|
|
@@ -253,9 +261,15 @@ function create(config) {
|
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
async function close() {
|
|
256
|
-
closed
|
|
264
|
+
// Drain BEFORE flipping closed=true (see _flush's `&& !closed` guard) so
|
|
265
|
+
// records queued just before shutdown reach the wire. Mirrors the webhook
|
|
266
|
+
// + cloudwatch sinks.
|
|
257
267
|
flushScheduler.cancel();
|
|
268
|
+
if (inFlightPromise) {
|
|
269
|
+
try { await inFlightPromise; } catch (_e) { /* surfaced via onDrop */ }
|
|
270
|
+
}
|
|
258
271
|
await _flush();
|
|
272
|
+
closed = true;
|
|
259
273
|
}
|
|
260
274
|
|
|
261
275
|
function stats() {
|