@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,1272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @module b.storage
|
|
4
|
+
* @featured true
|
|
5
|
+
* @nav Data
|
|
6
|
+
* @title Storage
|
|
7
|
+
*
|
|
8
|
+
* @intro
|
|
9
|
+
* Filesystem-and-cloud-backed object storage with sealed per-file
|
|
10
|
+
* encryption keys, classification routing, and residency enforcement.
|
|
11
|
+
*
|
|
12
|
+
* `b.storage` sits one layer above `b.objectStore`: the lower
|
|
13
|
+
* primitive abstracts the byte-level adapter (local FS, sigv4-style
|
|
14
|
+
* S3-compatible, GCS, Azure Blob, generic HTTP-PUT); this module
|
|
15
|
+
* adds the framework-shaped policy on top — multi-backend
|
|
16
|
+
* registration, per-call classification → backend dispatch,
|
|
17
|
+
* boot-time residency validation against `b.db.getDataResidency()`,
|
|
18
|
+
* per-file XChaCha20-Poly1305 encryption with the data key sealed
|
|
19
|
+
* into the framework's vault, and audit-chain emission for every
|
|
20
|
+
* read / write / delete / presign.
|
|
21
|
+
*
|
|
22
|
+
* Configuration accepts either the legacy single-backend shape
|
|
23
|
+
* (`{ backend, uploadDir }`) or the multi-backend shape
|
|
24
|
+
* (`{ backends: { name: cfg, ... }, defaultClassification,
|
|
25
|
+
* refuseUnclassified }`). Both normalize internally to the
|
|
26
|
+
* multi-backend form. `refuseUnclassified: true` forces every call
|
|
27
|
+
* to declare its `classification` explicitly, which is the right
|
|
28
|
+
* posture for apps mixing personal / operational / public data
|
|
29
|
+
* across different residency zones.
|
|
30
|
+
*
|
|
31
|
+
* Encrypted save/get is the default surface (`saveFile` /
|
|
32
|
+
* `getFileBuffer` / `getFileStream`); `saveRaw` / `getRawBuffer`
|
|
33
|
+
* skip the per-file encryption envelope for content that is
|
|
34
|
+
* already-public or already-encrypted (e.g. signed image assets,
|
|
35
|
+
* pre-encrypted backup bundles).
|
|
36
|
+
*
|
|
37
|
+
* @card
|
|
38
|
+
* Filesystem-and-cloud-backed object storage with sealed per-file encryption keys, classification routing, and residency enforcement.
|
|
39
|
+
*/
|
|
40
|
+
var C = require("./constants");
|
|
41
|
+
var { generateBytes, encryptPacked, decryptPacked } = require("./crypto");
|
|
42
|
+
var objectStore = require("./object-store");
|
|
43
|
+
var lazyRequire = require("./lazy-require");
|
|
44
|
+
var numericBounds = require("./numeric-bounds");
|
|
45
|
+
var canonicalJson = require("./canonical-json");
|
|
46
|
+
var { StorageError } = require("./framework-error");
|
|
47
|
+
|
|
48
|
+
var vault = lazyRequire(function () { return require("./vault"); });
|
|
49
|
+
var audit = lazyRequire(function () { return require("./audit"); });
|
|
50
|
+
var db = lazyRequire(function () { return require("./db"); });
|
|
51
|
+
|
|
52
|
+
var initialized = false;
|
|
53
|
+
var backends = {}; // name → backend instance from object-store
|
|
54
|
+
var defaultClassification = null;
|
|
55
|
+
var refuseUnclassified = false;
|
|
56
|
+
|
|
57
|
+
var _err = StorageError.factory;
|
|
58
|
+
|
|
59
|
+
// ---- Init ----
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @primitive b.storage.init
|
|
63
|
+
* @signature b.storage.init(opts)
|
|
64
|
+
* @since 0.1.0
|
|
65
|
+
* @status stable
|
|
66
|
+
* @related b.storage.saveFile, b.storage.listBackends, b.objectStore.buildBackend
|
|
67
|
+
*
|
|
68
|
+
* Register one or more storage backends and lock the framework into
|
|
69
|
+
* the configured policy. Idempotent — a second call after the first
|
|
70
|
+
* succeeds is a no-op (operators rebuild via `_resetForTest` only).
|
|
71
|
+
* Validates classification → residency mapping at boot so a
|
|
72
|
+
* misconfigured deployment (US backend serving EU personal data)
|
|
73
|
+
* fails fast instead of leaking on first write.
|
|
74
|
+
*
|
|
75
|
+
* @opts
|
|
76
|
+
* backend: "local" | "sigv4" | "gcs" | "azure-blob" | "http-put", // single-backend shorthand
|
|
77
|
+
* uploadDir: string, // local backend root (single-backend shorthand)
|
|
78
|
+
* backends: object, // multi-backend map: name -> backend cfg
|
|
79
|
+
* defaultClassification: string, // applied when a call omits { classification }
|
|
80
|
+
* refuseUnclassified: boolean, // refuse calls without explicit classification
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* // Single-backend, local FS — typical small-app shape.
|
|
84
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // Multi-backend with classification routing + residency tags.
|
|
88
|
+
* b.storage.init({
|
|
89
|
+
* backends: {
|
|
90
|
+
* "eu-private": {
|
|
91
|
+
* protocol: "local",
|
|
92
|
+
* rootDir: "/srv/eu/private",
|
|
93
|
+
* classifications: ["personal"],
|
|
94
|
+
* residencyTag: "EU",
|
|
95
|
+
* },
|
|
96
|
+
* "us-ops": {
|
|
97
|
+
* protocol: "local",
|
|
98
|
+
* rootDir: "/srv/us/ops",
|
|
99
|
+
* classifications: ["operational", "public"],
|
|
100
|
+
* residencyTag: "US",
|
|
101
|
+
* },
|
|
102
|
+
* },
|
|
103
|
+
* defaultClassification: "operational",
|
|
104
|
+
* refuseUnclassified: true,
|
|
105
|
+
* });
|
|
106
|
+
*/
|
|
107
|
+
function init(opts) {
|
|
108
|
+
if (initialized) return;
|
|
109
|
+
if (!opts) throw _err("INVALID_CONFIG", "storage.init() requires options", true);
|
|
110
|
+
|
|
111
|
+
// Normalize single-backend config into multi-backend form
|
|
112
|
+
var normalized = _normalizeConfig(opts);
|
|
113
|
+
|
|
114
|
+
defaultClassification = normalized.defaultClassification;
|
|
115
|
+
refuseUnclassified = !!normalized.refuseUnclassified;
|
|
116
|
+
|
|
117
|
+
backends = {};
|
|
118
|
+
for (var name in normalized.backends) {
|
|
119
|
+
var cfg = Object.assign({}, normalized.backends[name], { name: name });
|
|
120
|
+
backends[name] = objectStore.buildBackend(cfg);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Boot-time residency validation
|
|
124
|
+
_validateResidency();
|
|
125
|
+
|
|
126
|
+
initialized = true;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function _normalizeConfig(opts) {
|
|
130
|
+
if (opts.backends) {
|
|
131
|
+
return {
|
|
132
|
+
backends: opts.backends,
|
|
133
|
+
defaultClassification: opts.defaultClassification || null,
|
|
134
|
+
refuseUnclassified: !!opts.refuseUnclassified,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Single-backend syntax: { backend, uploadDir, ... }
|
|
138
|
+
if (opts.backend) {
|
|
139
|
+
if (opts.backend === "s3") {
|
|
140
|
+
throw _err("INVALID_CONFIG",
|
|
141
|
+
"storage backend 's3' is now spelled 'sigv4' (covers AWS S3, R2, B2, " +
|
|
142
|
+
"MinIO, Wasabi, Tigris, DO Spaces, IDrive e2, Storj, Linode). " +
|
|
143
|
+
"Use { backend: 'sigv4', endpoint, region, bucket, accessKeyId, secretAccessKey }.",
|
|
144
|
+
true);
|
|
145
|
+
}
|
|
146
|
+
if (opts.backend === "local") {
|
|
147
|
+
return {
|
|
148
|
+
backends: {
|
|
149
|
+
"default": {
|
|
150
|
+
protocol: "local",
|
|
151
|
+
rootDir: opts.uploadDir,
|
|
152
|
+
classifications: ["*"],
|
|
153
|
+
residencyTag: "unrestricted",
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
defaultClassification: null,
|
|
157
|
+
refuseUnclassified: false,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
if (opts.backend === "http-put" || opts.backend === "sigv4" || opts.backend === "gcs" || opts.backend === "azure-blob") {
|
|
161
|
+
// Forward as-is; user provided a single-backend spec for a remote protocol
|
|
162
|
+
return {
|
|
163
|
+
backends: { "default": Object.assign({}, opts, { name: undefined }) },
|
|
164
|
+
defaultClassification: null,
|
|
165
|
+
refuseUnclassified: false,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
throw _err("INVALID_CONFIG",
|
|
169
|
+
"storage.init: unknown backend '" + opts.backend + "'", true);
|
|
170
|
+
}
|
|
171
|
+
throw _err("INVALID_CONFIG",
|
|
172
|
+
"storage.init: must provide either { backend } or { backends }", true);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function _validateResidency() {
|
|
176
|
+
var residency;
|
|
177
|
+
try { residency = db().getDataResidency(); } catch (_e) { residency = null; }
|
|
178
|
+
if (!residency || !residency.region) return;
|
|
179
|
+
|
|
180
|
+
var allowed = [residency.region].concat(residency.allowedStorageRegions || []);
|
|
181
|
+
|
|
182
|
+
for (var name in backends) {
|
|
183
|
+
var b = backends[name];
|
|
184
|
+
var serves = b.classifications.indexOf("*") !== -1 || b.classifications.indexOf("personal") !== -1;
|
|
185
|
+
if (!serves) continue;
|
|
186
|
+
if (allowed.indexOf(b.residencyTag) === -1) {
|
|
187
|
+
throw _err(
|
|
188
|
+
"RESIDENCY_VIOLATION",
|
|
189
|
+
"backend '" + name + "' serves 'personal' data with residencyTag '" + b.residencyTag +
|
|
190
|
+
"' but app's dataResidency.region is '" + residency.region + "' (allowed: " + allowed.join(", ") + ")",
|
|
191
|
+
true
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// If defaultClassification is 'personal', confirm at least one backend serves it
|
|
197
|
+
if (defaultClassification === "personal") {
|
|
198
|
+
var found = false;
|
|
199
|
+
for (var n in backends) {
|
|
200
|
+
if (backends[n].servesClassification("personal")) { found = true; break; }
|
|
201
|
+
}
|
|
202
|
+
if (!found) {
|
|
203
|
+
throw _err("NO_PERSONAL_BACKEND",
|
|
204
|
+
"defaultClassification='personal' but no backend declares 'personal' in classifications", true);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// ---- Backend selection ----
|
|
210
|
+
|
|
211
|
+
function _pickBackend(opts) {
|
|
212
|
+
opts = opts || {};
|
|
213
|
+
if (opts.backend) {
|
|
214
|
+
var b = backends[opts.backend];
|
|
215
|
+
if (!b) throw _err("UNKNOWN_BACKEND", "no backend named '" + opts.backend + "'", true);
|
|
216
|
+
if (opts.classification && !b.servesClassification(opts.classification)) {
|
|
217
|
+
throw _err("CLASSIFICATION_MISMATCH",
|
|
218
|
+
"backend '" + opts.backend + "' does not serve classification '" + opts.classification + "'", true);
|
|
219
|
+
}
|
|
220
|
+
return { backend: b, classification: opts.classification || null };
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// refuseUnclassified forces every call to declare classification explicitly,
|
|
224
|
+
// even when defaultClassification is configured. The default is for
|
|
225
|
+
// convenience; refuseUnclassified is for explicit boundary enforcement.
|
|
226
|
+
if (refuseUnclassified && !opts.classification) {
|
|
227
|
+
throw _err("UNCLASSIFIED",
|
|
228
|
+
"saveFile requires { classification } (or set { backend } explicitly); " +
|
|
229
|
+
"framework is configured with refuseUnclassified: true", true);
|
|
230
|
+
}
|
|
231
|
+
var classification = opts.classification || defaultClassification;
|
|
232
|
+
if (!classification) {
|
|
233
|
+
// No classification + no refusal → pick any backend
|
|
234
|
+
for (var n in backends) return { backend: backends[n], classification: null };
|
|
235
|
+
throw _err("NO_BACKENDS", "no backends configured", true);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
for (var name in backends) {
|
|
239
|
+
if (backends[name].servesClassification(classification)) {
|
|
240
|
+
return { backend: backends[name], classification: classification };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
throw _err("NO_BACKEND_FOR_CLASSIFICATION",
|
|
244
|
+
"no backend serves classification '" + classification + "'", true);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ---- File encryption helpers ----
|
|
248
|
+
|
|
249
|
+
function _encryptBuffer(buffer) {
|
|
250
|
+
var key = generateBytes(C.BYTES.bytes(32));
|
|
251
|
+
var packed = encryptPacked(buffer, key);
|
|
252
|
+
var sealedKey = vault().seal(key.toString("base64"));
|
|
253
|
+
return { data: packed, encryptionKey: sealedKey };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function _decryptBuffer(packed, sealedKey) {
|
|
257
|
+
if (!sealedKey) {
|
|
258
|
+
throw _err("KEY_REQUIRED", "encryptionKey is required (no legacy plaintext support)", true);
|
|
259
|
+
}
|
|
260
|
+
var key = Buffer.from(vault().unseal(sealedKey), "base64");
|
|
261
|
+
return decryptPacked(packed, key);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// ---- Audit emission ----
|
|
265
|
+
|
|
266
|
+
function _emit(action, info) {
|
|
267
|
+
// safeEmit handles default-fill + try/catch. Audit must never block
|
|
268
|
+
// storage operations — if it fails the missing entry shows up at the
|
|
269
|
+
// next chain verify.
|
|
270
|
+
audit().safeEmit({ action: action, ...(info || {}) });
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// ---- Public API ----
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @primitive b.storage.saveFile
|
|
277
|
+
* @signature b.storage.saveFile(buffer, key, opts)
|
|
278
|
+
* @since 0.1.0
|
|
279
|
+
* @status stable
|
|
280
|
+
* @compliance gdpr, hipaa, pci-dss, soc2
|
|
281
|
+
* @related b.storage.getFileBuffer, b.storage.deleteFile, b.storage.saveRaw
|
|
282
|
+
*
|
|
283
|
+
* Encrypt `buffer` under a fresh XChaCha20-Poly1305 data key, seal
|
|
284
|
+
* the data key into the framework vault, and write the ciphertext to
|
|
285
|
+
* the backend selected by `opts.classification` (or `opts.backend`
|
|
286
|
+
* for explicit pinning). Returns the storage path plus the sealed
|
|
287
|
+
* key the caller MUST persist alongside the row that references the
|
|
288
|
+
* blob — without it, the bytes are unrecoverable. Emits a
|
|
289
|
+
* `system.storage.write` audit event with `{ backend, classification,
|
|
290
|
+
* residencyTag, sizeBytes }`.
|
|
291
|
+
*
|
|
292
|
+
* @opts
|
|
293
|
+
* classification: string, // route to a backend serving this classification
|
|
294
|
+
* backend: string, // explicit backend by name (still validates classification serve)
|
|
295
|
+
*
|
|
296
|
+
* @example
|
|
297
|
+
* var buf = Buffer.from("invoice pdf bytes");
|
|
298
|
+
* var saved = await b.storage.saveFile(buf, "invoices/2026/001.pdf", {
|
|
299
|
+
* classification: "personal",
|
|
300
|
+
* });
|
|
301
|
+
* // → { storedPath: "invoices/2026/001.pdf",
|
|
302
|
+
* // encryptionKey: "v1:...", // sealed; persist with the row
|
|
303
|
+
* // backend: "eu-private",
|
|
304
|
+
* // classification: "personal" }
|
|
305
|
+
*/
|
|
306
|
+
async function saveFile(buffer, key, opts) {
|
|
307
|
+
_requireInit();
|
|
308
|
+
if (!Buffer.isBuffer(buffer)) throw _err("INVALID_BODY", "saveFile body must be a Buffer", true);
|
|
309
|
+
opts = opts || {};
|
|
310
|
+
var picked = _pickBackend(opts);
|
|
311
|
+
var enc = _encryptBuffer(buffer);
|
|
312
|
+
var result = await picked.backend.put(key, enc.data, opts);
|
|
313
|
+
_emit("system.storage.write", {
|
|
314
|
+
metadata: {
|
|
315
|
+
backend: picked.backend.name,
|
|
316
|
+
classification: picked.classification,
|
|
317
|
+
residencyTag: picked.backend.residencyTag,
|
|
318
|
+
key: key,
|
|
319
|
+
sizeBytes: result.size != null ? result.size : enc.data.length,
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
storedPath: key,
|
|
324
|
+
encryptionKey: enc.encryptionKey,
|
|
325
|
+
backend: picked.backend.name,
|
|
326
|
+
classification: picked.classification,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @primitive b.storage.getFileBuffer
|
|
332
|
+
* @signature b.storage.getFileBuffer(key, sealedKey, opts)
|
|
333
|
+
* @since 0.1.0
|
|
334
|
+
* @status stable
|
|
335
|
+
* @related b.storage.saveFile, b.storage.getFileStream
|
|
336
|
+
*
|
|
337
|
+
* Fetch the ciphertext at `key` from the routed backend, unseal the
|
|
338
|
+
* per-file data key via the framework vault, and return the
|
|
339
|
+
* decrypted plaintext as a Buffer. The AEAD tag is verified before
|
|
340
|
+
* any plaintext is released — a tampered ciphertext throws
|
|
341
|
+
* `crypto/decrypt-failed`, never returns partial bytes. Emits
|
|
342
|
+
* `system.storage.read` with `{ backend, key, sizeBytes }`.
|
|
343
|
+
*
|
|
344
|
+
* @opts
|
|
345
|
+
* classification: string, // route to a backend serving this classification
|
|
346
|
+
* backend: string, // explicit backend by name
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* // Round-trip a small text payload through saveFile/getFileBuffer.
|
|
350
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
351
|
+
* var saved = await b.storage.saveFile(Buffer.from("hello"), "greet.txt");
|
|
352
|
+
* var roundTrip = await b.storage.getFileBuffer("greet.txt", saved.encryptionKey);
|
|
353
|
+
* roundTrip.toString("utf8"); // → "hello"
|
|
354
|
+
*/
|
|
355
|
+
async function getFileBuffer(key, sealedKey, opts) {
|
|
356
|
+
_requireInit();
|
|
357
|
+
opts = opts || {};
|
|
358
|
+
var picked = _pickBackend(opts);
|
|
359
|
+
var packed = await picked.backend.get(key);
|
|
360
|
+
var decrypted = _decryptBuffer(packed, sealedKey);
|
|
361
|
+
_emit("system.storage.read", {
|
|
362
|
+
metadata: {
|
|
363
|
+
backend: picked.backend.name,
|
|
364
|
+
key: key,
|
|
365
|
+
sizeBytes: decrypted.length,
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
return decrypted;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* @primitive b.storage.getFileStream
|
|
373
|
+
* @signature b.storage.getFileStream(key, sealedKey, opts)
|
|
374
|
+
* @since 0.1.0
|
|
375
|
+
* @status stable
|
|
376
|
+
* @related b.storage.getFileBuffer, b.storage.saveFile
|
|
377
|
+
*
|
|
378
|
+
* Buffer-then-stream variant of `getFileBuffer` — returns a
|
|
379
|
+
* `stream.Readable` once the AEAD tag has verified the entire
|
|
380
|
+
* ciphertext. Per-file XChaCha20-Poly1305 needs the whole frame
|
|
381
|
+
* before it can release the first byte; chunked AEAD with
|
|
382
|
+
* per-chunk tags would let us stream end-to-end at the cost of
|
|
383
|
+
* finer-grained tampering windows, so the framework defaults to
|
|
384
|
+
* the safe variant.
|
|
385
|
+
*
|
|
386
|
+
* @opts
|
|
387
|
+
* classification: string, // route to a backend serving this classification
|
|
388
|
+
* backend: string, // explicit backend by name
|
|
389
|
+
*
|
|
390
|
+
* @example
|
|
391
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
392
|
+
* var saved = await b.storage.saveFile(Buffer.from("stream-me"), "blob.bin");
|
|
393
|
+
* var stream = await b.storage.getFileStream("blob.bin", saved.encryptionKey);
|
|
394
|
+
* var chunks = [];
|
|
395
|
+
* for await (var chunk of stream) chunks.push(chunk);
|
|
396
|
+
* Buffer.concat(chunks).toString("utf8"); // → "stream-me"
|
|
397
|
+
*/
|
|
398
|
+
async function getFileStream(key, sealedKey, opts) {
|
|
399
|
+
// Buffer-then-stream: per-file XChaCha20 encryption needs the whole
|
|
400
|
+
// ciphertext to verify the AEAD tag before any plaintext can be released
|
|
401
|
+
// to the consumer. Chunked-encryption with per-chunk AEAD would let us
|
|
402
|
+
// stream end-to-end, but at the cost of finer-grained tampering windows.
|
|
403
|
+
var buf = await getFileBuffer(key, sealedKey, opts);
|
|
404
|
+
return require("node:stream").Readable.from(buf);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* @primitive b.storage.saveRaw
|
|
409
|
+
* @signature b.storage.saveRaw(buffer, key, opts)
|
|
410
|
+
* @since 0.1.0
|
|
411
|
+
* @status stable
|
|
412
|
+
* @related b.storage.saveFile, b.storage.getRawBuffer
|
|
413
|
+
*
|
|
414
|
+
* Write `buffer` to the routed backend as-is, skipping the per-file
|
|
415
|
+
* encryption envelope. Use for content that is already public
|
|
416
|
+
* (signed CDN assets, image thumbnails) or already encrypted
|
|
417
|
+
* (pre-sealed backup bundles); use `saveFile` for everything else.
|
|
418
|
+
* Audit metadata records `raw: true` so storage reads in the audit
|
|
419
|
+
* chain can be distinguished from encrypted reads.
|
|
420
|
+
*
|
|
421
|
+
* @opts
|
|
422
|
+
* classification: string, // route to a backend serving this classification
|
|
423
|
+
* backend: string, // explicit backend by name
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
427
|
+
* var saved = await b.storage.saveRaw(Buffer.from("public-bytes"), "logo.png");
|
|
428
|
+
* // → { storedPath: "logo.png", backend: "default" }
|
|
429
|
+
*/
|
|
430
|
+
async function saveRaw(buffer, key, opts) {
|
|
431
|
+
_requireInit();
|
|
432
|
+
if (!Buffer.isBuffer(buffer)) throw _err("INVALID_BODY", "saveRaw body must be a Buffer", true);
|
|
433
|
+
opts = opts || {};
|
|
434
|
+
var picked = _pickBackend(opts);
|
|
435
|
+
var result = await picked.backend.put(key, buffer, opts);
|
|
436
|
+
_emit("system.storage.write", {
|
|
437
|
+
metadata: {
|
|
438
|
+
backend: picked.backend.name,
|
|
439
|
+
classification: picked.classification,
|
|
440
|
+
residencyTag: picked.backend.residencyTag,
|
|
441
|
+
key: key,
|
|
442
|
+
sizeBytes: result.size != null ? result.size : buffer.length,
|
|
443
|
+
raw: true,
|
|
444
|
+
},
|
|
445
|
+
});
|
|
446
|
+
return { storedPath: key, backend: picked.backend.name };
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* @primitive b.storage.getRawBuffer
|
|
451
|
+
* @signature b.storage.getRawBuffer(key, opts)
|
|
452
|
+
* @since 0.1.0
|
|
453
|
+
* @status stable
|
|
454
|
+
* @related b.storage.saveRaw, b.storage.getFileBuffer
|
|
455
|
+
*
|
|
456
|
+
* Fetch the raw bytes at `key` from the routed backend. No
|
|
457
|
+
* decryption layer is applied — the caller receives whatever was
|
|
458
|
+
* stored, byte-for-byte. Pair with `saveRaw`; for encrypted blobs
|
|
459
|
+
* use `getFileBuffer` instead so the AEAD tag is verified.
|
|
460
|
+
*
|
|
461
|
+
* @opts
|
|
462
|
+
* classification: string, // route to a backend serving this classification
|
|
463
|
+
* backend: string, // explicit backend by name
|
|
464
|
+
*
|
|
465
|
+
* @example
|
|
466
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
467
|
+
* await b.storage.saveRaw(Buffer.from("raw-payload"), "asset.bin");
|
|
468
|
+
* var bytes = await b.storage.getRawBuffer("asset.bin");
|
|
469
|
+
* bytes.toString("utf8"); // → "raw-payload"
|
|
470
|
+
*/
|
|
471
|
+
async function getRawBuffer(key, opts) {
|
|
472
|
+
_requireInit();
|
|
473
|
+
opts = opts || {};
|
|
474
|
+
var picked = _pickBackend(opts);
|
|
475
|
+
return picked.backend.get(key);
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* @primitive b.storage.deleteFile
|
|
480
|
+
* @signature b.storage.deleteFile(key, opts)
|
|
481
|
+
* @since 0.1.0
|
|
482
|
+
* @status stable
|
|
483
|
+
* @compliance gdpr
|
|
484
|
+
* @related b.storage.saveFile, b.storage.exists
|
|
485
|
+
*
|
|
486
|
+
* Remove `key` from the routed backend. Returns `true` when the
|
|
487
|
+
* object existed and was removed, `false` when it was already
|
|
488
|
+
* absent. Emits `system.storage.delete` with `{ backend, key,
|
|
489
|
+
* existed }` so the audit chain records GDPR right-to-erasure
|
|
490
|
+
* flows. The sealed encryption key the caller persisted alongside
|
|
491
|
+
* the row should be discarded by the caller after a successful
|
|
492
|
+
* delete — without the bytes, the key has no recovery value.
|
|
493
|
+
*
|
|
494
|
+
* @opts
|
|
495
|
+
* classification: string, // route to a backend serving this classification
|
|
496
|
+
* backend: string, // explicit backend by name
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
500
|
+
* await b.storage.saveRaw(Buffer.from("doomed"), "tmp/x.bin");
|
|
501
|
+
* var existed = await b.storage.deleteFile("tmp/x.bin");
|
|
502
|
+
* // → true
|
|
503
|
+
* var second = await b.storage.deleteFile("tmp/x.bin");
|
|
504
|
+
* // → false
|
|
505
|
+
*/
|
|
506
|
+
async function deleteFile(key, opts) {
|
|
507
|
+
_requireInit();
|
|
508
|
+
opts = opts || {};
|
|
509
|
+
var picked = _pickBackend(opts);
|
|
510
|
+
var result = await picked.backend.delete(key);
|
|
511
|
+
_emit("system.storage.delete", {
|
|
512
|
+
metadata: {
|
|
513
|
+
backend: picked.backend.name,
|
|
514
|
+
key: key,
|
|
515
|
+
existed: result,
|
|
516
|
+
},
|
|
517
|
+
});
|
|
518
|
+
return result;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* @primitive b.storage.exists
|
|
523
|
+
* @signature b.storage.exists(key, opts)
|
|
524
|
+
* @since 0.1.0
|
|
525
|
+
* @status stable
|
|
526
|
+
* @related b.storage.deleteFile, b.storage.getFileBuffer
|
|
527
|
+
*
|
|
528
|
+
* HEAD-style existence check — returns `true` when the routed
|
|
529
|
+
* backend reports the key present, `false` on `NOT_FOUND`. Other
|
|
530
|
+
* backend errors propagate so transient outages aren't swallowed
|
|
531
|
+
* as "doesn't exist." Cheaper than a full GET when the caller only
|
|
532
|
+
* needs to gate a downstream operation on presence.
|
|
533
|
+
*
|
|
534
|
+
* @opts
|
|
535
|
+
* classification: string, // route to a backend serving this classification
|
|
536
|
+
* backend: string, // explicit backend by name
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
540
|
+
* await b.storage.saveRaw(Buffer.from("here"), "probe.bin");
|
|
541
|
+
* var present = await b.storage.exists("probe.bin");
|
|
542
|
+
* // → true
|
|
543
|
+
* var missing = await b.storage.exists("nope.bin");
|
|
544
|
+
* // → false
|
|
545
|
+
*/
|
|
546
|
+
async function exists(key, opts) {
|
|
547
|
+
_requireInit();
|
|
548
|
+
opts = opts || {};
|
|
549
|
+
var picked = _pickBackend(opts);
|
|
550
|
+
try {
|
|
551
|
+
await picked.backend.head(key);
|
|
552
|
+
return true;
|
|
553
|
+
} catch (e) {
|
|
554
|
+
if (e && e.code === "NOT_FOUND") return false;
|
|
555
|
+
throw e;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* @primitive b.storage.listBackends
|
|
561
|
+
* @signature b.storage.listBackends()
|
|
562
|
+
* @since 0.1.0
|
|
563
|
+
* @status stable
|
|
564
|
+
* @related b.storage.getBackend, b.storage.init
|
|
565
|
+
*
|
|
566
|
+
* Snapshot every registered backend with `{ name, protocol,
|
|
567
|
+
* classifications, residencyTag, breakerState }`. The
|
|
568
|
+
* `breakerState` is the live circuit-breaker state from the
|
|
569
|
+
* underlying `b.objectStore` adapter — handy for ops dashboards
|
|
570
|
+
* surfacing a degraded backend before it cascades.
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
574
|
+
* var info = b.storage.listBackends();
|
|
575
|
+
* info[0].name; // → "default"
|
|
576
|
+
* info[0].protocol; // → "local"
|
|
577
|
+
*/
|
|
578
|
+
function listBackends() {
|
|
579
|
+
_requireInit();
|
|
580
|
+
var out = [];
|
|
581
|
+
for (var name in backends) {
|
|
582
|
+
var entry = {
|
|
583
|
+
name: name,
|
|
584
|
+
protocol: backends[name].protocol,
|
|
585
|
+
classifications: backends[name].classifications.slice(),
|
|
586
|
+
residencyTag: backends[name].residencyTag,
|
|
587
|
+
breakerState: backends[name].breaker.getState(),
|
|
588
|
+
};
|
|
589
|
+
// Surface the resolved local rootDir so downstream operators
|
|
590
|
+
// building path-traversal guards or scratch-dir layouts read the
|
|
591
|
+
// live path (with config-reload propagation) directly from the
|
|
592
|
+
// backend rather than re-deriving from operator-supplied opts.
|
|
593
|
+
// Remote protocols (sigv4 / gcs / azure-blob / http-put) don't
|
|
594
|
+
// have a rootDir; the field stays absent for those.
|
|
595
|
+
if (backends[name].protocol === "local" && backends[name].raw && typeof backends[name].raw.rootDir === "string") {
|
|
596
|
+
entry.rootDir = backends[name].raw.rootDir;
|
|
597
|
+
}
|
|
598
|
+
out.push(entry);
|
|
599
|
+
}
|
|
600
|
+
return out;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
function _presign(direction, key, opts) {
|
|
604
|
+
_requireInit();
|
|
605
|
+
if (typeof key !== "string" || key.length === 0) {
|
|
606
|
+
throw _err("INVALID_KEY", "presigned" + direction + "Url: key is required", true);
|
|
607
|
+
}
|
|
608
|
+
opts = opts || {};
|
|
609
|
+
var picked = _pickBackend(opts);
|
|
610
|
+
var fnName = "presigned" + direction + "Url";
|
|
611
|
+
if (typeof picked.backend[fnName] !== "function") {
|
|
612
|
+
throw _err("PRESIGN_NOT_SUPPORTED",
|
|
613
|
+
"backend '" + picked.backend.name + "' (protocol '" + picked.backend.protocol +
|
|
614
|
+
"') does not support presigned " + direction.toLowerCase() + " URLs", true);
|
|
615
|
+
}
|
|
616
|
+
var result = picked.backend[fnName](Object.assign({}, opts, { key: key }));
|
|
617
|
+
_emit("system.storage.presign", {
|
|
618
|
+
metadata: {
|
|
619
|
+
direction: direction.toLowerCase(),
|
|
620
|
+
backend: picked.backend.name,
|
|
621
|
+
classification: picked.classification,
|
|
622
|
+
residencyTag: picked.backend.residencyTag,
|
|
623
|
+
key: key,
|
|
624
|
+
expiresAt: result.expiresAt,
|
|
625
|
+
},
|
|
626
|
+
});
|
|
627
|
+
return result;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* @primitive b.storage.presignedUploadUrl
|
|
632
|
+
* @signature b.storage.presignedUploadUrl(key, opts)
|
|
633
|
+
* @since 0.4.0
|
|
634
|
+
* @status stable
|
|
635
|
+
* @related b.storage.presignedDownloadUrl, b.storage.presignedUploadPolicy
|
|
636
|
+
*
|
|
637
|
+
* Issue a short-lived signed URL the client uses to PUT bytes
|
|
638
|
+
* directly to the object store, bypassing the framework process
|
|
639
|
+
* for the upload bytes. Backend-dependent: sigv4 / gcs / azure-blob
|
|
640
|
+
* support it natively; local / http-put backends throw
|
|
641
|
+
* `PRESIGN_NOT_SUPPORTED`. Emits `system.storage.presign` with
|
|
642
|
+
* `direction: "upload"`.
|
|
643
|
+
*
|
|
644
|
+
* @opts
|
|
645
|
+
* classification: string, // route to a backend serving this classification
|
|
646
|
+
* backend: string, // explicit backend by name
|
|
647
|
+
* expiresInSec: number, // URL lifetime; backend-defaulted when omitted
|
|
648
|
+
* contentType: string, // pin the upload Content-Type into the signature
|
|
649
|
+
*
|
|
650
|
+
* @example
|
|
651
|
+
* b.storage.init({
|
|
652
|
+
* backends: {
|
|
653
|
+
* "us-ops": {
|
|
654
|
+
* protocol: "sigv4",
|
|
655
|
+
* endpoint: "https://s3.us-east-1.amazonaws.com",
|
|
656
|
+
* region: "us-east-1",
|
|
657
|
+
* bucket: "uploads",
|
|
658
|
+
* accessKeyId: "AKIAEXAMPLE",
|
|
659
|
+
* secretAccessKey: "secret",
|
|
660
|
+
* classifications: ["operational"],
|
|
661
|
+
* residencyTag: "US",
|
|
662
|
+
* },
|
|
663
|
+
* },
|
|
664
|
+
* });
|
|
665
|
+
* var presigned = b.storage.presignedUploadUrl("incoming/x.bin", {
|
|
666
|
+
* backend: "us-ops",
|
|
667
|
+
* expiresInSec: 300,
|
|
668
|
+
* });
|
|
669
|
+
* presigned.method; // → "PUT"
|
|
670
|
+
*/
|
|
671
|
+
function presignedUploadUrl(key, opts) { return _presign("Upload", key, opts); }
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* @primitive b.storage.presignedDownloadUrl
|
|
675
|
+
* @signature b.storage.presignedDownloadUrl(key, opts)
|
|
676
|
+
* @since 0.4.0
|
|
677
|
+
* @status stable
|
|
678
|
+
* @related b.storage.presignedUploadUrl, b.storage.getFileBuffer
|
|
679
|
+
*
|
|
680
|
+
* Issue a short-lived signed URL the client uses to GET bytes
|
|
681
|
+
* directly from the object store. Same backend-support matrix as
|
|
682
|
+
* the upload variant. Use this only with `saveRaw` content —
|
|
683
|
+
* encrypted blobs (`saveFile`) need the per-file sealed key, which
|
|
684
|
+
* the framework does not expose to the client.
|
|
685
|
+
*
|
|
686
|
+
* @opts
|
|
687
|
+
* classification: string, // route to a backend serving this classification
|
|
688
|
+
* backend: string, // explicit backend by name
|
|
689
|
+
* expiresInSec: number, // URL lifetime; backend-defaulted when omitted
|
|
690
|
+
* responseHeaders: { // S3 response-header overrides (sigv4 backend)
|
|
691
|
+
* contentDisposition: string, // e.g. 'attachment; filename="invoice.pdf"'
|
|
692
|
+
* contentType: string,
|
|
693
|
+
* contentLanguage: string,
|
|
694
|
+
* contentEncoding: string,
|
|
695
|
+
* cacheControl: string,
|
|
696
|
+
* expires: string,
|
|
697
|
+
* },
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* b.storage.init({
|
|
701
|
+
* backends: {
|
|
702
|
+
* "us-ops": {
|
|
703
|
+
* protocol: "sigv4",
|
|
704
|
+
* endpoint: "https://s3.us-east-1.amazonaws.com",
|
|
705
|
+
* region: "us-east-1",
|
|
706
|
+
* bucket: "uploads",
|
|
707
|
+
* accessKeyId: "AKIAEXAMPLE",
|
|
708
|
+
* secretAccessKey: "secret",
|
|
709
|
+
* classifications: ["public"],
|
|
710
|
+
* residencyTag: "US",
|
|
711
|
+
* },
|
|
712
|
+
* },
|
|
713
|
+
* });
|
|
714
|
+
* var presigned = b.storage.presignedDownloadUrl("public/logo.png", {
|
|
715
|
+
* backend: "us-ops",
|
|
716
|
+
* expiresInSec: 60,
|
|
717
|
+
* responseHeaders: {
|
|
718
|
+
* contentDisposition: 'attachment; filename="logo.png"',
|
|
719
|
+
* },
|
|
720
|
+
* });
|
|
721
|
+
* presigned.method; // → "GET"
|
|
722
|
+
*/
|
|
723
|
+
function presignedDownloadUrl(key, opts) { return _presign("Download", key, opts); }
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* @primitive b.storage.presignedUploadPolicy
|
|
727
|
+
* @signature b.storage.presignedUploadPolicy(key, opts)
|
|
728
|
+
* @since 0.6.0
|
|
729
|
+
* @status stable
|
|
730
|
+
* @related b.storage.presignedUploadUrl, b.fileUpload
|
|
731
|
+
*
|
|
732
|
+
* Issue a signed POST-form policy (sigv4 / gcs) or vendor-equivalent
|
|
733
|
+
* PUT (azure-blob) that the client uploads against, with the body-
|
|
734
|
+
* size cap baked into the signature so an oversize upload is
|
|
735
|
+
* rejected by the object store, not by the framework process. Use
|
|
736
|
+
* this — not `presignedUploadUrl` — when the upload size matters
|
|
737
|
+
* and you can't trust the client. `result.enforcement` indicates
|
|
738
|
+
* whether the cap is server-side (`"server"`) or client-only
|
|
739
|
+
* (`"client-only"` — Azure SAS, where the operator must HEAD the
|
|
740
|
+
* blob post-upload to reject oversize). `local` and `http-put`
|
|
741
|
+
* backends throw `PRESIGN_NOT_SUPPORTED`.
|
|
742
|
+
*
|
|
743
|
+
* @opts
|
|
744
|
+
* classification: string, // route to a backend serving this classification
|
|
745
|
+
* backend: string, // explicit backend by name
|
|
746
|
+
* maxBytes: number, // body-size cap (required for size enforcement)
|
|
747
|
+
* expiresInSec: number, // policy lifetime; backend-defaulted when omitted
|
|
748
|
+
* contentType: string, // pin the upload Content-Type into the policy
|
|
749
|
+
*
|
|
750
|
+
* @example
|
|
751
|
+
* b.storage.init({
|
|
752
|
+
* backends: {
|
|
753
|
+
* "us-ops": {
|
|
754
|
+
* protocol: "sigv4",
|
|
755
|
+
* endpoint: "https://s3.us-east-1.amazonaws.com",
|
|
756
|
+
* region: "us-east-1",
|
|
757
|
+
* bucket: "uploads",
|
|
758
|
+
* accessKeyId: "AKIAEXAMPLE",
|
|
759
|
+
* secretAccessKey: "secret",
|
|
760
|
+
* classifications: ["operational"],
|
|
761
|
+
* residencyTag: "US",
|
|
762
|
+
* },
|
|
763
|
+
* },
|
|
764
|
+
* });
|
|
765
|
+
* var policy = b.storage.presignedUploadPolicy("user/avatar.png", {
|
|
766
|
+
* backend: "us-ops",
|
|
767
|
+
* maxBytes: 5 * 1024 * 1024, // 5 MiB cap, server-enforced
|
|
768
|
+
* expiresInSec: 300,
|
|
769
|
+
* contentType: "image/png",
|
|
770
|
+
* });
|
|
771
|
+
* policy.enforcement; // → "server"
|
|
772
|
+
*/
|
|
773
|
+
function presignedUploadPolicy(key, opts) {
|
|
774
|
+
_requireInit();
|
|
775
|
+
if (typeof key !== "string" || key.length === 0) {
|
|
776
|
+
throw _err("INVALID_KEY", "presignedUploadPolicy: key is required", true);
|
|
777
|
+
}
|
|
778
|
+
opts = opts || {};
|
|
779
|
+
var picked = _pickBackend(opts);
|
|
780
|
+
if (typeof picked.backend.presignedUploadPolicy !== "function") {
|
|
781
|
+
throw _err("PRESIGN_NOT_SUPPORTED",
|
|
782
|
+
"backend '" + picked.backend.name + "' (protocol '" + picked.backend.protocol +
|
|
783
|
+
"') does not support presigned upload policies", true);
|
|
784
|
+
}
|
|
785
|
+
var result = picked.backend.presignedUploadPolicy(Object.assign({}, opts, { key: key }));
|
|
786
|
+
_emit("system.storage.presign", {
|
|
787
|
+
metadata: {
|
|
788
|
+
direction: "upload-policy",
|
|
789
|
+
backend: picked.backend.name,
|
|
790
|
+
classification: picked.classification,
|
|
791
|
+
residencyTag: picked.backend.residencyTag,
|
|
792
|
+
key: key,
|
|
793
|
+
expiresAt: result.expiresAt,
|
|
794
|
+
maxBytes: result.maxBytes,
|
|
795
|
+
enforcement: result.enforcement,
|
|
796
|
+
},
|
|
797
|
+
});
|
|
798
|
+
return result;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* @primitive b.storage.getBackend
|
|
803
|
+
* @signature b.storage.getBackend(name)
|
|
804
|
+
* @since 0.6.0
|
|
805
|
+
* @status stable
|
|
806
|
+
* @related b.storage.listBackends, b.storage.init
|
|
807
|
+
*
|
|
808
|
+
* Return the named backend instance from the underlying
|
|
809
|
+
* `b.objectStore` adapter, or `null` when no backend with that
|
|
810
|
+
* name is registered. Most operator code routes through the
|
|
811
|
+
* dispatching primitives (`saveFile` / `getFileBuffer` / ...);
|
|
812
|
+
* `getBackend` is the escape hatch for adapter-specific operations
|
|
813
|
+
* (lifecycle policy ops, vendor-specific HEAD probes) the
|
|
814
|
+
* framework does not abstract.
|
|
815
|
+
*
|
|
816
|
+
* @example
|
|
817
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
818
|
+
* var backend = b.storage.getBackend("default");
|
|
819
|
+
* backend.protocol; // → "local"
|
|
820
|
+
* var missing = b.storage.getBackend("does-not-exist");
|
|
821
|
+
* // → null
|
|
822
|
+
*/
|
|
823
|
+
function getBackend(name) {
|
|
824
|
+
_requireInit();
|
|
825
|
+
return backends[name] || null;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
function _requireInit() {
|
|
829
|
+
if (!initialized) throw _err("NOT_INITIALIZED", "storage.init() must be called before any file operation", true);
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
// ---- chunk-scratch -------------------------------------------------
|
|
833
|
+
//
|
|
834
|
+
// Resumable-chunked-upload primitive. Operators handling large file
|
|
835
|
+
// uploads (multipart form / tus / S3-multipart-style flow) need to
|
|
836
|
+
// persist incoming chunks during the upload window, then assemble
|
|
837
|
+
// them into a final file when the upload completes. Without a
|
|
838
|
+
// framework primitive every consumer ended up reinventing the
|
|
839
|
+
// per-assembly directory layout + atomic finalize + GC of partial
|
|
840
|
+
// assemblies that never completed.
|
|
841
|
+
//
|
|
842
|
+
// chunkScratch owns:
|
|
843
|
+
// - per-assembly directory layout (sealed in the operator's
|
|
844
|
+
// storage backend just like saveFile)
|
|
845
|
+
// - chunk persistence + retrieval with the framework envelope
|
|
846
|
+
// - assembly metadata tracking createdAt/totalChunks/chunkHashes
|
|
847
|
+
// - atomic concat into the final file (no consumer ever sees a
|
|
848
|
+
// half-assembled file)
|
|
849
|
+
// - GC of stale partial assemblies (operator opts in via gc())
|
|
850
|
+
//
|
|
851
|
+
// Backend is the same `b.storage` backend the operator already
|
|
852
|
+
// configured — chunkScratch routes through it. No new backend
|
|
853
|
+
// concept. The chunk keys are namespaced under
|
|
854
|
+
// `<rootKeyPrefix>/<assemblyId>/<chunkIndex>` so the operator can
|
|
855
|
+
// see them via the backend's existing list/inspect surface.
|
|
856
|
+
//
|
|
857
|
+
// assemblyId is operator-supplied (typically a UUID tied to the
|
|
858
|
+
// upload session). Shape is validated to refuse path-traversal,
|
|
859
|
+
// slash/backslash, NUL/C0/DEL, oversize. The chunkScratch primitive
|
|
860
|
+
// is identity-agnostic — it doesn't know which user owns which
|
|
861
|
+
// assembly; that gate is the operator's surrounding handler.
|
|
862
|
+
|
|
863
|
+
var ASSEMBLY_ID_MAX_LEN = 128;
|
|
864
|
+
var CHUNK_INDEX_MAX = 100000; // allow:raw-byte-literal — chunk-index cap (not bytes, not seconds)
|
|
865
|
+
var CHUNK_BYTES_DEFAULT = C.BYTES.mib(16);
|
|
866
|
+
var STALE_DEFAULT_MS = C.TIME.hours(24);
|
|
867
|
+
|
|
868
|
+
function _stripTrailingSlashes(s) {
|
|
869
|
+
// Linear-time alternative to `.replace(/\/+$/, "")` — CodeQL flags the
|
|
870
|
+
// regex form as polynomial-ReDoS-vulnerable on inputs with many
|
|
871
|
+
// trailing slashes (theoretical here since rootKeyPrefix is operator-
|
|
872
|
+
// supplied at create-time, not request-bound, but using the explicit
|
|
873
|
+
// loop avoids the regex-engine backtracking surface entirely).
|
|
874
|
+
var end = s.length;
|
|
875
|
+
while (end > 0 && s.charCodeAt(end - 1) === 0x2F /* / */) end -= 1;
|
|
876
|
+
return end === s.length ? s : s.slice(0, end);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
function _validateAssemblyId(id) {
|
|
880
|
+
if (typeof id !== "string" || id.length === 0) {
|
|
881
|
+
throw _err("INVALID_ARGUMENT", "chunkScratch: assemblyId must be a non-empty string", true);
|
|
882
|
+
}
|
|
883
|
+
if (id.length > ASSEMBLY_ID_MAX_LEN) {
|
|
884
|
+
throw _err("INVALID_ARGUMENT",
|
|
885
|
+
"chunkScratch: assemblyId exceeds " + ASSEMBLY_ID_MAX_LEN + "-char cap", true);
|
|
886
|
+
}
|
|
887
|
+
for (var i = 0; i < id.length; i += 1) {
|
|
888
|
+
var c = id.charCodeAt(i);
|
|
889
|
+
// Refuse: C0 (0x00-0x1F), DEL (0x7F), slash, backslash, dot-prefix
|
|
890
|
+
if (c < 0x20 || c === 0x2F || c === 0x5C || c === 0x7F) {
|
|
891
|
+
throw _err("INVALID_ARGUMENT",
|
|
892
|
+
"chunkScratch: assemblyId carries forbidden character at byte " + i, true);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
// Refuse path-traversal shapes — operator-supplied ID should be a
|
|
896
|
+
// UUID-shape or opaque session token, not a path.
|
|
897
|
+
if (id.indexOf("..") !== -1 || id.charAt(0) === ".") {
|
|
898
|
+
throw _err("INVALID_ARGUMENT",
|
|
899
|
+
"chunkScratch: assemblyId carries path-traversal shape", true);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
function _validateChunkIndex(idx) {
|
|
904
|
+
if (typeof idx !== "number" || !Number.isInteger(idx) || idx < 0) {
|
|
905
|
+
throw _err("INVALID_ARGUMENT",
|
|
906
|
+
"chunkScratch: chunkIndex must be a non-negative integer", true);
|
|
907
|
+
}
|
|
908
|
+
if (idx >= CHUNK_INDEX_MAX) {
|
|
909
|
+
throw _err("INVALID_ARGUMENT",
|
|
910
|
+
"chunkScratch: chunkIndex exceeds cap " + CHUNK_INDEX_MAX, true);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
* @primitive b.storage.chunkScratch
|
|
916
|
+
* @signature b.storage.chunkScratch(opts?)
|
|
917
|
+
* @since 0.9.44
|
|
918
|
+
* @status stable
|
|
919
|
+
* @related b.storage.saveFile, b.storage.getFileBuffer
|
|
920
|
+
*
|
|
921
|
+
* Resumable-chunked-upload primitive. Persists incoming upload chunks
|
|
922
|
+
* during the upload window + atomically assembles them into the
|
|
923
|
+
* final file on completion. Owns per-assembly directory layout,
|
|
924
|
+
* envelope-encrypted chunk persistence, atomic finalize, and GC of
|
|
925
|
+
* partial assemblies.
|
|
926
|
+
*
|
|
927
|
+
* Composes existing primitives: each chunk routes through
|
|
928
|
+
* `b.storage.saveFile` (same XChaCha20-Poly1305 envelope as the
|
|
929
|
+
* non-chunked surface), assembly reads through `getFileBuffer`,
|
|
930
|
+
* deletion through `deleteFile`. No new crypto.
|
|
931
|
+
*
|
|
932
|
+
* Prior art / wire-protocol references:
|
|
933
|
+
* - tus.io v1.0.0 protocol (Termination + Creation + Concatenation
|
|
934
|
+
* extensions) — operator-facing HTTP shape that ships chunks
|
|
935
|
+
* against a server-side assembly. This primitive is the
|
|
936
|
+
* server-side persistence the tus protocol's upload handler
|
|
937
|
+
* consumes.
|
|
938
|
+
* - RFC 9110 §14.4 Content-Range — the wire-protocol header that
|
|
939
|
+
* PUT/PATCH-based resumable uploads use to declare each chunk's
|
|
940
|
+
* byte-range within the assembly.
|
|
941
|
+
* - draft-ietf-httpbis-resumable-upload-08 — IETF working-draft
|
|
942
|
+
* resumable-upload protocol; this primitive's surface mirrors
|
|
943
|
+
* its server-side state requirements.
|
|
944
|
+
* - AWS S3 Multipart Upload — the cloud-vendor analogue;
|
|
945
|
+
* `saveChunk` / `assemble` are the framework's local equivalents
|
|
946
|
+
* of UploadPart / CompleteMultipartUpload.
|
|
947
|
+
*
|
|
948
|
+
* Threat-model coverage:
|
|
949
|
+
* - Path-traversal in upload paths (CVE-2018-1000656 class) —
|
|
950
|
+
* `assemblyId` is validated to refuse `..`, `/`, `\`, NUL / C0
|
|
951
|
+
* controls, DEL, dot-prefix, and oversize. A hostile client
|
|
952
|
+
* can't escape the rootKeyPrefix namespace.
|
|
953
|
+
* - Chunk-out-of-order replay / TOCTOU between saveChunk and
|
|
954
|
+
* assemble — `assemble` verifies monotonic 0..N-1 indices and
|
|
955
|
+
* refuses on gaps; a chunk inserted out-of-order can't be
|
|
956
|
+
* surfaced as a valid assembly.
|
|
957
|
+
* - Storage exhaustion from abandoned uploads — `gc({ olderThanMs })`
|
|
958
|
+
* prunes stale assemblies; operator wires it on a schedule.
|
|
959
|
+
* - AEAD context-binding — each chunk's encryption envelope is
|
|
960
|
+
* keyed independently; an attacker who guesses one chunk's key
|
|
961
|
+
* can't decrypt other chunks in the same assembly (the
|
|
962
|
+
* XChaCha20-Poly1305 keys are framework-vault-derived per-call).
|
|
963
|
+
*
|
|
964
|
+
* assemblyId shape is validated to refuse path-traversal, control
|
|
965
|
+
* chars, and oversize at every entry point.
|
|
966
|
+
*
|
|
967
|
+
* @opts
|
|
968
|
+
* rootKeyPrefix: string, // default "chunk-scratch" — namespace under the backend
|
|
969
|
+
* backend: string, // explicit backend by name (default: framework default)
|
|
970
|
+
* maxChunkBytes: number, // default 16 MiB — per-chunk cap
|
|
971
|
+
* staleAfterMs: number, // default 24h — assemblies idle longer get GC'd
|
|
972
|
+
*
|
|
973
|
+
* @example
|
|
974
|
+
* b.storage.init({ backend: "local", uploadDir: "./data/uploads" });
|
|
975
|
+
* var cs = b.storage.chunkScratch({ rootKeyPrefix: "uploads/scratch" });
|
|
976
|
+
*
|
|
977
|
+
* // During upload — each PUT lands one chunk
|
|
978
|
+
* await cs.saveChunk({ assemblyId: "upload-abc", chunkIndex: 0, data: chunk0 });
|
|
979
|
+
* await cs.saveChunk({ assemblyId: "upload-abc", chunkIndex: 1, data: chunk1 });
|
|
980
|
+
* await cs.saveChunk({ assemblyId: "upload-abc", chunkIndex: 2, data: chunk2 });
|
|
981
|
+
*
|
|
982
|
+
* // On completion — atomic assemble + cleanup
|
|
983
|
+
* var assembled = await cs.assemble({ assemblyId: "upload-abc", expectedTotal: 3 });
|
|
984
|
+
* await cs.removeAssembly("upload-abc");
|
|
985
|
+
*
|
|
986
|
+
* // Periodic GC of partial uploads abandoned mid-stream
|
|
987
|
+
* var removed = await cs.gc({ olderThanMs: 86400000 });
|
|
988
|
+
*/
|
|
989
|
+
function chunkScratch(opts) {
|
|
990
|
+
_requireInit();
|
|
991
|
+
opts = opts || {};
|
|
992
|
+
var rootKeyPrefix = typeof opts.rootKeyPrefix === "string" && opts.rootKeyPrefix.length > 0
|
|
993
|
+
? _stripTrailingSlashes(opts.rootKeyPrefix)
|
|
994
|
+
: "chunk-scratch";
|
|
995
|
+
numericBounds.requirePositiveFiniteIntIfPresent(
|
|
996
|
+
opts.maxChunkBytes, "chunkScratch.maxChunkBytes", StorageError, "INVALID_ARGUMENT");
|
|
997
|
+
numericBounds.requirePositiveFiniteIntIfPresent(
|
|
998
|
+
opts.staleAfterMs, "chunkScratch.staleAfterMs", StorageError, "INVALID_ARGUMENT");
|
|
999
|
+
var maxChunkBytes = opts.maxChunkBytes !== undefined ? opts.maxChunkBytes : CHUNK_BYTES_DEFAULT;
|
|
1000
|
+
var staleAfterMs = opts.staleAfterMs !== undefined ? opts.staleAfterMs : STALE_DEFAULT_MS;
|
|
1001
|
+
var backendOverride = opts.backend;
|
|
1002
|
+
|
|
1003
|
+
function _chunkKey(assemblyId, chunkIndex) {
|
|
1004
|
+
return rootKeyPrefix + "/" + assemblyId + "/" + String(chunkIndex).padStart(8, "0") + ".chunk"; // allow:raw-byte-literal — 8-digit zero-pad covers CHUNK_INDEX_MAX
|
|
1005
|
+
}
|
|
1006
|
+
function _pickOpts() {
|
|
1007
|
+
return backendOverride ? { backend: backendOverride } : {};
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
async function saveChunk(args) {
|
|
1011
|
+
if (!args || typeof args !== "object") {
|
|
1012
|
+
throw _err("INVALID_ARGUMENT", "chunkScratch.saveChunk: args must be an object", true);
|
|
1013
|
+
}
|
|
1014
|
+
_validateAssemblyId(args.assemblyId);
|
|
1015
|
+
_validateChunkIndex(args.chunkIndex);
|
|
1016
|
+
if (!Buffer.isBuffer(args.data)) {
|
|
1017
|
+
throw _err("INVALID_ARGUMENT", "chunkScratch.saveChunk: data must be a Buffer", true);
|
|
1018
|
+
}
|
|
1019
|
+
if (args.data.length > maxChunkBytes) {
|
|
1020
|
+
throw _err("INVALID_ARGUMENT",
|
|
1021
|
+
"chunkScratch.saveChunk: chunk exceeds maxChunkBytes (" + args.data.length + " > " + maxChunkBytes + ")", true);
|
|
1022
|
+
}
|
|
1023
|
+
var saved = await saveFile(args.data, _chunkKey(args.assemblyId, args.chunkIndex), _pickOpts());
|
|
1024
|
+
_emit("system.storage.chunk_scratch.chunk_saved", {
|
|
1025
|
+
metadata: {
|
|
1026
|
+
assemblyId: args.assemblyId,
|
|
1027
|
+
chunkIndex: args.chunkIndex,
|
|
1028
|
+
sizeBytes: args.data.length,
|
|
1029
|
+
backend: saved.backend,
|
|
1030
|
+
},
|
|
1031
|
+
});
|
|
1032
|
+
return { encryptionKey: saved.encryptionKey, sizeBytes: args.data.length };
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
async function getChunk(args) {
|
|
1036
|
+
if (!args || typeof args !== "object") {
|
|
1037
|
+
throw _err("INVALID_ARGUMENT", "chunkScratch.getChunk: args must be an object", true);
|
|
1038
|
+
}
|
|
1039
|
+
_validateAssemblyId(args.assemblyId);
|
|
1040
|
+
_validateChunkIndex(args.chunkIndex);
|
|
1041
|
+
if (typeof args.encryptionKey !== "string" || args.encryptionKey.length === 0) {
|
|
1042
|
+
throw _err("INVALID_ARGUMENT", "chunkScratch.getChunk: encryptionKey required", true);
|
|
1043
|
+
}
|
|
1044
|
+
return getFileBuffer(_chunkKey(args.assemblyId, args.chunkIndex),
|
|
1045
|
+
args.encryptionKey, _pickOpts());
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
async function chunkExists(args) {
|
|
1049
|
+
_validateAssemblyId(args.assemblyId);
|
|
1050
|
+
_validateChunkIndex(args.chunkIndex);
|
|
1051
|
+
return exists(_chunkKey(args.assemblyId, args.chunkIndex), _pickOpts());
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
async function listChunks(assemblyId) {
|
|
1055
|
+
_validateAssemblyId(assemblyId);
|
|
1056
|
+
var picked = _pickBackend(_pickOpts());
|
|
1057
|
+
if (typeof picked.backend.list !== "function") {
|
|
1058
|
+
throw _err("UNSUPPORTED",
|
|
1059
|
+
"chunkScratch.listChunks: backend '" + picked.backend.name + "' does not implement list()", true);
|
|
1060
|
+
}
|
|
1061
|
+
var prefix = rootKeyPrefix + "/" + assemblyId + "/";
|
|
1062
|
+
var listRes = await picked.backend.list(prefix);
|
|
1063
|
+
var items = listRes && Array.isArray(listRes.items) ? listRes.items
|
|
1064
|
+
: Array.isArray(listRes) ? listRes : [];
|
|
1065
|
+
var indices = [];
|
|
1066
|
+
for (var i = 0; i < items.length; i += 1) {
|
|
1067
|
+
// Backends return either { key, size, lastModified } objects
|
|
1068
|
+
// (local + S3 + GCS) or bare key strings. Normalize.
|
|
1069
|
+
var item = items[i];
|
|
1070
|
+
var rawKey = typeof item === "string" ? item : item && item.key;
|
|
1071
|
+
if (typeof rawKey !== "string") continue;
|
|
1072
|
+
// The local backend's `list(prefix)` returns keys relative to
|
|
1073
|
+
// the prefix; cloud backends return absolute keys. Normalize
|
|
1074
|
+
// by stripping the prefix when present.
|
|
1075
|
+
var base = rawKey.indexOf(prefix) === 0 ? rawKey.slice(prefix.length) : rawKey;
|
|
1076
|
+
if (base === ".meta" || base.indexOf("/") !== -1) continue;
|
|
1077
|
+
if (!/^[0-9]{1,8}\.chunk$/.test(base)) continue;
|
|
1078
|
+
indices.push(parseInt(base.slice(0, -6), 10));
|
|
1079
|
+
}
|
|
1080
|
+
indices.sort(function (a, b) { return a - b; });
|
|
1081
|
+
return indices;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
async function countChunks(assemblyId) {
|
|
1085
|
+
var indices = await listChunks(assemblyId);
|
|
1086
|
+
return indices.length;
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
async function removeChunk(args) {
|
|
1090
|
+
_validateAssemblyId(args.assemblyId);
|
|
1091
|
+
_validateChunkIndex(args.chunkIndex);
|
|
1092
|
+
return deleteFile(_chunkKey(args.assemblyId, args.chunkIndex), _pickOpts());
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
async function assemble(args) {
|
|
1096
|
+
if (!args || typeof args !== "object") {
|
|
1097
|
+
throw _err("INVALID_ARGUMENT", "chunkScratch.assemble: args must be an object", true);
|
|
1098
|
+
}
|
|
1099
|
+
_validateAssemblyId(args.assemblyId);
|
|
1100
|
+
if (!Array.isArray(args.chunkEncryptionKeys) || args.chunkEncryptionKeys.length === 0) {
|
|
1101
|
+
throw _err("INVALID_ARGUMENT",
|
|
1102
|
+
"chunkScratch.assemble: chunkEncryptionKeys must be a non-empty array (one per chunk in order)", true);
|
|
1103
|
+
}
|
|
1104
|
+
var indices = await listChunks(args.assemblyId);
|
|
1105
|
+
if (typeof args.expectedTotal === "number" && indices.length !== args.expectedTotal) {
|
|
1106
|
+
throw _err("INCOMPLETE_ASSEMBLY",
|
|
1107
|
+
"chunkScratch.assemble: have " + indices.length + " chunks; expected " + args.expectedTotal, true);
|
|
1108
|
+
}
|
|
1109
|
+
if (indices.length !== args.chunkEncryptionKeys.length) {
|
|
1110
|
+
throw _err("INVALID_ARGUMENT",
|
|
1111
|
+
"chunkScratch.assemble: chunkEncryptionKeys.length (" + args.chunkEncryptionKeys.length +
|
|
1112
|
+
") must match chunk count (" + indices.length + ")", true);
|
|
1113
|
+
}
|
|
1114
|
+
// Verify monotonic 0..N-1 indices — no gaps.
|
|
1115
|
+
for (var i = 0; i < indices.length; i += 1) {
|
|
1116
|
+
if (indices[i] !== i) {
|
|
1117
|
+
throw _err("INCOMPLETE_ASSEMBLY",
|
|
1118
|
+
"chunkScratch.assemble: chunk gap at index " + i + " (found " + indices[i] + ")", true);
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
// Concatenate in order. Each chunk decrypts via its own envelope
|
|
1122
|
+
// key; the operator persisted the per-chunk key when saveChunk
|
|
1123
|
+
// returned it.
|
|
1124
|
+
var parts = [];
|
|
1125
|
+
var totalBytes = 0;
|
|
1126
|
+
for (var c = 0; c < indices.length; c += 1) {
|
|
1127
|
+
var buf = await getChunk({
|
|
1128
|
+
assemblyId: args.assemblyId,
|
|
1129
|
+
chunkIndex: c,
|
|
1130
|
+
encryptionKey: args.chunkEncryptionKeys[c],
|
|
1131
|
+
});
|
|
1132
|
+
parts.push(buf);
|
|
1133
|
+
totalBytes += buf.length;
|
|
1134
|
+
}
|
|
1135
|
+
_emit("system.storage.chunk_scratch.assembled", {
|
|
1136
|
+
metadata: {
|
|
1137
|
+
assemblyId: args.assemblyId,
|
|
1138
|
+
chunkCount: indices.length,
|
|
1139
|
+
sizeBytes: totalBytes,
|
|
1140
|
+
},
|
|
1141
|
+
});
|
|
1142
|
+
return Buffer.concat(parts, totalBytes);
|
|
1143
|
+
}
|
|
1144
|
+
|
|
1145
|
+
async function removeAssembly(assemblyId) {
|
|
1146
|
+
_validateAssemblyId(assemblyId);
|
|
1147
|
+
var indices = await listChunks(assemblyId);
|
|
1148
|
+
var removed = 0;
|
|
1149
|
+
for (var i = 0; i < indices.length; i += 1) {
|
|
1150
|
+
try { await removeChunk({ assemblyId: assemblyId, chunkIndex: indices[i] }); removed += 1; }
|
|
1151
|
+
catch (_e) { /* best-effort */ }
|
|
1152
|
+
}
|
|
1153
|
+
_emit("system.storage.chunk_scratch.removed", {
|
|
1154
|
+
metadata: { assemblyId: assemblyId, chunksRemoved: removed },
|
|
1155
|
+
});
|
|
1156
|
+
return { chunksRemoved: removed };
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
async function listAssemblies() {
|
|
1160
|
+
var picked = _pickBackend(_pickOpts());
|
|
1161
|
+
if (typeof picked.backend.list !== "function") {
|
|
1162
|
+
throw _err("UNSUPPORTED",
|
|
1163
|
+
"chunkScratch.listAssemblies: backend '" + picked.backend.name + "' does not implement list()", true);
|
|
1164
|
+
}
|
|
1165
|
+
var listRes = await picked.backend.list(rootKeyPrefix + "/");
|
|
1166
|
+
var items = listRes && Array.isArray(listRes.items) ? listRes.items
|
|
1167
|
+
: Array.isArray(listRes) ? listRes : [];
|
|
1168
|
+
var ids = {};
|
|
1169
|
+
var prefixWithSlash = rootKeyPrefix + "/";
|
|
1170
|
+
for (var i = 0; i < items.length; i += 1) {
|
|
1171
|
+
var item = items[i];
|
|
1172
|
+
var rawKey = typeof item === "string" ? item : item && item.key;
|
|
1173
|
+
if (typeof rawKey !== "string") continue;
|
|
1174
|
+
var rel = rawKey.indexOf(prefixWithSlash) === 0
|
|
1175
|
+
? rawKey.slice(prefixWithSlash.length) : rawKey;
|
|
1176
|
+
var slash = rel.indexOf("/");
|
|
1177
|
+
if (slash === -1) continue;
|
|
1178
|
+
ids[rel.slice(0, slash)] = true;
|
|
1179
|
+
}
|
|
1180
|
+
return canonicalJson.sortKeys(ids);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
async function listStaleAssemblies(args) {
|
|
1184
|
+
args = args || {};
|
|
1185
|
+
var olderThan = (typeof args.olderThanMs === "number" && args.olderThanMs > 0)
|
|
1186
|
+
? args.olderThanMs : staleAfterMs;
|
|
1187
|
+
var cutoff = Date.now() - olderThan;
|
|
1188
|
+
var picked = _pickBackend(_pickOpts());
|
|
1189
|
+
if (typeof picked.backend.list !== "function") {
|
|
1190
|
+
throw _err("UNSUPPORTED",
|
|
1191
|
+
"chunkScratch.listStaleAssemblies: backend does not implement list()", true);
|
|
1192
|
+
}
|
|
1193
|
+
var assemblies = await listAssemblies();
|
|
1194
|
+
var stale = [];
|
|
1195
|
+
for (var i = 0; i < assemblies.length; i += 1) {
|
|
1196
|
+
var assemblyId = assemblies[i];
|
|
1197
|
+
// Use the earliest chunk's mtime as the assembly's createdAt
|
|
1198
|
+
// proxy. Backends that surface mtime via list() inspect items;
|
|
1199
|
+
// others fall through to a stat probe on the first chunk.
|
|
1200
|
+
var indices = await listChunks(assemblyId);
|
|
1201
|
+
if (indices.length === 0) { stale.push(assemblyId); continue; }
|
|
1202
|
+
var firstKey = _chunkKey(assemblyId, indices[0]);
|
|
1203
|
+
var stat = null;
|
|
1204
|
+
if (typeof picked.backend.stat === "function") {
|
|
1205
|
+
try { stat = await picked.backend.stat(firstKey); } catch (_e) { stat = null; }
|
|
1206
|
+
}
|
|
1207
|
+
var mtime = stat && (stat.mtimeMs || (stat.mtime && stat.mtime.getTime && stat.mtime.getTime()));
|
|
1208
|
+
if (typeof mtime === "number" && mtime < cutoff) {
|
|
1209
|
+
stale.push(assemblyId);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return stale;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
async function gc(args) {
|
|
1216
|
+
args = args || {};
|
|
1217
|
+
var stale = await listStaleAssemblies({ olderThanMs: args.olderThanMs });
|
|
1218
|
+
var removed = [];
|
|
1219
|
+
for (var i = 0; i < stale.length; i += 1) {
|
|
1220
|
+
try {
|
|
1221
|
+
var r = await removeAssembly(stale[i]);
|
|
1222
|
+
removed.push({ assemblyId: stale[i], chunksRemoved: r.chunksRemoved });
|
|
1223
|
+
} catch (_e) { /* best-effort GC */ }
|
|
1224
|
+
}
|
|
1225
|
+
_emit("system.storage.chunk_scratch.gc", {
|
|
1226
|
+
metadata: { staleCount: stale.length, removedCount: removed.length },
|
|
1227
|
+
});
|
|
1228
|
+
return { removed: removed };
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
return {
|
|
1232
|
+
saveChunk: saveChunk,
|
|
1233
|
+
getChunk: getChunk,
|
|
1234
|
+
chunkExists: chunkExists,
|
|
1235
|
+
listChunks: listChunks,
|
|
1236
|
+
countChunks: countChunks,
|
|
1237
|
+
removeChunk: removeChunk,
|
|
1238
|
+
assemble: assemble,
|
|
1239
|
+
removeAssembly: removeAssembly,
|
|
1240
|
+
listAssemblies: listAssemblies,
|
|
1241
|
+
listStaleAssemblies: listStaleAssemblies,
|
|
1242
|
+
gc: gc,
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
function _resetForTest() {
|
|
1247
|
+
initialized = false;
|
|
1248
|
+
backends = {};
|
|
1249
|
+
defaultClassification = null;
|
|
1250
|
+
refuseUnclassified = false;
|
|
1251
|
+
vault.reset();
|
|
1252
|
+
audit.reset();
|
|
1253
|
+
db.reset();
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
module.exports = {
|
|
1257
|
+
init: init,
|
|
1258
|
+
saveFile: saveFile,
|
|
1259
|
+
getFileBuffer: getFileBuffer,
|
|
1260
|
+
getFileStream: getFileStream,
|
|
1261
|
+
saveRaw: saveRaw,
|
|
1262
|
+
getRawBuffer: getRawBuffer,
|
|
1263
|
+
deleteFile: deleteFile,
|
|
1264
|
+
exists: exists,
|
|
1265
|
+
presignedUploadUrl: presignedUploadUrl,
|
|
1266
|
+
presignedDownloadUrl: presignedDownloadUrl,
|
|
1267
|
+
presignedUploadPolicy: presignedUploadPolicy,
|
|
1268
|
+
listBackends: listBackends,
|
|
1269
|
+
getBackend: getBackend,
|
|
1270
|
+
chunkScratch: chunkScratch,
|
|
1271
|
+
_resetForTest: _resetForTest,
|
|
1272
|
+
};
|