@blamejs/blamejs-shop 0.0.44
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 +87 -0
- package/LICENSE +17 -0
- package/README.md +117 -0
- package/SECURITY.md +139 -0
- package/lib/admin.js +952 -0
- package/lib/analytics.js +267 -0
- package/lib/cart.js +279 -0
- package/lib/catalog-import.js +344 -0
- package/lib/catalog.js +769 -0
- package/lib/checkout.js +320 -0
- package/lib/config.js +151 -0
- package/lib/customers.js +322 -0
- package/lib/email.js +242 -0
- package/lib/externaldb-d1.js +283 -0
- package/lib/index.js +57 -0
- package/lib/inventory-alerts.js +198 -0
- package/lib/newsletter.js +142 -0
- package/lib/order.js +380 -0
- package/lib/payment.js +318 -0
- package/lib/pricing.js +185 -0
- package/lib/r2-bridge.js +169 -0
- package/lib/shipping.js +185 -0
- package/lib/storefront.js +2160 -0
- package/lib/subscriptions.js +410 -0
- package/lib/tax.js +161 -0
- package/lib/theme.js +194 -0
- package/lib/vendor/MANIFEST.json +19 -0
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +23 -0
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +34 -0
- package/lib/vendor/blamejs/.clusterfuzzlite/project.yaml +16 -0
- package/lib/vendor/blamejs/.dockerignore +45 -0
- package/lib/vendor/blamejs/.gitattributes +42 -0
- package/lib/vendor/blamejs/.github/CODEOWNERS +4 -0
- package/lib/vendor/blamejs/.github/FUNDING.yml +2 -0
- package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/bug_report.md +58 -0
- package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/lib/vendor/blamejs/.github/ISSUE_TEMPLATE/feature_request.md +99 -0
- package/lib/vendor/blamejs/.github/PULL_REQUEST_TEMPLATE.md +77 -0
- package/lib/vendor/blamejs/.github/dependabot.yml +37 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +148 -0
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +107 -0
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +122 -0
- package/lib/vendor/blamejs/.github/workflows/ci.yml +511 -0
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +50 -0
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +655 -0
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +406 -0
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +101 -0
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +134 -0
- package/lib/vendor/blamejs/.gitignore +102 -0
- package/lib/vendor/blamejs/.gitleaks.toml +166 -0
- package/lib/vendor/blamejs/.hadolint.yaml +18 -0
- package/lib/vendor/blamejs/.npmrc +5 -0
- package/lib/vendor/blamejs/.pinact.yaml +17 -0
- package/lib/vendor/blamejs/ARCHITECTURE.md +158 -0
- package/lib/vendor/blamejs/CHANGELOG.md +1351 -0
- package/lib/vendor/blamejs/CODE_OF_CONDUCT.md +86 -0
- package/lib/vendor/blamejs/CONTRIBUTING.md +156 -0
- package/lib/vendor/blamejs/GOVERNANCE.md +201 -0
- package/lib/vendor/blamejs/LICENSE +201 -0
- package/lib/vendor/blamejs/LTS-CALENDAR.md +29 -0
- package/lib/vendor/blamejs/MIGRATING.md +29 -0
- package/lib/vendor/blamejs/NOTICE +81 -0
- package/lib/vendor/blamejs/README.md +304 -0
- package/lib/vendor/blamejs/SECURITY.md +432 -0
- package/lib/vendor/blamejs/api-snapshot.json +48709 -0
- package/lib/vendor/blamejs/assets/BlameJS_Logo.png +0 -0
- package/lib/vendor/blamejs/assets/BlameJS_Logo.svg +129 -0
- package/lib/vendor/blamejs/bench/README.md +77 -0
- package/lib/vendor/blamejs/bench/_helpers.js +70 -0
- package/lib/vendor/blamejs/bench/baseline.json +183 -0
- package/lib/vendor/blamejs/bench/crypto-hash.bench.js +19 -0
- package/lib/vendor/blamejs/bench/crypto-symmetric.bench.js +28 -0
- package/lib/vendor/blamejs/bench/run.js +140 -0
- package/lib/vendor/blamejs/bench/safe-json.bench.js +31 -0
- package/lib/vendor/blamejs/bin/blamejs.js +13 -0
- package/lib/vendor/blamejs/docker/caddy/Caddyfile +46 -0
- package/lib/vendor/blamejs/docker/coredns/Corefile +37 -0
- package/lib/vendor/blamejs/docker/haproxy/haproxy.cfg +52 -0
- package/lib/vendor/blamejs/docker/init/generate-certs.sh +118 -0
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +87 -0
- package/lib/vendor/blamejs/docker/mitmproxy/config.yaml +16 -0
- package/lib/vendor/blamejs/docker/mongo/init-tls.sh +17 -0
- package/lib/vendor/blamejs/docker/mysql/my.cnf +12 -0
- package/lib/vendor/blamejs/docker/nats/nats.conf +33 -0
- package/lib/vendor/blamejs/docker/postgres/init-tls.sh +17 -0
- package/lib/vendor/blamejs/docker/postgres/postgresql.conf +18 -0
- package/lib/vendor/blamejs/docker/rabbitmq/rabbitmq.conf +18 -0
- package/lib/vendor/blamejs/docker/redis/redis.conf +15 -0
- package/lib/vendor/blamejs/docker/squid/squid.conf +24 -0
- package/lib/vendor/blamejs/docker/syslog/syslog-ng.conf +34 -0
- package/lib/vendor/blamejs/docker-compose.test.yml +545 -0
- package/lib/vendor/blamejs/docs/cis-postgres-crosswalk.md +102 -0
- package/lib/vendor/blamejs/docs/cis-sqlite-equivalent.md +92 -0
- package/lib/vendor/blamejs/eslint.config.mjs +204 -0
- package/lib/vendor/blamejs/examples/wiki/Caddyfile +40 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +218 -0
- package/lib/vendor/blamejs/examples/wiki/Dockerfile +120 -0
- package/lib/vendor/blamejs/examples/wiki/README.md +157 -0
- package/lib/vendor/blamejs/examples/wiki/cli-snapshot.json +250 -0
- package/lib/vendor/blamejs/examples/wiki/docker-compose.prod.yml +231 -0
- package/lib/vendor/blamejs/examples/wiki/docker-compose.yml +166 -0
- package/lib/vendor/blamejs/examples/wiki/env-snapshot.json +217 -0
- package/lib/vendor/blamejs/examples/wiki/lib/auto-site-entries.js +139 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +555 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-cli.js +507 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-env-vars.js +435 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-errors.js +282 -0
- package/lib/vendor/blamejs/examples/wiki/lib/harvest-vendored-deps.js +321 -0
- package/lib/vendor/blamejs/examples/wiki/lib/nav.js +15 -0
- package/lib/vendor/blamejs/examples/wiki/lib/opts-resolver.js +75 -0
- package/lib/vendor/blamejs/examples/wiki/lib/page-generator.js +508 -0
- package/lib/vendor/blamejs/examples/wiki/lib/section.js +276 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +587 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-doc-parser.js +318 -0
- package/lib/vendor/blamejs/examples/wiki/lib/symbol-index.js +122 -0
- package/lib/vendor/blamejs/examples/wiki/migrations/0001-pages-schema.js +74 -0
- package/lib/vendor/blamejs/examples/wiki/package.json +18 -0
- package/lib/vendor/blamejs/examples/wiki/public/img/blamejs-logo.png +0 -0
- package/lib/vendor/blamejs/examples/wiki/public/img/blamejs-logo.svg +129 -0
- package/lib/vendor/blamejs/examples/wiki/public/robots.txt +5 -0
- package/lib/vendor/blamejs/examples/wiki/public/vendor/MANIFEST.json +30 -0
- package/lib/vendor/blamejs/examples/wiki/public/vendor/prism.css +1 -0
- package/lib/vendor/blamejs/examples/wiki/public/vendor/prism.js +15 -0
- package/lib/vendor/blamejs/examples/wiki/public/wiki.css +1250 -0
- package/lib/vendor/blamejs/examples/wiki/routes/admin.js +366 -0
- package/lib/vendor/blamejs/examples/wiki/routes/integration.js +230 -0
- package/lib/vendor/blamejs/examples/wiki/routes/pages.js +266 -0
- package/lib/vendor/blamejs/examples/wiki/scripts/backfill-module-metadata.js +214 -0
- package/lib/vendor/blamejs/examples/wiki/seeders/prod/0001-default-pages.js +35 -0
- package/lib/vendor/blamejs/examples/wiki/seeders/prod/pages/_index.js +34 -0
- package/lib/vendor/blamejs/examples/wiki/seeders/prod/pages/api.js +76 -0
- package/lib/vendor/blamejs/examples/wiki/server.js +129 -0
- package/lib/vendor/blamejs/examples/wiki/site.config.js +197 -0
- package/lib/vendor/blamejs/examples/wiki/snippets/README.md +38 -0
- package/lib/vendor/blamejs/examples/wiki/snippets/auth/password-hash.example.js +15 -0
- package/lib/vendor/blamejs/examples/wiki/src/editor.js +103 -0
- package/lib/vendor/blamejs/examples/wiki/src/wiki.js +349 -0
- package/lib/vendor/blamejs/examples/wiki/test/AUDIT.md +155 -0
- package/lib/vendor/blamejs/examples/wiki/test/codebase-patterns.test.js +594 -0
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +741 -0
- package/lib/vendor/blamejs/examples/wiki/test/find-missing-pages.js +254 -0
- package/lib/vendor/blamejs/examples/wiki/test/integration.js +391 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-cli-snapshot.js +379 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-env-snapshot.js +346 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-nav-coverage.js +212 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-site-coverage.js +252 -0
- package/lib/vendor/blamejs/examples/wiki/test/validate-source-comment-blocks.js +107 -0
- package/lib/vendor/blamejs/examples/wiki/views/_layout.html +115 -0
- package/lib/vendor/blamejs/examples/wiki/views/admin/api-keys.html +51 -0
- package/lib/vendor/blamejs/examples/wiki/views/admin/dashboard.html +22 -0
- package/lib/vendor/blamejs/examples/wiki/views/admin/edit.html +17 -0
- package/lib/vendor/blamejs/examples/wiki/views/home.html +85 -0
- package/lib/vendor/blamejs/examples/wiki/views/login.html +18 -0
- package/lib/vendor/blamejs/examples/wiki/views/page.html +5 -0
- package/lib/vendor/blamejs/examples/wiki/views/partials/nav.html +13 -0
- package/lib/vendor/blamejs/examples/wiki/views/search.html +19 -0
- package/lib/vendor/blamejs/examples/wiki/wiki.config.js +15 -0
- package/lib/vendor/blamejs/fuzz/README.md +137 -0
- package/lib/vendor/blamejs/fuzz/_expected.js +35 -0
- package/lib/vendor/blamejs/fuzz/guard-agent-registry.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-csv.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/01-basic.csv +3 -0
- package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/02-formula.csv +1 -0
- package/lib/vendor/blamejs/fuzz/guard-csv_seed_corpus/03-hyperlink.csv +1 -0
- package/lib/vendor/blamejs/fuzz/guard-dsn.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-email.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-email_seed_corpus/01-basic.eml +5 -0
- package/lib/vendor/blamejs/fuzz/guard-envelope.fuzz.js +24 -0
- package/lib/vendor/blamejs/fuzz/guard-event-bus-payload.fuzz.js +24 -0
- package/lib/vendor/blamejs/fuzz/guard-event-bus-topic.fuzz.js +20 -0
- package/lib/vendor/blamejs/fuzz/guard-html.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/01-basic.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/02-script.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/03-event.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-html_seed_corpus/04-jsurl.html +1 -0
- package/lib/vendor/blamejs/fuzz/guard-idempotency-key.fuzz.js +20 -0
- package/lib/vendor/blamejs/fuzz/guard-imap-command.fuzz.js +35 -0
- package/lib/vendor/blamejs/fuzz/guard-jmap.fuzz.js +41 -0
- package/lib/vendor/blamejs/fuzz/guard-json.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/01-basic.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/02-proto.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/03-dupkey.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/04-nan.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-json_seed_corpus/05-bom.json +1 -0
- package/lib/vendor/blamejs/fuzz/guard-list-id.fuzz.js +21 -0
- package/lib/vendor/blamejs/fuzz/guard-list-unsubscribe.fuzz.js +25 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-compose.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-move.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-query.fuzz.js +27 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-reply.fuzz.js +23 -0
- package/lib/vendor/blamejs/fuzz/guard-mail-sieve.fuzz.js +36 -0
- package/lib/vendor/blamejs/fuzz/guard-managesieve-command.fuzz.js +26 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/01-basic.md +2 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/02-jsurl.md +1 -0
- package/lib/vendor/blamejs/fuzz/guard-markdown_seed_corpus/03-jsimg.md +1 -0
- package/lib/vendor/blamejs/fuzz/guard-message-id.fuzz.js +26 -0
- package/lib/vendor/blamejs/fuzz/guard-pop3-command.fuzz.js +23 -0
- package/lib/vendor/blamejs/fuzz/guard-posture-chain.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-saga-config.fuzz.js +32 -0
- package/lib/vendor/blamejs/fuzz/guard-smtp-command.fuzz.js +27 -0
- package/lib/vendor/blamejs/fuzz/guard-snapshot-envelope.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-stream-args.fuzz.js +22 -0
- package/lib/vendor/blamejs/fuzz/guard-svg.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-svg_seed_corpus/01-basic.svg +1 -0
- package/lib/vendor/blamejs/fuzz/guard-svg_seed_corpus/02-script.svg +1 -0
- package/lib/vendor/blamejs/fuzz/guard-tenant-id.fuzz.js +20 -0
- package/lib/vendor/blamejs/fuzz/guard-trace-context.fuzz.js +30 -0
- package/lib/vendor/blamejs/fuzz/guard-xml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-xml_seed_corpus/01-basic.xml +1 -0
- package/lib/vendor/blamejs/fuzz/guard-xml_seed_corpus/02-xxe.xml +1 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/01-basic.yaml +2 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/02-anchor.yaml +2 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/03-norway.yaml +1 -0
- package/lib/vendor/blamejs/fuzz/guard-yaml_seed_corpus/04-multidoc.yaml +4 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-ini.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-ini_seed_corpus/01-basic.ini +2 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-toml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-toml_seed_corpus/01-basic.toml +4 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-xml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-xml_seed_corpus/01-basic.xml +1 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-yaml.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/parsers__safe-yaml_seed_corpus/01-basic.yaml +4 -0
- package/lib/vendor/blamejs/fuzz/safe-decompress.fuzz.js +49 -0
- package/lib/vendor/blamejs/fuzz/safe-dns.fuzz.js +29 -0
- package/lib/vendor/blamejs/fuzz/safe-ical.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/safe-icap.fuzz.js +42 -0
- package/lib/vendor/blamejs/fuzz/safe-json.fuzz.js +25 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/01-object.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/02-array.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/03-string.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/04-proto.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-json_seed_corpus/05-deep.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/01-basic.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/02-filter.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/03-deepscan.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-jsonpath_seed_corpus/04-slice.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-mime.fuzz.js +27 -0
- package/lib/vendor/blamejs/fuzz/safe-mount-info.fuzz.js +33 -0
- package/lib/vendor/blamejs/fuzz/safe-sieve.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/safe-smtp.fuzz.js +64 -0
- package/lib/vendor/blamejs/fuzz/safe-url.fuzz.js +16 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/01-basic.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/02-userinfo.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/03-dangerous.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/04-data.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/05-ipv6.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-url_seed_corpus/06-idn.txt +1 -0
- package/lib/vendor/blamejs/fuzz/safe-vcard.fuzz.js +16 -0
- package/lib/vendor/blamejs/index.js +678 -0
- package/lib/vendor/blamejs/keys/release-pqc-pub.json +7 -0
- package/lib/vendor/blamejs/lib/_test/crypto-fixtures.js +67 -0
- package/lib/vendor/blamejs/lib/a2a-tasks.js +598 -0
- package/lib/vendor/blamejs/lib/a2a.js +407 -0
- package/lib/vendor/blamejs/lib/acme.js +1448 -0
- package/lib/vendor/blamejs/lib/agent-audit.js +45 -0
- package/lib/vendor/blamejs/lib/agent-event-bus.js +382 -0
- package/lib/vendor/blamejs/lib/agent-idempotency.js +497 -0
- package/lib/vendor/blamejs/lib/agent-orchestrator.js +717 -0
- package/lib/vendor/blamejs/lib/agent-posture-chain.js +366 -0
- package/lib/vendor/blamejs/lib/agent-saga.js +321 -0
- package/lib/vendor/blamejs/lib/agent-snapshot.js +676 -0
- package/lib/vendor/blamejs/lib/agent-stream.js +269 -0
- package/lib/vendor/blamejs/lib/agent-tenant.js +632 -0
- package/lib/vendor/blamejs/lib/agent-trace.js +281 -0
- package/lib/vendor/blamejs/lib/ai-adverse-decision.js +184 -0
- package/lib/vendor/blamejs/lib/ai-content-detect.js +268 -0
- package/lib/vendor/blamejs/lib/ai-input.js +201 -0
- package/lib/vendor/blamejs/lib/ai-model-manifest.js +363 -0
- package/lib/vendor/blamejs/lib/ai-pref.js +340 -0
- package/lib/vendor/blamejs/lib/api-key.js +721 -0
- package/lib/vendor/blamejs/lib/api-snapshot.js +458 -0
- package/lib/vendor/blamejs/lib/app-shutdown.js +557 -0
- package/lib/vendor/blamejs/lib/app.js +365 -0
- package/lib/vendor/blamejs/lib/archive.js +547 -0
- package/lib/vendor/blamejs/lib/arg-parser.js +697 -0
- package/lib/vendor/blamejs/lib/argon2-builtin.js +173 -0
- package/lib/vendor/blamejs/lib/asn1-der.js +424 -0
- package/lib/vendor/blamejs/lib/asyncapi-bindings.js +160 -0
- package/lib/vendor/blamejs/lib/asyncapi-traits.js +143 -0
- package/lib/vendor/blamejs/lib/asyncapi.js +575 -0
- package/lib/vendor/blamejs/lib/atomic-file.js +1023 -0
- package/lib/vendor/blamejs/lib/audit-chain.js +266 -0
- package/lib/vendor/blamejs/lib/audit-daily-review.js +389 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +751 -0
- package/lib/vendor/blamejs/lib/audit-tools.js +1113 -0
- package/lib/vendor/blamejs/lib/audit.js +1671 -0
- package/lib/vendor/blamejs/lib/auth/aal.js +169 -0
- package/lib/vendor/blamejs/lib/auth/access-lock.js +220 -0
- package/lib/vendor/blamejs/lib/auth/acr-vocabulary.js +265 -0
- package/lib/vendor/blamejs/lib/auth/ato-kill-switch.js +112 -0
- package/lib/vendor/blamejs/lib/auth/auth-time-tracker.js +111 -0
- package/lib/vendor/blamejs/lib/auth/bot-challenge.js +573 -0
- package/lib/vendor/blamejs/lib/auth/ciba.js +637 -0
- package/lib/vendor/blamejs/lib/auth/dpop.js +516 -0
- package/lib/vendor/blamejs/lib/auth/elevation-grant.js +306 -0
- package/lib/vendor/blamejs/lib/auth/fal.js +229 -0
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +681 -0
- package/lib/vendor/blamejs/lib/auth/jwt-external.js +519 -0
- package/lib/vendor/blamejs/lib/auth/jwt.js +430 -0
- package/lib/vendor/blamejs/lib/auth/lockout.js +449 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +2141 -0
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +657 -0
- package/lib/vendor/blamejs/lib/auth/oid4vp.js +531 -0
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +600 -0
- package/lib/vendor/blamejs/lib/auth/passkey.js +676 -0
- package/lib/vendor/blamejs/lib/auth/password.js +693 -0
- package/lib/vendor/blamejs/lib/auth/saml.js +2109 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-disclosure.js +95 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-holder.js +225 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc-issuer.js +197 -0
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +728 -0
- package/lib/vendor/blamejs/lib/auth/status-list.js +272 -0
- package/lib/vendor/blamejs/lib/auth/step-up-policy.js +335 -0
- package/lib/vendor/blamejs/lib/auth/step-up.js +454 -0
- package/lib/vendor/blamejs/lib/auth-bot-challenge.js +505 -0
- package/lib/vendor/blamejs/lib/auth-header.js +148 -0
- package/lib/vendor/blamejs/lib/backup/bundle.js +265 -0
- package/lib/vendor/blamejs/lib/backup/crypto.js +176 -0
- package/lib/vendor/blamejs/lib/backup/index.js +1001 -0
- package/lib/vendor/blamejs/lib/backup/manifest.js +443 -0
- package/lib/vendor/blamejs/lib/boot-gates.js +174 -0
- package/lib/vendor/blamejs/lib/breach-deadline.js +272 -0
- package/lib/vendor/blamejs/lib/break-glass.js +1753 -0
- package/lib/vendor/blamejs/lib/budr.js +205 -0
- package/lib/vendor/blamejs/lib/bundler.js +461 -0
- package/lib/vendor/blamejs/lib/cache-redis.js +256 -0
- package/lib/vendor/blamejs/lib/cache-status.js +288 -0
- package/lib/vendor/blamejs/lib/cache.js +1331 -0
- package/lib/vendor/blamejs/lib/calendar.js +1240 -0
- package/lib/vendor/blamejs/lib/canonical-json.js +143 -0
- package/lib/vendor/blamejs/lib/cdn-cache-control.js +473 -0
- package/lib/vendor/blamejs/lib/cert.js +763 -0
- package/lib/vendor/blamejs/lib/chain-writer.js +259 -0
- package/lib/vendor/blamejs/lib/circuit-breaker.js +101 -0
- package/lib/vendor/blamejs/lib/cli-helpers.js +237 -0
- package/lib/vendor/blamejs/lib/cli.js +2328 -0
- package/lib/vendor/blamejs/lib/client-hints.js +318 -0
- package/lib/vendor/blamejs/lib/cloud-events.js +277 -0
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +317 -0
- package/lib/vendor/blamejs/lib/cluster-storage.js +351 -0
- package/lib/vendor/blamejs/lib/cluster.js +1017 -0
- package/lib/vendor/blamejs/lib/cms-codec.js +826 -0
- package/lib/vendor/blamejs/lib/codepoint-class.js +262 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-logging.js +190 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +205 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-risk.js +189 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +200 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +821 -0
- package/lib/vendor/blamejs/lib/compliance-eaa.js +204 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions-aliases.js +167 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions-fetcher.js +206 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions-fuzzy.js +297 -0
- package/lib/vendor/blamejs/lib/compliance-sanctions.js +569 -0
- package/lib/vendor/blamejs/lib/compliance.js +1558 -0
- package/lib/vendor/blamejs/lib/config-drift.js +426 -0
- package/lib/vendor/blamejs/lib/config.js +446 -0
- package/lib/vendor/blamejs/lib/consent.js +369 -0
- package/lib/vendor/blamejs/lib/constants.js +209 -0
- package/lib/vendor/blamejs/lib/content-credentials.js +704 -0
- package/lib/vendor/blamejs/lib/cookies.js +560 -0
- package/lib/vendor/blamejs/lib/cra-report.js +299 -0
- package/lib/vendor/blamejs/lib/credential-hash.js +394 -0
- package/lib/vendor/blamejs/lib/crypto-field.js +1017 -0
- package/lib/vendor/blamejs/lib/crypto-hpke-pq.js +187 -0
- package/lib/vendor/blamejs/lib/crypto-hpke.js +256 -0
- package/lib/vendor/blamejs/lib/crypto.js +1908 -0
- package/lib/vendor/blamejs/lib/csp.js +271 -0
- package/lib/vendor/blamejs/lib/csv.js +418 -0
- package/lib/vendor/blamejs/lib/daemon.js +481 -0
- package/lib/vendor/blamejs/lib/dark-patterns.js +488 -0
- package/lib/vendor/blamejs/lib/data-act.js +328 -0
- package/lib/vendor/blamejs/lib/db-collection.js +587 -0
- package/lib/vendor/blamejs/lib/db-declare-row-policy.js +267 -0
- package/lib/vendor/blamejs/lib/db-declare-view.js +420 -0
- package/lib/vendor/blamejs/lib/db-file-lifecycle.js +333 -0
- package/lib/vendor/blamejs/lib/db-query.js +802 -0
- package/lib/vendor/blamejs/lib/db-role-context.js +50 -0
- package/lib/vendor/blamejs/lib/db-schema.js +322 -0
- package/lib/vendor/blamejs/lib/db.js +3111 -0
- package/lib/vendor/blamejs/lib/dbsc.js +299 -0
- package/lib/vendor/blamejs/lib/ddl-change-control.js +523 -0
- package/lib/vendor/blamejs/lib/deprecate.js +377 -0
- package/lib/vendor/blamejs/lib/dev.js +405 -0
- package/lib/vendor/blamejs/lib/dora.js +402 -0
- package/lib/vendor/blamejs/lib/dr-runbook.js +368 -0
- package/lib/vendor/blamejs/lib/dsr.js +1188 -0
- package/lib/vendor/blamejs/lib/dual-control.js +526 -0
- package/lib/vendor/blamejs/lib/early-hints.js +212 -0
- package/lib/vendor/blamejs/lib/error-page.js +420 -0
- package/lib/vendor/blamejs/lib/events.js +214 -0
- package/lib/vendor/blamejs/lib/external-db-migrate.js +659 -0
- package/lib/vendor/blamejs/lib/external-db.js +1877 -0
- package/lib/vendor/blamejs/lib/fapi2.js +394 -0
- package/lib/vendor/blamejs/lib/fda-21cfr11.js +395 -0
- package/lib/vendor/blamejs/lib/fdx.js +370 -0
- package/lib/vendor/blamejs/lib/fedcm.js +264 -0
- package/lib/vendor/blamejs/lib/file-type.js +360 -0
- package/lib/vendor/blamejs/lib/file-upload.js +1256 -0
- package/lib/vendor/blamejs/lib/flag-cache.js +136 -0
- package/lib/vendor/blamejs/lib/flag-evaluation-context.js +135 -0
- package/lib/vendor/blamejs/lib/flag-providers.js +279 -0
- package/lib/vendor/blamejs/lib/flag-targeting.js +210 -0
- package/lib/vendor/blamejs/lib/flag.js +346 -0
- package/lib/vendor/blamejs/lib/forms.js +525 -0
- package/lib/vendor/blamejs/lib/framework-error.js +724 -0
- package/lib/vendor/blamejs/lib/framework-schema.js +845 -0
- package/lib/vendor/blamejs/lib/framework-sha1-hibp.js +34 -0
- package/lib/vendor/blamejs/lib/fsm.js +469 -0
- package/lib/vendor/blamejs/lib/gate-contract.js +1661 -0
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +261 -0
- package/lib/vendor/blamejs/lib/graphql-federation.js +234 -0
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +179 -0
- package/lib/vendor/blamejs/lib/guard-all.js +555 -0
- package/lib/vendor/blamejs/lib/guard-archive.js +901 -0
- package/lib/vendor/blamejs/lib/guard-auth.js +451 -0
- package/lib/vendor/blamejs/lib/guard-cidr.js +676 -0
- package/lib/vendor/blamejs/lib/guard-csv.js +1176 -0
- package/lib/vendor/blamejs/lib/guard-domain.js +814 -0
- package/lib/vendor/blamejs/lib/guard-dsn.js +382 -0
- package/lib/vendor/blamejs/lib/guard-email.js +951 -0
- package/lib/vendor/blamejs/lib/guard-envelope.js +294 -0
- package/lib/vendor/blamejs/lib/guard-event-bus-payload.js +217 -0
- package/lib/vendor/blamejs/lib/guard-event-bus-topic.js +150 -0
- package/lib/vendor/blamejs/lib/guard-filename.js +956 -0
- package/lib/vendor/blamejs/lib/guard-graphql.js +731 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-aria.js +164 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-forms.js +144 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-tables.js +154 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag-tagwalk.js +44 -0
- package/lib/vendor/blamejs/lib/guard-html-wcag.js +470 -0
- package/lib/vendor/blamejs/lib/guard-html.js +1209 -0
- package/lib/vendor/blamejs/lib/guard-idempotency-key.js +151 -0
- package/lib/vendor/blamejs/lib/guard-image.js +584 -0
- package/lib/vendor/blamejs/lib/guard-imap-command.js +337 -0
- package/lib/vendor/blamejs/lib/guard-jmap.js +321 -0
- package/lib/vendor/blamejs/lib/guard-json.js +935 -0
- package/lib/vendor/blamejs/lib/guard-jsonpath.js +512 -0
- package/lib/vendor/blamejs/lib/guard-jwt.js +772 -0
- package/lib/vendor/blamejs/lib/guard-list-id.js +318 -0
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +412 -0
- package/lib/vendor/blamejs/lib/guard-mail-compose.js +282 -0
- package/lib/vendor/blamejs/lib/guard-mail-move.js +202 -0
- package/lib/vendor/blamejs/lib/guard-mail-query.js +310 -0
- package/lib/vendor/blamejs/lib/guard-mail-reply.js +172 -0
- package/lib/vendor/blamejs/lib/guard-mail-sieve.js +207 -0
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +566 -0
- package/lib/vendor/blamejs/lib/guard-markdown.js +768 -0
- package/lib/vendor/blamejs/lib/guard-message-id.js +267 -0
- package/lib/vendor/blamejs/lib/guard-mime.js +609 -0
- package/lib/vendor/blamejs/lib/guard-oauth.js +650 -0
- package/lib/vendor/blamejs/lib/guard-pdf.js +569 -0
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +317 -0
- package/lib/vendor/blamejs/lib/guard-posture-chain.js +201 -0
- package/lib/vendor/blamejs/lib/guard-regex.js +632 -0
- package/lib/vendor/blamejs/lib/guard-saga-config.js +157 -0
- package/lib/vendor/blamejs/lib/guard-shell.js +522 -0
- package/lib/vendor/blamejs/lib/guard-smtp-command.js +594 -0
- package/lib/vendor/blamejs/lib/guard-snapshot-envelope.js +168 -0
- package/lib/vendor/blamejs/lib/guard-stream-args.js +166 -0
- package/lib/vendor/blamejs/lib/guard-svg.js +1163 -0
- package/lib/vendor/blamejs/lib/guard-template.js +490 -0
- package/lib/vendor/blamejs/lib/guard-tenant-id.js +138 -0
- package/lib/vendor/blamejs/lib/guard-time.js +586 -0
- package/lib/vendor/blamejs/lib/guard-trace-context.js +172 -0
- package/lib/vendor/blamejs/lib/guard-uuid.js +548 -0
- package/lib/vendor/blamejs/lib/guard-xml.js +666 -0
- package/lib/vendor/blamejs/lib/guard-yaml.js +726 -0
- package/lib/vendor/blamejs/lib/hal.js +125 -0
- package/lib/vendor/blamejs/lib/handlers.js +350 -0
- package/lib/vendor/blamejs/lib/honeytoken.js +168 -0
- package/lib/vendor/blamejs/lib/html-balance.js +347 -0
- package/lib/vendor/blamejs/lib/http-client-cache.js +923 -0
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +519 -0
- package/lib/vendor/blamejs/lib/http-client.js +2152 -0
- package/lib/vendor/blamejs/lib/http-message-signature.js +589 -0
- package/lib/vendor/blamejs/lib/http2-teardown.js +34 -0
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +398 -0
- package/lib/vendor/blamejs/lib/i18n.js +931 -0
- package/lib/vendor/blamejs/lib/iab-mspa.js +257 -0
- package/lib/vendor/blamejs/lib/iab-tcf.js +461 -0
- package/lib/vendor/blamejs/lib/importmap-integrity.js +90 -0
- package/lib/vendor/blamejs/lib/inbox.js +435 -0
- package/lib/vendor/blamejs/lib/incident-report.js +314 -0
- package/lib/vendor/blamejs/lib/ip-utils.js +102 -0
- package/lib/vendor/blamejs/lib/jobs.js +185 -0
- package/lib/vendor/blamejs/lib/jose-jwe-experimental.js +228 -0
- package/lib/vendor/blamejs/lib/jsonapi.js +230 -0
- package/lib/vendor/blamejs/lib/keychain.js +865 -0
- package/lib/vendor/blamejs/lib/lazy-require.js +48 -0
- package/lib/vendor/blamejs/lib/legal-hold.js +374 -0
- package/lib/vendor/blamejs/lib/local-db-thin.js +321 -0
- package/lib/vendor/blamejs/lib/log-stream-cloudwatch.js +369 -0
- package/lib/vendor/blamejs/lib/log-stream-local.js +146 -0
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +410 -0
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +286 -0
- package/lib/vendor/blamejs/lib/log-stream-syslog.js +310 -0
- package/lib/vendor/blamejs/lib/log-stream-webhook.js +199 -0
- package/lib/vendor/blamejs/lib/log-stream.js +584 -0
- package/lib/vendor/blamejs/lib/log.js +625 -0
- package/lib/vendor/blamejs/lib/lro.js +200 -0
- package/lib/vendor/blamejs/lib/mail-agent.js +786 -0
- package/lib/vendor/blamejs/lib/mail-arc-sign.js +417 -0
- package/lib/vendor/blamejs/lib/mail-arf.js +343 -0
- package/lib/vendor/blamejs/lib/mail-auth.js +2144 -0
- package/lib/vendor/blamejs/lib/mail-bimi.js +1047 -0
- package/lib/vendor/blamejs/lib/mail-bounce.js +955 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +1286 -0
- package/lib/vendor/blamejs/lib/mail-crypto-smime.js +789 -0
- package/lib/vendor/blamejs/lib/mail-crypto.js +108 -0
- package/lib/vendor/blamejs/lib/mail-dav.js +1224 -0
- package/lib/vendor/blamejs/lib/mail-deploy.js +1119 -0
- package/lib/vendor/blamejs/lib/mail-dkim.js +1250 -0
- package/lib/vendor/blamejs/lib/mail-greylist.js +448 -0
- package/lib/vendor/blamejs/lib/mail-helo.js +473 -0
- package/lib/vendor/blamejs/lib/mail-journal.js +435 -0
- package/lib/vendor/blamejs/lib/mail-mdn.js +424 -0
- package/lib/vendor/blamejs/lib/mail-rbl.js +392 -0
- package/lib/vendor/blamejs/lib/mail-require-tls.js +198 -0
- package/lib/vendor/blamejs/lib/mail-scan.js +502 -0
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +629 -0
- package/lib/vendor/blamejs/lib/mail-server-imap.js +1858 -0
- package/lib/vendor/blamejs/lib/mail-server-jmap.js +1565 -0
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +908 -0
- package/lib/vendor/blamejs/lib/mail-server-mx.js +969 -0
- package/lib/vendor/blamejs/lib/mail-server-pop3.js +915 -0
- package/lib/vendor/blamejs/lib/mail-server-rate-limit.js +315 -0
- package/lib/vendor/blamejs/lib/mail-server-registry.js +378 -0
- package/lib/vendor/blamejs/lib/mail-server-submission.js +1396 -0
- package/lib/vendor/blamejs/lib/mail-server-tls.js +445 -0
- package/lib/vendor/blamejs/lib/mail-sieve.js +557 -0
- package/lib/vendor/blamejs/lib/mail-spam-score.js +284 -0
- package/lib/vendor/blamejs/lib/mail-srs.js +248 -0
- package/lib/vendor/blamejs/lib/mail-store-fts.js +394 -0
- package/lib/vendor/blamejs/lib/mail-store.js +929 -0
- package/lib/vendor/blamejs/lib/mail-unsubscribe.js +400 -0
- package/lib/vendor/blamejs/lib/mail.js +1971 -0
- package/lib/vendor/blamejs/lib/mcp-tool-registry.js +473 -0
- package/lib/vendor/blamejs/lib/mcp.js +950 -0
- package/lib/vendor/blamejs/lib/metrics.js +1503 -0
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +177 -0
- package/lib/vendor/blamejs/lib/middleware/ai-act-disclosure.js +203 -0
- package/lib/vendor/blamejs/lib/middleware/api-encrypt.js +981 -0
- package/lib/vendor/blamejs/lib/middleware/assetlinks.js +137 -0
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +171 -0
- package/lib/vendor/blamejs/lib/middleware/attach-user.js +220 -0
- package/lib/vendor/blamejs/lib/middleware/bearer-auth.js +293 -0
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +1519 -0
- package/lib/vendor/blamejs/lib/middleware/bot-disclose.js +183 -0
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +217 -0
- package/lib/vendor/blamejs/lib/middleware/clear-site-data.js +122 -0
- package/lib/vendor/blamejs/lib/middleware/compose-pipeline.js +355 -0
- package/lib/vendor/blamejs/lib/middleware/compression.js +489 -0
- package/lib/vendor/blamejs/lib/middleware/cookies.js +130 -0
- package/lib/vendor/blamejs/lib/middleware/cors.js +386 -0
- package/lib/vendor/blamejs/lib/middleware/csp-nonce.js +388 -0
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +167 -0
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +499 -0
- package/lib/vendor/blamejs/lib/middleware/daily-byte-quota.js +243 -0
- package/lib/vendor/blamejs/lib/middleware/db-role-for.js +304 -0
- package/lib/vendor/blamejs/lib/middleware/dpop.js +402 -0
- package/lib/vendor/blamejs/lib/middleware/error-handler.js +69 -0
- package/lib/vendor/blamejs/lib/middleware/fetch-metadata.js +168 -0
- package/lib/vendor/blamejs/lib/middleware/flag-context.js +110 -0
- package/lib/vendor/blamejs/lib/middleware/gpc.js +153 -0
- package/lib/vendor/blamejs/lib/middleware/headers.js +242 -0
- package/lib/vendor/blamejs/lib/middleware/health.js +438 -0
- package/lib/vendor/blamejs/lib/middleware/host-allowlist.js +189 -0
- package/lib/vendor/blamejs/lib/middleware/idempotency-key.js +964 -0
- package/lib/vendor/blamejs/lib/middleware/index.js +183 -0
- package/lib/vendor/blamejs/lib/middleware/nel.js +214 -0
- package/lib/vendor/blamejs/lib/middleware/network-allowlist.js +237 -0
- package/lib/vendor/blamejs/lib/middleware/no-cache.js +106 -0
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +177 -0
- package/lib/vendor/blamejs/lib/middleware/protected-resource-metadata.js +277 -0
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +556 -0
- package/lib/vendor/blamejs/lib/middleware/request-id.js +79 -0
- package/lib/vendor/blamejs/lib/middleware/request-log.js +205 -0
- package/lib/vendor/blamejs/lib/middleware/require-aal.js +138 -0
- package/lib/vendor/blamejs/lib/middleware/require-auth.js +144 -0
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +290 -0
- package/lib/vendor/blamejs/lib/middleware/require-content-type.js +113 -0
- package/lib/vendor/blamejs/lib/middleware/require-methods.js +97 -0
- package/lib/vendor/blamejs/lib/middleware/require-mtls.js +212 -0
- package/lib/vendor/blamejs/lib/middleware/require-step-up.js +226 -0
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +375 -0
- package/lib/vendor/blamejs/lib/middleware/security-headers.js +285 -0
- package/lib/vendor/blamejs/lib/middleware/security-txt.js +170 -0
- package/lib/vendor/blamejs/lib/middleware/span-http-server.js +280 -0
- package/lib/vendor/blamejs/lib/middleware/speculation-rules.js +323 -0
- package/lib/vendor/blamejs/lib/middleware/sse.js +200 -0
- package/lib/vendor/blamejs/lib/middleware/trace-log-correlation.js +167 -0
- package/lib/vendor/blamejs/lib/middleware/trace-propagate.js +148 -0
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +749 -0
- package/lib/vendor/blamejs/lib/middleware/web-app-manifest.js +164 -0
- package/lib/vendor/blamejs/lib/migration-files.js +37 -0
- package/lib/vendor/blamejs/lib/migrations.js +385 -0
- package/lib/vendor/blamejs/lib/mime-parse.js +198 -0
- package/lib/vendor/blamejs/lib/money.js +699 -0
- package/lib/vendor/blamejs/lib/mtls-ca.js +572 -0
- package/lib/vendor/blamejs/lib/mtls-engine-default.js +501 -0
- package/lib/vendor/blamejs/lib/network-byte-quota.js +308 -0
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +533 -0
- package/lib/vendor/blamejs/lib/network-dns.js +1930 -0
- package/lib/vendor/blamejs/lib/network-heartbeat.js +425 -0
- package/lib/vendor/blamejs/lib/network-nts.js +574 -0
- package/lib/vendor/blamejs/lib/network-proxy.js +265 -0
- package/lib/vendor/blamejs/lib/network-smtp-policy.js +836 -0
- package/lib/vendor/blamejs/lib/network-tls.js +3126 -0
- package/lib/vendor/blamejs/lib/network.js +346 -0
- package/lib/vendor/blamejs/lib/nis2-report.js +181 -0
- package/lib/vendor/blamejs/lib/nist-crosswalk.js +293 -0
- package/lib/vendor/blamejs/lib/nonce-store.js +177 -0
- package/lib/vendor/blamejs/lib/notify.js +683 -0
- package/lib/vendor/blamejs/lib/ntp-check.js +458 -0
- package/lib/vendor/blamejs/lib/numeric-bounds.js +111 -0
- package/lib/vendor/blamejs/lib/numeric-checks.js +40 -0
- package/lib/vendor/blamejs/lib/object-store/azure-blob-bucket-ops.js +349 -0
- package/lib/vendor/blamejs/lib/object-store/azure-blob.js +488 -0
- package/lib/vendor/blamejs/lib/object-store/gcs-bucket-ops.js +351 -0
- package/lib/vendor/blamejs/lib/object-store/gcs.js +515 -0
- package/lib/vendor/blamejs/lib/object-store/http-put.js +153 -0
- package/lib/vendor/blamejs/lib/object-store/http-request.js +38 -0
- package/lib/vendor/blamejs/lib/object-store/index.js +197 -0
- package/lib/vendor/blamejs/lib/object-store/local.js +163 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4-bucket-ops.js +1133 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +957 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +420 -0
- package/lib/vendor/blamejs/lib/observability-tracer.js +395 -0
- package/lib/vendor/blamejs/lib/observability.js +720 -0
- package/lib/vendor/blamejs/lib/openapi-paths-builder.js +248 -0
- package/lib/vendor/blamejs/lib/openapi-schema-walk.js +192 -0
- package/lib/vendor/blamejs/lib/openapi-security.js +169 -0
- package/lib/vendor/blamejs/lib/openapi-yaml.js +154 -0
- package/lib/vendor/blamejs/lib/openapi.js +489 -0
- package/lib/vendor/blamejs/lib/otel-export.js +278 -0
- package/lib/vendor/blamejs/lib/outbox.js +547 -0
- package/lib/vendor/blamejs/lib/pagination.js +542 -0
- package/lib/vendor/blamejs/lib/parsers/index.js +91 -0
- package/lib/vendor/blamejs/lib/parsers/safe-env.js +642 -0
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +293 -0
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +784 -0
- package/lib/vendor/blamejs/lib/parsers/safe-xml.js +390 -0
- package/lib/vendor/blamejs/lib/parsers/safe-yaml.js +1015 -0
- package/lib/vendor/blamejs/lib/permissions.js +793 -0
- package/lib/vendor/blamejs/lib/pick.js +105 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +351 -0
- package/lib/vendor/blamejs/lib/pqc-gate.js +279 -0
- package/lib/vendor/blamejs/lib/pqc-software.js +271 -0
- package/lib/vendor/blamejs/lib/problem-details.js +482 -0
- package/lib/vendor/blamejs/lib/process-spawn.js +196 -0
- package/lib/vendor/blamejs/lib/promise-pool.js +162 -0
- package/lib/vendor/blamejs/lib/protobuf-encoder.js +190 -0
- package/lib/vendor/blamejs/lib/protocol-dispatcher.js +161 -0
- package/lib/vendor/blamejs/lib/public-suffix.js +403 -0
- package/lib/vendor/blamejs/lib/pubsub-cluster.js +154 -0
- package/lib/vendor/blamejs/lib/pubsub-redis.js +167 -0
- package/lib/vendor/blamejs/lib/pubsub.js +463 -0
- package/lib/vendor/blamejs/lib/queue-local.js +476 -0
- package/lib/vendor/blamejs/lib/queue-redis.js +745 -0
- package/lib/vendor/blamejs/lib/queue-sqs.js +319 -0
- package/lib/vendor/blamejs/lib/queue.js +1016 -0
- package/lib/vendor/blamejs/lib/redact.js +1007 -0
- package/lib/vendor/blamejs/lib/redis-client.js +520 -0
- package/lib/vendor/blamejs/lib/render.js +285 -0
- package/lib/vendor/blamejs/lib/request-helpers.js +767 -0
- package/lib/vendor/blamejs/lib/resource-access-lock.js +116 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +340 -0
- package/lib/vendor/blamejs/lib/restore-rollback.js +365 -0
- package/lib/vendor/blamejs/lib/restore.js +409 -0
- package/lib/vendor/blamejs/lib/retention.js +640 -0
- package/lib/vendor/blamejs/lib/retry.js +523 -0
- package/lib/vendor/blamejs/lib/router.js +1289 -0
- package/lib/vendor/blamejs/lib/safe-async.js +1184 -0
- package/lib/vendor/blamejs/lib/safe-buffer.js +562 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +297 -0
- package/lib/vendor/blamejs/lib/safe-dns.js +665 -0
- package/lib/vendor/blamejs/lib/safe-ical.js +634 -0
- package/lib/vendor/blamejs/lib/safe-icap.js +502 -0
- package/lib/vendor/blamejs/lib/safe-json.js +946 -0
- package/lib/vendor/blamejs/lib/safe-jsonpath.js +285 -0
- package/lib/vendor/blamejs/lib/safe-mime.js +831 -0
- package/lib/vendor/blamejs/lib/safe-mount-info.js +306 -0
- package/lib/vendor/blamejs/lib/safe-path.js +254 -0
- package/lib/vendor/blamejs/lib/safe-redirect.js +106 -0
- package/lib/vendor/blamejs/lib/safe-schema.js +1810 -0
- package/lib/vendor/blamejs/lib/safe-sieve.js +684 -0
- package/lib/vendor/blamejs/lib/safe-smtp.js +185 -0
- package/lib/vendor/blamejs/lib/safe-sql.js +363 -0
- package/lib/vendor/blamejs/lib/safe-url.js +428 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +473 -0
- package/lib/vendor/blamejs/lib/sandbox-worker.js +135 -0
- package/lib/vendor/blamejs/lib/sandbox.js +358 -0
- package/lib/vendor/blamejs/lib/scheduler.js +827 -0
- package/lib/vendor/blamejs/lib/sd-notify.js +269 -0
- package/lib/vendor/blamejs/lib/sec-cyber.js +214 -0
- package/lib/vendor/blamejs/lib/security-assert.js +395 -0
- package/lib/vendor/blamejs/lib/seeders.js +620 -0
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +309 -0
- package/lib/vendor/blamejs/lib/self-update.js +804 -0
- package/lib/vendor/blamejs/lib/server-timing.js +174 -0
- package/lib/vendor/blamejs/lib/session-device-binding.js +431 -0
- package/lib/vendor/blamejs/lib/session-stores.js +138 -0
- package/lib/vendor/blamejs/lib/session.js +1162 -0
- package/lib/vendor/blamejs/lib/slug.js +381 -0
- package/lib/vendor/blamejs/lib/sse.js +349 -0
- package/lib/vendor/blamejs/lib/ssrf-guard.js +792 -0
- package/lib/vendor/blamejs/lib/standard-webhooks.js +183 -0
- package/lib/vendor/blamejs/lib/static.js +1249 -0
- package/lib/vendor/blamejs/lib/storage.js +1272 -0
- package/lib/vendor/blamejs/lib/stream-throttle.js +235 -0
- package/lib/vendor/blamejs/lib/structured-fields.js +244 -0
- package/lib/vendor/blamejs/lib/subject.js +667 -0
- package/lib/vendor/blamejs/lib/tcpa-10dlc.js +175 -0
- package/lib/vendor/blamejs/lib/template.js +931 -0
- package/lib/vendor/blamejs/lib/tenant-quota.js +545 -0
- package/lib/vendor/blamejs/lib/test-harness.js +275 -0
- package/lib/vendor/blamejs/lib/testing.js +1185 -0
- package/lib/vendor/blamejs/lib/time.js +578 -0
- package/lib/vendor/blamejs/lib/tls-exporter.js +239 -0
- package/lib/vendor/blamejs/lib/totp.js +318 -0
- package/lib/vendor/blamejs/lib/tracing.js +546 -0
- package/lib/vendor/blamejs/lib/uuid.js +207 -0
- package/lib/vendor/blamejs/lib/validate-opts.js +381 -0
- package/lib/vendor/blamejs/lib/vault/index.js +638 -0
- package/lib/vendor/blamejs/lib/vault/passphrase-ops.js +311 -0
- package/lib/vendor/blamejs/lib/vault/passphrase-source.js +198 -0
- package/lib/vendor/blamejs/lib/vault/rotate.js +803 -0
- package/lib/vendor/blamejs/lib/vault/seal-pem-file.js +471 -0
- package/lib/vendor/blamejs/lib/vault/wrap.js +296 -0
- package/lib/vendor/blamejs/lib/vault-aad.js +259 -0
- package/lib/vendor/blamejs/lib/vendor/.vendor-data-pubkey +4 -0
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +161 -0
- package/lib/vendor/blamejs/lib/vendor/bimi-trust-anchors.data.js +68 -0
- package/lib/vendor/blamejs/lib/vendor/bimi-trust-anchors.pem +33 -0
- package/lib/vendor/blamejs/lib/vendor/common-passwords-top-10000.data.js +1325 -0
- package/lib/vendor/blamejs/lib/vendor/common-passwords-top-10000.txt +10002 -0
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +9 -0
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +18 -0
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +181 -0
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +16382 -0
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5881 -0
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +328 -0
- package/lib/vendor/blamejs/lib/vendor/vendor-data-pubkey.js +16 -0
- package/lib/vendor/blamejs/lib/vendor-data.js +520 -0
- package/lib/vendor/blamejs/lib/vex.js +630 -0
- package/lib/vendor/blamejs/lib/watcher.js +608 -0
- package/lib/vendor/blamejs/lib/web-push-vapid.js +322 -0
- package/lib/vendor/blamejs/lib/webhook.js +977 -0
- package/lib/vendor/blamejs/lib/websocket-channels.js +327 -0
- package/lib/vendor/blamejs/lib/websocket.js +1561 -0
- package/lib/vendor/blamejs/lib/wiki-concepts.js +338 -0
- package/lib/vendor/blamejs/lib/worker-pool.js +464 -0
- package/lib/vendor/blamejs/lib/ws-client.js +978 -0
- package/lib/vendor/blamejs/lib/xml-c14n.js +506 -0
- package/lib/vendor/blamejs/memory/specs/node-26-map-getorinsert-migration.md +164 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +19 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/README.md +88 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/build.sh +26 -0
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/project.yaml +28 -0
- package/lib/vendor/blamejs/package.json +81 -0
- package/lib/vendor/blamejs/release-notes/v0.0.x.json +310 -0
- package/lib/vendor/blamejs/release-notes/v0.1.x.json +1798 -0
- package/lib/vendor/blamejs/release-notes/v0.10.x.json +1288 -0
- package/lib/vendor/blamejs/release-notes/v0.11.x.json +2551 -0
- package/lib/vendor/blamejs/release-notes/v0.12.0.json +64 -0
- package/lib/vendor/blamejs/release-notes/v0.12.1.json +32 -0
- package/lib/vendor/blamejs/release-notes/v0.12.2.json +45 -0
- package/lib/vendor/blamejs/release-notes/v0.2.x.json +706 -0
- package/lib/vendor/blamejs/release-notes/v0.3.x.json +786 -0
- package/lib/vendor/blamejs/release-notes/v0.4.x.json +588 -0
- package/lib/vendor/blamejs/release-notes/v0.5.x.json +390 -0
- package/lib/vendor/blamejs/release-notes/v0.6.x.json +1947 -0
- package/lib/vendor/blamejs/release-notes/v0.7.x.json +3811 -0
- package/lib/vendor/blamejs/release-notes/v0.8.x.json +3318 -0
- package/lib/vendor/blamejs/release-notes/v0.9.x.json +2257 -0
- package/lib/vendor/blamejs/scripts/build-vendored-sbom.js +325 -0
- package/lib/vendor/blamejs/scripts/check-api-snapshot.js +62 -0
- package/lib/vendor/blamejs/scripts/check-changelog-extract.js +108 -0
- package/lib/vendor/blamejs/scripts/check-pack-against-gitignore.js +83 -0
- package/lib/vendor/blamejs/scripts/check-services.js +483 -0
- package/lib/vendor/blamejs/scripts/check-vendor-currency.js +349 -0
- package/lib/vendor/blamejs/scripts/consolidate-release-notes.js +216 -0
- package/lib/vendor/blamejs/scripts/gen-migrating.js +275 -0
- package/lib/vendor/blamejs/scripts/generate-changelog-entry.js +577 -0
- package/lib/vendor/blamejs/scripts/generate-release-signing-key.js +79 -0
- package/lib/vendor/blamejs/scripts/publish-dep-confusion-placeholder.sh +101 -0
- package/lib/vendor/blamejs/scripts/refresh-api-snapshot.js +31 -0
- package/lib/vendor/blamejs/scripts/refresh-vendor-manifest.js +132 -0
- package/lib/vendor/blamejs/scripts/release.js +652 -0
- package/lib/vendor/blamejs/scripts/sha3-digest.js +62 -0
- package/lib/vendor/blamejs/scripts/sign-release-artifact.js +92 -0
- package/lib/vendor/blamejs/scripts/test-integration.js +181 -0
- package/lib/vendor/blamejs/scripts/test-wiki-integration.js +126 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +77 -0
- package/lib/vendor/blamejs/scripts/vendor-data-gen.js +186 -0
- package/lib/vendor/blamejs/scripts/vendor-data-keygen.js +101 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +278 -0
- package/lib/vendor/blamejs/test/00-primitives.js +19075 -0
- package/lib/vendor/blamejs/test/10-state.js +622 -0
- package/lib/vendor/blamejs/test/20-db.js +561 -0
- package/lib/vendor/blamejs/test/30-chain.js +2110 -0
- package/lib/vendor/blamejs/test/40-consumers.js +2453 -0
- package/lib/vendor/blamejs/test/50-integration.js +486 -0
- package/lib/vendor/blamejs/test/_helpers.js +10 -0
- package/lib/vendor/blamejs/test/_smoke-worker.js +69 -0
- package/lib/vendor/blamejs/test/fixtures/exploit-corpus/corpus.json +368 -0
- package/lib/vendor/blamejs/test/fixtures/http-client-stream-payload.txt +2 -0
- package/lib/vendor/blamejs/test/fixtures/worker-pool/echo.js +52 -0
- package/lib/vendor/blamejs/test/helpers/_codebase-shingle-worker.js +24 -0
- package/lib/vendor/blamejs/test/helpers/_codebase-shingle.js +203 -0
- package/lib/vendor/blamejs/test/helpers/_shape-match.js +513 -0
- package/lib/vendor/blamejs/test/helpers/check.js +36 -0
- package/lib/vendor/blamejs/test/helpers/cluster.js +70 -0
- package/lib/vendor/blamejs/test/helpers/db.js +143 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +207 -0
- package/lib/vendor/blamejs/test/helpers/fs-watch.js +101 -0
- package/lib/vendor/blamejs/test/helpers/http.js +14 -0
- package/lib/vendor/blamejs/test/helpers/index.js +93 -0
- package/lib/vendor/blamejs/test/helpers/json-round-trip.js +120 -0
- package/lib/vendor/blamejs/test/helpers/mocks.js +20 -0
- package/lib/vendor/blamejs/test/helpers/otel.js +13 -0
- package/lib/vendor/blamejs/test/helpers/services.js +380 -0
- package/lib/vendor/blamejs/test/helpers/wait.js +206 -0
- package/lib/vendor/blamejs/test/integration/cache.test.js +235 -0
- package/lib/vendor/blamejs/test/integration/cluster-provider-mysql.test.js +174 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +611 -0
- package/lib/vendor/blamejs/test/integration/http-client.test.js +129 -0
- package/lib/vendor/blamejs/test/integration/log-stream.test.js +219 -0
- package/lib/vendor/blamejs/test/integration/mail-crypto-smime.test.js +181 -0
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +152 -0
- package/lib/vendor/blamejs/test/integration/mail-smtp.test.js +161 -0
- package/lib/vendor/blamejs/test/integration/mtls-ca.test.js +289 -0
- package/lib/vendor/blamejs/test/integration/network-dns.test.js +123 -0
- package/lib/vendor/blamejs/test/integration/network-heartbeat.test.js +101 -0
- package/lib/vendor/blamejs/test/integration/ntp-check.test.js +89 -0
- package/lib/vendor/blamejs/test/integration/object-store-sigv4.test.js +403 -0
- package/lib/vendor/blamejs/test/integration/pqc-pkcs8-forward-compat.test.js +271 -0
- package/lib/vendor/blamejs/test/integration/pubsub.test.js +137 -0
- package/lib/vendor/blamejs/test/integration/queue-redis.test.js +352 -0
- package/lib/vendor/blamejs/test/integration/redis-client-tls.test.js +96 -0
- package/lib/vendor/blamejs/test/integration/ssrf-guard.test.js +98 -0
- package/lib/vendor/blamejs/test/integration/websocket-permessage-deflate.test.js +261 -0
- package/lib/vendor/blamejs/test/integration/ws-client-roundtrip.test.js +230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +211 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a.test.js +59 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/access-lock.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +219 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-event-bus.test.js +266 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-orchestrator.test.js +390 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-posture-chain.test.js +174 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +279 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +322 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-stream.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-tenant.test.js +302 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-trace.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-adverse-decision.test.js +44 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-content-detect.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-input.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-model-manifest.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ai-pref.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +1080 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +311 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-zip-stream.test.js +291 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +267 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asyncapi.test.js +929 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file-conflict-path.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-cve-defensive.test.js +176 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-daily-review.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-export-cadf.test.js +97 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-framework-namespaces.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-segregation.test.js +115 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-ml-dsa-65.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-use-store.test.js +246 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge-verifier.test.js +485 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-bot-challenge.test.js +331 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-lockout.test.js +572 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password-audit.test.js +61 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/azure-blob-bucket-ops.test.js +258 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-worker.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/bearer-auth.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-chunked-malformed.test.js +131 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/body-parser-smuggling.test.js +118 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/boot-gates.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/breach-deadline.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +861 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/budr.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/bundler-engine.test.js +209 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache-status.test.js +129 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +871 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/canonical-json-jcs.test.js +43 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cdn-cache-control.test.js +243 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-api-key.test.js +147 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-audit-verify-chain.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-backup.test.js +135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-config-drift.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +75 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-file-type.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-helpers.test.js +145 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-mtls.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-password.test.js +97 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-restore.test.js +160 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-retention.test.js +84 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-security.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-vault.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/client-hints.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +237 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +9600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-cascade.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-eaa.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +712 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance.test.js +278 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/config-drift.test.js +97 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/config.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cors.test.js +357 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cra-report.test.js +31 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/credential-hash.test.js +226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-base64url.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-envelope.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +193 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hpke-pq.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hpke.test.js +155 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-mlkem768-x25519.test.js +129 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-namespace-hash.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-random-int.test.js +72 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-builder.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-nonce.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +180 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +210 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daily-byte-quota.test.js +153 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/data-act.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-collection-extensions.test.js +226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-collection.test.js +136 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-init-extensions.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-cross-schema.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query-extensions.test.js +191 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-role-for.test.js +228 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-vacuum.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-worm.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +184 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/declare-row-policy.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/declare-view.test.js +303 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dns-dnssec-algorithm.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dns-null-mx.test.js +39 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dora.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dr-runbook.test.js +59 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr-state-rules.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +786 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/early-hints.test.js +147 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/events.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/exploit-replay.test.js +243 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-hardening.test.js +181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-routing.test.js +531 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +118 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fapi2.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fda-21cfr11.test.js +156 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fdx.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +434 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +432 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-type.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +887 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forensic-snapshot.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fsm.test.js +375 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gcs-bucket-ops.test.js +321 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/graphql-federation.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-agent-registry.test.js +87 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-all.test.js +328 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +339 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-csv.test.js +694 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-dsn.test.js +296 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-email.test.js +234 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-envelope.test.js +192 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-event-bus-payload.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-event-bus-topic.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +386 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html-wcag.test.js +859 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +357 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-imap-command.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jmap.test.js +174 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-json.test.js +317 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-list-id.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-list-unsubscribe.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-compose.test.js +111 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-move.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-query.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-reply.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mail-sieve.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +301 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +265 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-message-id.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +161 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-posture-chain.test.js +100 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-saga-config.test.js +79 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-smtp-command.test.js +269 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-snapshot-envelope.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-stream-args.test.js +78 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +288 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-tenant-id.test.js +69 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-trace-context.test.js +102 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-xml.test.js +202 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-yaml.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/hal.test.js +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/honeytoken.test.js +50 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +37 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +692 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-stream.test.js +280 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +225 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +203 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +991 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/iab-mspa.test.js +63 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/iab-tcf.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +612 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/importmap-integrity.test.js +56 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/inbox.test.js +166 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/incident-report.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jose-jwe-experimental.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-api.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-round-trip-helper.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +159 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/legal-hold.test.js +118 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/local-db-thin.test.js +150 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-cloudwatch.test.js +489 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp-grpc.test.js +207 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream-otlp.test.js +283 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/lro.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +417 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-arf.test.js +208 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +910 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +502 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +680 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-canspam.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +149 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +297 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +514 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy-tlsrpt.test.js +369 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +627 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-feedback-id.test.js +56 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-greylist.test.js +217 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +283 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-journal.test.js +217 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-mdn.test.js +334 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-rbl.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-require-tls.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +336 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +732 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +840 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +130 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +285 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +229 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +394 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-tls.test.js +147 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-spam-score.test.js +204 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-srs.test.js +152 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +279 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-unsubscribe.test.js +165 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +439 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-tool-registry.test.js +202 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +155 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-shadow-registry.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +224 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-compose-pipeline.test.js +278 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/money.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-paths.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nel.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-allowlist.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-byte-quota.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +372 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +635 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-heartbeat-passive.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls-build-options.test.js +130 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls-ct-inclusion.test.js +179 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +447 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +369 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nis2-report.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nist-crosswalk.test.js +42 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/no-cache.test.js +98 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/notify.test.js +707 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/numeric-bounds.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oauth-callback.test.js +72 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +597 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openapi.test.js +877 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/otel-export.test.js +257 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pagination.test.js +522 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +216 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +324 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +546 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +153 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-software.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/problem-details.test.js +195 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/process-spawn.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/promise-pool.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/protected-resource-metadata.test.js +68 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/protobuf-encoder.test.js +138 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/protocol-dispatcher.test.js +174 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/public-suffix.test.js +197 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +232 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-dlq-extend-lease.test.js +178 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +322 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-priority-rate-progress.test.js +266 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-sqs.test.js +300 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-cluster.test.js +338 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-registry.test.js +75 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact-dlp.test.js +246 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redis-client.test.js +130 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +335 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-log.test.js +170 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-auth-cache-control.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-mtls.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/resource-access-lock.test.js +52 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention-floor.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retry.test.js +535 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-cross-origin-redirect.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +128 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-loops.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async-parallel.test.js +170 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +248 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +451 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +289 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-icap.test.js +206 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-jsonpath.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +339 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mount-info.test.js +180 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +78 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sieve.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-smtp.test.js +95 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url-idn-homograph.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +257 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/saml-slo.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +228 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler-exactly-once.test.js +238 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +700 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-notify.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sec-cyber.test.js +85 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +107 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-headers.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/seeders.test.js +816 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update-standalone-verifier.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +302 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/server-timing.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +247 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-extensions.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/shape-match.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +952 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-multipart-sse.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/slug.test.js +330 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/smtp-policy.test.js +233 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/source-comment-blocks.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/speculation-rules.test.js +319 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sse.test.js +148 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +283 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/standard-webhooks.test.js +67 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +266 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/step-up.test.js +487 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-chunk-scratch.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +773 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/stream-throttle.test.js +173 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/structured-fields.test.js +180 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tcpa-10dlc.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +571 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/test-harness.test.js +190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/testing-request.test.js +119 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/testing.test.js +522 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-exporter.test.js +168 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-ocsp-ct.test.js +275 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-ocsp-verify.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-pinset-drift.test.js +35 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tls-preferred-groups.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tracing.test.js +280 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/uuid.test.js +93 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-aad.test.js +277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-seal-pem-file.test.js +252 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vendor-data.test.js +149 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vendor-manifest.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vex.test.js +661 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +308 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/web-push-vapid.test.js +144 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +674 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket-channels.test.js +360 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/worker-pool.test.js +302 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +349 -0
- package/lib/vendor/blamejs/test/layer-1-state/api-key.test.js +717 -0
- package/lib/vendor/blamejs/test/layer-5-integration/bundler-output.test.js +444 -0
- package/lib/vendor/blamejs/test/layer-5-integration/guard-host-integration.test.js +597 -0
- package/lib/vendor/blamejs/test/layer-5-integration/security-chaos.test.js +308 -0
- package/lib/vendor/blamejs/test/smoke.js +431 -0
- package/lib/webhooks.js +305 -0
- package/package.json +43 -0
|
@@ -0,0 +1,1331 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.cache
|
|
4
|
+
* @nav Data
|
|
5
|
+
* @title Cache
|
|
6
|
+
*
|
|
7
|
+
* @intro
|
|
8
|
+
* LRU + TTL cache with operator-supplied namespacing, drop-silent
|
|
9
|
+
* key validation on hot-path observability, and pluggable backends
|
|
10
|
+
* that share semantics across single-process and clustered nodes.
|
|
11
|
+
*
|
|
12
|
+
* Three first-class backends ship in the box:
|
|
13
|
+
*
|
|
14
|
+
* - "memory" (default) — Map + LRU eviction (maxEntries) + bytes
|
|
15
|
+
* eviction (maxBytes) + periodic sweep. Single-process accuracy.
|
|
16
|
+
* - "cluster" — _blamejs_cache table via cluster-storage. One
|
|
17
|
+
* table serves every CacheInstance via "<namespace>:<key>"
|
|
18
|
+
* composite key; ON CONFLICT UPSERT for atomic set.
|
|
19
|
+
* - "redis" — cache-redis client; sliding TTL via EXPIRE; tag
|
|
20
|
+
* wipes via SCAN+DEL on a per-namespace prefix.
|
|
21
|
+
*
|
|
22
|
+
* A `{ get, set, del, clear, size, close }` operator-supplied
|
|
23
|
+
* object is the custom-backend escape hatch (Memcached, in-memory
|
|
24
|
+
* harnesses, anything else with the same async surface).
|
|
25
|
+
*
|
|
26
|
+
* Hot-path validation policy:
|
|
27
|
+
*
|
|
28
|
+
* - create() opts → throw at boot (config-time)
|
|
29
|
+
* - key arg on get/set/del → throw at call site (programming bug)
|
|
30
|
+
* - per-call ttlMs override → throw at call site (silent footgun
|
|
31
|
+
* if accepted)
|
|
32
|
+
* - audit / observability → drop silent (hot-path sink)
|
|
33
|
+
* - method-after-close → throw BAD_STATE
|
|
34
|
+
*
|
|
35
|
+
* Security defaults that are NOT opt-in:
|
|
36
|
+
*
|
|
37
|
+
* - auditClear: true mass purges are operator-action shaped
|
|
38
|
+
* - auditFailures: true backend errors are signal
|
|
39
|
+
* - hot-path get/set/hit/miss/eviction → observability only
|
|
40
|
+
* (the audit chain would drown at any reasonable QPS)
|
|
41
|
+
*
|
|
42
|
+
* Returned `CacheInstance` shape:
|
|
43
|
+
*
|
|
44
|
+
* get(key) → value | undefined
|
|
45
|
+
* set(key, value, opts?) → void (opts: { ttlMs, tags, seal })
|
|
46
|
+
* del(key) → boolean
|
|
47
|
+
* has(key) → boolean (does NOT bump LRU recency)
|
|
48
|
+
* clear(opts?) → number (opts: { req, context })
|
|
49
|
+
* size() → number
|
|
50
|
+
* bytes() → number (memory backend only)
|
|
51
|
+
* wrap(key, fn, opts?) → fn's return (opts: { ttlMs, singleFlight })
|
|
52
|
+
* invalidateTag(tag, opts?) → number (opts: { req, context })
|
|
53
|
+
* getTags(key) → string[] | null
|
|
54
|
+
* close() → void
|
|
55
|
+
*
|
|
56
|
+
* Stale-while-revalidate, single-flight wrap (concurrent calls
|
|
57
|
+
* collapse to one compute), tag-based bulk invalidation (memory +
|
|
58
|
+
* cluster), and cross-node invalidation via b.pubsub are all built
|
|
59
|
+
* in — operator opts in via the `staleWhileRevalidate` /
|
|
60
|
+
* `invalidationPubsub` opts.
|
|
61
|
+
*
|
|
62
|
+
* What is NOT in the box: maxBytes on the cluster backend (would
|
|
63
|
+
* require an aggregate query per set; operator prunes the shared
|
|
64
|
+
* table on their own schedule) and per-entry exact slidingTtl on
|
|
65
|
+
* the cluster backend (sliding extends by the cache's defaultTtlMs;
|
|
66
|
+
* operators with mixed-TTL writes wanting strict per-entry sliding
|
|
67
|
+
* use the memory backend or extend at the application layer).
|
|
68
|
+
*
|
|
69
|
+
* @card
|
|
70
|
+
* LRU + TTL cache with operator-supplied namespacing, drop-silent key validation on hot-path observability, and pluggable backends that share semantics across single-process and clustered nodes.
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
var cacheRedis = require("./cache-redis");
|
|
74
|
+
var redisClient = require("./redis-client");
|
|
75
|
+
var clusterStorage = require("./cluster-storage");
|
|
76
|
+
var C = require("./constants");
|
|
77
|
+
var lazyRequire = require("./lazy-require");
|
|
78
|
+
var { boot } = require("./log");
|
|
79
|
+
var numericChecks = require("./numeric-checks");
|
|
80
|
+
var requestHelpers = require("./request-helpers");
|
|
81
|
+
var safeAsync = require("./safe-async");
|
|
82
|
+
var safeJson = require("./safe-json");
|
|
83
|
+
var validateOpts = require("./validate-opts");
|
|
84
|
+
var { CacheError } = require("./framework-error");
|
|
85
|
+
|
|
86
|
+
var log = boot("cache");
|
|
87
|
+
var observability = lazyRequire(function () { return require("./observability"); });
|
|
88
|
+
// D-L5 — opt-in vault seal for cluster-backend cache values. Lazy so
|
|
89
|
+
// vault-not-initialized in tests with a memory cache doesn't crash
|
|
90
|
+
// at module load.
|
|
91
|
+
var vault = lazyRequire(function () { return require("./vault"); });
|
|
92
|
+
// Marker bytes that prefix sealed values in _blamejs_cache.valueJson —
|
|
93
|
+
// "blamejs:cache.sealed:" + base64-of-vault-sealed-payload. The
|
|
94
|
+
// non-prefixed cache rows pass straight through JSON.parse as before
|
|
95
|
+
// so the seal opt is a strict per-call upgrade with no migration.
|
|
96
|
+
var CACHE_SEAL_PREFIX = "blamejs:cache.sealed:";
|
|
97
|
+
|
|
98
|
+
var _err = CacheError.factory;
|
|
99
|
+
|
|
100
|
+
var DEFAULTS = Object.freeze({
|
|
101
|
+
backend: "memory",
|
|
102
|
+
ttlMs: C.TIME.minutes(5),
|
|
103
|
+
maxEntries: C.BYTES.bytes(10000),
|
|
104
|
+
maxBytes: Infinity,
|
|
105
|
+
sweepIntervalMs: C.TIME.minutes(1),
|
|
106
|
+
staleWhileRevalidate: false,
|
|
107
|
+
slidingTtl: false,
|
|
108
|
+
auditFailures: true,
|
|
109
|
+
auditClear: true,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// ---- Config-time validation helpers (throw on bad input) ----
|
|
113
|
+
|
|
114
|
+
var _isFiniteNonNegative = numericChecks.isFiniteNonNegative;
|
|
115
|
+
var _isPositiveInt = numericChecks.isPositiveInt;
|
|
116
|
+
|
|
117
|
+
// ttlMs accepts: any non-negative finite number OR Infinity. NaN, negative,
|
|
118
|
+
// or non-number is rejected.
|
|
119
|
+
function _validateTtl(name, value) {
|
|
120
|
+
if (value === Infinity) return;
|
|
121
|
+
if (typeof value !== "number" || isNaN(value) || !isFinite(value) || value < 0) {
|
|
122
|
+
throw _err("BAD_OPT", name + " must be a non-negative finite number or Infinity, got " +
|
|
123
|
+
(typeof value) + " " + JSON.stringify(value));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function _validateMaxEntries(value) {
|
|
128
|
+
if (value === Infinity) return;
|
|
129
|
+
if (!_isPositiveInt(value)) {
|
|
130
|
+
throw _err("BAD_OPT", "cache.create: maxEntries must be a positive integer or Infinity, got " +
|
|
131
|
+
JSON.stringify(value));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function _validateMaxBytes(value) {
|
|
136
|
+
if (value === Infinity) return;
|
|
137
|
+
if (!_isFiniteNonNegative(value) || value < 1) {
|
|
138
|
+
throw _err("BAD_OPT", "cache.create: maxBytes must be a positive finite number or Infinity, got " +
|
|
139
|
+
JSON.stringify(value));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Default sizeOf — best-effort byte estimate. Operators with structured
|
|
144
|
+
// values (large objects, custom classes) should pass their own sizeOf
|
|
145
|
+
// for accuracy.
|
|
146
|
+
function _defaultSizeOf(value) {
|
|
147
|
+
if (value === null || value === undefined) return 0;
|
|
148
|
+
if (Buffer.isBuffer(value)) return value.length;
|
|
149
|
+
if (typeof value === "string") return Buffer.byteLength(value, "utf8");
|
|
150
|
+
if (typeof value === "number" || typeof value === "boolean") return C.BYTES.bytes(8);
|
|
151
|
+
// Fallback: round-trip through JSON. Cost is real; documented in the
|
|
152
|
+
// DEFAULTS docstring so operators with hot-path size accounting know
|
|
153
|
+
// to supply their own sizeOf.
|
|
154
|
+
try { return Buffer.byteLength(JSON.stringify(value), "utf8"); }
|
|
155
|
+
catch (_e) { return 0; }
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function _validateBackendObject(backend) {
|
|
159
|
+
var required = ["get", "set", "del", "clear", "size", "close"];
|
|
160
|
+
if (typeof backend !== "object" || backend === null) {
|
|
161
|
+
throw _err("BAD_OPT", "cache.create: custom backend must be an object");
|
|
162
|
+
}
|
|
163
|
+
for (var i = 0; i < required.length; i++) {
|
|
164
|
+
if (typeof backend[required[i]] !== "function") {
|
|
165
|
+
throw _err("BAD_OPT", "cache.create: custom backend missing method '" + required[i] +
|
|
166
|
+
"' (required: " + required.join(", ") + ")");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function _validateCreateOpts(opts) {
|
|
172
|
+
validateOpts.requireObject(opts, "cache.create", CacheError);
|
|
173
|
+
validateOpts.requireNonEmptyString(opts.namespace, "cache.create: namespace", CacheError, "BAD_OPT");
|
|
174
|
+
// Composite cluster-key separator is ":" — namespace must not contain it
|
|
175
|
+
// or two namespaces could collide ("a:b" + "c" = "a:b:c" = "a" + "b:c").
|
|
176
|
+
if (opts.namespace.indexOf(":") !== -1) {
|
|
177
|
+
throw _err("BAD_OPT", "cache.create: namespace must not contain ':' (used as cluster-key separator), got " +
|
|
178
|
+
JSON.stringify(opts.namespace));
|
|
179
|
+
}
|
|
180
|
+
if (opts.backend !== undefined) {
|
|
181
|
+
if (typeof opts.backend === "string") {
|
|
182
|
+
if (opts.backend !== "memory" && opts.backend !== "cluster" && opts.backend !== "redis") {
|
|
183
|
+
throw _err("BAD_OPT", "cache.create: backend string must be 'memory' | 'cluster' | 'redis', got " +
|
|
184
|
+
JSON.stringify(opts.backend));
|
|
185
|
+
}
|
|
186
|
+
if (opts.backend === "redis") {
|
|
187
|
+
if (typeof opts.redisUrl !== "string" || opts.redisUrl.length === 0) {
|
|
188
|
+
throw _err("BAD_OPT", "cache.create: backend='redis' requires opts.redisUrl (e.g. redis://localhost:6379/0)");
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
_validateBackendObject(opts.backend);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (opts.ttlMs !== undefined) _validateTtl("cache.create: ttlMs", opts.ttlMs);
|
|
196
|
+
if (opts.maxEntries !== undefined) _validateMaxEntries(opts.maxEntries);
|
|
197
|
+
if (opts.maxBytes !== undefined) _validateMaxBytes(opts.maxBytes);
|
|
198
|
+
validateOpts.optionalFunction(opts.sizeOf, "cache.create: sizeOf", CacheError);
|
|
199
|
+
validateOpts.optionalBoolean(opts.slidingTtl, "cache.create: slidingTtl", CacheError);
|
|
200
|
+
if (opts.sweepIntervalMs !== undefined) {
|
|
201
|
+
validateOpts.optionalFiniteNonNegative(opts.sweepIntervalMs, "cache.create: sweepIntervalMs", CacheError);
|
|
202
|
+
if (opts.sweepIntervalMs < C.TIME.seconds(1)) {
|
|
203
|
+
throw _err("BAD_OPT", "cache.create: sweepIntervalMs must be >= 1000ms, got " +
|
|
204
|
+
JSON.stringify(opts.sweepIntervalMs));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
validateOpts.optionalBoolean(opts.staleWhileRevalidate, "cache.create: staleWhileRevalidate", CacheError);
|
|
208
|
+
validateOpts.optionalBoolean(opts.auditFailures, "cache.create: auditFailures", CacheError);
|
|
209
|
+
validateOpts.optionalBoolean(opts.auditClear, "cache.create: auditClear", CacheError);
|
|
210
|
+
validateOpts.auditShape(opts.audit, "cache.create", CacheError);
|
|
211
|
+
validateOpts.observabilityShape(opts.observability, "cache.create", CacheError);
|
|
212
|
+
validateOpts.optionalFunction(opts.clock, "cache.create: clock", CacheError);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function _validateKey(key, ctx) {
|
|
216
|
+
if (typeof key !== "string" || key.length === 0) {
|
|
217
|
+
throw _err("BAD_KEY", ctx + ": key must be a non-empty string, got " +
|
|
218
|
+
(typeof key) + " " + JSON.stringify(key));
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// ---- Memory backend ----
|
|
223
|
+
// LRU realized by Map insertion order (Node Map iterates in insertion order;
|
|
224
|
+
// re-inserting a key on hit moves it to the most-recent position).
|
|
225
|
+
|
|
226
|
+
function _memoryBackend(cfg) {
|
|
227
|
+
var entries = new Map(); // key → { value, expiresAt, ttlMs, bytes, tags }
|
|
228
|
+
var maxEntries = cfg.maxEntries;
|
|
229
|
+
var maxBytes = cfg.maxBytes;
|
|
230
|
+
var sizeOf = cfg.sizeOf;
|
|
231
|
+
var slidingTtl = cfg.slidingTtl;
|
|
232
|
+
var clock = cfg.clock;
|
|
233
|
+
var emitObs = cfg.emitObs;
|
|
234
|
+
var namespace = cfg.namespace;
|
|
235
|
+
var sweepTimer = null;
|
|
236
|
+
var totalBytes = 0;
|
|
237
|
+
|
|
238
|
+
// tag → Set<key>. Bidirectional with entry.tags for fast invalidate.
|
|
239
|
+
var tagIndex = new Map();
|
|
240
|
+
|
|
241
|
+
function _isExpired(entry, now) {
|
|
242
|
+
return entry.expiresAt !== Infinity && entry.expiresAt <= now;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function _untrack(key, entry) {
|
|
246
|
+
if (!entry) return;
|
|
247
|
+
totalBytes -= entry.bytes || 0;
|
|
248
|
+
if (totalBytes < 0) totalBytes = 0;
|
|
249
|
+
if (entry.tags && entry.tags.length > 0) {
|
|
250
|
+
for (var i = 0; i < entry.tags.length; i++) {
|
|
251
|
+
var s = tagIndex.get(entry.tags[i]);
|
|
252
|
+
if (s) {
|
|
253
|
+
s.delete(key);
|
|
254
|
+
if (s.size === 0) tagIndex.delete(entry.tags[i]);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function _evictByCounts() {
|
|
261
|
+
while (maxEntries !== Infinity && entries.size > maxEntries) {
|
|
262
|
+
var oldest = entries.keys().next().value;
|
|
263
|
+
var e = entries.get(oldest);
|
|
264
|
+
_untrack(oldest, e);
|
|
265
|
+
entries.delete(oldest);
|
|
266
|
+
emitObs("cache.eviction.size", { namespace: namespace });
|
|
267
|
+
}
|
|
268
|
+
while (maxBytes !== Infinity && totalBytes > maxBytes && entries.size > 0) {
|
|
269
|
+
var oldestB = entries.keys().next().value;
|
|
270
|
+
var eb = entries.get(oldestB);
|
|
271
|
+
_untrack(oldestB, eb);
|
|
272
|
+
entries.delete(oldestB);
|
|
273
|
+
emitObs("cache.eviction.bytes", { namespace: namespace });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async function get(key) {
|
|
278
|
+
var now = clock();
|
|
279
|
+
var entry = entries.get(key);
|
|
280
|
+
if (!entry) return undefined;
|
|
281
|
+
if (_isExpired(entry, now)) {
|
|
282
|
+
_untrack(key, entry);
|
|
283
|
+
entries.delete(key);
|
|
284
|
+
emitObs("cache.eviction.expired", { namespace: namespace });
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
// Sliding TTL: extend lifetime on each successful read by the
|
|
288
|
+
// entry's original ttlMs. Infinity stays Infinity.
|
|
289
|
+
if (slidingTtl && entry.ttlMs !== Infinity && typeof entry.ttlMs === "number") {
|
|
290
|
+
entry.expiresAt = now + entry.ttlMs;
|
|
291
|
+
}
|
|
292
|
+
// LRU recency bump: re-insert moves to the most-recent slot.
|
|
293
|
+
entries.delete(key);
|
|
294
|
+
entries.set(key, entry);
|
|
295
|
+
return entry.value;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function set(key, value, expiresAt, meta) {
|
|
299
|
+
// Existing key replacement: untrack first to rebalance bytes + tags.
|
|
300
|
+
var prior = entries.get(key);
|
|
301
|
+
if (prior) {
|
|
302
|
+
_untrack(key, prior);
|
|
303
|
+
entries.delete(key);
|
|
304
|
+
}
|
|
305
|
+
var bytes = sizeOf(value) || 0;
|
|
306
|
+
var ttlMs = meta && typeof meta.ttlMs === "number" ? meta.ttlMs : null;
|
|
307
|
+
var tags = (meta && Array.isArray(meta.tags)) ? meta.tags.slice() : null;
|
|
308
|
+
entries.set(key, {
|
|
309
|
+
value: value,
|
|
310
|
+
expiresAt: expiresAt,
|
|
311
|
+
ttlMs: ttlMs,
|
|
312
|
+
bytes: bytes,
|
|
313
|
+
tags: tags,
|
|
314
|
+
});
|
|
315
|
+
totalBytes += bytes;
|
|
316
|
+
if (tags && tags.length > 0) {
|
|
317
|
+
for (var i = 0; i < tags.length; i++) {
|
|
318
|
+
var s = tagIndex.get(tags[i]);
|
|
319
|
+
if (!s) { s = new Set(); tagIndex.set(tags[i], s); }
|
|
320
|
+
s.add(key);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
_evictByCounts();
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
async function del(key) {
|
|
327
|
+
var entry = entries.get(key);
|
|
328
|
+
if (!entry) return false;
|
|
329
|
+
_untrack(key, entry);
|
|
330
|
+
entries.delete(key);
|
|
331
|
+
return true;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
async function has(key) {
|
|
335
|
+
var entry = entries.get(key);
|
|
336
|
+
if (!entry) return false;
|
|
337
|
+
if (_isExpired(entry, clock())) {
|
|
338
|
+
_untrack(key, entry);
|
|
339
|
+
entries.delete(key);
|
|
340
|
+
emitObs("cache.eviction.expired", { namespace: namespace });
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async function clear() {
|
|
347
|
+
var n = entries.size;
|
|
348
|
+
entries.clear();
|
|
349
|
+
tagIndex.clear();
|
|
350
|
+
totalBytes = 0;
|
|
351
|
+
return n;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async function size() {
|
|
355
|
+
// Lazy purge: count only non-expired so size() reflects "live" entries.
|
|
356
|
+
var now = clock();
|
|
357
|
+
var live = 0;
|
|
358
|
+
for (var entry of entries.values()) {
|
|
359
|
+
if (!_isExpired(entry, now)) live++;
|
|
360
|
+
}
|
|
361
|
+
return live;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async function invalidateTag(tag) {
|
|
365
|
+
var keys = tagIndex.get(tag);
|
|
366
|
+
if (!keys || keys.size === 0) return 0;
|
|
367
|
+
var purged = 0;
|
|
368
|
+
var toDelete = Array.from(keys);
|
|
369
|
+
for (var i = 0; i < toDelete.length; i++) {
|
|
370
|
+
var k = toDelete[i];
|
|
371
|
+
var entry = entries.get(k);
|
|
372
|
+
if (entry) {
|
|
373
|
+
_untrack(k, entry);
|
|
374
|
+
entries.delete(k);
|
|
375
|
+
purged++;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
return purged;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
async function getTags(key) {
|
|
382
|
+
var entry = entries.get(key);
|
|
383
|
+
if (!entry) return null;
|
|
384
|
+
return entry.tags ? entry.tags.slice() : [];
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
async function bytes() {
|
|
388
|
+
return totalBytes;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function _sweep() {
|
|
392
|
+
var now = clock();
|
|
393
|
+
var purged = 0;
|
|
394
|
+
for (var k of Array.from(entries.keys())) {
|
|
395
|
+
var e = entries.get(k);
|
|
396
|
+
if (_isExpired(e, now)) {
|
|
397
|
+
_untrack(k, e);
|
|
398
|
+
entries.delete(k);
|
|
399
|
+
purged++;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (purged > 0) {
|
|
403
|
+
for (var i = 0; i < purged; i++) emitObs("cache.eviction.expired", { namespace: namespace });
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function _startSweep(intervalMs) {
|
|
408
|
+
if (sweepTimer) return;
|
|
409
|
+
sweepTimer = safeAsync.repeating(_sweep, intervalMs, { name: "cache-sweep" });
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
async function close() {
|
|
413
|
+
if (sweepTimer) { sweepTimer.stop(); sweepTimer = null; }
|
|
414
|
+
entries.clear();
|
|
415
|
+
tagIndex.clear();
|
|
416
|
+
totalBytes = 0;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
name: "memory",
|
|
421
|
+
get: get,
|
|
422
|
+
set: set,
|
|
423
|
+
del: del,
|
|
424
|
+
has: has,
|
|
425
|
+
clear: clear,
|
|
426
|
+
size: size,
|
|
427
|
+
bytes: bytes,
|
|
428
|
+
invalidateTag: invalidateTag,
|
|
429
|
+
getTags: getTags,
|
|
430
|
+
close: close,
|
|
431
|
+
_startSweep: _startSweep,
|
|
432
|
+
// Test hook: raw entries map for state inspection
|
|
433
|
+
_entries: entries,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// ---- Cluster backend ----
|
|
438
|
+
// Single _blamejs_cache table; cacheKey = "<namespace>:<key>". JSON-only
|
|
439
|
+
// value serialization. UPSERT via ON CONFLICT for atomic set.
|
|
440
|
+
|
|
441
|
+
function _clusterBackend(cfg) {
|
|
442
|
+
var namespace = cfg.namespace;
|
|
443
|
+
var clock = cfg.clock;
|
|
444
|
+
var emitObs = cfg.emitObs;
|
|
445
|
+
var slidingTtl = cfg.slidingTtl;
|
|
446
|
+
var defaultTtlMs = cfg.defaultTtlMs;
|
|
447
|
+
|
|
448
|
+
// Composite cluster key. Namespace was validated to not contain ":"
|
|
449
|
+
// at create time, so the split is unambiguous.
|
|
450
|
+
function _composedKey(key) { return namespace + ":" + key; }
|
|
451
|
+
|
|
452
|
+
async function get(key) {
|
|
453
|
+
var now = clock();
|
|
454
|
+
var result = await clusterStorage.execute(
|
|
455
|
+
"SELECT valueJson, expiresAt FROM _blamejs_cache WHERE cacheKey = ?",
|
|
456
|
+
[_composedKey(key)]
|
|
457
|
+
);
|
|
458
|
+
if (!result || !result.rows || result.rows.length === 0) return undefined;
|
|
459
|
+
var row = result.rows[0];
|
|
460
|
+
if (row.expiresAt <= now) {
|
|
461
|
+
// Lazy purge: opportunistic delete on stale read.
|
|
462
|
+
try {
|
|
463
|
+
await clusterStorage.execute(
|
|
464
|
+
"DELETE FROM _blamejs_cache WHERE cacheKey = ? AND expiresAt <= ?",
|
|
465
|
+
[_composedKey(key), now]
|
|
466
|
+
);
|
|
467
|
+
} catch (_e) { /* sweeper will catch it next pass */ }
|
|
468
|
+
emitObs("cache.eviction.expired", { namespace: namespace });
|
|
469
|
+
return undefined;
|
|
470
|
+
}
|
|
471
|
+
// Sliding TTL on cluster: extend by the cache's defaultTtlMs (we don't
|
|
472
|
+
// store per-row ttl). Operators with mixed-TTL writes wanting strict
|
|
473
|
+
// per-entry sliding use the memory backend or extend at app layer.
|
|
474
|
+
// Fire-and-forget — best-effort lifetime extension.
|
|
475
|
+
if (slidingTtl && defaultTtlMs !== Infinity && typeof defaultTtlMs === "number") {
|
|
476
|
+
var newExpires = now + defaultTtlMs;
|
|
477
|
+
clusterStorage.execute(
|
|
478
|
+
"UPDATE _blamejs_cache SET expiresAt = ?, updatedAt = ? " +
|
|
479
|
+
"WHERE cacheKey = ? AND expiresAt > ?",
|
|
480
|
+
[newExpires, now, _composedKey(key), now]
|
|
481
|
+
).catch(function () { /* best-effort */ });
|
|
482
|
+
}
|
|
483
|
+
var stored = row.valueJson;
|
|
484
|
+
// D-L5 — sealed-row decode. Sealed entries are prefixed at write
|
|
485
|
+
// time so the unseal-on-read path is a strict opt-in: rows
|
|
486
|
+
// written without seal:true continue parsing as before.
|
|
487
|
+
if (typeof stored === "string" && stored.indexOf(CACHE_SEAL_PREFIX) === 0) {
|
|
488
|
+
try {
|
|
489
|
+
var unsealed = vault().unseal(stored.substring(CACHE_SEAL_PREFIX.length));
|
|
490
|
+
return safeJson.parse(unsealed, { maxBytes: C.BYTES.mib(64) });
|
|
491
|
+
} catch (_e) { return undefined; }
|
|
492
|
+
}
|
|
493
|
+
try { return safeJson.parse(stored, { maxBytes: C.BYTES.mib(64) }); }
|
|
494
|
+
catch (_e) { return undefined; }
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
async function set(key, value, expiresAt, meta) {
|
|
498
|
+
// safeJson.stringify refuses Buffer / circular / Date round-trip
|
|
499
|
+
// ambiguity that vanilla JSON.stringify silently flattens. The
|
|
500
|
+
// failure mode without this is "cache returns a structurally-
|
|
501
|
+
// changed value, app code treats it as the original" — a subtle
|
|
502
|
+
// freshness bug that's hard to debug.
|
|
503
|
+
var json = safeJson.stringify(value);
|
|
504
|
+
// D-L5 — opt-in vault seal. When the caller passes seal: true,
|
|
505
|
+
// wrap the JSON via b.vault.seal (XChaCha20-Poly1305) before
|
|
506
|
+
// landing in _blamejs_cache.valueJson. The marker prefix is what
|
|
507
|
+
// get() looks for to know it must unseal on read.
|
|
508
|
+
if (meta && meta.seal === true) {
|
|
509
|
+
json = CACHE_SEAL_PREFIX + vault().seal(json);
|
|
510
|
+
}
|
|
511
|
+
var storedExpires = (expiresAt === Infinity) ? Number.MAX_SAFE_INTEGER : expiresAt;
|
|
512
|
+
var now = clock();
|
|
513
|
+
var ck = _composedKey(key);
|
|
514
|
+
// SQLite + Postgres both honor ON CONFLICT (cacheKey) DO UPDATE.
|
|
515
|
+
await clusterStorage.execute(
|
|
516
|
+
"INSERT INTO _blamejs_cache (cacheKey, valueJson, expiresAt, updatedAt) " +
|
|
517
|
+
"VALUES (?, ?, ?, ?) " +
|
|
518
|
+
"ON CONFLICT (cacheKey) DO UPDATE SET " +
|
|
519
|
+
"valueJson = ?, expiresAt = ?, updatedAt = ?",
|
|
520
|
+
[ck, json, storedExpires, now, json, storedExpires, now]
|
|
521
|
+
);
|
|
522
|
+
// Tag handling: drop any prior tags for this key (tags can change
|
|
523
|
+
// across sets), then INSERT the new ones. The PRIMARY KEY on
|
|
524
|
+
// (cacheKey, tag) makes the INSERT idempotent if duplicate tags
|
|
525
|
+
// sneak in.
|
|
526
|
+
var tags = meta && Array.isArray(meta.tags) ? meta.tags : null;
|
|
527
|
+
await clusterStorage.execute(
|
|
528
|
+
"DELETE FROM _blamejs_cache_tags WHERE cacheKey = ?",
|
|
529
|
+
[ck]
|
|
530
|
+
);
|
|
531
|
+
if (tags && tags.length > 0) {
|
|
532
|
+
for (var i = 0; i < tags.length; i++) {
|
|
533
|
+
await clusterStorage.execute(
|
|
534
|
+
"INSERT INTO _blamejs_cache_tags (cacheKey, tag) VALUES (?, ?) " +
|
|
535
|
+
"ON CONFLICT (cacheKey, tag) DO NOTHING",
|
|
536
|
+
[ck, tags[i]]
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async function del(key) {
|
|
543
|
+
var ck = _composedKey(key);
|
|
544
|
+
var result = await clusterStorage.execute(
|
|
545
|
+
"DELETE FROM _blamejs_cache WHERE cacheKey = ?",
|
|
546
|
+
[ck]
|
|
547
|
+
);
|
|
548
|
+
// Drop any matching tag rows. Best-effort: a stale tag row pointing
|
|
549
|
+
// at a non-existent cacheKey is dropped on the next invalidateTag
|
|
550
|
+
// sweep (by the JOIN-shape DELETE) anyway.
|
|
551
|
+
await clusterStorage.execute(
|
|
552
|
+
"DELETE FROM _blamejs_cache_tags WHERE cacheKey = ?",
|
|
553
|
+
[ck]
|
|
554
|
+
).catch(function () { /* best-effort */ });
|
|
555
|
+
return !!(result && result.rowCount && result.rowCount > 0);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
async function invalidateTag(tag) {
|
|
559
|
+
// Find every cacheKey carrying the tag (namespace-scoped via the LIKE
|
|
560
|
+
// on the composed key), delete from the cache table + the junction.
|
|
561
|
+
var like = namespace + ":%";
|
|
562
|
+
var keysResult = await clusterStorage.execute(
|
|
563
|
+
"SELECT cacheKey FROM _blamejs_cache_tags WHERE tag = ? AND cacheKey LIKE ?",
|
|
564
|
+
[tag, like]
|
|
565
|
+
);
|
|
566
|
+
var keys = (keysResult && keysResult.rows) || [];
|
|
567
|
+
if (keys.length === 0) {
|
|
568
|
+
// Nothing to invalidate; still drop any orphan tag rows for
|
|
569
|
+
// this tag scoped to our namespace.
|
|
570
|
+
await clusterStorage.execute(
|
|
571
|
+
"DELETE FROM _blamejs_cache_tags WHERE tag = ? AND cacheKey LIKE ?",
|
|
572
|
+
[tag, like]
|
|
573
|
+
);
|
|
574
|
+
return 0;
|
|
575
|
+
}
|
|
576
|
+
var purged = 0;
|
|
577
|
+
for (var i = 0; i < keys.length; i++) {
|
|
578
|
+
var ck = keys[i].cacheKey;
|
|
579
|
+
var r = await clusterStorage.execute(
|
|
580
|
+
"DELETE FROM _blamejs_cache WHERE cacheKey = ?",
|
|
581
|
+
[ck]
|
|
582
|
+
);
|
|
583
|
+
if (r && r.rowCount > 0) purged += r.rowCount;
|
|
584
|
+
await clusterStorage.execute(
|
|
585
|
+
"DELETE FROM _blamejs_cache_tags WHERE cacheKey = ?",
|
|
586
|
+
[ck]
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
return purged;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
async function getTags(key) {
|
|
593
|
+
var result = await clusterStorage.execute(
|
|
594
|
+
"SELECT tag FROM _blamejs_cache_tags WHERE cacheKey = ?",
|
|
595
|
+
[_composedKey(key)]
|
|
596
|
+
);
|
|
597
|
+
if (!result || !result.rows) return [];
|
|
598
|
+
return result.rows.map(function (r) { return r.tag; });
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
async function has(key) {
|
|
602
|
+
// Existence check without recency bump — cluster backend doesn't
|
|
603
|
+
// track LRU at all, so "without bumping" is automatic. Honors
|
|
604
|
+
// expiresAt the same as get().
|
|
605
|
+
var now = clock();
|
|
606
|
+
var result = await clusterStorage.execute(
|
|
607
|
+
"SELECT expiresAt FROM _blamejs_cache WHERE cacheKey = ? AND expiresAt > ?",
|
|
608
|
+
[_composedKey(key), now]
|
|
609
|
+
);
|
|
610
|
+
return !!(result && result.rows && result.rows.length > 0);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
async function clear() {
|
|
614
|
+
// Namespace-scoped wipe so two CacheInstance instances sharing the
|
|
615
|
+
// table don't cross-purge each other.
|
|
616
|
+
var like = namespace + ":%";
|
|
617
|
+
var result = await clusterStorage.execute(
|
|
618
|
+
"DELETE FROM _blamejs_cache WHERE cacheKey LIKE ?",
|
|
619
|
+
[like]
|
|
620
|
+
);
|
|
621
|
+
// Drop matching tag rows in the same namespace.
|
|
622
|
+
await clusterStorage.execute(
|
|
623
|
+
"DELETE FROM _blamejs_cache_tags WHERE cacheKey LIKE ?",
|
|
624
|
+
[like]
|
|
625
|
+
).catch(function () { /* best-effort */ });
|
|
626
|
+
return (result && result.rowCount) || 0;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
async function size() {
|
|
630
|
+
var now = clock();
|
|
631
|
+
var like = namespace + ":%";
|
|
632
|
+
var result = await clusterStorage.execute(
|
|
633
|
+
"SELECT COUNT(*) AS n FROM _blamejs_cache WHERE cacheKey LIKE ? AND expiresAt > ?",
|
|
634
|
+
[like, now]
|
|
635
|
+
);
|
|
636
|
+
if (!result || !result.rows || result.rows.length === 0) return 0;
|
|
637
|
+
return result.rows[0].n || 0;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
async function _sweep() {
|
|
641
|
+
var now = clock();
|
|
642
|
+
var like = namespace + ":%";
|
|
643
|
+
// Capture the to-be-purged keys first so we can drop matching tag
|
|
644
|
+
// rows in the same sweep — keeps the junction table free of orphans
|
|
645
|
+
// pointing at expired cacheKeys.
|
|
646
|
+
var expiredResult = await clusterStorage.execute(
|
|
647
|
+
"SELECT cacheKey FROM _blamejs_cache WHERE cacheKey LIKE ? AND expiresAt <= ?",
|
|
648
|
+
[like, now]
|
|
649
|
+
);
|
|
650
|
+
var expiredKeys = (expiredResult && expiredResult.rows) || [];
|
|
651
|
+
await clusterStorage.execute(
|
|
652
|
+
"DELETE FROM _blamejs_cache WHERE cacheKey LIKE ? AND expiresAt <= ?",
|
|
653
|
+
[like, now]
|
|
654
|
+
);
|
|
655
|
+
for (var i = 0; i < expiredKeys.length; i++) {
|
|
656
|
+
await clusterStorage.execute(
|
|
657
|
+
"DELETE FROM _blamejs_cache_tags WHERE cacheKey = ?",
|
|
658
|
+
[expiredKeys[i].cacheKey]
|
|
659
|
+
).catch(function () { /* best-effort */ });
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function _startSweep(intervalMs) {
|
|
664
|
+
cfg._sweepTimer = safeAsync.repeating(_sweep, intervalMs, { name: "cache-sweep-cluster" });
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
async function close() {
|
|
668
|
+
if (cfg._sweepTimer) { cfg._sweepTimer.stop(); cfg._sweepTimer = null; }
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return {
|
|
672
|
+
name: "cluster",
|
|
673
|
+
get: get,
|
|
674
|
+
set: set,
|
|
675
|
+
del: del,
|
|
676
|
+
has: has,
|
|
677
|
+
clear: clear,
|
|
678
|
+
size: size,
|
|
679
|
+
close: close,
|
|
680
|
+
invalidateTag: invalidateTag,
|
|
681
|
+
getTags: getTags,
|
|
682
|
+
_startSweep: _startSweep,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// ---- Custom backend wrapper ----
|
|
687
|
+
// Operator-supplied { get, set, del, clear, size, close } — wrap to
|
|
688
|
+
// uniform-shape (no _startSweep, _entries). The operator is responsible
|
|
689
|
+
// for their own expiration; we pass expiresAt to set().
|
|
690
|
+
|
|
691
|
+
function _customBackend(operatorBackend, cfg) {
|
|
692
|
+
return {
|
|
693
|
+
name: "custom",
|
|
694
|
+
get: function (key) { return operatorBackend.get(key); },
|
|
695
|
+
set: function (key, value, expiresAt, meta) {
|
|
696
|
+
// Older 3-arg backends remain compatible — meta is opt-in.
|
|
697
|
+
return operatorBackend.set(key, value, expiresAt, meta);
|
|
698
|
+
},
|
|
699
|
+
del: function (key) { return operatorBackend.del(key); },
|
|
700
|
+
has: function (key) {
|
|
701
|
+
// Optional has() — fall back to get-and-coerce if operator didn't
|
|
702
|
+
// implement it.
|
|
703
|
+
if (typeof operatorBackend.has === "function") return operatorBackend.has(key);
|
|
704
|
+
return Promise.resolve(operatorBackend.get(key)).then(function (v) { return v !== undefined; });
|
|
705
|
+
},
|
|
706
|
+
clear: function () { return operatorBackend.clear(); },
|
|
707
|
+
size: function () { return operatorBackend.size(); },
|
|
708
|
+
bytes: function () {
|
|
709
|
+
if (typeof operatorBackend.bytes === "function") return operatorBackend.bytes();
|
|
710
|
+
return Promise.resolve(0);
|
|
711
|
+
},
|
|
712
|
+
invalidateTag: function (tag) {
|
|
713
|
+
if (typeof operatorBackend.invalidateTag === "function") return operatorBackend.invalidateTag(tag);
|
|
714
|
+
return Promise.resolve(0);
|
|
715
|
+
},
|
|
716
|
+
getTags: function (key) {
|
|
717
|
+
if (typeof operatorBackend.getTags === "function") return operatorBackend.getTags(key);
|
|
718
|
+
return Promise.resolve(null);
|
|
719
|
+
},
|
|
720
|
+
close: function () { return operatorBackend.close(); },
|
|
721
|
+
_startSweep: function () { /* operator backend manages its own sweep */ },
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// ---- Public create ----
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* @primitive b.cache.create
|
|
729
|
+
* @signature b.cache.create(opts)
|
|
730
|
+
* @since 0.1.0
|
|
731
|
+
* @status stable
|
|
732
|
+
* @related b.pubsub.create, b.audit
|
|
733
|
+
*
|
|
734
|
+
* Build a `CacheInstance` bound to a `namespace`. The instance owns
|
|
735
|
+
* its sweep timer, its backend connection, its single-flight inflight
|
|
736
|
+
* map, and (when `invalidationPubsub` is supplied) a pubsub
|
|
737
|
+
* subscription that mirrors `del` / `clear` / `invalidateTag` events
|
|
738
|
+
* across nodes. Multiple instances coexist — a "session.user" memory
|
|
739
|
+
* cache and a "billing.invoice" cluster cache share neither keys nor
|
|
740
|
+
* tags. `close()` releases everything.
|
|
741
|
+
*
|
|
742
|
+
* The `backend` opt picks the storage tier: `"memory"` (default,
|
|
743
|
+
* single-process LRU+TTL), `"cluster"` (shared SQL table for
|
|
744
|
+
* multi-node coherence), `"redis"` (when `redisUrl` is supplied;
|
|
745
|
+
* native EXPIRE-based TTL), or an operator-supplied object with
|
|
746
|
+
* `{ get, set, del, clear, size, close }` for any other store.
|
|
747
|
+
* Backends are interchangeable from the caller's perspective —
|
|
748
|
+
* `await cache.get(key)` returns the same shape regardless.
|
|
749
|
+
*
|
|
750
|
+
* @opts
|
|
751
|
+
* namespace: string, // required; collision domain; must not contain ':'
|
|
752
|
+
* backend: "memory" | "cluster" | "redis" | object, // default "memory"
|
|
753
|
+
* ttlMs: number | Infinity, // default C.TIME.minutes(5)
|
|
754
|
+
* maxEntries: number | Infinity, // memory backend cap; default 10000
|
|
755
|
+
* maxBytes: number | Infinity, // memory backend cap; default Infinity
|
|
756
|
+
* sizeOf: function(value) -> number, // memory bytes accounting override
|
|
757
|
+
* sweepIntervalMs: number, // expired-entry sweep cadence; default C.TIME.minutes(1); minimum 1000
|
|
758
|
+
* staleWhileRevalidate: boolean, // wrap() serves stale + refreshes in background; default false
|
|
759
|
+
* slidingTtl: boolean, // bump expiresAt on hit; default false
|
|
760
|
+
* auditFailures: boolean, // emit audit on backend errors; default true
|
|
761
|
+
* auditClear: boolean, // emit audit on clear / invalidateTag; default true
|
|
762
|
+
* audit: { emit } | b.audit, // audit sink override
|
|
763
|
+
* observability: { event } | b.observability, // metrics sink override
|
|
764
|
+
* clock: function() -> number, // Date.now() override (testing)
|
|
765
|
+
* invalidationPubsub: b.pubsub instance, // cross-node del/clear/tag mirroring
|
|
766
|
+
* redisUrl: string, // backend === "redis" only; required there
|
|
767
|
+
* redisPassword: string, // backend === "redis" only
|
|
768
|
+
* redisUsername: string, // backend === "redis" only
|
|
769
|
+
* redisTls: boolean, // backend === "redis" only
|
|
770
|
+
* redisCa: string | Buffer, // backend === "redis" only; PEM CA bundle
|
|
771
|
+
* redisServername: string, // backend === "redis" only; SNI override
|
|
772
|
+
* redisConnectTimeoutMs: number, // backend === "redis" only
|
|
773
|
+
* redisCommandTimeoutMs: number, // backend === "redis" only
|
|
774
|
+
* redisMaxReconnectAttempts: number, // backend === "redis" only
|
|
775
|
+
*
|
|
776
|
+
* @example
|
|
777
|
+
* var b = require("@blamejs/core");
|
|
778
|
+
* var C = b.constants;
|
|
779
|
+
*
|
|
780
|
+
* // Simple set/get against the default memory backend.
|
|
781
|
+
* var sessions = b.cache.create({
|
|
782
|
+
* namespace: "session.user",
|
|
783
|
+
* ttlMs: C.TIME.minutes(5),
|
|
784
|
+
* maxEntries: 10000,
|
|
785
|
+
* });
|
|
786
|
+
* await sessions.set("u-42", { uid: "u-42", role: "admin" });
|
|
787
|
+
* var hit = await sessions.get("u-42");
|
|
788
|
+
* // → { uid: "u-42", role: "admin" }
|
|
789
|
+
*
|
|
790
|
+
* @example
|
|
791
|
+
* var b = require("@blamejs/core");
|
|
792
|
+
* var C = b.constants;
|
|
793
|
+
*
|
|
794
|
+
* // wrap() pattern with per-call TTL override + single-flight.
|
|
795
|
+
* // Concurrent callers collapse to one DB read; subsequent reads
|
|
796
|
+
* // serve from cache for 10 minutes.
|
|
797
|
+
* var profiles = b.cache.create({
|
|
798
|
+
* namespace: "billing.profile",
|
|
799
|
+
* ttlMs: C.TIME.minutes(2),
|
|
800
|
+
* });
|
|
801
|
+
* var profile = await profiles.wrap(
|
|
802
|
+
* "u-42",
|
|
803
|
+
* function () { return { uid: "u-42", plan: "pro" }; },
|
|
804
|
+
* { ttlMs: C.TIME.minutes(10) }
|
|
805
|
+
* );
|
|
806
|
+
* // → { uid: "u-42", plan: "pro" }
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
* var b = require("@blamejs/core");
|
|
810
|
+
* var C = b.constants;
|
|
811
|
+
*
|
|
812
|
+
* // Cluster-shared cache: every node sees the same entries via the
|
|
813
|
+
* // _blamejs_cache table. Tag-based bulk invalidation purges across
|
|
814
|
+
* // every namespace member in one call.
|
|
815
|
+
* var inventory = b.cache.create({
|
|
816
|
+
* namespace: "catalog.item",
|
|
817
|
+
* backend: "cluster",
|
|
818
|
+
* ttlMs: C.TIME.minutes(15),
|
|
819
|
+
* });
|
|
820
|
+
* await inventory.set("sku-1001", { qty: 42 }, { tags: ["warehouse:east"] });
|
|
821
|
+
* var purged = await inventory.invalidateTag("warehouse:east");
|
|
822
|
+
* // → 1
|
|
823
|
+
*/
|
|
824
|
+
function create(opts) {
|
|
825
|
+
opts = opts || {};
|
|
826
|
+
validateOpts(opts, [
|
|
827
|
+
"namespace", "backend", "ttlMs", "maxEntries", "maxBytes", "sizeOf",
|
|
828
|
+
"sweepIntervalMs", "staleWhileRevalidate", "slidingTtl",
|
|
829
|
+
"auditFailures", "auditClear",
|
|
830
|
+
"audit", "observability", "clock",
|
|
831
|
+
// backend === "redis" connection options. Ignored for memory /
|
|
832
|
+
// cluster / custom-backend modes.
|
|
833
|
+
"redisUrl", "redisPassword", "redisUsername", "redisTls", "redisCa",
|
|
834
|
+
"redisServername", "redisConnectTimeoutMs", "redisCommandTimeoutMs",
|
|
835
|
+
"redisMaxReconnectAttempts",
|
|
836
|
+
// Cross-node invalidation: when set, every successful
|
|
837
|
+
// del/clear/invalidateTag publishes an event on the supplied
|
|
838
|
+
// pubsub instance. Other cache instances on other nodes (or in
|
|
839
|
+
// other processes sharing the pubsub backend) react locally —
|
|
840
|
+
// mostly useful for the memory backend so stale per-node entries
|
|
841
|
+
// don't survive a global tag wipe. The cluster + redis backends
|
|
842
|
+
// are coherent by virtue of their shared store, but a hot
|
|
843
|
+
// memory-tier on top of either still benefits.
|
|
844
|
+
"invalidationPubsub",
|
|
845
|
+
], "cache");
|
|
846
|
+
_validateCreateOpts(opts);
|
|
847
|
+
var cfg0 = validateOpts.applyDefaults(opts, DEFAULTS);
|
|
848
|
+
|
|
849
|
+
var namespace = opts.namespace;
|
|
850
|
+
var backendKind = cfg0.backend;
|
|
851
|
+
var defaultTtlMs = cfg0.ttlMs;
|
|
852
|
+
var maxEntries = cfg0.maxEntries;
|
|
853
|
+
var maxBytes = cfg0.maxBytes;
|
|
854
|
+
var sizeOf = (typeof opts.sizeOf === "function") ? opts.sizeOf : _defaultSizeOf;
|
|
855
|
+
var sweepIntervalMs = cfg0.sweepIntervalMs;
|
|
856
|
+
var staleRevalidate = cfg0.staleWhileRevalidate;
|
|
857
|
+
var slidingTtl = cfg0.slidingTtl;
|
|
858
|
+
var auditFailures = cfg0.auditFailures;
|
|
859
|
+
var auditClear = cfg0.auditClear;
|
|
860
|
+
var audit = opts.audit || null;
|
|
861
|
+
var operatorObs = opts.observability || null;
|
|
862
|
+
var clock = opts.clock || function () { return Date.now(); };
|
|
863
|
+
var invalidationPubsub = opts.invalidationPubsub || null;
|
|
864
|
+
if (invalidationPubsub && (
|
|
865
|
+
typeof invalidationPubsub.publish !== "function" ||
|
|
866
|
+
typeof invalidationPubsub.subscribe !== "function" ||
|
|
867
|
+
typeof invalidationPubsub.unsubscribe !== "function")) {
|
|
868
|
+
throw _err("BAD_OPT",
|
|
869
|
+
"cache.create: invalidationPubsub must implement { publish, subscribe, unsubscribe } (b.pubsub.create instance)");
|
|
870
|
+
}
|
|
871
|
+
var invalidationChannel = "cache:" + namespace + ":invalidate";
|
|
872
|
+
var invalidationToken = null;
|
|
873
|
+
// Re-entrancy guard — when we receive an invalidation event from
|
|
874
|
+
// another node we MUST NOT re-publish it (infinite fan-out loop).
|
|
875
|
+
var inboundInvalidation = false;
|
|
876
|
+
|
|
877
|
+
function emitObs(name, labels) {
|
|
878
|
+
try {
|
|
879
|
+
if (operatorObs) operatorObs.event(name, 1, labels || {});
|
|
880
|
+
else observability().event(name, 1, labels || {});
|
|
881
|
+
} catch (_e) { /* hot-path observability sink — drops silent on internal throws */ }
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
var emitAudit = validateOpts.makeAuditEmitter(audit);
|
|
885
|
+
|
|
886
|
+
function _actor(callerOpts) {
|
|
887
|
+
return requestHelpers.resolveActorWithOverride(callerOpts);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
function _backendFailedAudit(op, err) {
|
|
891
|
+
if (!auditFailures) return;
|
|
892
|
+
emitAudit("cache.backend.failed", {
|
|
893
|
+
actor: requestHelpers.extractActorContext(null),
|
|
894
|
+
resource: { kind: "cache", id: namespace },
|
|
895
|
+
outcome: "failure",
|
|
896
|
+
reason: "backend-error",
|
|
897
|
+
metadata: { op: op, code: (err && err.code) || null, message: (err && err.message) || String(err) },
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// Resolve backend
|
|
902
|
+
var cfg = {
|
|
903
|
+
namespace: namespace,
|
|
904
|
+
maxEntries: maxEntries,
|
|
905
|
+
maxBytes: maxBytes,
|
|
906
|
+
sizeOf: sizeOf,
|
|
907
|
+
slidingTtl: slidingTtl,
|
|
908
|
+
defaultTtlMs: defaultTtlMs,
|
|
909
|
+
clock: clock,
|
|
910
|
+
emitObs: emitObs,
|
|
911
|
+
_sweepTimer: null,
|
|
912
|
+
};
|
|
913
|
+
var backend;
|
|
914
|
+
if (backendKind === "memory") {
|
|
915
|
+
backend = _memoryBackend(cfg);
|
|
916
|
+
} else if (backendKind === "cluster") {
|
|
917
|
+
backend = _clusterBackend(cfg);
|
|
918
|
+
} else if (backendKind === "redis") {
|
|
919
|
+
backend = _customBackend(cacheRedis.create(Object.assign(
|
|
920
|
+
redisClient.pickClientOpts(opts, "redis"),
|
|
921
|
+
{
|
|
922
|
+
namespace: namespace,
|
|
923
|
+
slidingTtl: slidingTtl,
|
|
924
|
+
defaultTtlMs: defaultTtlMs,
|
|
925
|
+
clock: clock,
|
|
926
|
+
emitObs: emitObs,
|
|
927
|
+
}
|
|
928
|
+
)), cfg);
|
|
929
|
+
} else {
|
|
930
|
+
backend = _customBackend(opts.backend, cfg);
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
backend._startSweep(sweepIntervalMs);
|
|
934
|
+
|
|
935
|
+
var closed = false;
|
|
936
|
+
function _ensureOpen(method) {
|
|
937
|
+
if (closed) {
|
|
938
|
+
throw _err("BAD_STATE", "cache." + method + ": cache instance has been closed");
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
// Single-flight inflight map for wrap()
|
|
943
|
+
var inflight = new Map();
|
|
944
|
+
|
|
945
|
+
// Stale-while-revalidate tracking (per-instance, in-memory). When SWR
|
|
946
|
+
// is on, wrap() stores entries with a HARD TTL of 2× ttlMs and tracks
|
|
947
|
+
// the SOFT expiration here. Reads after soft but before hard return
|
|
948
|
+
// the cached value AND kick off a background refresh; reads after
|
|
949
|
+
// hard fall through to a normal miss + compute. The soft-TTL map is
|
|
950
|
+
// memory-only even when the backend is cluster — refreshes are a
|
|
951
|
+
// best-effort optimization, not a correctness invariant, so a cache
|
|
952
|
+
// miss after restart (no soft data) just means we serve fresh once.
|
|
953
|
+
var softExpiry = new Map(); // key → softExpiresAt
|
|
954
|
+
var swrInflight = new Map(); // key → background-refresh promise
|
|
955
|
+
var SWR_HARD_MULTIPLIER = 2;
|
|
956
|
+
|
|
957
|
+
// ---- Public methods ----
|
|
958
|
+
|
|
959
|
+
function _resolveTtl(callerOpts, methodName) {
|
|
960
|
+
if (callerOpts && callerOpts.ttlMs !== undefined) {
|
|
961
|
+
_validateTtl("cache." + methodName + ": ttlMs", callerOpts.ttlMs);
|
|
962
|
+
return callerOpts.ttlMs;
|
|
963
|
+
}
|
|
964
|
+
return defaultTtlMs;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
async function get(key) {
|
|
968
|
+
_ensureOpen("get");
|
|
969
|
+
_validateKey(key, "cache.get");
|
|
970
|
+
var v;
|
|
971
|
+
try { v = await backend.get(key); }
|
|
972
|
+
catch (e) {
|
|
973
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "get" });
|
|
974
|
+
_backendFailedAudit("get", e);
|
|
975
|
+
throw e;
|
|
976
|
+
}
|
|
977
|
+
if (v === undefined) emitObs("cache.miss", { namespace: namespace });
|
|
978
|
+
else emitObs("cache.hit", { namespace: namespace });
|
|
979
|
+
return v;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
async function set(key, value, callerOpts) {
|
|
983
|
+
_ensureOpen("set");
|
|
984
|
+
_validateKey(key, "cache.set");
|
|
985
|
+
var ttlMs = _resolveTtl(callerOpts, "set");
|
|
986
|
+
if (ttlMs === 0) return; // 0 means "do not cache"
|
|
987
|
+
var expiresAt = (ttlMs === Infinity) ? Infinity : (clock() + ttlMs);
|
|
988
|
+
var tags = (callerOpts && Array.isArray(callerOpts.tags)) ? callerOpts.tags : null;
|
|
989
|
+
if (tags) {
|
|
990
|
+
for (var i = 0; i < tags.length; i++) {
|
|
991
|
+
if (typeof tags[i] !== "string" || tags[i].length === 0) {
|
|
992
|
+
throw _err("BAD_OPT", "cache.set: tags must be an array of non-empty strings");
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
// D-L5 — opt-in vault seal. Strict-shape check: must be the literal
|
|
997
|
+
// boolean true, not just truthy. Backends that don't support seal
|
|
998
|
+
// (memory, custom) ignore the flag transparently; cluster backend
|
|
999
|
+
// wraps valueJson via b.vault.seal before INSERT.
|
|
1000
|
+
var seal = !!(callerOpts && callerOpts.seal === true);
|
|
1001
|
+
if (seal && backend.name !== "cluster") {
|
|
1002
|
+
throw _err("BAD_OPT",
|
|
1003
|
+
"cache.set: seal: true is only supported on the cluster backend " +
|
|
1004
|
+
"(this cache instance uses '" + (backend.name || "custom") + "'). " +
|
|
1005
|
+
"Memory-backed caches do not need seal because the value never reaches disk; " +
|
|
1006
|
+
"custom backends wrap their own at-rest encryption.");
|
|
1007
|
+
}
|
|
1008
|
+
try { await backend.set(key, value, expiresAt, { ttlMs: ttlMs, tags: tags, seal: seal }); }
|
|
1009
|
+
catch (e) {
|
|
1010
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "set" });
|
|
1011
|
+
_backendFailedAudit("set", e);
|
|
1012
|
+
throw e;
|
|
1013
|
+
}
|
|
1014
|
+
emitObs("cache.set", { namespace: namespace });
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
async function del(key) {
|
|
1018
|
+
_ensureOpen("del");
|
|
1019
|
+
_validateKey(key, "cache.del");
|
|
1020
|
+
var existed;
|
|
1021
|
+
try { existed = await backend.del(key); }
|
|
1022
|
+
catch (e) {
|
|
1023
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "del" });
|
|
1024
|
+
_backendFailedAudit("del", e);
|
|
1025
|
+
throw e;
|
|
1026
|
+
}
|
|
1027
|
+
if (existed) emitObs("cache.del", { namespace: namespace });
|
|
1028
|
+
softExpiry.delete(key);
|
|
1029
|
+
_publishInvalidation({ kind: "del", key: key });
|
|
1030
|
+
return existed;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
async function has(key) {
|
|
1034
|
+
_ensureOpen("has");
|
|
1035
|
+
_validateKey(key, "cache.has");
|
|
1036
|
+
try { return await backend.has(key); }
|
|
1037
|
+
catch (e) {
|
|
1038
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "has" });
|
|
1039
|
+
_backendFailedAudit("has", e);
|
|
1040
|
+
throw e;
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
async function clear(callerOpts) {
|
|
1045
|
+
_ensureOpen("clear");
|
|
1046
|
+
var purged;
|
|
1047
|
+
try { purged = await backend.clear(); }
|
|
1048
|
+
catch (e) {
|
|
1049
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "clear" });
|
|
1050
|
+
_backendFailedAudit("clear", e);
|
|
1051
|
+
throw e;
|
|
1052
|
+
}
|
|
1053
|
+
emitObs("cache.clear", { namespace: namespace });
|
|
1054
|
+
if (auditClear) {
|
|
1055
|
+
emitAudit("cache.cleared", {
|
|
1056
|
+
actor: _actor(callerOpts),
|
|
1057
|
+
resource: { kind: "cache", id: namespace },
|
|
1058
|
+
outcome: "success",
|
|
1059
|
+
metadata: { itemCount: purged },
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
// Drop any in-flight wrap promises — operator clear means "consumers
|
|
1063
|
+
// should re-fetch", and in-flight resolves would seed stale entries
|
|
1064
|
+
// post-clear.
|
|
1065
|
+
inflight.clear();
|
|
1066
|
+
swrInflight.clear();
|
|
1067
|
+
softExpiry.clear();
|
|
1068
|
+
_publishInvalidation({ kind: "clear" });
|
|
1069
|
+
return purged;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
async function size() {
|
|
1073
|
+
_ensureOpen("size");
|
|
1074
|
+
try { return await backend.size(); }
|
|
1075
|
+
catch (e) {
|
|
1076
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "size" });
|
|
1077
|
+
_backendFailedAudit("size", e);
|
|
1078
|
+
throw e;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
async function bytes() {
|
|
1083
|
+
_ensureOpen("bytes");
|
|
1084
|
+
try {
|
|
1085
|
+
if (typeof backend.bytes !== "function") return 0;
|
|
1086
|
+
return await backend.bytes();
|
|
1087
|
+
} catch (e) {
|
|
1088
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "bytes" });
|
|
1089
|
+
_backendFailedAudit("bytes", e);
|
|
1090
|
+
throw e;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
async function invalidateTag(tag, callerOpts) {
|
|
1095
|
+
_ensureOpen("invalidateTag");
|
|
1096
|
+
if (typeof tag !== "string" || tag.length === 0) {
|
|
1097
|
+
throw _err("BAD_OPT", "cache.invalidateTag: tag must be a non-empty string");
|
|
1098
|
+
}
|
|
1099
|
+
if (typeof backend.invalidateTag !== "function") {
|
|
1100
|
+
throw _err("NOT_SUPPORTED",
|
|
1101
|
+
"cache.invalidateTag: backend '" + (backend.name || "custom") +
|
|
1102
|
+
"' does not implement invalidateTag. Operator-supplied custom backends " +
|
|
1103
|
+
"must export invalidateTag(tag) → number to participate in tag-based wipes.");
|
|
1104
|
+
}
|
|
1105
|
+
var purged;
|
|
1106
|
+
try { purged = await backend.invalidateTag(tag); }
|
|
1107
|
+
catch (e) {
|
|
1108
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "invalidateTag" });
|
|
1109
|
+
_backendFailedAudit("invalidateTag", e);
|
|
1110
|
+
throw e;
|
|
1111
|
+
}
|
|
1112
|
+
emitObs("cache.tag.invalidated", { namespace: namespace, tag: tag });
|
|
1113
|
+
if (auditClear && purged > 0) {
|
|
1114
|
+
emitAudit("cache.tag.invalidated", {
|
|
1115
|
+
actor: _actor(callerOpts),
|
|
1116
|
+
resource: { kind: "cache.tag", id: namespace + ":" + tag },
|
|
1117
|
+
outcome: "success",
|
|
1118
|
+
metadata: { tag: tag, itemCount: purged },
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
// Drop in-flight wrap promises whose key WOULD have just been
|
|
1122
|
+
// invalidated. We don't track per-key tags inflight, so a coarse
|
|
1123
|
+
// drop matches clear()'s safer-than-stale posture.
|
|
1124
|
+
inflight.clear();
|
|
1125
|
+
swrInflight.clear();
|
|
1126
|
+
_publishInvalidation({ kind: "tag", tag: tag });
|
|
1127
|
+
return purged;
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
async function getTags(key) {
|
|
1131
|
+
_ensureOpen("getTags");
|
|
1132
|
+
_validateKey(key, "cache.getTags");
|
|
1133
|
+
if (typeof backend.getTags !== "function") return null;
|
|
1134
|
+
try { return await backend.getTags(key); }
|
|
1135
|
+
catch (e) {
|
|
1136
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "getTags" });
|
|
1137
|
+
_backendFailedAudit("getTags", e);
|
|
1138
|
+
throw e;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
function _backgroundRefresh(key, fn, ttlMs) {
|
|
1143
|
+
if (swrInflight.has(key)) return; // already refreshing
|
|
1144
|
+
var p = (async function () {
|
|
1145
|
+
var startedAt = clock();
|
|
1146
|
+
var computed;
|
|
1147
|
+
try { computed = await fn(); }
|
|
1148
|
+
finally {
|
|
1149
|
+
emitObs("cache.wrap.compute", { namespace: namespace, ms: clock() - startedAt });
|
|
1150
|
+
}
|
|
1151
|
+
var expiresAt = _writeWithSwr(key, computed, ttlMs);
|
|
1152
|
+
void expiresAt;
|
|
1153
|
+
return computed;
|
|
1154
|
+
})();
|
|
1155
|
+
swrInflight.set(key, p);
|
|
1156
|
+
p.then(
|
|
1157
|
+
function () { swrInflight.delete(key); },
|
|
1158
|
+
function (_e) {
|
|
1159
|
+
swrInflight.delete(key);
|
|
1160
|
+
// Background refresh failed; stale value already served. Surface
|
|
1161
|
+
// via observability so operators see it without breaking the
|
|
1162
|
+
// request that triggered the refresh.
|
|
1163
|
+
emitObs("cache.refresh.failed", { namespace: namespace });
|
|
1164
|
+
}
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
function _writeWithSwr(key, value, ttlMs) {
|
|
1169
|
+
if (ttlMs === 0) return null; // 0 means "do not cache"
|
|
1170
|
+
var now = clock();
|
|
1171
|
+
var hardTtlMs = (ttlMs === Infinity)
|
|
1172
|
+
? Infinity
|
|
1173
|
+
: (staleRevalidate ? ttlMs * SWR_HARD_MULTIPLIER : ttlMs);
|
|
1174
|
+
var expiresAt = (hardTtlMs === Infinity) ? Infinity : (now + hardTtlMs);
|
|
1175
|
+
if (staleRevalidate && ttlMs !== Infinity) {
|
|
1176
|
+
softExpiry.set(key, now + ttlMs);
|
|
1177
|
+
} else {
|
|
1178
|
+
softExpiry.delete(key);
|
|
1179
|
+
}
|
|
1180
|
+
// Backend write — failure surfaces via observability + audit but
|
|
1181
|
+
// doesn't bubble (caller already has the computed value).
|
|
1182
|
+
backend.set(key, value, expiresAt, { ttlMs: ttlMs }).catch(function (e) {
|
|
1183
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "set" });
|
|
1184
|
+
_backendFailedAudit("set", e);
|
|
1185
|
+
});
|
|
1186
|
+
return expiresAt;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
async function wrap(key, fn, callerOpts) {
|
|
1190
|
+
_ensureOpen("wrap");
|
|
1191
|
+
_validateKey(key, "cache.wrap");
|
|
1192
|
+
if (typeof fn !== "function") {
|
|
1193
|
+
throw _err("BAD_OPT", "cache.wrap: fn must be a function, got " + typeof fn);
|
|
1194
|
+
}
|
|
1195
|
+
var ttlMs = _resolveTtl(callerOpts, "wrap");
|
|
1196
|
+
var singleFlight = !(callerOpts && callerOpts.singleFlight === false);
|
|
1197
|
+
|
|
1198
|
+
var existing;
|
|
1199
|
+
try { existing = await backend.get(key); }
|
|
1200
|
+
catch (e) {
|
|
1201
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "get" });
|
|
1202
|
+
_backendFailedAudit("get", e);
|
|
1203
|
+
throw e;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
if (existing !== undefined) {
|
|
1207
|
+
// SWR: served from backend, but might be stale (past soft TTL).
|
|
1208
|
+
var soft = softExpiry.get(key);
|
|
1209
|
+
var now = clock();
|
|
1210
|
+
if (staleRevalidate && soft !== undefined && soft <= now) {
|
|
1211
|
+
emitObs("cache.hit", { namespace: namespace });
|
|
1212
|
+
_backgroundRefresh(key, fn, ttlMs);
|
|
1213
|
+
return existing;
|
|
1214
|
+
}
|
|
1215
|
+
emitObs("cache.hit", { namespace: namespace });
|
|
1216
|
+
return existing;
|
|
1217
|
+
}
|
|
1218
|
+
emitObs("cache.miss", { namespace: namespace });
|
|
1219
|
+
|
|
1220
|
+
if (singleFlight && inflight.has(key)) {
|
|
1221
|
+
emitObs("cache.wrap.singleflight.collapsed", { namespace: namespace });
|
|
1222
|
+
return inflight.get(key);
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
var promise = (async function () {
|
|
1226
|
+
var startedAt = clock();
|
|
1227
|
+
var computed;
|
|
1228
|
+
try { computed = await fn(); }
|
|
1229
|
+
finally {
|
|
1230
|
+
emitObs("cache.wrap.compute", { namespace: namespace, ms: clock() - startedAt });
|
|
1231
|
+
}
|
|
1232
|
+
if (ttlMs !== 0) {
|
|
1233
|
+
if (staleRevalidate) {
|
|
1234
|
+
_writeWithSwr(key, computed, ttlMs);
|
|
1235
|
+
} else {
|
|
1236
|
+
var expiresAt = (ttlMs === Infinity) ? Infinity : (clock() + ttlMs);
|
|
1237
|
+
try { await backend.set(key, computed, expiresAt, { ttlMs: ttlMs }); }
|
|
1238
|
+
catch (e) {
|
|
1239
|
+
emitObs("cache.backend.failed", { namespace: namespace, op: "set" });
|
|
1240
|
+
_backendFailedAudit("set", e);
|
|
1241
|
+
// Failed write doesn't fail the wrap — caller still gets the
|
|
1242
|
+
// computed value; cache just didn't persist.
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return computed;
|
|
1247
|
+
})();
|
|
1248
|
+
if (singleFlight) {
|
|
1249
|
+
inflight.set(key, promise);
|
|
1250
|
+
promise.then(
|
|
1251
|
+
function () { inflight.delete(key); },
|
|
1252
|
+
function () { inflight.delete(key); }
|
|
1253
|
+
);
|
|
1254
|
+
}
|
|
1255
|
+
return promise;
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
function _publishInvalidation(ev) {
|
|
1259
|
+
if (!invalidationPubsub || inboundInvalidation) return;
|
|
1260
|
+
try { invalidationPubsub.publish(invalidationChannel, ev); }
|
|
1261
|
+
catch (_e) { /* publish best-effort — local invalidation already happened */ }
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
async function _onInboundInvalidation(ev /*, meta */) {
|
|
1265
|
+
if (!ev || closed) return;
|
|
1266
|
+
inboundInvalidation = true;
|
|
1267
|
+
try {
|
|
1268
|
+
if (ev.kind === "tag" && typeof ev.tag === "string" &&
|
|
1269
|
+
typeof backend.invalidateTag === "function") {
|
|
1270
|
+
try { await backend.invalidateTag(ev.tag); }
|
|
1271
|
+
catch (e) { log.debug("invalidation-apply-failed", { op: "invalidateTag", tag: ev.tag, error: e.message }); }
|
|
1272
|
+
} else if (ev.kind === "del" && typeof ev.key === "string") {
|
|
1273
|
+
try { await backend.del(ev.key); }
|
|
1274
|
+
catch (e) { log.debug("invalidation-apply-failed", { op: "del", key: ev.key, error: e.message }); }
|
|
1275
|
+
} else if (ev.kind === "clear") {
|
|
1276
|
+
try { await backend.clear(); }
|
|
1277
|
+
catch (e) { log.debug("invalidation-apply-failed", { op: "clear", error: e.message }); }
|
|
1278
|
+
}
|
|
1279
|
+
// Wipe local in-flight memoization so a freshly-invalidated key
|
|
1280
|
+
// can't resolve from a still-pending fetch on this node.
|
|
1281
|
+
inflight.clear();
|
|
1282
|
+
swrInflight.clear();
|
|
1283
|
+
softExpiry.clear();
|
|
1284
|
+
} finally {
|
|
1285
|
+
inboundInvalidation = false;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
if (invalidationPubsub) {
|
|
1290
|
+
invalidationToken = invalidationPubsub.subscribe(invalidationChannel, _onInboundInvalidation);
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
async function close() {
|
|
1294
|
+
if (closed) return;
|
|
1295
|
+
closed = true;
|
|
1296
|
+
if (invalidationPubsub && invalidationToken) {
|
|
1297
|
+
try { invalidationPubsub.unsubscribe(invalidationToken); }
|
|
1298
|
+
catch (e) { log.debug("close-cleanup-failed", { op: "unsubscribe", error: e.message }); }
|
|
1299
|
+
invalidationToken = null;
|
|
1300
|
+
}
|
|
1301
|
+
inflight.clear();
|
|
1302
|
+
swrInflight.clear();
|
|
1303
|
+
softExpiry.clear();
|
|
1304
|
+
try { await backend.close(); }
|
|
1305
|
+
catch (_e) { /* close best-effort */ }
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
return {
|
|
1309
|
+
get: get,
|
|
1310
|
+
set: set,
|
|
1311
|
+
del: del,
|
|
1312
|
+
has: has,
|
|
1313
|
+
clear: clear,
|
|
1314
|
+
size: size,
|
|
1315
|
+
bytes: bytes,
|
|
1316
|
+
wrap: wrap,
|
|
1317
|
+
invalidateTag: invalidateTag,
|
|
1318
|
+
getTags: getTags,
|
|
1319
|
+
close: close,
|
|
1320
|
+
namespace: namespace,
|
|
1321
|
+
// Test hooks
|
|
1322
|
+
_backend: backend,
|
|
1323
|
+
_inflight: inflight,
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
module.exports = {
|
|
1328
|
+
create: create,
|
|
1329
|
+
CacheError: CacheError,
|
|
1330
|
+
DEFAULTS: DEFAULTS,
|
|
1331
|
+
};
|