@blamejs/blamejs-shop 0.4.31 → 0.4.33
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 +4 -0
- package/README.md +1 -1
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +400 -282
- 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 +28 -0
- package/lib/vendor/blamejs/MIGRATING.md +55 -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/elevation-grant.js +6 -2
- package/lib/vendor/blamejs/lib/auth/oauth.js +66 -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 +36 -7
- 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 +210 -4
- package/lib/vendor/blamejs/lib/consent.js +82 -29
- package/lib/vendor/blamejs/lib/constants.js +27 -11
- package/lib/vendor/blamejs/lib/credential-hash.js +9 -0
- 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 +117 -42
- 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 +47 -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 +169 -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/release-notes/v0.15.7.json +43 -0
- package/lib/vendor/blamejs/scripts/check-services.js +21 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +67 -0
- package/lib/vendor/blamejs/scripts/release.js +398 -38
- package/lib/vendor/blamejs/test/00-primitives.js +168 -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 +1196 -14
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/credential-hash.test.js +18 -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/retention-floor.test.js +59 -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 +362 -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/scheduler-watchdog-stale-settle.test.js +71 -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 +2 -2
- 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
|
@@ -53,6 +53,11 @@ var nodeUrl = require("node:url");
|
|
|
53
53
|
var { URL } = require("node:url");
|
|
54
54
|
|
|
55
55
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
56
|
+
// ssrf-guard requires safe-url at top of file (the SSRF gate parses through
|
|
57
|
+
// the framework's defensive URL parser); lazyRequire breaks that cycle so the
|
|
58
|
+
// canonicalizer can reuse ssrf-guard's IP-literal canonicalization without an
|
|
59
|
+
// at-load circular require.
|
|
60
|
+
var ssrfGuard = lazyRequire(function () { return require("./ssrf-guard"); });
|
|
56
61
|
|
|
57
62
|
/**
|
|
58
63
|
* @primitive b.safeUrl.ALLOW_HTTP_TLS
|
|
@@ -168,9 +173,9 @@ var ALLOW_ANY = Object.freeze(["http:", "https:", "ws:", "wss:"]);
|
|
|
168
173
|
* Extends `FrameworkError`. Carries a stable `.code`:
|
|
169
174
|
* `safe-url/missing` / `safe-url/too-long` / `safe-url/malformed` /
|
|
170
175
|
* `safe-url/protocol-disallowed` / `safe-url/userinfo-disallowed` /
|
|
171
|
-
* `safe-url/idn-homograph` / `safe-url/
|
|
172
|
-
* inspects `.code` to translate
|
|
173
|
-
* leaking parser internals.
|
|
176
|
+
* `safe-url/idn-homograph` / `safe-url/uncanonicalizable` /
|
|
177
|
+
* `safe-url/bad-opt`. HTTP middleware inspects `.code` to translate
|
|
178
|
+
* the throw into a 400 without leaking parser internals.
|
|
174
179
|
*
|
|
175
180
|
* @example
|
|
176
181
|
* var b = require("blamejs");
|
|
@@ -205,6 +210,38 @@ function _makeError(errorClass, code, message) {
|
|
|
205
210
|
// payloads) override via opts.maxUrlLength.
|
|
206
211
|
var DEFAULT_MAX_URL_LENGTH = C.BYTES.kib(8);
|
|
207
212
|
|
|
213
|
+
// RFC 3986 §6.2.2 percent-encoding normalization applied CONSERVATIVELY to a
|
|
214
|
+
// path segment string: uppercase the two hex digits of every valid escape
|
|
215
|
+
// (§6.2.2.2) and decode an escape of an unreserved character to its literal
|
|
216
|
+
// (§6.2.2.3). A malformed escape (`%`, `%g`, `%4`) is passed through verbatim
|
|
217
|
+
// so no information is invented. Query and fragment are NOT touched —
|
|
218
|
+
// reordering / re-decoding there can change application semantics (a `%26`
|
|
219
|
+
// inside a value is NOT the same as a literal `&`).
|
|
220
|
+
function _normalizePctPath(path) {
|
|
221
|
+
if (typeof path !== "string" || path.indexOf("%") === -1) return path;
|
|
222
|
+
var out = "";
|
|
223
|
+
for (var i = 0; i < path.length; i += 1) {
|
|
224
|
+
var ch = path.charAt(i);
|
|
225
|
+
if (ch === "%") {
|
|
226
|
+
// The escape's two hex digits — sliced to a fixed two-char window so
|
|
227
|
+
// the regex test runs on a length-bounded string (no ReDoS surface).
|
|
228
|
+
var pair = path.slice(i + 1, i + 3);
|
|
229
|
+
if (pair.length === 2 && codepointClass.HEX_PAIR_RE.test(pair)) {
|
|
230
|
+
var cc = parseInt(pair, 16);
|
|
231
|
+
if (codepointClass.isUnreserved(cc)) {
|
|
232
|
+
out += String.fromCharCode(cc);
|
|
233
|
+
} else {
|
|
234
|
+
out += "%" + pair.toUpperCase();
|
|
235
|
+
}
|
|
236
|
+
i += 2;
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
out += ch;
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
|
|
208
245
|
/**
|
|
209
246
|
* @primitive b.safeUrl.parse
|
|
210
247
|
* @signature b.safeUrl.parse(url, opts?)
|
|
@@ -416,9 +453,139 @@ function format(url) {
|
|
|
416
453
|
}
|
|
417
454
|
}
|
|
418
455
|
|
|
456
|
+
/**
|
|
457
|
+
* @primitive b.safeUrl.canonicalize
|
|
458
|
+
* @signature b.safeUrl.canonicalize(input, opts?)
|
|
459
|
+
* @since 0.15.6
|
|
460
|
+
* @status stable
|
|
461
|
+
* @related b.safeUrl.parse, b.ssrfGuard.canonicalizeHost, b.ssrfGuard.checkUrl
|
|
462
|
+
*
|
|
463
|
+
* Return the single canonical, comparable form of a URL so two
|
|
464
|
+
* spellings of the same destination compare equal as strings. The use
|
|
465
|
+
* cases are host allowlists, dedup / cache keys, and SSRF pre-checks —
|
|
466
|
+
* exactly the places an attacker reaches for an obfuscated host
|
|
467
|
+
* (`http://0177.0.0.1/`, `http://2130706433/`, `http://[::ffff:7f00:1]/`,
|
|
468
|
+
* an IDN homograph, a trailing-dot or default-port variation) to slip
|
|
469
|
+
* past a naive `===` allowlist. Routing every comparison through one
|
|
470
|
+
* audited canonicalizer closes that class instead of leaving each
|
|
471
|
+
* caller to re-derive normalization (which is how the bypasses happen).
|
|
472
|
+
*
|
|
473
|
+
* The canonical form is built from `parse`'s defensive gates plus the
|
|
474
|
+
* security-relevant normalization set:
|
|
475
|
+
*
|
|
476
|
+
* - Scheme and host lowercased (the WHATWG URL parser does this).
|
|
477
|
+
* - Host IDN labels emitted as their punycode `xn--` A-label; a
|
|
478
|
+
* mixed-script / confusable host label THROWS exactly as
|
|
479
|
+
* `parse` does (a homograph is never silently passed) unless the
|
|
480
|
+
* caller opts in via `allowMixedScript` / `allowedScripts`.
|
|
481
|
+
* - A trailing dot on the host is removed (`example.com.` →
|
|
482
|
+
* `example.com`) — DNS-equivalent but breaks string comparison.
|
|
483
|
+
* - An IP-literal host in ANY notation collapses to one canonical
|
|
484
|
+
* string via `b.ssrfGuard.canonicalizeHost` (the SAME byte parser
|
|
485
|
+
* the SSRF classifier matches on): IPv4 decimal / octal / hex /
|
|
486
|
+
* shorthand → dotted-quad; IPv6 (incl. IPv4-mapped + any
|
|
487
|
+
* zero-compression) → RFC 5952 lower-hex, bracketed.
|
|
488
|
+
* - The default port for the scheme is stripped (`:80` http/ws,
|
|
489
|
+
* `:443` https/wss — the parser does this).
|
|
490
|
+
* - Path `.` / `..` segments resolved (WHATWG), then RFC 3986 §6.2.2
|
|
491
|
+
* percent-normalization applied to the path: hex digits uppercased,
|
|
492
|
+
* escapes of unreserved characters decoded. Query and fragment are
|
|
493
|
+
* left BYTE-FOR-BYTE as parsed — reordering or re-decoding there can
|
|
494
|
+
* change application semantics.
|
|
495
|
+
*
|
|
496
|
+
* Throws `SafeUrlError` (or `opts.errorClass`): the `parse` codes for a
|
|
497
|
+
* missing / too-long / malformed / disallowed-scheme / userinfo /
|
|
498
|
+
* homograph input, plus `safe-url/uncanonicalizable` when a parsed URL
|
|
499
|
+
* cannot be reduced to a safe canonical form. This is a config /
|
|
500
|
+
* entry-point validator — it THROWS on bad input, it does NOT return a
|
|
501
|
+
* best-effort string.
|
|
502
|
+
*
|
|
503
|
+
* @opts
|
|
504
|
+
* allowedSchemes: string[], // default ALLOW_ANY (http/https/ws/wss); canonicalize is a compare tool, not a fetch gate
|
|
505
|
+
* allowUserinfo: boolean, // default false; opt-in to keep user:pass@ (still discouraged)
|
|
506
|
+
* allowMixedScript: boolean, // default false; opt-in to mixed-script host labels
|
|
507
|
+
* allowedScripts: string[], // narrow mixed-script allowlist (e.g. ["latin","cyrillic"])
|
|
508
|
+
* maxUrlLength: number, // default 8192 (RFC 7230 §3.1.1)
|
|
509
|
+
* errorClass: Function, // throw this instead of SafeUrlError
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* var b = require("blamejs");
|
|
513
|
+
*
|
|
514
|
+
* // Every obfuscated loopback spelling collapses to one string.
|
|
515
|
+
* b.safeUrl.canonicalize("http://0177.0.0.1/"); // → "http://127.0.0.1/"
|
|
516
|
+
* b.safeUrl.canonicalize("http://2130706433/"); // → "http://127.0.0.1/"
|
|
517
|
+
* b.safeUrl.canonicalize("http://127.1/"); // → "http://127.0.0.1/"
|
|
518
|
+
*
|
|
519
|
+
* // Case, default port, trailing dot, and `..` all normalize.
|
|
520
|
+
* b.safeUrl.canonicalize("https://Example.COM:443/a/../b");
|
|
521
|
+
* // → "https://example.com/b"
|
|
522
|
+
*
|
|
523
|
+
* // A disallowed scheme throws SafeUrlError.
|
|
524
|
+
* try { b.safeUrl.canonicalize("ftp://example.com/"); }
|
|
525
|
+
* catch (e) { e.code; } // → "safe-url/protocol-disallowed"
|
|
526
|
+
*/
|
|
527
|
+
function canonicalize(input, opts) {
|
|
528
|
+
opts = opts || {};
|
|
529
|
+
var allowedSchemes = Array.isArray(opts.allowedSchemes) && opts.allowedSchemes.length > 0
|
|
530
|
+
? opts.allowedSchemes
|
|
531
|
+
: ALLOW_ANY;
|
|
532
|
+
|
|
533
|
+
// Route through parse — it owns the length cap, the scheme allowlist,
|
|
534
|
+
// userinfo refusal, and the IDN-homograph defense. A parse throw (with
|
|
535
|
+
// its stable .code) propagates unchanged so callers branch on the same
|
|
536
|
+
// codes parse documents.
|
|
537
|
+
var parsed = parse(input, {
|
|
538
|
+
allowedProtocols: allowedSchemes,
|
|
539
|
+
maxUrlLength: opts.maxUrlLength,
|
|
540
|
+
allowUserinfo: opts.allowUserinfo,
|
|
541
|
+
allowMixedScript: opts.allowMixedScript,
|
|
542
|
+
allowedScripts: opts.allowedScripts,
|
|
543
|
+
errorClass: opts.errorClass,
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
try {
|
|
547
|
+
// The parser already lowercased the scheme + host, stripped the
|
|
548
|
+
// default port, emitted IDN as punycode, and resolved `.`/`..`. The
|
|
549
|
+
// canonicalizer adds: IP-literal collapse (shared with the SSRF
|
|
550
|
+
// classifier), trailing-dot removal, and path percent-normalization.
|
|
551
|
+
var scheme = parsed.protocol; // e.g. "https:"
|
|
552
|
+
var rawHost = parsed.hostname; // already lowercase / punycode / default-port-free
|
|
553
|
+
var canonHost = ssrfGuard().canonicalizeHost(rawHost);
|
|
554
|
+
// canonicalizeHost returns IPv6 UNbracketed; a URL authority needs the
|
|
555
|
+
// brackets back. net.isIP via the colon is a sufficient discriminator
|
|
556
|
+
// (a DNS label can't contain a colon).
|
|
557
|
+
var host = canonHost.indexOf(":") !== -1 ? "[" + canonHost + "]" : canonHost;
|
|
558
|
+
|
|
559
|
+
// Userinfo (`user:pass@`) is deliberately DROPPED from the canonical form.
|
|
560
|
+
// The canonical string is built to be compared, used as a dedup / cache
|
|
561
|
+
// key, or logged; carrying a credential into any of those leaks it, and
|
|
562
|
+
// the username/password are not part of the resource's target identity for
|
|
563
|
+
// an allowlist / SSRF decision. parse() already refuses userinfo unless
|
|
564
|
+
// allowUserinfo:true; even then, the canonical output omits it (never reads
|
|
565
|
+
// parsed.password), so two URLs that differ only in credentials canonicalize
|
|
566
|
+
// equal.
|
|
567
|
+
|
|
568
|
+
var port = parsed.port !== "" ? ":" + parsed.port : "";
|
|
569
|
+
var path = _normalizePctPath(parsed.pathname);
|
|
570
|
+
// Query + fragment: byte-for-byte as the parser emitted them. Reordering
|
|
571
|
+
// a query or re-decoding a value changes semantics — out of scope for a
|
|
572
|
+
// safe canonicalizer.
|
|
573
|
+
var query = parsed.search;
|
|
574
|
+
var fragment = parsed.hash;
|
|
575
|
+
|
|
576
|
+
return scheme + "//" + host + port + path + query + fragment;
|
|
577
|
+
} catch (e) {
|
|
578
|
+
if (e && e.isSafeUrlError) throw e;
|
|
579
|
+
throw _makeError(opts.errorClass, "safe-url/uncanonicalizable",
|
|
580
|
+
"safeUrl.canonicalize could not reduce the URL to a canonical form: " +
|
|
581
|
+
((e && e.message) || String(e)));
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
419
585
|
module.exports = {
|
|
420
586
|
parse: parse,
|
|
421
587
|
format: format,
|
|
588
|
+
canonicalize: canonicalize,
|
|
422
589
|
SafeUrlError: SafeUrlError,
|
|
423
590
|
ALLOW_HTTP_TLS: ALLOW_HTTP_TLS,
|
|
424
591
|
ALLOW_HTTP_ALL: ALLOW_HTTP_ALL,
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
|
|
64
64
|
var C = require("./constants");
|
|
65
65
|
var { defineClass } = require("./framework-error");
|
|
66
|
+
var gateContract = require("./gate-contract");
|
|
66
67
|
|
|
67
68
|
var SafeVcardError = defineClass("SafeVcardError", { alwaysPermanent: true });
|
|
68
69
|
|
|
@@ -90,12 +91,7 @@ var PROFILES = Object.freeze({
|
|
|
90
91
|
}),
|
|
91
92
|
});
|
|
92
93
|
|
|
93
|
-
var COMPLIANCE_POSTURES =
|
|
94
|
-
hipaa: "strict",
|
|
95
|
-
"pci-dss": "strict",
|
|
96
|
-
gdpr: "strict",
|
|
97
|
-
soc2: "strict",
|
|
98
|
-
});
|
|
94
|
+
var COMPLIANCE_POSTURES = gateContract.ALL_STRICT_POSTURES;
|
|
99
95
|
|
|
100
96
|
// Property-name allowlist per RFC 6350 §6 (vCard 4.0 property
|
|
101
97
|
// registry) + RFC 2426 §3 (legacy 3.0 properties retained for
|
|
@@ -217,24 +213,6 @@ function parse(text, opts) {
|
|
|
217
213
|
return { vcards: vcards };
|
|
218
214
|
}
|
|
219
215
|
|
|
220
|
-
/**
|
|
221
|
-
* @primitive b.safeVcard.compliancePosture
|
|
222
|
-
* @signature b.safeVcard.compliancePosture(name)
|
|
223
|
-
* @since 0.9.81
|
|
224
|
-
* @status stable
|
|
225
|
-
* @related b.safeVcard.parse
|
|
226
|
-
*
|
|
227
|
-
* Map a compliance-posture name to its profile. Returns the profile
|
|
228
|
-
* string for a known posture, `null` for unknown names.
|
|
229
|
-
*
|
|
230
|
-
* @example
|
|
231
|
-
* b.safeVcard.compliancePosture("hipaa"); // -> "strict"
|
|
232
|
-
* b.safeVcard.compliancePosture("loose"); // -> null
|
|
233
|
-
*/
|
|
234
|
-
function compliancePosture(name) {
|
|
235
|
-
return COMPLIANCE_POSTURES[name] || null;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
216
|
// ---- Internal ----
|
|
239
217
|
|
|
240
218
|
function _resolveCaps(opts) {
|
|
@@ -462,12 +440,19 @@ function _preview(s) {
|
|
|
462
440
|
return s.length > 64 ? s.slice(0, 64) + "..." : s; // log-preview length cap
|
|
463
441
|
}
|
|
464
442
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
443
|
+
// compliancePosture is assembled by gateContract.defineParser below; its
|
|
444
|
+
// wiki section renders from the single-sourced @abiTemplate (defineParser)
|
|
445
|
+
// block in gate-contract.js, instantiated for this guard by the page
|
|
446
|
+
// generator.
|
|
447
|
+
module.exports = gateContract.defineParser({
|
|
448
|
+
name: "vcard",
|
|
449
|
+
entry: parse,
|
|
450
|
+
entryName: "parse",
|
|
451
|
+
errorClass: SafeVcardError,
|
|
452
|
+
profiles: PROFILES,
|
|
453
|
+
postures: COMPLIANCE_POSTURES,
|
|
454
|
+
extra: {
|
|
455
|
+
KNOWN_PROPERTIES: KNOWN_PROPERTIES,
|
|
456
|
+
EMBED_PROPERTIES: EMBED_PROPERTIES,
|
|
457
|
+
},
|
|
458
|
+
});
|
|
@@ -43,6 +43,7 @@ var lazyRequire = require("./lazy-require");
|
|
|
43
43
|
var audit = lazyRequire(function () { return require("./audit"); });
|
|
44
44
|
var log = lazyRequire(function () { return require("./log").boot("scheduler"); });
|
|
45
45
|
var clusterStorage = require("./cluster-storage");
|
|
46
|
+
var sql = require("./sql");
|
|
46
47
|
var validateOpts = require("./validate-opts");
|
|
47
48
|
var C = require("./constants");
|
|
48
49
|
var { SchedulerError } = require("./framework-error");
|
|
@@ -51,6 +52,18 @@ var DEFAULT_MAX_JOB_MS = C.TIME.minutes(10);
|
|
|
51
52
|
var DEFAULT_TICK_RETENTION_MS = C.TIME.days(7);
|
|
52
53
|
var DEFAULT_TICK_PRUNE_INTERVAL_MS = C.TIME.minutes(1);
|
|
53
54
|
|
|
55
|
+
// b.sql opts for every _blamejs_scheduler_ticks statement: thread the ACTIVE
|
|
56
|
+
// backend dialect (clusterStorage.dialect() — "sqlite" single-node,
|
|
57
|
+
// "postgres" | "mysql" in cluster mode) so the emitted identifier quoting +
|
|
58
|
+
// dialect idioms (ON CONFLICT DO NOTHING vs the MySQL no-op fold) match the
|
|
59
|
+
// backend the SQL dispatches to. Defaulting to "sqlite" works on Postgres
|
|
60
|
+
// only by accident (both double-quote identifiers) and emits the wrong
|
|
61
|
+
// quoting on MySQL. clusterStorage.execute still rewrites the bare table name
|
|
62
|
+
// + translates `?` placeholders at dispatch; this controls only the builder-
|
|
63
|
+
// side quoting + idiom selection. The table name stays BARE (no quoteName)
|
|
64
|
+
// so clusterStorage's prefix rewrite still fires.
|
|
65
|
+
function _ticksSqlOpts() { return { dialect: clusterStorage.dialect() }; }
|
|
66
|
+
|
|
54
67
|
// ---- Cron parsing ----
|
|
55
68
|
|
|
56
69
|
var CRON_SHORTHANDS = {
|
|
@@ -475,6 +488,10 @@ function create(opts) {
|
|
|
475
488
|
lastError: null,
|
|
476
489
|
running: false,
|
|
477
490
|
runningSince: 0,
|
|
491
|
+
// Monotonic run tag. The watchdog and each fire bump it, so a run the
|
|
492
|
+
// watchdog abandoned can't clobber state / emit a stale settle event
|
|
493
|
+
// when its slow promise finally resolves.
|
|
494
|
+
runGeneration: 0,
|
|
478
495
|
fires: 0,
|
|
479
496
|
misses: 0, // skipped because previous run still in-flight
|
|
480
497
|
nonLeaderSkips: 0,
|
|
@@ -497,7 +514,7 @@ function create(opts) {
|
|
|
497
514
|
task.nextRun = Date.now() + spec.every;
|
|
498
515
|
}
|
|
499
516
|
task.exprDesc = "every " + spec.every + "ms" +
|
|
500
|
-
(spec.baseline ? "
|
|
517
|
+
(spec.baseline ? " anchored " + spec.baseline : "") +
|
|
501
518
|
(tz ? " " + tz : "");
|
|
502
519
|
}
|
|
503
520
|
|
|
@@ -527,6 +544,8 @@ function create(opts) {
|
|
|
527
544
|
(maxJobMs / C.TIME.seconds(1)) + "s — forcing reset");
|
|
528
545
|
} catch (_e) { /* logger best-effort */ }
|
|
529
546
|
_emit("system.scheduler.task.watchdog", { name: task.name }, "failure");
|
|
547
|
+
// Supersede the abandoned run so its late settle is ignored.
|
|
548
|
+
task.runGeneration++;
|
|
530
549
|
task.running = false;
|
|
531
550
|
} else {
|
|
532
551
|
task.misses++;
|
|
@@ -562,13 +581,23 @@ function create(opts) {
|
|
|
562
581
|
var tickKey = task.name + ":" + nominalRun;
|
|
563
582
|
var claimedBy = (typeof clusterInstance.currentNodeId === "function")
|
|
564
583
|
? clusterInstance.currentNodeId() : "unknown";
|
|
565
|
-
clusterStorage
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
[tickKey,
|
|
571
|
-
|
|
584
|
+
// BARE logical table name — clusterStorage rewrites _blamejs_scheduler_ticks
|
|
585
|
+
// to the configured prefix and placeholderizes the ? markers. The
|
|
586
|
+
// PRIMARY KEY race on tickKey deduplicates the split-brain window; the
|
|
587
|
+
// loser's ON CONFLICT DO NOTHING reports zero rowCount and skips.
|
|
588
|
+
var claimBuilt = sql.upsert("_blamejs_scheduler_ticks", _ticksSqlOpts()) // allow:hand-rolled-sql — bare logical name for clusterStorage rewrite
|
|
589
|
+
.columns(["tickKey", "name", "scheduledAtUnix", "claimedAtUnix", "claimedBy"])
|
|
590
|
+
.values({
|
|
591
|
+
tickKey: tickKey,
|
|
592
|
+
name: task.name,
|
|
593
|
+
scheduledAtUnix: nominalRun,
|
|
594
|
+
claimedAtUnix: Date.now(),
|
|
595
|
+
claimedBy: claimedBy,
|
|
596
|
+
})
|
|
597
|
+
.onConflict(["tickKey"])
|
|
598
|
+
.doNothing()
|
|
599
|
+
.toSql();
|
|
600
|
+
clusterStorage.execute(claimBuilt.sql, claimBuilt.params).then(function (result) {
|
|
572
601
|
var won = (result && result.rowCount > 0);
|
|
573
602
|
if (won) {
|
|
574
603
|
_runFire(task);
|
|
@@ -604,10 +633,10 @@ function create(opts) {
|
|
|
604
633
|
var threshold = Date.now() - (
|
|
605
634
|
typeof olderThanMs === "number" ? olderThanMs : tickRetentionMs
|
|
606
635
|
);
|
|
607
|
-
var
|
|
608
|
-
"
|
|
609
|
-
|
|
610
|
-
);
|
|
636
|
+
var pruneBuilt = sql.delete("_blamejs_scheduler_ticks", _ticksSqlOpts()) // allow:hand-rolled-sql — bare logical name for clusterStorage rewrite
|
|
637
|
+
.where("scheduledAtUnix", "<", threshold)
|
|
638
|
+
.toSql();
|
|
639
|
+
var result = await clusterStorage.execute(pruneBuilt.sql, pruneBuilt.params);
|
|
611
640
|
var removed = (result && result.rowCount) || 0;
|
|
612
641
|
if (removed > 0) {
|
|
613
642
|
_emit("system.scheduler.tick.pruned", {
|
|
@@ -642,6 +671,10 @@ function create(opts) {
|
|
|
642
671
|
task.runningSince = Date.now();
|
|
643
672
|
task.lastRun = new Date().toISOString();
|
|
644
673
|
var startedAt = Date.now();
|
|
674
|
+
// Tag this run. The settle handlers below only write back if the tag still
|
|
675
|
+
// matches — so a run the watchdog reset (or a newer fire) can't clobber the
|
|
676
|
+
// current run's state or emit a stale success/failure when it settles late.
|
|
677
|
+
var gen = (task.runGeneration = (task.runGeneration || 0) + 1);
|
|
645
678
|
|
|
646
679
|
var promise;
|
|
647
680
|
try {
|
|
@@ -655,6 +688,7 @@ function create(opts) {
|
|
|
655
688
|
}
|
|
656
689
|
|
|
657
690
|
Promise.resolve(promise).then(function (_v) {
|
|
691
|
+
if (task.runGeneration !== gen) return; // watchdog/newer fire superseded this run
|
|
658
692
|
task.running = false;
|
|
659
693
|
task.runningSince = 0;
|
|
660
694
|
task.lastFinish = new Date().toISOString();
|
|
@@ -666,6 +700,7 @@ function create(opts) {
|
|
|
666
700
|
viaJob: !!task.job,
|
|
667
701
|
});
|
|
668
702
|
}, function (e) {
|
|
703
|
+
if (task.runGeneration !== gen) return; // watchdog/newer fire superseded this run
|
|
669
704
|
task.running = false;
|
|
670
705
|
task.runningSince = 0;
|
|
671
706
|
task.lastFinish = new Date().toISOString();
|