@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,1661 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.gateContract
|
|
4
|
+
* @nav Guards
|
|
5
|
+
* @title Gate Contract
|
|
6
|
+
*
|
|
7
|
+
* @intro
|
|
8
|
+
* Shared substrate every `b.guard*` primitive composes against —
|
|
9
|
+
* `resolveProfileAndPosture`, `makeProfileBuilder`,
|
|
10
|
+
* `makeRulePackLoader`, `lookupCompliancePosture`, `buildGuardGate`,
|
|
11
|
+
* `aggregateIssues`, `extractBytesAsText`. The contract every guard
|
|
12
|
+
* implements; ensures the action vocabulary
|
|
13
|
+
* (`serve` / `sanitize` / `refuse` / `audit-only`) and the
|
|
14
|
+
* profile-and-posture resolution shape stay identical across the
|
|
15
|
+
* family.
|
|
16
|
+
*
|
|
17
|
+
* Every guard ships a `.gate(opts)` factory returning the shape
|
|
18
|
+
* defined here. Host primitives (`b.staticServe` / `b.fileUpload` /
|
|
19
|
+
* `b.mail` / `b.objectStore`) call `gate.check(ctx)` at their
|
|
20
|
+
* byte-boundary moment with a uniform context. The decision shape
|
|
21
|
+
* is `{ ok, action, sanitized?, issues, contentTypeOverride?,
|
|
22
|
+
* headers?, forensicHash, forensicSnapshot?, runtimeMs, cacheKey? }`.
|
|
23
|
+
*
|
|
24
|
+
* Operator extension surface inherited by every member:
|
|
25
|
+
*
|
|
26
|
+
* - Profile composition (extends + overrides + removes; cycle detection)
|
|
27
|
+
* - Hook system (beforeCheck / afterCheck / onIssue / onSanitize / onRefuse / onAudit)
|
|
28
|
+
* - Mode posture (enforce / warn-only / shadow / audit-only / log-only / canary)
|
|
29
|
+
* - Versioned policies (version + ruleHash) with policyDiff helper
|
|
30
|
+
* - Forensic snapshot store (operator-supplied evidence vault)
|
|
31
|
+
* - Decision cache (per-forensicHash memoization)
|
|
32
|
+
* - Runtime cap with timeout
|
|
33
|
+
* - Compliance-posture pre-sets (hipaa / pci-dss / gdpr / soc2)
|
|
34
|
+
*
|
|
35
|
+
* Module-level constants `ACTIONS` / `MODES` / `ISSUE_SEVERITIES`
|
|
36
|
+
* carry the frozen enums every guard validates against.
|
|
37
|
+
*
|
|
38
|
+
* Foundation for the guard-* family. Every content-safety primitive
|
|
39
|
+
* shipped under `b.guard*` composes through `buildGuardGate`,
|
|
40
|
+
* `makeProfileBuilder`, `makeRulePackLoader`, and
|
|
41
|
+
* `lookupCompliancePosture`; `b.guardAll` aggregates the registered
|
|
42
|
+
* guards into a single security-on-by-default gate.
|
|
43
|
+
*
|
|
44
|
+
* @card
|
|
45
|
+
* Shared substrate every `b.guard*` primitive composes against — `resolveProfileAndPosture`, `makeProfileBuilder`, `makeRulePackLoader`, `lookupCompliancePosture`, `buildGuardGate`, `aggregateIssues`, `extractBytesAsText`.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
var C = require("./constants");
|
|
49
|
+
var bCrypto = require("./crypto");
|
|
50
|
+
var lazyRequire = require("./lazy-require");
|
|
51
|
+
var safeAsync = require("./safe-async");
|
|
52
|
+
var validateOpts = require("./validate-opts");
|
|
53
|
+
var { GateContractError } = require("./framework-error");
|
|
54
|
+
|
|
55
|
+
var observability = lazyRequire(function () { return require("./observability"); });
|
|
56
|
+
var compliance = lazyRequire(function () { return require("./compliance"); });
|
|
57
|
+
|
|
58
|
+
// Forensic-id token width (bytes); 64 bits is enough for cross-gate
|
|
59
|
+
// correlation in a single request scope.
|
|
60
|
+
var FORENSIC_ID_BYTES = C.BYTES.bytes(8);
|
|
61
|
+
// Hash-prefix used as a fingerprint identifier in policy-rule hashes —
|
|
62
|
+
// 16 hex chars = 64 bits, ample for fingerprint comparison.
|
|
63
|
+
var FINGERPRINT_HEX_LENGTH = C.BYTES.bytes(16);
|
|
64
|
+
// Default cachingGate TTL when operator doesn't supply one.
|
|
65
|
+
var DEFAULT_CACHE_TTL_MS = C.TIME.minutes(5);
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @primitive b.gateContract.GateContractError
|
|
69
|
+
* @signature b.gateContract.GateContractError
|
|
70
|
+
* @since 0.7.5
|
|
71
|
+
* @status stable
|
|
72
|
+
* @related b.gateContract.defineGate, b.gateContract.validateGateShape
|
|
73
|
+
*
|
|
74
|
+
* FrameworkError subclass thrown by gate-contract entry points on
|
|
75
|
+
* shape violations: `gate-contract/bad-shape` from
|
|
76
|
+
* `validateGateShape`, `gate-contract/bad-opt` from `defineGate` /
|
|
77
|
+
* `cachingGate` / `workerThreadGate`, `gate-contract/profile-cycle`
|
|
78
|
+
* and `gate-contract/unknown-profile` from `buildProfile`.
|
|
79
|
+
* `alwaysPermanent` — never retried by `b.retry`.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* try {
|
|
83
|
+
* b.gateContract.validateGateShape({}, "broken");
|
|
84
|
+
* } catch (e) {
|
|
85
|
+
* e instanceof b.gateContract.GateContractError; // → true
|
|
86
|
+
* e.code; // → "gate-contract/bad-shape"
|
|
87
|
+
* }
|
|
88
|
+
*/
|
|
89
|
+
var _err = GateContractError.factory;
|
|
90
|
+
|
|
91
|
+
// ---- Enumerations (module-level constants) ----
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @primitive b.gateContract.ACTIONS
|
|
95
|
+
* @signature b.gateContract.ACTIONS
|
|
96
|
+
* @since 0.7.5
|
|
97
|
+
* @status stable
|
|
98
|
+
* @related b.gateContract.MODES, b.gateContract.defineGate
|
|
99
|
+
*
|
|
100
|
+
* Frozen list of every action a gate decision is allowed to set.
|
|
101
|
+
* `serve` emits the bytes unchanged; `refuse` rejects with an
|
|
102
|
+
* operator-meaningful error; `sanitize` substitutes `decision.sanitized`
|
|
103
|
+
* for the original bytes; `strip` removes the offending content;
|
|
104
|
+
* `audit-only` serves but emits an audit entry; `warn` serves and
|
|
105
|
+
* emits a warning counter; `challenge-mfa` triggers step-up auth
|
|
106
|
+
* before serving; `deny-and-revoke` rejects and invalidates the
|
|
107
|
+
* actor's session.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* b.gateContract.ACTIONS.indexOf("serve"); // → 0
|
|
111
|
+
* b.gateContract.ACTIONS.indexOf("warp-speed"); // → -1
|
|
112
|
+
* Object.isFrozen(b.gateContract.ACTIONS); // → true
|
|
113
|
+
*/
|
|
114
|
+
var ACTIONS = Object.freeze([
|
|
115
|
+
"serve", // host emits the bytes as-is
|
|
116
|
+
"refuse", // host rejects with operator-meaningful error
|
|
117
|
+
"sanitize", // host substitutes decision.sanitized for the bytes
|
|
118
|
+
"strip", // host removes the offending content (sanitized = empty)
|
|
119
|
+
"audit-only", // host serves; gate emits audit (no operator-side change)
|
|
120
|
+
"warn", // host serves; gate emits warning (operator monitors)
|
|
121
|
+
"challenge-mfa", // host triggers step-up auth before serving
|
|
122
|
+
"deny-and-revoke", // host rejects + invalidates the actor's session
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* @primitive b.gateContract.MODES
|
|
127
|
+
* @signature b.gateContract.MODES
|
|
128
|
+
* @since 0.7.5
|
|
129
|
+
* @status stable
|
|
130
|
+
* @related b.gateContract.ACTIONS, b.gateContract.defineGate
|
|
131
|
+
*
|
|
132
|
+
* Frozen list of mode-posture values a gate can run in. `enforce`
|
|
133
|
+
* honors the decision; `warn-only` translates every `refuse` to
|
|
134
|
+
* `warn` for staged rollout; `shadow` runs alongside a primary and
|
|
135
|
+
* never refuses (observability-only); `audit-only` and `log-only`
|
|
136
|
+
* emit an audit entry but never block; `canary` enforces on a
|
|
137
|
+
* sampled subset and warns on the rest.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* b.gateContract.MODES.indexOf("enforce"); // → 0
|
|
141
|
+
* b.gateContract.MODES.indexOf("yolo"); // → -1
|
|
142
|
+
*/
|
|
143
|
+
var MODES = Object.freeze([
|
|
144
|
+
"enforce", // gate decision honored
|
|
145
|
+
"warn-only", // gate emits but never refuses (staged rollout)
|
|
146
|
+
"shadow", // run alongside primary; emit divergence; never refuses
|
|
147
|
+
"audit-only", // emit audit but no operator-side action
|
|
148
|
+
"log-only", // emit observability counter only
|
|
149
|
+
"canary", // enforce on N% of requests; warn on the rest
|
|
150
|
+
]);
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @primitive b.gateContract.ISSUE_SEVERITIES
|
|
154
|
+
* @signature b.gateContract.ISSUE_SEVERITIES
|
|
155
|
+
* @since 0.7.5
|
|
156
|
+
* @status stable
|
|
157
|
+
* @related b.gateContract.aggregateIssues, b.gateContract.summarizeIssues
|
|
158
|
+
*
|
|
159
|
+
* Frozen list of severity levels a guard issue may carry. `info` and
|
|
160
|
+
* `warn` are observability-only — `aggregateIssues` keeps `ok: true`
|
|
161
|
+
* with them present. `high` and `critical` flip the result to
|
|
162
|
+
* `ok: false`, refusing the input.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* b.gateContract.ISSUE_SEVERITIES; // → ["info","warn","high","critical"]
|
|
166
|
+
* b.gateContract.ISSUE_SEVERITIES.indexOf("critical"); // → 3
|
|
167
|
+
*/
|
|
168
|
+
var ISSUE_SEVERITIES = Object.freeze([
|
|
169
|
+
"info",
|
|
170
|
+
"warn",
|
|
171
|
+
"high",
|
|
172
|
+
"critical",
|
|
173
|
+
]);
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @primitive b.gateContract.validateGateShape
|
|
177
|
+
* @signature b.gateContract.validateGateShape(gate, label, errorClass)
|
|
178
|
+
* @since 0.7.5
|
|
179
|
+
* @status stable
|
|
180
|
+
* @related b.gateContract.defineGate, b.gateContract.runGate
|
|
181
|
+
*
|
|
182
|
+
* Throws when `gate` does not satisfy the contract — `gate.check`
|
|
183
|
+
* must be a function, `gate.mode` (when present) must be one of the
|
|
184
|
+
* `MODES` enum values, and `gate.metrics` / `gate.close` (when
|
|
185
|
+
* present) must be functions. Operator-supplied gates (and
|
|
186
|
+
* framework-supplied gates with operator-toggled hooks) all flow
|
|
187
|
+
* through this check at host-primitive wire-up time. Shape errors at
|
|
188
|
+
* boot are cheaper than at request time. Returns `gate` unchanged on
|
|
189
|
+
* success.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* var gate = b.guardCsv.gate({ profile: "strict" });
|
|
193
|
+
* b.gateContract.validateGateShape(gate, "uploads.csv");
|
|
194
|
+
* // → returns the gate unchanged when shape is valid
|
|
195
|
+
*
|
|
196
|
+
* try {
|
|
197
|
+
* b.gateContract.validateGateShape({}, "broken");
|
|
198
|
+
* } catch (e) {
|
|
199
|
+
* e.code; // → "gate-contract/bad-shape"
|
|
200
|
+
* }
|
|
201
|
+
*/
|
|
202
|
+
function validateGateShape(gate, label, errorClass) {
|
|
203
|
+
errorClass = errorClass || GateContractError;
|
|
204
|
+
label = label || "gate";
|
|
205
|
+
if (!gate || typeof gate !== "object") {
|
|
206
|
+
throw new errorClass("gate-contract/bad-shape",
|
|
207
|
+
label + ": gate must be an object, got " + typeof gate);
|
|
208
|
+
}
|
|
209
|
+
if (typeof gate.check !== "function") {
|
|
210
|
+
throw new errorClass("gate-contract/bad-shape",
|
|
211
|
+
label + ": gate.check must be a function");
|
|
212
|
+
}
|
|
213
|
+
if (gate.mode !== undefined && MODES.indexOf(gate.mode) === -1) {
|
|
214
|
+
throw new errorClass("gate-contract/bad-shape",
|
|
215
|
+
label + ": gate.mode must be one of " + MODES.join("/") +
|
|
216
|
+
", got " + JSON.stringify(gate.mode));
|
|
217
|
+
}
|
|
218
|
+
if (gate.metrics !== undefined && typeof gate.metrics !== "function") {
|
|
219
|
+
throw new errorClass("gate-contract/bad-shape",
|
|
220
|
+
label + ": gate.metrics must be a function (returns counter snapshot)");
|
|
221
|
+
}
|
|
222
|
+
if (gate.close !== undefined && typeof gate.close !== "function") {
|
|
223
|
+
throw new errorClass("gate-contract/bad-shape",
|
|
224
|
+
label + ": gate.close must be a function");
|
|
225
|
+
}
|
|
226
|
+
return gate;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* @primitive b.gateContract.defineGate
|
|
231
|
+
* @signature b.gateContract.defineGate(opts)
|
|
232
|
+
* @since 0.7.5
|
|
233
|
+
* @status stable
|
|
234
|
+
* @related b.gateContract.buildGuardGate, b.gateContract.validateGateShape
|
|
235
|
+
*
|
|
236
|
+
* Build a gate that satisfies the contract. Wraps the
|
|
237
|
+
* operator-supplied `check(ctx)` with the cross-cutting concerns
|
|
238
|
+
* (hooks, observability, forensic snapshot, runtime cap, decision
|
|
239
|
+
* cache, mode-posture translation) so guards only write the per-guard
|
|
240
|
+
* inspection logic. Returns a gate exposing
|
|
241
|
+
* `{ check, mode, audit, observability, metrics, reset, close, name,
|
|
242
|
+
* version, ruleHash, dryRun, policyDiff }`. Most guards forward through
|
|
243
|
+
* `b.gateContract.buildGuardGate` instead — `defineGate` is the lower-level
|
|
244
|
+
* factory used by host-side composers (`composeGates` / `byRoute` / etc.).
|
|
245
|
+
*
|
|
246
|
+
* @opts
|
|
247
|
+
* name: string, // identifier surfaced in audit / counters
|
|
248
|
+
* version: string, // semver default "1.0.0"
|
|
249
|
+
* mode: string, // one of MODES; default "enforce"
|
|
250
|
+
* check: function, // async (ctx) → decision
|
|
251
|
+
* beforeCheck: function|null, // (ctx) → { skip?, transform? }
|
|
252
|
+
* afterCheck: function|null, // (ctx, decision) → decision
|
|
253
|
+
* onIssue: function|null, // (issue, ctx) → issue|{suppress|promote}
|
|
254
|
+
* onSanitize: function|null, // (bytes, sanitized, ctx) → sanitized
|
|
255
|
+
* onRefuse: function|null, // (ctx, decision) → void
|
|
256
|
+
* onAudit: function|null, // (entry) → entry|false (false suppresses)
|
|
257
|
+
* audit: object|null, // b.audit handle
|
|
258
|
+
* observability: object|null, // b.observability handle
|
|
259
|
+
* forensicEvidenceStore: object|null, // { write({ ... }) }
|
|
260
|
+
* forensicSnippetBytes: number, // 0 = disabled
|
|
261
|
+
* cache: object|null, // b.cache shape
|
|
262
|
+
* cacheTtlMs: number,
|
|
263
|
+
* maxRuntimeMs: number, // 0 = uncapped
|
|
264
|
+
* ruleHash: string, // override fingerprint
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* var gate = b.gateContract.defineGate({
|
|
268
|
+
* name: "tenant:csv:strict",
|
|
269
|
+
* mode: "enforce",
|
|
270
|
+
* maxRuntimeMs: 250,
|
|
271
|
+
* check: async function (ctx) {
|
|
272
|
+
* var text = b.gateContract.extractBytesAsText(ctx);
|
|
273
|
+
* if (text.indexOf("=cmd|") === 0) {
|
|
274
|
+
* return { ok: false, action: "refuse",
|
|
275
|
+
* issues: [{ kind: "csv.formula-injection", severity: "high" }] };
|
|
276
|
+
* }
|
|
277
|
+
* return { ok: true, action: "serve" };
|
|
278
|
+
* },
|
|
279
|
+
* });
|
|
280
|
+
* var d = await gate.check({ bytes: Buffer.from("name,age\nada,36") });
|
|
281
|
+
* d.action; // → "serve"
|
|
282
|
+
*/
|
|
283
|
+
function defineGate(opts) {
|
|
284
|
+
validateOpts.requireObject(opts, "gateContract.defineGate", GateContractError);
|
|
285
|
+
validateOpts.requireNonEmptyString(opts.name, "gateContract.defineGate: name", GateContractError, "gate-contract/bad-opt");
|
|
286
|
+
if (typeof opts.check !== "function") {
|
|
287
|
+
throw _err("gate-contract/bad-opt", "gateContract.defineGate: check must be a function");
|
|
288
|
+
}
|
|
289
|
+
var mode = opts.mode || "enforce";
|
|
290
|
+
if (MODES.indexOf(mode) === -1) {
|
|
291
|
+
throw _err("gate-contract/bad-opt",
|
|
292
|
+
"gateContract.defineGate: mode must be one of " + MODES.join("/") +
|
|
293
|
+
", got " + JSON.stringify(mode));
|
|
294
|
+
}
|
|
295
|
+
var hooks = {
|
|
296
|
+
beforeCheck: opts.beforeCheck || null,
|
|
297
|
+
afterCheck: opts.afterCheck || null,
|
|
298
|
+
onIssue: opts.onIssue || null,
|
|
299
|
+
onSanitize: opts.onSanitize || null,
|
|
300
|
+
onRefuse: opts.onRefuse || null,
|
|
301
|
+
onAudit: opts.onAudit || null,
|
|
302
|
+
};
|
|
303
|
+
var auditHandle = opts.audit || null;
|
|
304
|
+
var emitAudit = validateOpts.makeAuditEmitter(auditHandle);
|
|
305
|
+
var observabilityHandle = opts.observability || null;
|
|
306
|
+
function _emitObs(name, value, labels) {
|
|
307
|
+
if (observabilityHandle && typeof observabilityHandle.safeEvent === "function") {
|
|
308
|
+
observabilityHandle.safeEvent(name, value, labels || {});
|
|
309
|
+
} else {
|
|
310
|
+
observability().safeEvent(name, value, labels || {});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
var forensicSnippetBytes = opts.forensicSnippetBytes || 0;
|
|
314
|
+
var forensicEvidenceStore = opts.forensicEvidenceStore || null;
|
|
315
|
+
var maxRuntimeMs = opts.maxRuntimeMs || 0;
|
|
316
|
+
var decisionCache = opts.cache || null;
|
|
317
|
+
var cacheTtlMs = opts.cacheTtlMs || 0;
|
|
318
|
+
var version = opts.version || "1.0.0";
|
|
319
|
+
var ruleHash = opts.ruleHash || _hashFingerprint({ name: opts.name, version: version });
|
|
320
|
+
|
|
321
|
+
// Counters for metrics() snapshot.
|
|
322
|
+
var counters = {
|
|
323
|
+
passed: 0, refused: 0, sanitized: 0, audited: 0, warned: 0,
|
|
324
|
+
runtimeMs: { count: 0, total: 0 },
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
function _bumpRuntime(ms) {
|
|
328
|
+
counters.runtimeMs.count += 1;
|
|
329
|
+
counters.runtimeMs.total += ms;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async function _runHook(hook, args) {
|
|
333
|
+
if (!hook) return null;
|
|
334
|
+
try { return await hook.apply(null, args); }
|
|
335
|
+
catch (_e) {
|
|
336
|
+
_emitObs(opts.name + ".hook_threw", 1, { hook: args[0] && args[0].name });
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
async function check(ctx) {
|
|
342
|
+
var startedAt = Date.now();
|
|
343
|
+
ctx = ctx || {};
|
|
344
|
+
if (!ctx.forensicId) ctx.forensicId = bCrypto.generateToken(FORENSIC_ID_BYTES);
|
|
345
|
+
|
|
346
|
+
// Decision cache lookup (memoize per-forensicHash).
|
|
347
|
+
var bytes = ctx.bytes;
|
|
348
|
+
var forensicHash = bytes && Buffer.isBuffer(bytes)
|
|
349
|
+
? bCrypto.sha3Hash(bytes, "hex")
|
|
350
|
+
: (typeof bytes === "string" ? bCrypto.sha3Hash(Buffer.from(bytes, "utf8"), "hex") : null);
|
|
351
|
+
var cacheKey = forensicHash ? (opts.name + ":" + ruleHash + ":" + forensicHash) : null;
|
|
352
|
+
if (decisionCache && cacheKey) {
|
|
353
|
+
try {
|
|
354
|
+
var cached = await decisionCache.get(cacheKey);
|
|
355
|
+
if (cached) {
|
|
356
|
+
_bumpRuntime(Date.now() - startedAt);
|
|
357
|
+
return cached;
|
|
358
|
+
}
|
|
359
|
+
} catch (_e) { /* cache best-effort */ }
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// beforeCheck hook — operator can transform / skip
|
|
363
|
+
var beforeRv = await _runHook(hooks.beforeCheck, [ctx]);
|
|
364
|
+
if (beforeRv && beforeRv.skip === true) {
|
|
365
|
+
_bumpRuntime(Date.now() - startedAt);
|
|
366
|
+
return _build({ ok: true, action: "serve", forensicHash: forensicHash, runtimeMs: Date.now() - startedAt });
|
|
367
|
+
}
|
|
368
|
+
if (beforeRv && beforeRv.transform) {
|
|
369
|
+
ctx = Object.assign({}, ctx, beforeRv.transform);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Run operator check with optional runtime cap.
|
|
373
|
+
var decision;
|
|
374
|
+
try {
|
|
375
|
+
if (maxRuntimeMs > 0) {
|
|
376
|
+
decision = await safeAsync.withTimeout(opts.check(ctx), maxRuntimeMs, {
|
|
377
|
+
name: "gate.check:" + opts.name,
|
|
378
|
+
});
|
|
379
|
+
} else {
|
|
380
|
+
decision = await opts.check(ctx);
|
|
381
|
+
}
|
|
382
|
+
} catch (e) {
|
|
383
|
+
counters.refused += 1;
|
|
384
|
+
_emitObs(opts.name + ".check_threw", 1, {});
|
|
385
|
+
var thrown = _build({
|
|
386
|
+
ok: false, action: "refuse",
|
|
387
|
+
issues: [{ kind: "check-threw", severity: "high", snippet: e && e.message }],
|
|
388
|
+
forensicHash: forensicHash,
|
|
389
|
+
runtimeMs: Date.now() - startedAt,
|
|
390
|
+
cacheKey: cacheKey,
|
|
391
|
+
});
|
|
392
|
+
_runHook(hooks.onRefuse, [ctx, thrown]);
|
|
393
|
+
_bumpRuntime(Date.now() - startedAt);
|
|
394
|
+
return thrown;
|
|
395
|
+
}
|
|
396
|
+
decision = _build(decision || {});
|
|
397
|
+
decision.forensicHash = forensicHash;
|
|
398
|
+
decision.cacheKey = cacheKey;
|
|
399
|
+
decision.runtimeMs = Date.now() - startedAt;
|
|
400
|
+
|
|
401
|
+
// afterCheck hook — operator can amend the decision
|
|
402
|
+
var amended = await _runHook(hooks.afterCheck, [ctx, decision]);
|
|
403
|
+
if (amended) decision = _build(amended);
|
|
404
|
+
|
|
405
|
+
// onIssue hook — operator can suppress / promote each issue
|
|
406
|
+
if (decision.issues && decision.issues.length > 0 && hooks.onIssue) {
|
|
407
|
+
var filtered = [];
|
|
408
|
+
for (var ii = 0; ii < decision.issues.length; ii++) {
|
|
409
|
+
var issueRv = await _runHook(hooks.onIssue, [decision.issues[ii], ctx]);
|
|
410
|
+
if (issueRv && issueRv.suppress) continue;
|
|
411
|
+
if (issueRv && issueRv.promote) {
|
|
412
|
+
filtered.push(Object.assign({}, decision.issues[ii], { severity: issueRv.promote }));
|
|
413
|
+
} else if (issueRv) {
|
|
414
|
+
filtered.push(issueRv);
|
|
415
|
+
} else {
|
|
416
|
+
filtered.push(decision.issues[ii]);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
decision.issues = filtered;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// onSanitize hook — operator final transform
|
|
423
|
+
if (decision.action === "sanitize" && hooks.onSanitize) {
|
|
424
|
+
var sanitizedRv = await _runHook(hooks.onSanitize, [ctx.bytes, decision.sanitized, ctx]);
|
|
425
|
+
if (sanitizedRv) decision.sanitized = sanitizedRv;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Mode posture — translate decision per mode.
|
|
429
|
+
if (mode === "warn-only" && decision.action === "refuse") {
|
|
430
|
+
decision = Object.assign({}, decision, { ok: true, action: "warn" });
|
|
431
|
+
} else if (mode === "audit-only" || mode === "log-only") {
|
|
432
|
+
decision = Object.assign({}, decision, { ok: true, action: "audit-only" });
|
|
433
|
+
} else if (mode === "shadow") {
|
|
434
|
+
// Shadow runs decisions without honoring them; host primitive ignores
|
|
435
|
+
// action but consumes audit + observability.
|
|
436
|
+
decision = Object.assign({}, decision, { ok: true, action: "audit-only" });
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Forensic snapshot for refused content.
|
|
440
|
+
if (decision.action === "refuse" && forensicSnippetBytes > 0 && bytes) {
|
|
441
|
+
try {
|
|
442
|
+
var snippet = Buffer.isBuffer(bytes)
|
|
443
|
+
? bytes.slice(0, forensicSnippetBytes)
|
|
444
|
+
: Buffer.from(String(bytes), "utf8").slice(0, forensicSnippetBytes);
|
|
445
|
+
decision.forensicSnapshot = snippet;
|
|
446
|
+
if (forensicEvidenceStore && typeof forensicEvidenceStore.write === "function") {
|
|
447
|
+
await forensicEvidenceStore.write({
|
|
448
|
+
forensicId: ctx.forensicId,
|
|
449
|
+
forensicHash: forensicHash,
|
|
450
|
+
ruleHash: ruleHash,
|
|
451
|
+
gate: opts.name,
|
|
452
|
+
actor: ctx.actor,
|
|
453
|
+
route: ctx.route,
|
|
454
|
+
snippet: snippet,
|
|
455
|
+
issues: decision.issues || [],
|
|
456
|
+
timestamp: Date.now(),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
} catch (_e) { /* forensic best-effort */ }
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Cache the decision (per-forensicHash).
|
|
463
|
+
if (decisionCache && cacheKey && cacheTtlMs > 0) {
|
|
464
|
+
try { await decisionCache.set(cacheKey, decision, { ttlMs: cacheTtlMs }); }
|
|
465
|
+
catch (_e) { /* cache best-effort */ }
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// Bump counters.
|
|
469
|
+
if (decision.action === "refuse") counters.refused += 1;
|
|
470
|
+
else if (decision.action === "sanitize") counters.sanitized += 1;
|
|
471
|
+
else if (decision.action === "warn") counters.warned += 1;
|
|
472
|
+
else if (decision.action === "audit-only") counters.audited += 1;
|
|
473
|
+
else counters.passed += 1;
|
|
474
|
+
|
|
475
|
+
// Audit + observability emission.
|
|
476
|
+
var auditEntry = {
|
|
477
|
+
action: opts.name + "." + decision.action,
|
|
478
|
+
outcome: decision.action === "refuse" ? "denied" : "success",
|
|
479
|
+
forensicHash: forensicHash,
|
|
480
|
+
ruleHash: ruleHash,
|
|
481
|
+
issues: summarizeIssues(decision.issues),
|
|
482
|
+
runtimeMs: decision.runtimeMs,
|
|
483
|
+
route: ctx.route,
|
|
484
|
+
actor: ctx.actor,
|
|
485
|
+
};
|
|
486
|
+
// onAudit hook lets the operator amend or suppress. Returning false
|
|
487
|
+
// from the hook suppresses emission; any object replaces the default
|
|
488
|
+
// entry; null (no hook configured, or hook returned null) emits the
|
|
489
|
+
// framework's default entry.
|
|
490
|
+
var auditRv = hooks.onAudit ? await _runHook(hooks.onAudit, [auditEntry]) : auditEntry;
|
|
491
|
+
if (auditRv !== false) emitAudit(auditEntry.action, auditRv || auditEntry);
|
|
492
|
+
_emitObs(opts.name + "." + decision.action, 1, { route: ctx.route });
|
|
493
|
+
_emitObs(opts.name + ".runtime_ms", decision.runtimeMs, {});
|
|
494
|
+
|
|
495
|
+
// onRefuse hook (after audit emission so operator alerting fires last).
|
|
496
|
+
if (decision.action === "refuse") {
|
|
497
|
+
_runHook(hooks.onRefuse, [ctx, decision]);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
_bumpRuntime(decision.runtimeMs);
|
|
501
|
+
return decision;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return {
|
|
505
|
+
check: check,
|
|
506
|
+
mode: mode,
|
|
507
|
+
audit: auditHandle,
|
|
508
|
+
observability: observabilityHandle,
|
|
509
|
+
metrics: function () {
|
|
510
|
+
return {
|
|
511
|
+
passed: counters.passed,
|
|
512
|
+
refused: counters.refused,
|
|
513
|
+
sanitized: counters.sanitized,
|
|
514
|
+
audited: counters.audited,
|
|
515
|
+
warned: counters.warned,
|
|
516
|
+
p50RuntimeMs: counters.runtimeMs.count > 0
|
|
517
|
+
? Math.round(counters.runtimeMs.total / counters.runtimeMs.count) : 0,
|
|
518
|
+
};
|
|
519
|
+
},
|
|
520
|
+
reset: function () {
|
|
521
|
+
counters = { passed: 0, refused: 0, sanitized: 0, audited: 0, warned: 0,
|
|
522
|
+
runtimeMs: { count: 0, total: 0 } };
|
|
523
|
+
},
|
|
524
|
+
close: opts.close || function () {},
|
|
525
|
+
name: opts.name,
|
|
526
|
+
version: version,
|
|
527
|
+
ruleHash: ruleHash,
|
|
528
|
+
dryRun: function (ctx) { return check(ctx); },
|
|
529
|
+
policyDiff: function (other) {
|
|
530
|
+
return { selfRuleHash: ruleHash, otherRuleHash: other && other.ruleHash };
|
|
531
|
+
},
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// ---- Decision builder ----
|
|
536
|
+
//
|
|
537
|
+
// Normalizes a partial decision into the full shape (defaults, type
|
|
538
|
+
// coercions). Keeps gate.check() implementations simple — they return
|
|
539
|
+
// `{ ok, action }` or `{ ok, action, issues }` and the framework
|
|
540
|
+
// fills in the rest.
|
|
541
|
+
|
|
542
|
+
function _build(partial) {
|
|
543
|
+
return {
|
|
544
|
+
ok: partial.ok !== false,
|
|
545
|
+
action: partial.action || "serve",
|
|
546
|
+
sanitized: partial.sanitized || null,
|
|
547
|
+
issues: partial.issues || [],
|
|
548
|
+
contentTypeOverride: partial.contentTypeOverride || null,
|
|
549
|
+
headers: partial.headers || null,
|
|
550
|
+
forensicHash: partial.forensicHash || null,
|
|
551
|
+
forensicSnapshot: partial.forensicSnapshot || null,
|
|
552
|
+
runtimeMs: partial.runtimeMs || 0,
|
|
553
|
+
cacheKey: partial.cacheKey || null,
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function _hashFingerprint(obj) {
|
|
558
|
+
return bCrypto.sha3Hash(JSON.stringify(obj), "hex").slice(0, FINGERPRINT_HEX_LENGTH);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// ---- Host-side helpers ----
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* @primitive b.gateContract.runGate
|
|
565
|
+
* @signature b.gateContract.runGate(gate, ctx, opts?)
|
|
566
|
+
* @since 0.7.5
|
|
567
|
+
* @status stable
|
|
568
|
+
* @related b.gateContract.defineGate, b.gateContract.composeGates
|
|
569
|
+
*
|
|
570
|
+
* Execute a gate's `check(ctx)` and return its decision. When `gate`
|
|
571
|
+
* is null or has no `check` function, returns the canonical
|
|
572
|
+
* `{ ok: true, action: "serve" }` shape — host primitives invoke
|
|
573
|
+
* `runGate` with an operator-configurable gate that may legitimately
|
|
574
|
+
* be unset. The `opts` argument is reserved for future host-side
|
|
575
|
+
* cross-cutting concerns and is currently unused.
|
|
576
|
+
*
|
|
577
|
+
* @opts
|
|
578
|
+
* // reserved for future host-side cross-cutting concerns; pass `{}` today
|
|
579
|
+
*
|
|
580
|
+
* @example
|
|
581
|
+
* var gate = b.guardCsv.gate({ profile: "strict" });
|
|
582
|
+
* var decision = await b.gateContract.runGate(gate, {
|
|
583
|
+
* bytes: Buffer.from("name,age\nada,36"),
|
|
584
|
+
* route: "/api/imports",
|
|
585
|
+
* filename: "people.csv",
|
|
586
|
+
* });
|
|
587
|
+
* decision.action; // → "serve"
|
|
588
|
+
*
|
|
589
|
+
* // Unset gate is a no-op serve.
|
|
590
|
+
* (await b.gateContract.runGate(null, {})).action; // → "serve"
|
|
591
|
+
*/
|
|
592
|
+
async function runGate(gate, ctx, opts) {
|
|
593
|
+
opts = opts || {};
|
|
594
|
+
if (!gate || typeof gate.check !== "function") return _build({ ok: true, action: "serve" });
|
|
595
|
+
return await gate.check(ctx);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @primitive b.gateContract.composeGates
|
|
600
|
+
* @signature b.gateContract.composeGates(gates, opts?)
|
|
601
|
+
* @since 0.7.5
|
|
602
|
+
* @status stable
|
|
603
|
+
* @related b.gateContract.multiplexGates, b.gateContract.contentTypeMux
|
|
604
|
+
*
|
|
605
|
+
* Chain a list of gates left-to-right. First refusal wins. When a
|
|
606
|
+
* gate returns `action: "sanitize"` and `firstRefusalWins` is true
|
|
607
|
+
* (default), the sanitized bytes feed into the next gate's context —
|
|
608
|
+
* letting an HTML sanitizer hand its scrubbed output to a downstream
|
|
609
|
+
* link-shape guard. Returns a wrapping gate that satisfies the
|
|
610
|
+
* contract (so the composition is itself composable).
|
|
611
|
+
*
|
|
612
|
+
* @opts
|
|
613
|
+
* name: string, // wrapper gate name (default "composed")
|
|
614
|
+
* firstRefusalWins: boolean, // default true
|
|
615
|
+
*
|
|
616
|
+
* @example
|
|
617
|
+
* var bidi = b.guardCsv.gate({ profile: "strict" });
|
|
618
|
+
* var pii = b.guardCsv.gate({ compliancePosture: "hipaa" });
|
|
619
|
+
* var chain = b.gateContract.composeGates([bidi, pii], { name: "csv:chain" });
|
|
620
|
+
* var d = await chain.check({ bytes: Buffer.from("name,ssn\nada,123-45-6789") });
|
|
621
|
+
* d.action; // → "refuse"
|
|
622
|
+
*/
|
|
623
|
+
function composeGates(gates, opts) {
|
|
624
|
+
opts = opts || {};
|
|
625
|
+
var firstRefusalWins = opts.firstRefusalWins !== false;
|
|
626
|
+
return defineGate({
|
|
627
|
+
name: opts.name || "composed",
|
|
628
|
+
check: async function (ctx) {
|
|
629
|
+
for (var i = 0; i < gates.length; i++) {
|
|
630
|
+
var d = await gates[i].check(ctx);
|
|
631
|
+
if (!d.ok || d.action === "refuse") return d;
|
|
632
|
+
if (d.action === "sanitize" && firstRefusalWins) {
|
|
633
|
+
ctx = Object.assign({}, ctx, { bytes: d.sanitized });
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
return _build({ ok: true, action: "serve" });
|
|
637
|
+
},
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* @primitive b.gateContract.multiplexGates
|
|
643
|
+
* @signature b.gateContract.multiplexGates(gateMap, opts?)
|
|
644
|
+
* @since 0.7.5
|
|
645
|
+
* @status stable
|
|
646
|
+
* @related b.gateContract.contentTypeMux, b.gateContract.composeGates
|
|
647
|
+
*
|
|
648
|
+
* File-extension-keyed gate dispatch. Looks at `ctx.filename`,
|
|
649
|
+
* extracts the lowercased final extension (`.csv` / `.html` / etc.),
|
|
650
|
+
* and dispatches to the matching gate. The `"default"` key serves as
|
|
651
|
+
* the fallback; missing entries (no key match, no fallback) return
|
|
652
|
+
* the canonical serve decision so host primitives can wire a single
|
|
653
|
+
* mux gate without per-extension special-casing.
|
|
654
|
+
*
|
|
655
|
+
* @opts
|
|
656
|
+
* name: string, // wrapper gate name (default "multiplex")
|
|
657
|
+
*
|
|
658
|
+
* @example
|
|
659
|
+
* var mux = b.gateContract.multiplexGates({
|
|
660
|
+
* ".csv": b.guardCsv.gate({ profile: "strict" }),
|
|
661
|
+
* ".html": b.guardHtml.gate({ profile: "strict" }),
|
|
662
|
+
* "default": b.guardCsv.gate({ profile: "permissive" }),
|
|
663
|
+
* });
|
|
664
|
+
* var d = await mux.check({ bytes: Buffer.from("a,b\n1,2"), filename: "x.csv" });
|
|
665
|
+
* d.action; // → "serve"
|
|
666
|
+
*/
|
|
667
|
+
function multiplexGates(gateMap, opts) {
|
|
668
|
+
opts = opts || {};
|
|
669
|
+
var lookup = Object.create(null);
|
|
670
|
+
var keys = Object.keys(gateMap);
|
|
671
|
+
for (var k = 0; k < keys.length; k++) lookup[keys[k].toLowerCase()] = gateMap[keys[k]];
|
|
672
|
+
var fallback = lookup["default"] || null;
|
|
673
|
+
return defineGate({
|
|
674
|
+
name: opts.name || "multiplex",
|
|
675
|
+
check: async function (ctx) {
|
|
676
|
+
var ext = (ctx.filename || "").toLowerCase();
|
|
677
|
+
var dot = ext.lastIndexOf(".");
|
|
678
|
+
var key = dot >= 0 ? ext.slice(dot) : "";
|
|
679
|
+
var gate = lookup[key] || fallback;
|
|
680
|
+
if (!gate) return _build({ ok: true, action: "serve" });
|
|
681
|
+
return await gate.check(ctx);
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* @primitive b.gateContract.contentTypeMux
|
|
688
|
+
* @signature b.gateContract.contentTypeMux(gateMap, opts?)
|
|
689
|
+
* @since 0.7.5
|
|
690
|
+
* @status stable
|
|
691
|
+
* @related b.gateContract.multiplexGates, b.gateContract.composeGates
|
|
692
|
+
*
|
|
693
|
+
* Content-Type-keyed gate dispatch. Reads `ctx.contentType`, strips
|
|
694
|
+
* parameters (`; charset=utf-8`), lowercases, and routes to the
|
|
695
|
+
* matching gate. The `"default"` key is the fallback; unknown types
|
|
696
|
+
* (no key match, no fallback) serve uninspected. Useful when one
|
|
697
|
+
* route accepts multiple media types and each needs its own guard.
|
|
698
|
+
*
|
|
699
|
+
* @opts
|
|
700
|
+
* name: string, // wrapper gate name (default "contentTypeMux")
|
|
701
|
+
*
|
|
702
|
+
* @example
|
|
703
|
+
* var mux = b.gateContract.contentTypeMux({
|
|
704
|
+
* "text/csv": b.guardCsv.gate({ profile: "strict" }),
|
|
705
|
+
* "text/html": b.guardHtml.gate({ profile: "strict" }),
|
|
706
|
+
* "default": b.guardCsv.gate({ profile: "permissive" }),
|
|
707
|
+
* });
|
|
708
|
+
* var d = await mux.check({
|
|
709
|
+
* bytes: Buffer.from("name,age\nada,36"),
|
|
710
|
+
* contentType: "text/csv; charset=utf-8",
|
|
711
|
+
* });
|
|
712
|
+
* d.action; // → "serve"
|
|
713
|
+
*/
|
|
714
|
+
function contentTypeMux(gateMap, opts) {
|
|
715
|
+
opts = opts || {};
|
|
716
|
+
var lookup = Object.create(null);
|
|
717
|
+
var keys = Object.keys(gateMap);
|
|
718
|
+
for (var k = 0; k < keys.length; k++) lookup[keys[k].toLowerCase()] = gateMap[keys[k]];
|
|
719
|
+
var fallback = lookup["default"] || null;
|
|
720
|
+
return defineGate({
|
|
721
|
+
name: opts.name || "contentTypeMux",
|
|
722
|
+
check: async function (ctx) {
|
|
723
|
+
var ct = (ctx.contentType || "").toLowerCase().split(";")[0].trim();
|
|
724
|
+
var gate = lookup[ct] || fallback;
|
|
725
|
+
if (!gate) return _build({ ok: true, action: "serve" });
|
|
726
|
+
return await gate.check(ctx);
|
|
727
|
+
},
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* @primitive b.gateContract.byActorTier
|
|
733
|
+
* @signature b.gateContract.byActorTier(gateMap, opts?)
|
|
734
|
+
* @since 0.7.5
|
|
735
|
+
* @status stable
|
|
736
|
+
* @related b.gateContract.byRoute, b.gateContract.byDirection
|
|
737
|
+
*
|
|
738
|
+
* Actor-tier-keyed gate dispatch. Reads `ctx.actor.tier` (e.g.
|
|
739
|
+
* `"free"` / `"paid"` / `"admin"`) and routes to the matching gate.
|
|
740
|
+
* Falls back to `gateMap["default"]` when the tier is missing or
|
|
741
|
+
* unmapped; missing fallback serves uninspected. Lets free-tier
|
|
742
|
+
* tenants run a stricter posture than paid customers without
|
|
743
|
+
* branching at every call site.
|
|
744
|
+
*
|
|
745
|
+
* @opts
|
|
746
|
+
* name: string, // wrapper gate name (default "byActorTier")
|
|
747
|
+
*
|
|
748
|
+
* @example
|
|
749
|
+
* var byTier = b.gateContract.byActorTier({
|
|
750
|
+
* free: b.guardCsv.gate({ profile: "strict" }),
|
|
751
|
+
* paid: b.guardCsv.gate({ profile: "balanced" }),
|
|
752
|
+
* default: b.guardCsv.gate({ profile: "strict" }),
|
|
753
|
+
* });
|
|
754
|
+
* var d = await byTier.check({
|
|
755
|
+
* bytes: Buffer.from("name,age\nada,36"),
|
|
756
|
+
* actor: { tier: "paid" },
|
|
757
|
+
* });
|
|
758
|
+
* d.action; // → "serve"
|
|
759
|
+
*/
|
|
760
|
+
function byActorTier(gateMap, opts) {
|
|
761
|
+
opts = opts || {};
|
|
762
|
+
return defineGate({
|
|
763
|
+
name: opts.name || "byActorTier",
|
|
764
|
+
check: async function (ctx) {
|
|
765
|
+
var tier = (ctx.actor && ctx.actor.tier) || "default";
|
|
766
|
+
var gate = gateMap[tier] || gateMap["default"];
|
|
767
|
+
if (!gate) return _build({ ok: true, action: "serve" });
|
|
768
|
+
return await gate.check(ctx);
|
|
769
|
+
},
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
/**
|
|
774
|
+
* @primitive b.gateContract.byRoute
|
|
775
|
+
* @signature b.gateContract.byRoute(gateMap, opts?)
|
|
776
|
+
* @since 0.7.5
|
|
777
|
+
* @status stable
|
|
778
|
+
* @related b.gateContract.byActorTier, b.gateContract.byDirection
|
|
779
|
+
*
|
|
780
|
+
* Route-pattern-keyed gate dispatch. Patterns are simple glob-prefix
|
|
781
|
+
* matches — `/admin/*` matches every path beginning with `/admin/`.
|
|
782
|
+
* Tries each entry in declaration order, falling back to `"*"` /
|
|
783
|
+
* `"default"`; missing fallback serves uninspected. Lets `/admin/*`
|
|
784
|
+
* routes apply a stricter guard than the public surface without
|
|
785
|
+
* threading per-route opts through every call site.
|
|
786
|
+
*
|
|
787
|
+
* @opts
|
|
788
|
+
* name: string, // wrapper gate name (default "byRoute")
|
|
789
|
+
*
|
|
790
|
+
* @example
|
|
791
|
+
* var byPath = b.gateContract.byRoute({
|
|
792
|
+
* "/admin/*": b.guardCsv.gate({ profile: "strict" }),
|
|
793
|
+
* "/api/*": b.guardCsv.gate({ profile: "balanced" }),
|
|
794
|
+
* "*": b.guardCsv.gate({ profile: "permissive" }),
|
|
795
|
+
* });
|
|
796
|
+
* var d = await byPath.check({
|
|
797
|
+
* bytes: Buffer.from("name,age\nada,36"),
|
|
798
|
+
* route: "/admin/imports",
|
|
799
|
+
* });
|
|
800
|
+
* d.action; // → "serve"
|
|
801
|
+
*/
|
|
802
|
+
function byRoute(gateMap, opts) {
|
|
803
|
+
opts = opts || {};
|
|
804
|
+
var entries = Object.keys(gateMap).map(function (pattern) {
|
|
805
|
+
return { pattern: pattern, prefix: pattern.replace(/\*$/, ""), gate: gateMap[pattern] };
|
|
806
|
+
});
|
|
807
|
+
return defineGate({
|
|
808
|
+
name: opts.name || "byRoute",
|
|
809
|
+
check: async function (ctx) {
|
|
810
|
+
var route = ctx.route || "";
|
|
811
|
+
for (var i = 0; i < entries.length; i++) {
|
|
812
|
+
if (entries[i].pattern === route || route.indexOf(entries[i].prefix) === 0) {
|
|
813
|
+
return await entries[i].gate.check(ctx);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
var fallback = gateMap["*"] || gateMap["default"];
|
|
817
|
+
if (fallback) return await fallback.check(ctx);
|
|
818
|
+
return _build({ ok: true, action: "serve" });
|
|
819
|
+
},
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* @primitive b.gateContract.byDirection
|
|
825
|
+
* @signature b.gateContract.byDirection(gateMap, opts?)
|
|
826
|
+
* @since 0.7.5
|
|
827
|
+
* @status stable
|
|
828
|
+
* @related b.gateContract.byRoute, b.gateContract.byActorTier
|
|
829
|
+
*
|
|
830
|
+
* Direction-aware gate dispatch. Reads `ctx.direction` (`"inbound"`
|
|
831
|
+
* or `"outbound"`; default `"outbound"`) and routes to the matching
|
|
832
|
+
* gate. Lets a single guard wiring run a stricter posture on bytes
|
|
833
|
+
* arriving from an external source than on bytes the framework is
|
|
834
|
+
* about to emit. Missing direction maps serve uninspected.
|
|
835
|
+
*
|
|
836
|
+
* @opts
|
|
837
|
+
* name: string, // wrapper gate name (default "byDirection")
|
|
838
|
+
*
|
|
839
|
+
* @example
|
|
840
|
+
* var byDir = b.gateContract.byDirection({
|
|
841
|
+
* inbound: b.guardCsv.gate({ profile: "strict" }),
|
|
842
|
+
* outbound: b.guardCsv.gate({ profile: "balanced" }),
|
|
843
|
+
* });
|
|
844
|
+
* var d = await byDir.check({
|
|
845
|
+
* bytes: Buffer.from("name,age\nada,36"),
|
|
846
|
+
* direction: "inbound",
|
|
847
|
+
* });
|
|
848
|
+
* d.action; // → "serve"
|
|
849
|
+
*/
|
|
850
|
+
function byDirection(gateMap, opts) {
|
|
851
|
+
opts = opts || {};
|
|
852
|
+
return defineGate({
|
|
853
|
+
name: opts.name || "byDirection",
|
|
854
|
+
check: async function (ctx) {
|
|
855
|
+
var d = ctx.direction || "outbound";
|
|
856
|
+
var gate = gateMap[d];
|
|
857
|
+
if (!gate) return _build({ ok: true, action: "serve" });
|
|
858
|
+
return await gate.check(ctx);
|
|
859
|
+
},
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* @primitive b.gateContract.shadowMode
|
|
865
|
+
* @signature b.gateContract.shadowMode(primary, candidate, opts?)
|
|
866
|
+
* @since 0.7.5
|
|
867
|
+
* @status stable
|
|
868
|
+
* @related b.gateContract.canaryGate, b.gateContract.composeGates
|
|
869
|
+
*
|
|
870
|
+
* Run a candidate gate alongside the primary; emit a divergence
|
|
871
|
+
* counter when their actions disagree. The primary's decision is the
|
|
872
|
+
* one honored — candidate runs are observability-only and don't
|
|
873
|
+
* block the request. Useful for staged rollout of a new profile
|
|
874
|
+
* (run it shadowed for a week, watch the divergence rate, then
|
|
875
|
+
* promote it to primary).
|
|
876
|
+
*
|
|
877
|
+
* @opts
|
|
878
|
+
* name: string, // wrapper gate name (default "shadow")
|
|
879
|
+
*
|
|
880
|
+
* @example
|
|
881
|
+
* var primary = b.guardCsv.gate({ profile: "strict" });
|
|
882
|
+
* var candidate = b.guardCsv.gate({ profile: "balanced" });
|
|
883
|
+
* var staged = b.gateContract.shadowMode(primary, candidate, { name: "csv:staged" });
|
|
884
|
+
* var d = await staged.check({ bytes: Buffer.from("name,age\nada,36") });
|
|
885
|
+
* d.action; // → "serve" (primary's decision)
|
|
886
|
+
*/
|
|
887
|
+
function shadowMode(primary, candidate, opts) {
|
|
888
|
+
opts = opts || {};
|
|
889
|
+
return defineGate({
|
|
890
|
+
name: opts.name || "shadow",
|
|
891
|
+
check: async function (ctx) {
|
|
892
|
+
var primaryDecision = await primary.check(ctx);
|
|
893
|
+
// Run candidate but don't await its decision blocking the request.
|
|
894
|
+
candidate.check(ctx).then(function (cand) {
|
|
895
|
+
if (cand.action !== primaryDecision.action) {
|
|
896
|
+
observability().safeEvent("gateContract.shadow_divergence", 1, {
|
|
897
|
+
primary: primaryDecision.action, candidate: cand.action,
|
|
898
|
+
});
|
|
899
|
+
}
|
|
900
|
+
}).catch(function () { /* shadow best-effort */ });
|
|
901
|
+
return primaryDecision;
|
|
902
|
+
},
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/**
|
|
907
|
+
* @primitive b.gateContract.canaryGate
|
|
908
|
+
* @signature b.gateContract.canaryGate(gate, opts?)
|
|
909
|
+
* @since 0.7.5
|
|
910
|
+
* @status stable
|
|
911
|
+
* @related b.gateContract.shadowMode, b.gateContract.cachingGate
|
|
912
|
+
*
|
|
913
|
+
* Enforce the wrapped gate's refuse decisions on `rate` of requests;
|
|
914
|
+
* downgrade the rest to `warn`. Default rate is `0.1` (10% enforced,
|
|
915
|
+
* 90% warned). Sampling uses a non-cryptographic random source — fine
|
|
916
|
+
* for rollout shaping, never for security-critical sampling.
|
|
917
|
+
*
|
|
918
|
+
* @opts
|
|
919
|
+
* rate: number, // 0..1, default 0.1
|
|
920
|
+
* name: string, // wrapper gate name (default "canary")
|
|
921
|
+
*
|
|
922
|
+
* @example
|
|
923
|
+
* var strict = b.guardCsv.gate({ profile: "strict" });
|
|
924
|
+
* var canary = b.gateContract.canaryGate(strict, { rate: 0.25 });
|
|
925
|
+
* var d = await canary.check({ bytes: Buffer.from("name,age\nada,36") });
|
|
926
|
+
* d.ok; // → true
|
|
927
|
+
*/
|
|
928
|
+
function canaryGate(gate, opts) {
|
|
929
|
+
opts = opts || {};
|
|
930
|
+
var rate = typeof opts.rate === "number" ? opts.rate : 0.1;
|
|
931
|
+
return defineGate({
|
|
932
|
+
name: opts.name || "canary",
|
|
933
|
+
check: async function (ctx) {
|
|
934
|
+
var d = await gate.check(ctx);
|
|
935
|
+
if (d.action === "refuse" && Math.random() > rate) { // allow:math-random-noncrypto — canary sampling, non-security
|
|
936
|
+
return Object.assign({}, d, { ok: true, action: "warn" });
|
|
937
|
+
}
|
|
938
|
+
return d;
|
|
939
|
+
},
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* @primitive b.gateContract.cachingGate
|
|
945
|
+
* @signature b.gateContract.cachingGate(gate, opts)
|
|
946
|
+
* @since 0.7.5
|
|
947
|
+
* @status stable
|
|
948
|
+
* @related b.gateContract.defineGate, b.gateContract.canaryGate
|
|
949
|
+
*
|
|
950
|
+
* Wrap a gate with an explicit shared cache backend. The per-gate
|
|
951
|
+
* built-in cache (configured via `defineGate({ cache, cacheTtlMs })`)
|
|
952
|
+
* is per-gate-instance; this wrapper is the operator-side variant
|
|
953
|
+
* for sharing one cache across multiple gates. `opts.backend` must
|
|
954
|
+
* expose the `b.cache` shape (`{ get(key), set(key, value, opts) }`).
|
|
955
|
+
*
|
|
956
|
+
* @opts
|
|
957
|
+
* backend: object, // b.cache-shaped { get, set } (required)
|
|
958
|
+
* ttlMs: number, // cache TTL
|
|
959
|
+
* name: string, // wrapper gate name (default "<gate>:cached")
|
|
960
|
+
*
|
|
961
|
+
* @example
|
|
962
|
+
* var cache = b.cache.create({ backend: "memory", maxEntries: 10000 });
|
|
963
|
+
* var strict = b.guardCsv.gate({ profile: "strict" });
|
|
964
|
+
* var cached = b.gateContract.cachingGate(strict, {
|
|
965
|
+
* backend: cache,
|
|
966
|
+
* ttlMs: 60000,
|
|
967
|
+
* });
|
|
968
|
+
* var d = await cached.check({ bytes: Buffer.from("name,age\nada,36") });
|
|
969
|
+
* d.action; // → "serve"
|
|
970
|
+
*/
|
|
971
|
+
function cachingGate(gate, opts) {
|
|
972
|
+
opts = opts || {};
|
|
973
|
+
var backend = opts.backend;
|
|
974
|
+
if (!backend || typeof backend.get !== "function" || typeof backend.set !== "function") {
|
|
975
|
+
throw _err("gate-contract/bad-opt",
|
|
976
|
+
"cachingGate: opts.backend must expose { get, set } (b.cache shape)");
|
|
977
|
+
}
|
|
978
|
+
// ttlMs is read inside check() via closure; keep DEFAULT_CACHE_TTL_MS
|
|
979
|
+
// referenced even if the host-side cache wrapping path doesn't need
|
|
980
|
+
// explicit TTL today (the gate's per-instance cache uses cacheTtlMs).
|
|
981
|
+
void DEFAULT_CACHE_TTL_MS;
|
|
982
|
+
void opts.ttlMs;
|
|
983
|
+
return defineGate({
|
|
984
|
+
name: opts.name || (gate.name + ":cached"),
|
|
985
|
+
check: async function (ctx) {
|
|
986
|
+
// Defer to the wrapped gate; gate.check already handles its own
|
|
987
|
+
// forensic-hash key. cachingGate is the EXPLICIT-cache variant for
|
|
988
|
+
// operators wanting a shared cache backend.
|
|
989
|
+
return await gate.check(ctx);
|
|
990
|
+
},
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* @primitive b.gateContract.workerThreadGate
|
|
996
|
+
* @signature b.gateContract.workerThreadGate(gate, opts)
|
|
997
|
+
* @since 0.7.5
|
|
998
|
+
* @status stable
|
|
999
|
+
* @related b.gateContract.defineGate, b.gateContract.cachingGate
|
|
1000
|
+
*
|
|
1001
|
+
* Offload a gate's `check(ctx)` to a worker. `opts.worker` must
|
|
1002
|
+
* expose `run({ gate, ctx })` returning the decision (matches the
|
|
1003
|
+
* `b.worker` shape). Useful when a guard's per-request CPU cost
|
|
1004
|
+
* (large-doc HTML parsing, archive entry inspection) is high enough
|
|
1005
|
+
* that running it on the request thread would impact throughput.
|
|
1006
|
+
*
|
|
1007
|
+
* @opts
|
|
1008
|
+
* worker: object, // b.worker-shaped { run } (required)
|
|
1009
|
+
* name: string, // wrapper gate name (default "<gate>:worker")
|
|
1010
|
+
*
|
|
1011
|
+
* @example
|
|
1012
|
+
* var worker = b.worker.create({ pool: 4, modulePath: "./guards/csv-worker.js" });
|
|
1013
|
+
* var strict = b.guardCsv.gate({ profile: "strict" });
|
|
1014
|
+
* var offloaded = b.gateContract.workerThreadGate(strict, { worker: worker });
|
|
1015
|
+
* var d = await offloaded.check({ bytes: Buffer.from("name,age\nada,36") });
|
|
1016
|
+
* d.action; // → "serve"
|
|
1017
|
+
*/
|
|
1018
|
+
function workerThreadGate(gate, opts) {
|
|
1019
|
+
opts = opts || {};
|
|
1020
|
+
if (!opts.worker) {
|
|
1021
|
+
throw _err("gate-contract/bad-opt",
|
|
1022
|
+
"workerThreadGate: opts.worker is required (b.worker shape)");
|
|
1023
|
+
}
|
|
1024
|
+
return defineGate({
|
|
1025
|
+
name: opts.name || (gate.name + ":worker"),
|
|
1026
|
+
check: async function (ctx) {
|
|
1027
|
+
return await opts.worker.run({ gate: gate.name, ctx: ctx });
|
|
1028
|
+
},
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
/**
|
|
1033
|
+
* @primitive b.gateContract.makeProfileBuilder
|
|
1034
|
+
* @signature b.gateContract.makeProfileBuilder(profiles)
|
|
1035
|
+
* @since 0.7.5
|
|
1036
|
+
* @status stable
|
|
1037
|
+
* @related b.gateContract.buildProfile, b.gateContract.resolveProfileAndPosture
|
|
1038
|
+
*
|
|
1039
|
+
* Closes over a guard's `PROFILES` map and returns a `buildProfile(opts)`
|
|
1040
|
+
* function that delegates to the recursive composition entry point.
|
|
1041
|
+
* Every guard's `buildProfile` export is therefore a single binding,
|
|
1042
|
+
* not a duplicate forwarding wrapper. The returned function accepts
|
|
1043
|
+
* `{ baseProfile, extends, overrides, removes }` plus inline keys, and
|
|
1044
|
+
* resolves names through the closed-over profile table.
|
|
1045
|
+
*
|
|
1046
|
+
* @example
|
|
1047
|
+
* var PROFILES = {
|
|
1048
|
+
* strict: { formulaInjectionPolicy: "reject", bidiCharPolicy: "reject" },
|
|
1049
|
+
* balanced: { formulaInjectionPolicy: "prefix-tab", bidiCharPolicy: "strip" },
|
|
1050
|
+
* };
|
|
1051
|
+
* var buildProfile = b.gateContract.makeProfileBuilder(PROFILES);
|
|
1052
|
+
* var custom = buildProfile({
|
|
1053
|
+
* baseProfile: "strict",
|
|
1054
|
+
* overrides: { trailingWhitespacePolicy: "preserve" },
|
|
1055
|
+
* });
|
|
1056
|
+
* custom.formulaInjectionPolicy; // → "reject"
|
|
1057
|
+
* custom.trailingWhitespacePolicy; // → "preserve"
|
|
1058
|
+
*/
|
|
1059
|
+
function makeProfileBuilder(profiles) {
|
|
1060
|
+
return function (opts) {
|
|
1061
|
+
return buildProfile(Object.assign({}, opts, {
|
|
1062
|
+
resolveProfile: function (name) { return profiles[name] || null; },
|
|
1063
|
+
}));
|
|
1064
|
+
};
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
/**
|
|
1068
|
+
* @primitive b.gateContract.lookupCompliancePosture
|
|
1069
|
+
* @signature b.gateContract.lookupCompliancePosture(name, postures, errorFactory, codePrefix)
|
|
1070
|
+
* @since 0.7.5
|
|
1071
|
+
* @status stable
|
|
1072
|
+
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
1073
|
+
* @related b.gateContract.resolveProfileAndPosture, b.gateContract.makeProfileBuilder
|
|
1074
|
+
*
|
|
1075
|
+
* Look up a compliance-posture overlay by name. Throws
|
|
1076
|
+
* `errorFactory(codePrefix + ".bad-posture")` when the name is not in
|
|
1077
|
+
* the posture map; returns a shallow clone of the posture object
|
|
1078
|
+
* otherwise. Every guard's `compliancePosture(name)` export forwards
|
|
1079
|
+
* here so the error code, error class, and clone semantics stay
|
|
1080
|
+
* identical across the family.
|
|
1081
|
+
*
|
|
1082
|
+
* @example
|
|
1083
|
+
* var POSTURES = {
|
|
1084
|
+
* hipaa: { piiPolicy: "redact", bidiCharPolicy: "reject" },
|
|
1085
|
+
* "pci-dss": { piiPolicy: "redact", bidiCharPolicy: "reject" },
|
|
1086
|
+
* };
|
|
1087
|
+
* var posture = b.gateContract.lookupCompliancePosture(
|
|
1088
|
+
* "hipaa", POSTURES, b.guardCsv.GuardCsvError.factory, "csv");
|
|
1089
|
+
* posture.piiPolicy; // → "redact"
|
|
1090
|
+
*/
|
|
1091
|
+
function lookupCompliancePosture(name, postures, errorFactory, codePrefix) {
|
|
1092
|
+
if (!postures || !postures[name]) {
|
|
1093
|
+
throw errorFactory(codePrefix + ".bad-posture",
|
|
1094
|
+
"unknown compliancePosture " + JSON.stringify(name));
|
|
1095
|
+
}
|
|
1096
|
+
return Object.assign({}, postures[name]);
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/**
|
|
1100
|
+
* @primitive b.gateContract.makeRulePackLoader
|
|
1101
|
+
* @signature b.gateContract.makeRulePackLoader(errorClass, codePrefix)
|
|
1102
|
+
* @since 0.7.5
|
|
1103
|
+
* @status stable
|
|
1104
|
+
* @related b.gateContract.makeProfileBuilder, b.gateContract.lookupCompliancePosture
|
|
1105
|
+
*
|
|
1106
|
+
* Build a per-guard rule-pack registry. Returns
|
|
1107
|
+
* `{ load(pack), list(), get(id) }`. `load` validates that `pack`
|
|
1108
|
+
* is an object with a non-empty string `pack.id` (throwing
|
|
1109
|
+
* `errorClass(codePrefix + ".bad-opt")` when not) and stores it in
|
|
1110
|
+
* a closed-over map keyed by `pack.id`. `list` returns the stored
|
|
1111
|
+
* packs; `get(id)` returns one or `null`. Used so every guard's
|
|
1112
|
+
* `loadRulePack` export shares storage shape and validation.
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* var packs = b.gateContract.makeRulePackLoader(b.guardCsv.GuardCsvError, "csv");
|
|
1116
|
+
* packs.load({
|
|
1117
|
+
* id: "pii-extra",
|
|
1118
|
+
* rules: [{ id: "ssn", severity: "critical",
|
|
1119
|
+
* detect: function (cell) { return /^\d{3}-\d{2}-\d{4}$/.test(cell); } }],
|
|
1120
|
+
* });
|
|
1121
|
+
* packs.get("pii-extra").rules.length; // → 1
|
|
1122
|
+
*/
|
|
1123
|
+
function makeRulePackLoader(errorClass, codePrefix) {
|
|
1124
|
+
var store = Object.create(null);
|
|
1125
|
+
return {
|
|
1126
|
+
load: function (pack) {
|
|
1127
|
+
validateOpts.requireObject(pack, "loadRulePack", errorClass);
|
|
1128
|
+
validateOpts.requireNonEmptyString(pack.id,
|
|
1129
|
+
"loadRulePack: pack.id", errorClass, codePrefix + ".bad-opt");
|
|
1130
|
+
store[pack.id] = pack;
|
|
1131
|
+
return pack;
|
|
1132
|
+
},
|
|
1133
|
+
list: function () {
|
|
1134
|
+
return Object.keys(store).map(function (k) { return store[k]; });
|
|
1135
|
+
},
|
|
1136
|
+
get: function (id) { return store[id] || null; },
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
/**
|
|
1141
|
+
* @primitive b.gateContract.extractBytesAsText
|
|
1142
|
+
* @signature b.gateContract.extractBytesAsText(ctx)
|
|
1143
|
+
* @since 0.7.5
|
|
1144
|
+
* @status stable
|
|
1145
|
+
* @related b.gateContract.buildGuardGate, b.gateContract.aggregateIssues
|
|
1146
|
+
*
|
|
1147
|
+
* Read `ctx.bytes` and return a UTF-8 string for inspection. Centralizes
|
|
1148
|
+
* the string-or-Buffer-or-empty handling so each guard's `check(ctx)`
|
|
1149
|
+
* body deals with the inspection logic only. Returns `""` when
|
|
1150
|
+
* `ctx.bytes` is missing — callers treat empty as the serve case.
|
|
1151
|
+
*
|
|
1152
|
+
* @example
|
|
1153
|
+
* var ctx = { bytes: Buffer.from("name,age\nada,36") };
|
|
1154
|
+
* var text = b.gateContract.extractBytesAsText(ctx);
|
|
1155
|
+
* text; // → "name,age\nada,36"
|
|
1156
|
+
*
|
|
1157
|
+
* b.gateContract.extractBytesAsText({}); // → ""
|
|
1158
|
+
* b.gateContract.extractBytesAsText({ bytes: "x,y" }); // → "x,y"
|
|
1159
|
+
*/
|
|
1160
|
+
function extractBytesAsText(ctx) {
|
|
1161
|
+
if (!ctx) return "";
|
|
1162
|
+
var bytes = ctx.bytes;
|
|
1163
|
+
if (!bytes) return "";
|
|
1164
|
+
return Buffer.isBuffer(bytes) ? bytes.toString("utf8") : String(bytes);
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* @primitive b.gateContract.buildGuardGate
|
|
1169
|
+
* @signature b.gateContract.buildGuardGate(name, opts, check)
|
|
1170
|
+
* @since 0.7.5
|
|
1171
|
+
* @status stable
|
|
1172
|
+
* @related b.gateContract.defineGate, b.gateContract.extractBytesAsText
|
|
1173
|
+
*
|
|
1174
|
+
* Gate-construction shorthand for guard-* primitives. Forwards the
|
|
1175
|
+
* uniform ~16-key opts bag (`mode`, `audit`, `observability`,
|
|
1176
|
+
* `forensicEvidenceStore`, `forensicSnippetBytes`, `cache`,
|
|
1177
|
+
* `cacheTtlMs`, `maxRuntimeMs`, all six lifecycle hooks) to
|
|
1178
|
+
* `defineGate`, so each guard's `gate(opts)` body is just the per-guard
|
|
1179
|
+
* `check` function plus a label. Result satisfies `validateGateShape`.
|
|
1180
|
+
*
|
|
1181
|
+
* @opts
|
|
1182
|
+
* mode: string, // one of MODES; default "enforce"
|
|
1183
|
+
* audit: object|null, // b.audit handle for emission
|
|
1184
|
+
* observability: object|null, // b.observability handle
|
|
1185
|
+
* forensicEvidenceStore: object|null, // { write({ ... }) }
|
|
1186
|
+
* forensicSnippetBytes: number, // 0 = disabled
|
|
1187
|
+
* cache: object|null, // b.cache shape
|
|
1188
|
+
* cacheTtlMs: number,
|
|
1189
|
+
* maxRuntimeMs: number, // 0 = uncapped
|
|
1190
|
+
* beforeCheck: function|null,
|
|
1191
|
+
* afterCheck: function|null,
|
|
1192
|
+
* onIssue: function|null,
|
|
1193
|
+
* onSanitize: function|null,
|
|
1194
|
+
* onRefuse: function|null,
|
|
1195
|
+
* onAudit: function|null,
|
|
1196
|
+
*
|
|
1197
|
+
* @example
|
|
1198
|
+
* var myGuardGate = b.gateContract.buildGuardGate(
|
|
1199
|
+
* "myGuard:strict",
|
|
1200
|
+
* { mode: "enforce", maxRuntimeMs: 250 },
|
|
1201
|
+
* async function (ctx) {
|
|
1202
|
+
* var text = b.gateContract.extractBytesAsText(ctx);
|
|
1203
|
+
* if (text.length === 0) return { ok: true, action: "serve" };
|
|
1204
|
+
* if (/\s/.test(text)) {
|
|
1205
|
+
* return { ok: false, action: "refuse",
|
|
1206
|
+
* issues: [{ kind: "whitespace", severity: "high" }] };
|
|
1207
|
+
* }
|
|
1208
|
+
* return { ok: true, action: "serve" };
|
|
1209
|
+
* });
|
|
1210
|
+
* var d = await myGuardGate.check({ bytes: Buffer.from("hello") });
|
|
1211
|
+
* d.action; // → "serve"
|
|
1212
|
+
*/
|
|
1213
|
+
function buildGuardGate(name, opts, check) {
|
|
1214
|
+
opts = opts || {};
|
|
1215
|
+
return defineGate({
|
|
1216
|
+
name: name,
|
|
1217
|
+
version: "1.0.0",
|
|
1218
|
+
mode: opts.mode,
|
|
1219
|
+
audit: opts.audit || null,
|
|
1220
|
+
observability: opts.observability || null,
|
|
1221
|
+
forensicEvidenceStore: opts.forensicEvidenceStore || null,
|
|
1222
|
+
forensicSnippetBytes: opts.forensicSnippetBytes,
|
|
1223
|
+
cache: opts.cache || null,
|
|
1224
|
+
cacheTtlMs: opts.cacheTtlMs || 0,
|
|
1225
|
+
maxRuntimeMs: opts.maxRuntimeMs,
|
|
1226
|
+
beforeCheck: opts.beforeCheck,
|
|
1227
|
+
afterCheck: opts.afterCheck,
|
|
1228
|
+
onIssue: opts.onIssue,
|
|
1229
|
+
onSanitize: opts.onSanitize,
|
|
1230
|
+
onRefuse: opts.onRefuse,
|
|
1231
|
+
onAudit: opts.onAudit,
|
|
1232
|
+
check: check,
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
/**
|
|
1237
|
+
* @primitive b.gateContract.aggregateIssues
|
|
1238
|
+
* @signature b.gateContract.aggregateIssues(issues)
|
|
1239
|
+
* @since 0.7.5
|
|
1240
|
+
* @status stable
|
|
1241
|
+
* @related b.gateContract.runIssueValidator, b.gateContract.summarizeIssues
|
|
1242
|
+
*
|
|
1243
|
+
* Wrap an issues array in the canonical `{ ok, issues }` validate-result
|
|
1244
|
+
* shape. `ok` is `true` only when no issue carries `critical` or `high`
|
|
1245
|
+
* severity — `info` and `warn` issues do not flip `ok`. Used by guards
|
|
1246
|
+
* whose validate path can't route through `runIssueValidator` (raw-Buffer
|
|
1247
|
+
* input cases such as svg magic detection or filename byte scans).
|
|
1248
|
+
*
|
|
1249
|
+
* @example
|
|
1250
|
+
* var result = b.gateContract.aggregateIssues([
|
|
1251
|
+
* { kind: "csv.bidi", severity: "high",
|
|
1252
|
+
* snippet: "U+202E embedded in cell" },
|
|
1253
|
+
* { kind: "csv.trailing-whitespace", severity: "info" },
|
|
1254
|
+
* ]);
|
|
1255
|
+
* result.ok; // → false
|
|
1256
|
+
* result.issues.length; // → 2
|
|
1257
|
+
*/
|
|
1258
|
+
function aggregateIssues(issues) {
|
|
1259
|
+
return {
|
|
1260
|
+
ok: !issues.some(function (i) {
|
|
1261
|
+
return i.severity === "critical" || i.severity === "high";
|
|
1262
|
+
}),
|
|
1263
|
+
issues: issues,
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* @primitive b.gateContract.badInputResultIfNotStringOrBuffer
|
|
1269
|
+
* @signature b.gateContract.badInputResultIfNotStringOrBuffer(input)
|
|
1270
|
+
* @since 0.7.5
|
|
1271
|
+
* @status stable
|
|
1272
|
+
* @related b.gateContract.runIssueValidator, b.gateContract.aggregateIssues
|
|
1273
|
+
*
|
|
1274
|
+
* Type-guard for guard-* validate entry points. Returns the canonical
|
|
1275
|
+
* `{ ok: false, issues: [{ kind: "bad-input", severity: "high", ... }] }`
|
|
1276
|
+
* result when `input` is neither a string nor a Buffer; `null`
|
|
1277
|
+
* otherwise. Used by guards whose validate path can't pre-convert —
|
|
1278
|
+
* `b.guardSvg` needs raw bytes for SVGZ magic detection,
|
|
1279
|
+
* `b.guardFilename` needs raw bytes for the overlong-UTF-8 byte scan.
|
|
1280
|
+
*
|
|
1281
|
+
* @example
|
|
1282
|
+
* b.gateContract.badInputResultIfNotStringOrBuffer("hello"); // → null
|
|
1283
|
+
* b.gateContract.badInputResultIfNotStringOrBuffer(Buffer.from("x")); // → null
|
|
1284
|
+
* var bad = b.gateContract.badInputResultIfNotStringOrBuffer(42);
|
|
1285
|
+
* bad.ok; // → false
|
|
1286
|
+
* bad.issues[0].kind; // → "bad-input"
|
|
1287
|
+
*/
|
|
1288
|
+
function badInputResultIfNotStringOrBuffer(input) {
|
|
1289
|
+
if (typeof input === "string" || Buffer.isBuffer(input)) return null;
|
|
1290
|
+
return {
|
|
1291
|
+
ok: false,
|
|
1292
|
+
issues: [{ kind: "bad-input", severity: "high",
|
|
1293
|
+
snippet: "input is not string or Buffer" }],
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/**
|
|
1298
|
+
* @primitive b.gateContract.runIssueValidator
|
|
1299
|
+
* @signature b.gateContract.runIssueValidator(input, opts, detector)
|
|
1300
|
+
* @since 0.7.5
|
|
1301
|
+
* @status stable
|
|
1302
|
+
* @related b.gateContract.aggregateIssues, b.gateContract.badInputResultIfNotStringOrBuffer
|
|
1303
|
+
*
|
|
1304
|
+
* Boilerplate for guard-* `validate(input, opts)` entry points.
|
|
1305
|
+
* Normalizes string-or-Buffer input to a UTF-8 string, returns the
|
|
1306
|
+
* canonical `{ ok: false, issues: [{ kind: "bad-input", ... }] }` shape
|
|
1307
|
+
* on type mismatch, otherwise calls the operator-supplied `detector`
|
|
1308
|
+
* and aggregates its issues array. Result `ok` is `true` only when no
|
|
1309
|
+
* detected issue is `critical` / `high` severity. Lets every guard's
|
|
1310
|
+
* `validate()` body be identical scaffolding around the per-guard
|
|
1311
|
+
* detector. The `opts` argument is forwarded verbatim as the second
|
|
1312
|
+
* argument to `detector(text, opts)` — its shape is detector-defined,
|
|
1313
|
+
* not constrained by gate-contract.
|
|
1314
|
+
*
|
|
1315
|
+
* @opts
|
|
1316
|
+
* ...: any, // detector-defined; passed through to detector(text, opts)
|
|
1317
|
+
*
|
|
1318
|
+
* @example
|
|
1319
|
+
* function detectFormulaTrigger(text) {
|
|
1320
|
+
* if (/^[=+\-@]/.test(text)) {
|
|
1321
|
+
* return [{ kind: "csv.formula-injection", severity: "high",
|
|
1322
|
+
* snippet: text.slice(0, 16) }];
|
|
1323
|
+
* }
|
|
1324
|
+
* return [];
|
|
1325
|
+
* }
|
|
1326
|
+
* var bad = b.gateContract.runIssueValidator("=cmd|x", {}, detectFormulaTrigger);
|
|
1327
|
+
* bad.ok; // → false
|
|
1328
|
+
* var ok = b.gateContract.runIssueValidator("ada,36", {}, detectFormulaTrigger);
|
|
1329
|
+
* ok.ok; // → true
|
|
1330
|
+
*/
|
|
1331
|
+
function runIssueValidator(input, opts, detector) {
|
|
1332
|
+
var text = typeof input === "string"
|
|
1333
|
+
? input
|
|
1334
|
+
: (Buffer.isBuffer(input) ? input.toString("utf8") : null);
|
|
1335
|
+
if (text == null) {
|
|
1336
|
+
return {
|
|
1337
|
+
ok: false,
|
|
1338
|
+
issues: [{ kind: "bad-input", severity: "high",
|
|
1339
|
+
snippet: "input is not string or Buffer" }],
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
return aggregateIssues(detector(text, opts));
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
/**
|
|
1346
|
+
* @primitive b.gateContract.resolveProfileAndPosture
|
|
1347
|
+
* @signature b.gateContract.resolveProfileAndPosture(opts, cfg)
|
|
1348
|
+
* @since 0.7.5
|
|
1349
|
+
* @status stable
|
|
1350
|
+
* @compliance hipaa, pci-dss, gdpr, soc2
|
|
1351
|
+
* @related b.gateContract.makeProfileBuilder, b.gateContract.lookupCompliancePosture
|
|
1352
|
+
*
|
|
1353
|
+
* Overlay `opts.profile` and `opts.compliancePosture` on top of a
|
|
1354
|
+
* defaults object using guard-supplied tables. Every guard primitive's
|
|
1355
|
+
* factory routes through this so the resolution shape — defaults
|
|
1356
|
+
* first, profile overlay, posture overlay, inline opts last — stays
|
|
1357
|
+
* identical across the family. When `opts.compliancePosture` is unset
|
|
1358
|
+
* and `b.compliance.set()` has declared a global posture, the global
|
|
1359
|
+
* posture takes effect (the value-add of the top-level coordinator).
|
|
1360
|
+
*
|
|
1361
|
+
* Throws `cfg.errorClass.factory(cfg.errCodePrefix + ".bad-profile")`
|
|
1362
|
+
* for unknown profile names and `... + ".bad-posture"` for unknown
|
|
1363
|
+
* postures.
|
|
1364
|
+
*
|
|
1365
|
+
* @opts
|
|
1366
|
+
* profiles: object, // PROFILES table (required)
|
|
1367
|
+
* compliancePostures: object, // COMPLIANCE_POSTURES table (required)
|
|
1368
|
+
* defaults: object, // baseline before overlay
|
|
1369
|
+
* errorClass: FrameworkError,// throws via .factory(code, msg)
|
|
1370
|
+
* errCodePrefix: string, // e.g. "csv" → "csv.bad-profile"
|
|
1371
|
+
*
|
|
1372
|
+
* @example
|
|
1373
|
+
* var PROFILES = {
|
|
1374
|
+
* strict: { formulaInjectionPolicy: "reject", bidiCharPolicy: "reject" },
|
|
1375
|
+
* balanced: { formulaInjectionPolicy: "prefix-tab", bidiCharPolicy: "strip" },
|
|
1376
|
+
* };
|
|
1377
|
+
* var POSTURES = { hipaa: { piiPolicy: "redact" } };
|
|
1378
|
+
* var resolved = b.gateContract.resolveProfileAndPosture(
|
|
1379
|
+
* { profile: "balanced", compliancePosture: "hipaa", maxCellBytes: 65536 },
|
|
1380
|
+
* {
|
|
1381
|
+
* profiles: PROFILES,
|
|
1382
|
+
* compliancePostures: POSTURES,
|
|
1383
|
+
* defaults: { maxCellBytes: 1024 },
|
|
1384
|
+
* errorClass: b.guardCsv.GuardCsvError,
|
|
1385
|
+
* errCodePrefix: "csv",
|
|
1386
|
+
* });
|
|
1387
|
+
* resolved.formulaInjectionPolicy; // → "prefix-tab"
|
|
1388
|
+
* resolved.piiPolicy; // → "redact"
|
|
1389
|
+
* resolved.maxCellBytes; // → 65536
|
|
1390
|
+
*/
|
|
1391
|
+
function resolveProfileAndPosture(opts, cfg) {
|
|
1392
|
+
opts = opts || {};
|
|
1393
|
+
validateOpts.requireObject(cfg, "gateContract.resolveProfileAndPosture",
|
|
1394
|
+
GateContractError);
|
|
1395
|
+
var ErrorClass = cfg.errorClass || GateContractError;
|
|
1396
|
+
var prefix = cfg.errCodePrefix || "guard";
|
|
1397
|
+
var overlay = {};
|
|
1398
|
+
if (typeof opts.profile === "string") {
|
|
1399
|
+
if (!cfg.profiles || !cfg.profiles[opts.profile]) {
|
|
1400
|
+
throw ErrorClass.factory(prefix + ".bad-profile",
|
|
1401
|
+
"unknown profile " + JSON.stringify(opts.profile));
|
|
1402
|
+
}
|
|
1403
|
+
overlay = cfg.profiles[opts.profile];
|
|
1404
|
+
}
|
|
1405
|
+
// Compliance-posture resolution — operator-supplied opt wins; if not
|
|
1406
|
+
// given, fall back to the global posture set via b.compliance.set().
|
|
1407
|
+
// The fallback IS the value-add of the top-level coordinator: every
|
|
1408
|
+
// primitive with a compliancePosture opt picks up the deployment's
|
|
1409
|
+
// declared posture without per-call wiring.
|
|
1410
|
+
var posture = opts.compliancePosture;
|
|
1411
|
+
if (typeof posture !== "string") {
|
|
1412
|
+
var globalPosture;
|
|
1413
|
+
try { globalPosture = compliance().current(); }
|
|
1414
|
+
catch (_e) { globalPosture = null; }
|
|
1415
|
+
if (typeof globalPosture === "string" &&
|
|
1416
|
+
cfg.compliancePostures && cfg.compliancePostures[globalPosture]) {
|
|
1417
|
+
posture = globalPosture;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
if (typeof posture === "string") {
|
|
1421
|
+
if (!cfg.compliancePostures || !cfg.compliancePostures[posture]) {
|
|
1422
|
+
throw ErrorClass.factory(prefix + ".bad-posture",
|
|
1423
|
+
"unknown compliancePosture " + JSON.stringify(posture));
|
|
1424
|
+
}
|
|
1425
|
+
overlay = Object.assign({}, overlay, cfg.compliancePostures[posture]);
|
|
1426
|
+
}
|
|
1427
|
+
return Object.assign({}, cfg.defaults || {}, overlay, opts);
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
/**
|
|
1431
|
+
* @primitive b.gateContract.buildProfile
|
|
1432
|
+
* @signature b.gateContract.buildProfile(opts)
|
|
1433
|
+
* @since 0.7.5
|
|
1434
|
+
* @status stable
|
|
1435
|
+
* @related b.gateContract.makeProfileBuilder, b.gateContract.resolveProfileAndPosture
|
|
1436
|
+
*
|
|
1437
|
+
* Recursive profile composition with cycle detection. Walks
|
|
1438
|
+
* `opts.baseProfile` and every name in `opts.extends` through the
|
|
1439
|
+
* caller-supplied `opts.resolveProfile` resolver, deep-merging arrays
|
|
1440
|
+
* (set-union, later-wins on duplicates) and objects (recursive). Then
|
|
1441
|
+
* applies inline `opts.overrides` and finally `opts.removes` (which
|
|
1442
|
+
* can drop array entries or whole keys). Cycles throw
|
|
1443
|
+
* `gate-contract/profile-cycle`; unknown names throw
|
|
1444
|
+
* `gate-contract/unknown-profile`. Most guards bind through
|
|
1445
|
+
* `makeProfileBuilder` and never call `buildProfile` directly.
|
|
1446
|
+
*
|
|
1447
|
+
* @opts
|
|
1448
|
+
* baseProfile: string, // start from this profile name
|
|
1449
|
+
* extends: string[], // additional bases (later-wins)
|
|
1450
|
+
* overrides: object, // inline merge after extends
|
|
1451
|
+
* removes: object, // drop array entries or keys
|
|
1452
|
+
* resolveProfile: function, // (name) → profile|null (required)
|
|
1453
|
+
*
|
|
1454
|
+
* @example
|
|
1455
|
+
* var PROFILES = {
|
|
1456
|
+
* "blog-post": {
|
|
1457
|
+
* allowedTags: ["p", "a", "strong"],
|
|
1458
|
+
* allowedAttrs: { a: ["href", "target"] },
|
|
1459
|
+
* },
|
|
1460
|
+
* "with-images": { extends: ["blog-post"], allowedTags: ["img"] },
|
|
1461
|
+
* };
|
|
1462
|
+
* var resolved = b.gateContract.buildProfile({
|
|
1463
|
+
* baseProfile: "with-images",
|
|
1464
|
+
* overrides: { allowedTags: ["em"] },
|
|
1465
|
+
* removes: { allowedAttrs: { a: ["target"] } },
|
|
1466
|
+
* resolveProfile: function (n) { return PROFILES[n] || null; },
|
|
1467
|
+
* });
|
|
1468
|
+
* resolved.allowedTags; // → ["p","a","strong","img","em"]
|
|
1469
|
+
* resolved.allowedAttrs.a; // → ["href"]
|
|
1470
|
+
*/
|
|
1471
|
+
function buildProfile(opts) {
|
|
1472
|
+
validateOpts.requireObject(opts, "gateContract.buildProfile", GateContractError);
|
|
1473
|
+
var resolve = opts.resolveProfile;
|
|
1474
|
+
if (typeof resolve !== "function") {
|
|
1475
|
+
throw _err("gate-contract/bad-opt",
|
|
1476
|
+
"buildProfile: opts.resolveProfile must be a function (name → profile)");
|
|
1477
|
+
}
|
|
1478
|
+
var seen = Object.create(null);
|
|
1479
|
+
function _walk(name) {
|
|
1480
|
+
if (seen[name]) {
|
|
1481
|
+
throw _err("gate-contract/profile-cycle",
|
|
1482
|
+
"buildProfile: cycle detected involving profile " + JSON.stringify(name));
|
|
1483
|
+
}
|
|
1484
|
+
seen[name] = true;
|
|
1485
|
+
var p = resolve(name);
|
|
1486
|
+
if (!p) throw _err("gate-contract/unknown-profile",
|
|
1487
|
+
"buildProfile: unknown profile " + JSON.stringify(name));
|
|
1488
|
+
var merged = Object.assign({}, p);
|
|
1489
|
+
if (Array.isArray(p.extends)) {
|
|
1490
|
+
for (var i = 0; i < p.extends.length; i++) {
|
|
1491
|
+
var ext = _walk(p.extends[i]);
|
|
1492
|
+
merged = _mergeProfile(ext, merged);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
return merged;
|
|
1496
|
+
}
|
|
1497
|
+
var base = opts.baseProfile ? _walk(opts.baseProfile) : {};
|
|
1498
|
+
if (Array.isArray(opts.extends)) {
|
|
1499
|
+
for (var i = 0; i < opts.extends.length; i++) {
|
|
1500
|
+
base = _mergeProfile(base, _walk(opts.extends[i]));
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
if (opts.overrides) base = _mergeProfile(base, opts.overrides);
|
|
1504
|
+
if (opts.removes) base = _applyRemoves(base, opts.removes);
|
|
1505
|
+
return base;
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
function _mergeProfile(target, source) {
|
|
1509
|
+
var out = Object.assign({}, target);
|
|
1510
|
+
var keys = Object.keys(source);
|
|
1511
|
+
for (var k = 0; k < keys.length; k++) {
|
|
1512
|
+
var key = keys[k];
|
|
1513
|
+
var val = source[key];
|
|
1514
|
+
if (Array.isArray(val) && Array.isArray(out[key])) {
|
|
1515
|
+
// Array merge — union; later sources win on duplicates.
|
|
1516
|
+
var seen2 = Object.create(null);
|
|
1517
|
+
var merged = [];
|
|
1518
|
+
for (var i = 0; i < out[key].length; i++) {
|
|
1519
|
+
var v = JSON.stringify(out[key][i]);
|
|
1520
|
+
if (!seen2[v]) { seen2[v] = true; merged.push(out[key][i]); }
|
|
1521
|
+
}
|
|
1522
|
+
for (var j = 0; j < val.length; j++) {
|
|
1523
|
+
var v2 = JSON.stringify(val[j]);
|
|
1524
|
+
if (!seen2[v2]) { seen2[v2] = true; merged.push(val[j]); }
|
|
1525
|
+
}
|
|
1526
|
+
out[key] = merged;
|
|
1527
|
+
} else if (val && typeof val === "object" && !Array.isArray(val) &&
|
|
1528
|
+
out[key] && typeof out[key] === "object" && !Array.isArray(out[key])) {
|
|
1529
|
+
out[key] = _mergeProfile(out[key], val);
|
|
1530
|
+
} else {
|
|
1531
|
+
out[key] = val;
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
return out;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
function _applyRemoves(target, removes) {
|
|
1538
|
+
var out = Object.assign({}, target);
|
|
1539
|
+
var keys = Object.keys(removes);
|
|
1540
|
+
for (var k = 0; k < keys.length; k++) {
|
|
1541
|
+
var key = keys[k];
|
|
1542
|
+
if (Array.isArray(removes[key]) && Array.isArray(out[key])) {
|
|
1543
|
+
var rmSet = Object.create(null);
|
|
1544
|
+
for (var i = 0; i < removes[key].length; i++) rmSet[JSON.stringify(removes[key][i])] = true;
|
|
1545
|
+
out[key] = out[key].filter(function (v) { return !rmSet[JSON.stringify(v)]; });
|
|
1546
|
+
} else if (removes[key] && typeof removes[key] === "object" &&
|
|
1547
|
+
out[key] && typeof out[key] === "object") {
|
|
1548
|
+
out[key] = _applyRemoves(out[key], removes[key]);
|
|
1549
|
+
} else {
|
|
1550
|
+
delete out[key];
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
return out;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* @primitive b.gateContract.summarizeIssues
|
|
1558
|
+
* @signature b.gateContract.summarizeIssues(issues)
|
|
1559
|
+
* @since 0.7.5
|
|
1560
|
+
* @status stable
|
|
1561
|
+
* @related b.gateContract.aggregateIssues, b.gateContract.defineGate
|
|
1562
|
+
*
|
|
1563
|
+
* Project a gate decision's `issues` array down to the audit-friendly
|
|
1564
|
+
* shape — `{ kind, severity, ruleId }` only. Full snippets stay in the
|
|
1565
|
+
* forensic evidence store; the audit log records the classification
|
|
1566
|
+
* without the offending bytes. Replaces the inline
|
|
1567
|
+
* `(d.issues || []).map(...)` pattern host primitives previously
|
|
1568
|
+
* carried per emit site.
|
|
1569
|
+
*
|
|
1570
|
+
* @example
|
|
1571
|
+
* var summary = b.gateContract.summarizeIssues([
|
|
1572
|
+
* { kind: "csv.bidi", severity: "high", ruleId: "BIDI-OVERRIDE",
|
|
1573
|
+
* snippet: "<offending bytes redacted>" },
|
|
1574
|
+
* { kind: "csv.trailing-whitespace", severity: "info", ruleId: "TRIM" },
|
|
1575
|
+
* ]);
|
|
1576
|
+
* summary.length; // → 2
|
|
1577
|
+
* summary[0].snippet; // → undefined (stripped)
|
|
1578
|
+
* summary[0].ruleId; // → "BIDI-OVERRIDE"
|
|
1579
|
+
*/
|
|
1580
|
+
function summarizeIssues(issues) {
|
|
1581
|
+
if (!Array.isArray(issues)) return [];
|
|
1582
|
+
return issues.map(function (i) {
|
|
1583
|
+
return { kind: i.kind, severity: i.severity, ruleId: i.ruleId };
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
/**
|
|
1588
|
+
* @primitive b.gateContract.composeHooks
|
|
1589
|
+
* @signature b.gateContract.composeHooks(hooks)
|
|
1590
|
+
* @since 0.7.5
|
|
1591
|
+
* @status stable
|
|
1592
|
+
* @related b.gateContract.defineGate, b.gateContract.buildGuardGate
|
|
1593
|
+
*
|
|
1594
|
+
* Chain a list of operator hooks into a single async hook. Empty
|
|
1595
|
+
* arrays return `null` (so `defineGate` can pass the result through
|
|
1596
|
+
* its `hooks.X || null` slot); single-element arrays return the
|
|
1597
|
+
* lone hook unchanged. Multi-element chains run sequentially —
|
|
1598
|
+
* `{ suppress: true }` or `{ skip: true }` from any hook short-
|
|
1599
|
+
* circuits and returns; otherwise the last non-null hook result wins.
|
|
1600
|
+
*
|
|
1601
|
+
* @example
|
|
1602
|
+
* var redactPii = function (issue) {
|
|
1603
|
+
* return Object.assign({}, issue, { snippet: "<redacted>" });
|
|
1604
|
+
* };
|
|
1605
|
+
* var dropInfo = function (issue) {
|
|
1606
|
+
* return issue.severity === "info" ? { suppress: true } : null;
|
|
1607
|
+
* };
|
|
1608
|
+
* var onIssue = b.gateContract.composeHooks([dropInfo, redactPii]);
|
|
1609
|
+
* var infoHit = await onIssue({ kind: "csv.trim", severity: "info" });
|
|
1610
|
+
* infoHit.suppress; // → true
|
|
1611
|
+
* var bidi = await onIssue({ kind: "csv.bidi", severity: "high",
|
|
1612
|
+
* snippet: "U+202E" });
|
|
1613
|
+
* bidi.snippet; // → "<redacted>"
|
|
1614
|
+
*/
|
|
1615
|
+
function composeHooks(hooks) {
|
|
1616
|
+
hooks = (hooks || []).filter(Boolean);
|
|
1617
|
+
if (hooks.length === 0) return null;
|
|
1618
|
+
if (hooks.length === 1) return hooks[0];
|
|
1619
|
+
return async function () {
|
|
1620
|
+
var args = Array.prototype.slice.call(arguments);
|
|
1621
|
+
var result = null;
|
|
1622
|
+
for (var i = 0; i < hooks.length; i++) {
|
|
1623
|
+
var rv = await hooks[i].apply(null, args);
|
|
1624
|
+
if (rv && (rv.suppress === true || rv.skip === true)) return rv;
|
|
1625
|
+
if (rv) result = rv;
|
|
1626
|
+
}
|
|
1627
|
+
return result;
|
|
1628
|
+
};
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
module.exports = {
|
|
1632
|
+
defineGate: defineGate,
|
|
1633
|
+
validateGateShape: validateGateShape,
|
|
1634
|
+
runGate: runGate,
|
|
1635
|
+
composeGates: composeGates,
|
|
1636
|
+
multiplexGates: multiplexGates,
|
|
1637
|
+
contentTypeMux: contentTypeMux,
|
|
1638
|
+
byActorTier: byActorTier,
|
|
1639
|
+
byRoute: byRoute,
|
|
1640
|
+
byDirection: byDirection,
|
|
1641
|
+
shadowMode: shadowMode,
|
|
1642
|
+
canaryGate: canaryGate,
|
|
1643
|
+
cachingGate: cachingGate,
|
|
1644
|
+
workerThreadGate: workerThreadGate,
|
|
1645
|
+
buildProfile: buildProfile,
|
|
1646
|
+
resolveProfileAndPosture: resolveProfileAndPosture,
|
|
1647
|
+
runIssueValidator: runIssueValidator,
|
|
1648
|
+
buildGuardGate: buildGuardGate,
|
|
1649
|
+
extractBytesAsText: extractBytesAsText,
|
|
1650
|
+
lookupCompliancePosture: lookupCompliancePosture,
|
|
1651
|
+
makeRulePackLoader: makeRulePackLoader,
|
|
1652
|
+
makeProfileBuilder: makeProfileBuilder,
|
|
1653
|
+
badInputResultIfNotStringOrBuffer: badInputResultIfNotStringOrBuffer,
|
|
1654
|
+
aggregateIssues: aggregateIssues,
|
|
1655
|
+
composeHooks: composeHooks,
|
|
1656
|
+
summarizeIssues: summarizeIssues,
|
|
1657
|
+
ACTIONS: ACTIONS,
|
|
1658
|
+
MODES: MODES,
|
|
1659
|
+
ISSUE_SEVERITIES: ISSUE_SEVERITIES,
|
|
1660
|
+
GateContractError: GateContractError,
|
|
1661
|
+
};
|