@blamejs/blamejs-shop 0.5.12 → 0.5.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/lib/asset-manifest.json +1 -1
- package/lib/vendor/MANIFEST.json +632 -416
- package/lib/vendor/blamejs/.clusterfuzzlite/Dockerfile +21 -10
- package/lib/vendor/blamejs/.clusterfuzzlite/build.sh +30 -9
- package/lib/vendor/blamejs/.github/dependabot.yml +8 -0
- package/lib/vendor/blamejs/.github/workflows/actions-lint.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/cflite_batch.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/cflite_pr.yml +7 -2
- package/lib/vendor/blamejs/.github/workflows/ci.yml +21 -21
- package/lib/vendor/blamejs/.github/workflows/codeql.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/npm-publish.yml +4 -4
- package/lib/vendor/blamejs/.github/workflows/release-container.yml +7 -7
- package/lib/vendor/blamejs/.github/workflows/scorecard.yml +3 -3
- package/lib/vendor/blamejs/.github/workflows/sha-to-tag-verify.yml +1 -1
- package/lib/vendor/blamejs/.gitignore +2 -0
- package/lib/vendor/blamejs/CHANGELOG.md +122 -0
- package/lib/vendor/blamejs/NOTICE +26 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -1
- package/lib/vendor/blamejs/api-snapshot.json +207 -5
- package/lib/vendor/blamejs/docker/keycloak/realm-blamejs-test.json +29 -0
- package/lib/vendor/blamejs/examples/wiki/DEPLOY.md +1 -0
- package/lib/vendor/blamejs/examples/wiki/lib/build-app.js +31 -0
- package/lib/vendor/blamejs/examples/wiki/lib/source-comment-block-validator.js +109 -0
- package/lib/vendor/blamejs/examples/wiki/nginx.conf +106 -0
- package/lib/vendor/blamejs/examples/wiki/package-lock.json +1 -1
- package/lib/vendor/blamejs/examples/wiki/test/e2e.js +92 -0
- package/lib/vendor/blamejs/fuzz/asn1-der.fuzz.js +28 -0
- package/lib/vendor/blamejs/fuzz/cms-codec.fuzz.js +17 -0
- package/lib/vendor/blamejs/fuzz/link-header.fuzz.js +18 -0
- package/lib/vendor/blamejs/index.js +6 -0
- package/lib/vendor/blamejs/lib/a2a.js +4 -4
- package/lib/vendor/blamejs/lib/agent-idempotency.js +18 -2
- package/lib/vendor/blamejs/lib/agent-saga.js +36 -8
- package/lib/vendor/blamejs/lib/agent-snapshot.js +63 -6
- package/lib/vendor/blamejs/lib/app-shutdown.js +23 -20
- package/lib/vendor/blamejs/lib/archive-read.js +8 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +12 -2
- package/lib/vendor/blamejs/lib/arg-parser.js +49 -5
- package/lib/vendor/blamejs/lib/asn1-der.js +12 -0
- package/lib/vendor/blamejs/lib/audit-sign.js +47 -1
- package/lib/vendor/blamejs/lib/audit.js +71 -8
- package/lib/vendor/blamejs/lib/auth/ciba.js +14 -2
- package/lib/vendor/blamejs/lib/auth/fido-mds3.js +58 -47
- package/lib/vendor/blamejs/lib/auth/jwt.js +34 -0
- package/lib/vendor/blamejs/lib/auth/oauth.js +90 -13
- package/lib/vendor/blamejs/lib/auth/oid4vci.js +20 -17
- package/lib/vendor/blamejs/lib/auth/openid-federation.js +214 -23
- package/lib/vendor/blamejs/lib/auth/saml.js +38 -20
- package/lib/vendor/blamejs/lib/auth/sd-jwt-vc.js +10 -4
- package/lib/vendor/blamejs/lib/backup/bundle.js +13 -3
- package/lib/vendor/blamejs/lib/backup/index.js +16 -5
- package/lib/vendor/blamejs/lib/backup/manifest.js +18 -5
- package/lib/vendor/blamejs/lib/base32.js +21 -0
- package/lib/vendor/blamejs/lib/break-glass.js +19 -10
- package/lib/vendor/blamejs/lib/bundler.js +5 -1
- package/lib/vendor/blamejs/lib/cache-status.js +3 -7
- package/lib/vendor/blamejs/lib/calendar.js +21 -1
- package/lib/vendor/blamejs/lib/cbor.js +12 -1
- package/lib/vendor/blamejs/lib/cert.js +29 -11
- package/lib/vendor/blamejs/lib/cli.js +94 -24
- package/lib/vendor/blamejs/lib/cloud-events.js +2 -2
- package/lib/vendor/blamejs/lib/cluster-provider-db.js +13 -3
- package/lib/vendor/blamejs/lib/codepoint-class.js +85 -0
- package/lib/vendor/blamejs/lib/compliance-ai-act-prohibited.js +8 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act-transparency.js +19 -4
- package/lib/vendor/blamejs/lib/compliance-ai-act.js +6 -8
- package/lib/vendor/blamejs/lib/content-credentials.js +1 -1
- package/lib/vendor/blamejs/lib/content-digest.js +2 -1
- package/lib/vendor/blamejs/lib/cookies.js +13 -3
- package/lib/vendor/blamejs/lib/cose.js +31 -16
- package/lib/vendor/blamejs/lib/crypto-field.js +32 -0
- package/lib/vendor/blamejs/lib/crypto-oprf.js +11 -2
- package/lib/vendor/blamejs/lib/crypto-xwing.js +22 -4
- package/lib/vendor/blamejs/lib/crypto.js +314 -19
- package/lib/vendor/blamejs/lib/csp.js +11 -3
- package/lib/vendor/blamejs/lib/daemon.js +270 -24
- package/lib/vendor/blamejs/lib/dark-patterns.js +5 -2
- package/lib/vendor/blamejs/lib/db-declare-view.js +2 -2
- package/lib/vendor/blamejs/lib/db-query.js +34 -7
- package/lib/vendor/blamejs/lib/db.js +18 -6
- package/lib/vendor/blamejs/lib/dbsc.js +17 -0
- package/lib/vendor/blamejs/lib/dev.js +21 -2
- package/lib/vendor/blamejs/lib/dsr.js +157 -102
- package/lib/vendor/blamejs/lib/external-db.js +41 -2
- package/lib/vendor/blamejs/lib/file-upload.js +25 -7
- package/lib/vendor/blamejs/lib/flag-providers.js +27 -15
- package/lib/vendor/blamejs/lib/forms.js +113 -27
- package/lib/vendor/blamejs/lib/gate-contract.js +23 -10
- package/lib/vendor/blamejs/lib/gdpr-ropa.js +8 -1
- package/lib/vendor/blamejs/lib/guard-agent-registry.js +1 -1
- package/lib/vendor/blamejs/lib/guard-archive.js +2 -2
- package/lib/vendor/blamejs/lib/guard-cidr.js +27 -1
- package/lib/vendor/blamejs/lib/guard-graphql.js +30 -11
- package/lib/vendor/blamejs/lib/guard-html.js +26 -53
- package/lib/vendor/blamejs/lib/guard-image.js +24 -5
- package/lib/vendor/blamejs/lib/guard-imap-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-jmap.js +19 -3
- package/lib/vendor/blamejs/lib/guard-jwt.js +18 -2
- package/lib/vendor/blamejs/lib/guard-list-unsubscribe.js +2 -2
- package/lib/vendor/blamejs/lib/guard-managesieve-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-markdown.js +11 -24
- package/lib/vendor/blamejs/lib/guard-pdf.js +18 -2
- package/lib/vendor/blamejs/lib/guard-pop3-command.js +10 -2
- package/lib/vendor/blamejs/lib/guard-regex.js +8 -5
- package/lib/vendor/blamejs/lib/guard-svg.js +31 -32
- package/lib/vendor/blamejs/lib/guard-time.js +1 -1
- package/lib/vendor/blamejs/lib/guard-uuid.js +2 -2
- package/lib/vendor/blamejs/lib/html-balance.js +3 -3
- package/lib/vendor/blamejs/lib/http-client-cache.js +82 -4
- package/lib/vendor/blamejs/lib/http-client-cookie-jar.js +16 -1
- package/lib/vendor/blamejs/lib/http-client.js +39 -7
- package/lib/vendor/blamejs/lib/http-message-signature.js +35 -1
- package/lib/vendor/blamejs/lib/i18n-messageformat.js +31 -6
- package/lib/vendor/blamejs/lib/i18n.js +35 -21
- package/lib/vendor/blamejs/lib/incident-report.js +8 -1
- package/lib/vendor/blamejs/lib/ip-utils.js +11 -1
- package/lib/vendor/blamejs/lib/json-path.js +23 -1
- package/lib/vendor/blamejs/lib/jwk.js +20 -3
- package/lib/vendor/blamejs/lib/link-header.js +2 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp-grpc.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream-otlp.js +5 -1
- package/lib/vendor/blamejs/lib/log-stream.js +8 -3
- package/lib/vendor/blamejs/lib/mail-auth.js +123 -22
- package/lib/vendor/blamejs/lib/mail-bimi.js +1 -1
- package/lib/vendor/blamejs/lib/mail-bounce.js +8 -0
- package/lib/vendor/blamejs/lib/mail-crypto-pgp.js +46 -10
- package/lib/vendor/blamejs/lib/mail-dav.js +22 -3
- package/lib/vendor/blamejs/lib/mail-dkim.js +96 -30
- package/lib/vendor/blamejs/lib/mail-helo.js +6 -1
- package/lib/vendor/blamejs/lib/mail-scan.js +23 -16
- package/lib/vendor/blamejs/lib/mail-send-deliver.js +34 -8
- package/lib/vendor/blamejs/lib/mail-server-imap.js +3 -4
- package/lib/vendor/blamejs/lib/mail-server-managesieve.js +7 -11
- package/lib/vendor/blamejs/lib/mail-server-mx.js +93 -7
- package/lib/vendor/blamejs/lib/mail-server-registry.js +8 -2
- package/lib/vendor/blamejs/lib/mail.js +15 -5
- package/lib/vendor/blamejs/lib/metrics.js +268 -63
- package/lib/vendor/blamejs/lib/middleware/age-gate.js +7 -1
- package/lib/vendor/blamejs/lib/middleware/asyncapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/body-parser.js +19 -4
- package/lib/vendor/blamejs/lib/middleware/bot-guard.js +5 -9
- package/lib/vendor/blamejs/lib/middleware/csp-report.js +40 -8
- package/lib/vendor/blamejs/lib/middleware/csrf-protect.js +24 -10
- package/lib/vendor/blamejs/lib/middleware/dpop.js +10 -5
- package/lib/vendor/blamejs/lib/middleware/index.js +6 -1
- package/lib/vendor/blamejs/lib/middleware/nel.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/openapi-serve.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/rate-limit.js +12 -1
- package/lib/vendor/blamejs/lib/middleware/require-bound-key.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/scim-server.js +1 -1
- package/lib/vendor/blamejs/lib/middleware/tus-upload.js +6 -2
- package/lib/vendor/blamejs/lib/mtls-ca.js +18 -2
- package/lib/vendor/blamejs/lib/network-dns-resolver.js +11 -1
- package/lib/vendor/blamejs/lib/network-dns.js +21 -2
- package/lib/vendor/blamejs/lib/network-tls.js +69 -7
- package/lib/vendor/blamejs/lib/nonce-store.js +9 -1
- package/lib/vendor/blamejs/lib/object-store/gcs.js +7 -0
- package/lib/vendor/blamejs/lib/object-store/sigv4.js +31 -0
- package/lib/vendor/blamejs/lib/observability-otlp-exporter.js +1 -1
- package/lib/vendor/blamejs/lib/outbox.js +1 -1
- package/lib/vendor/blamejs/lib/parsers/safe-ini.js +9 -1
- package/lib/vendor/blamejs/lib/parsers/safe-toml.js +10 -1
- package/lib/vendor/blamejs/lib/permissions.js +6 -3
- package/lib/vendor/blamejs/lib/pid-probe.js +55 -0
- package/lib/vendor/blamejs/lib/pqc-agent.js +8 -1
- package/lib/vendor/blamejs/lib/pqc-software.js +3 -3
- package/lib/vendor/blamejs/lib/pubsub.js +20 -9
- package/lib/vendor/blamejs/lib/queue-local.js +8 -1
- package/lib/vendor/blamejs/lib/queue-redis.js +5 -0
- package/lib/vendor/blamejs/lib/redact.js +54 -0
- package/lib/vendor/blamejs/lib/restore-bundle.js +10 -2
- package/lib/vendor/blamejs/lib/restore.js +19 -0
- package/lib/vendor/blamejs/lib/retention.js +12 -4
- package/lib/vendor/blamejs/lib/router.js +60 -6
- package/lib/vendor/blamejs/lib/safe-buffer.js +69 -0
- package/lib/vendor/blamejs/lib/safe-decompress.js +8 -2
- package/lib/vendor/blamejs/lib/safe-dns.js +25 -20
- package/lib/vendor/blamejs/lib/safe-ical.js +7 -3
- package/lib/vendor/blamejs/lib/safe-mime.js +12 -1
- package/lib/vendor/blamejs/lib/safe-object.js +80 -0
- package/lib/vendor/blamejs/lib/safe-path.js +52 -4
- package/lib/vendor/blamejs/lib/safe-redirect.js +10 -2
- package/lib/vendor/blamejs/lib/safe-schema.js +4 -1
- package/lib/vendor/blamejs/lib/safe-sieve.js +33 -1
- package/lib/vendor/blamejs/lib/safe-sql.js +88 -0
- package/lib/vendor/blamejs/lib/safe-vcard.js +7 -3
- package/lib/vendor/blamejs/lib/scheduler.js +8 -1
- package/lib/vendor/blamejs/lib/security-assert.js +6 -6
- package/lib/vendor/blamejs/lib/self-update-standalone-verifier.js +74 -27
- package/lib/vendor/blamejs/lib/self-update.js +517 -87
- package/lib/vendor/blamejs/lib/server-timing.js +2 -4
- package/lib/vendor/blamejs/lib/session.js +34 -12
- package/lib/vendor/blamejs/lib/sql.js +15 -1
- package/lib/vendor/blamejs/lib/ssrf-guard.js +52 -0
- package/lib/vendor/blamejs/lib/static.js +55 -13
- package/lib/vendor/blamejs/lib/storage.js +8 -2
- package/lib/vendor/blamejs/lib/subject.js +6 -1
- package/lib/vendor/blamejs/lib/tenant-quota.js +52 -13
- package/lib/vendor/blamejs/lib/tls-exporter.js +3 -3
- package/lib/vendor/blamejs/lib/tsa.js +34 -13
- package/lib/vendor/blamejs/lib/uri-template.js +8 -1
- package/lib/vendor/blamejs/lib/vault/index.js +13 -0
- package/lib/vendor/blamejs/lib/vc.js +44 -5
- package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +26 -26
- package/lib/vendor/blamejs/lib/vendor/noble-ciphers.cjs +792 -1
- package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +3443 -1
- package/lib/vendor/blamejs/lib/vendor/noble-post-quantum.cjs +2737 -1
- package/lib/vendor/blamejs/lib/vendor/pki.cjs +39550 -13
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.dat +55 -53
- package/lib/vendor/blamejs/lib/vendor/public-suffix-list.data.js +5551 -5554
- package/lib/vendor/blamejs/lib/vendor/simplewebauthn-server.cjs +22459 -32
- package/lib/vendor/blamejs/lib/watcher.js +89 -17
- package/lib/vendor/blamejs/lib/webhook-dispatcher.js +25 -3
- package/lib/vendor/blamejs/lib/webhook.js +12 -2
- package/lib/vendor/blamejs/lib/ws-client.js +32 -1
- package/lib/vendor/blamejs/lib/xml-c14n.js +29 -1
- package/lib/vendor/blamejs/oss-fuzz/projects/blamejs/Dockerfile +1 -1
- package/lib/vendor/blamejs/package-lock.json +2 -2
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.x.json +1462 -0
- package/lib/vendor/blamejs/release-notes/v0.17.0.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.1.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.10.json +30 -0
- package/lib/vendor/blamejs/release-notes/v0.17.11.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.12.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.13.json +77 -0
- package/lib/vendor/blamejs/release-notes/v0.17.14.json +40 -0
- package/lib/vendor/blamejs/release-notes/v0.17.15.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.16.json +27 -0
- package/lib/vendor/blamejs/release-notes/v0.17.17.json +31 -0
- package/lib/vendor/blamejs/release-notes/v0.17.18.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.19.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.2.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.20.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.21.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.22.json +18 -0
- package/lib/vendor/blamejs/release-notes/v0.17.3.json +43 -0
- package/lib/vendor/blamejs/release-notes/v0.17.4.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.5.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.6.json +26 -0
- package/lib/vendor/blamejs/release-notes/v0.17.7.json +35 -0
- package/lib/vendor/blamejs/release-notes/v0.17.8.json +22 -0
- package/lib/vendor/blamejs/release-notes/v0.17.9.json +26 -0
- package/lib/vendor/blamejs/scripts/validate-source-comment-blocks.js +4 -0
- package/lib/vendor/blamejs/scripts/vendor-update.sh +293 -9
- package/lib/vendor/blamejs/socket.yml +94 -0
- package/lib/vendor/blamejs/test/00-primitives.js +605 -0
- package/lib/vendor/blamejs/test/helpers/drivers.js +12 -9
- package/lib/vendor/blamejs/test/integration/audit-stack-mysql.test.js +90 -1
- package/lib/vendor/blamejs/test/integration/audit-stack-postgres.test.js +122 -1
- package/lib/vendor/blamejs/test/integration/data-layer-mysql.test.js +30 -0
- package/lib/vendor/blamejs/test/integration/data-layer-pg.test.js +29 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-mysql.test.js +479 -0
- package/lib/vendor/blamejs/test/integration/dsr-cluster-pg.test.js +487 -0
- package/lib/vendor/blamejs/test/integration/federation-auth.test.js +313 -5
- package/lib/vendor/blamejs/test/integration/mail-dkim.test.js +80 -0
- package/lib/vendor/blamejs/test/integration/openid-federation-chain.test.js +275 -0
- package/lib/vendor/blamejs/test/integration/webhook-dispatcher-pg.test.js +96 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/a2a-tasks.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/acme.test.js +1649 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/age-gate.test.js +33 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-idempotency.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-saga.test.js +60 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/agent-snapshot.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/api-encrypt.test.js +891 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/app-shutdown.test.js +128 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-adapters.test.js +271 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +628 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar-read.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-wrap.test.js +227 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/arg-parser.test.js +15 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/asn1-der.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/atomic-file.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-sign-anchor.test.js +141 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit-tools.test.js +624 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/audit.test.js +769 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-jwt-defenses.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth.test.js +1697 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oid4vp.test.js +495 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-password.test.js +500 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml.test.js +1809 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-status-list.test.js +243 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index.test.js +2226 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-manifest-signature.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/base32.test.js +105 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/break-glass.test.js +693 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cache.test.js +603 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/calendar.test.js +557 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/case-insensitive-security-token-guard.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cbor.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cert.test.js +843 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba-authreqid-binding.test.js +77 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/ciba.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/clear-site-data.test.js +18 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-erase.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cli.test.js +2790 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster-lease-renewal-ttl.test.js +114 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cluster.test.js +1032 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cms-codec.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +739 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/codepoint-class.test.js +8 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-ai-act.test.js +194 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-lifecycle-proto-key.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/compliance-sanctions.test.js +254 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials.test.js +613 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/cookies.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/cose.test.js +407 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-adversarial.test.js +352 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field-derived-hash.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-field.test.js +575 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-files-parallel.test.js +10 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-hash-stream.test.js +24 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +17 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-spki-pin.test.js +183 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto-xwing.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/crypto.test.js +345 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csp-report.test.js +58 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/csv.test.js +48 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/daemon.test.js +459 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dark-patterns.test.js +19 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-query.test.js +1019 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db-raw-residency-gate.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/db.test.js +1621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ddl-change-control.test.js +462 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/dnssec.test.js +323 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dpop-middleware-verify.test.js +562 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/dsr.test.js +901 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/dual-control.test.js +249 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db-migrate.test.js +561 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/external-db.test.js +1214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fal.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/fedcm-dbsc.test.js +46 -20
- package/lib/vendor/blamejs/test/layer-0-primitives/federation-vc-suite.test.js +147 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/fido-mds3.test.js +907 -38
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload-content-safety-skip-audit.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/file-upload.test.js +1135 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/flag.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/forms.test.js +747 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gate-contract.test.js +1855 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/gdpr-ropa.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-archive.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-auth.test.js +117 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-cidr.test.js +151 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-domain.test.js +422 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-filename.test.js +424 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-gate-disposition-coverage.test.js → guard-gate-disposition.test.js} +1 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-graphql.test.js +340 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-html.test.js +29 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-idempotency-key.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-image.test.js +519 -45
- 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 +51 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jsonpath.test.js +66 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-jwt.test.js +436 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-managesieve-command.test.js +25 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-markdown.test.js +16 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-mime.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-oauth.test.js +140 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pdf.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-pop3-command.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-regex.test.js +99 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-shell.test.js +76 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{guard-sql-coverage.test.js → guard-sql.test.js} +3 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-svg.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-template.test.js +71 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-time.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/guard-uuid.test.js +86 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/html-balance.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache-authorization.test.js +347 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client-cache.test.js +908 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-client.test.js +2874 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/http-message-signature.test.js +643 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n-messageformat.test.js +38 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/i18n.test.js +1153 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/idempotency-key.test.js +494 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ip-utils.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jsdoc-example-execution.test.js +177 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-path.test.js +103 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/json-schema.test.js +214 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwk.test.js +41 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/jwt-external.test.js +276 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log-stream.test.js +241 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/log.test.js +106 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-agent.test.js +441 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth.test.js +2136 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bimi.test.js +759 -12
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-bounce.test.js +811 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp-experimental.test.js +401 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-pgp.test.js +751 -8
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto-smime.test.js +864 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-crypto.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dav.test.js +830 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-deploy.test.js +635 -86
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-dkim.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-helo.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-scan.test.js +199 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-send-deliver.test.js +686 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-imap.test.js +778 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-jmap.test.js +1438 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-managesieve.test.js +449 -6
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-mx.test.js +773 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-pop3.test.js +623 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-rate-limit.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-registry.test.js +13 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-server-submission.test.js +877 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-sieve.test.js +326 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store-fts.test.js +55 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-store.test.js +242 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail.test.js +1596 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp.test.js +440 -4
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-snapshot.test.js +89 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics.test.js +1230 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-assetlinks.test.js +113 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-body-parser.test.js +1169 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-bot-disclose.test.js +123 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-cookies.test.js +108 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-gpc.test.js +121 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-headers.test.js +163 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-host-allowlist.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-require-content-type.test.js +127 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{middleware-tus-upload-coverage.test.js → middleware-tus-upload.test.js} +45 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/middleware-web-app-manifest.test.js +132 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mtls-ca-crl-fingerprint-only.test.js +92 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns-resolver.test.js +65 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-dns.test.js +1727 -1
- package/lib/vendor/blamejs/test/layer-0-primitives/network-nts.test.js +699 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy.test.js +1181 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/network-tls.test.js +1876 -3
- package/lib/vendor/blamejs/test/layer-0-primitives/network.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/nonce-store-enforce-replay-nonboolean.test.js +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ntp-check.test.js +122 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability-tracing.test.js +378 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/observability.test.js +77 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/oid4vci.test.js +1016 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/openid-federation.test.js +946 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/outbox.test.js +818 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/own-property-membership-guards.test.js +109 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-safe-toml.test.js +543 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/{parsers-safe-yaml-coverage.test.js → parsers-safe-yaml.test.js} +2 -2
- package/lib/vendor/blamejs/test/layer-0-primitives/parsers-standalone.test.js +73 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/passkey.test.js +649 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/permissions.test.js +524 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pqc-agent-curve.test.js +22 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/pubsub.test.js +295 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue-flow-repeat.test.js +36 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/queue.test.js +83 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/rate-limit-xff-spoofing.test.js +34 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/redact.test.js +1031 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/request-helpers.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/require-bound-key.test.js +401 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/restore-empty-manifest-wipe.test.js +154 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/retention.test.js +600 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-host-path-injection.test.js +231 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router-tls0rtt.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/router.test.js +1277 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-async.test.js +133 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer-linear-scans.test.js +14 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-buffer.test.js +80 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-decompress.test.js +28 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-dns.test.js +245 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ical.test.js +32 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-ini.test.js +376 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-json.test.js +175 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-mime.test.js +518 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-object.test.js +62 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-path.test.js +30 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-schema.test.js +104 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-sql.test.js +142 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-url.test.js +112 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/safe-vcard.test.js +26 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scheduler.test.js +157 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/scim-server.test.js +396 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sd-jwt-vc.test.js +930 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/security-assert.test.js +755 -82
- package/lib/vendor/blamejs/test/layer-0-primitives/self-update.test.js +1053 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-device-binding.test.js +200 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/session-strict-binding-missing-failclosed.test.js +110 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sigv4-bucket-ops.test.js +636 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-offset-without-limit.test.js +94 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/sql.test.js +1190 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ssrf-guard.test.js +21 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/static.test.js +850 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage-presigned-url.test.js +146 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/storage.test.js +621 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/subject.test.js +47 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/template.test.js +582 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tenant-quota.test.js +587 -25
- package/lib/vendor/blamejs/test/layer-0-primitives/time.test.js +11 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/tsa.test.js +524 -63
- package/lib/vendor/blamejs/test/layer-0-primitives/uri-template.test.js +27 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault-rotate.test.js +866 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vault.test.js +74 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/vc.test.js +215 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/watcher.test.js +550 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook-dispatcher.test.js +388 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/webhook.test.js +262 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/websocket.test.js +1294 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/ws-client.test.js +629 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/xml-c14n-attr-normalization.test.js +164 -0
- package/lib/vendor/blamejs/test/smoke.js +2 -0
- package/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.16.0.json +0 -44
- package/lib/vendor/blamejs/release-notes/v0.16.1.json +0 -36
- package/lib/vendor/blamejs/release-notes/v0.16.2.json +0 -71
- package/lib/vendor/blamejs/release-notes/v0.16.3.json +0 -71
- package/lib/vendor/blamejs/test/layer-0-primitives/acme-coverage.test.js +0 -441
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-oauth-coverage.test.js +0 -482
- package/lib/vendor/blamejs/test/layer-0-primitives/auth-saml-coverage.test.js +0 -671
- package/lib/vendor/blamejs/test/layer-0-primitives/backup-index-coverage.test.js +0 -690
- package/lib/vendor/blamejs/test/layer-0-primitives/cli-coverage.test.js +0 -238
- package/lib/vendor/blamejs/test/layer-0-primitives/content-credentials-coverage.test.js +0 -319
- package/lib/vendor/blamejs/test/layer-0-primitives/keychain-coverage.test.js +0 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/mail-auth-coverage.test.js +0 -437
- package/lib/vendor/blamejs/test/layer-0-primitives/mcp-coverage.test.js +0 -443
- package/lib/vendor/blamejs/test/layer-0-primitives/metrics-coverage.test.js +0 -395
- package/lib/vendor/blamejs/test/layer-0-primitives/network-smtp-policy-coverage.test.js +0 -565
- package/lib/vendor/blamejs/test/layer-0-primitives/router-coverage.test.js +0 -592
- package/lib/vendor/blamejs/test/layer-0-primitives/sql-coverage.test.js +0 -422
- package/lib/vendor/blamejs/test/layer-0-primitives/test-coverage.test.js +0 -573
|
@@ -867,6 +867,532 @@ function testJmapCatalogueCarriesCalendarMethods() {
|
|
|
867
867
|
check("CalendarEvent/get accepted in JMAP catalogue", reg && typeof reg.dispatch === "function");
|
|
868
868
|
}
|
|
869
869
|
|
|
870
|
+
// ---- Uncovered error / adversarial / defensive / option-default branches ----
|
|
871
|
+
|
|
872
|
+
function _expectValidateCode(label, jsCal, codeFragment) {
|
|
873
|
+
var threw = null;
|
|
874
|
+
try { b.calendar.validate(jsCal); } catch (e) { threw = e; }
|
|
875
|
+
check(label, threw && (threw.code || "").indexOf(codeFragment) !== -1);
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
function testValidateOversizeUid() {
|
|
879
|
+
// uid length cap (RFC-shape anti-DoS). A 1025-char uid is refused
|
|
880
|
+
// with the dedicated code; a 1024-char uid is accepted.
|
|
881
|
+
var bigUid = new Array(1026).join("u"); // 1025 chars
|
|
882
|
+
check("oversize-uid length precondition", bigUid.length === 1025);
|
|
883
|
+
_expectValidateCode("uid > 1024 bytes refused",
|
|
884
|
+
{ "@type": "Event", uid: bigUid, updated: "2026-05-21T10:00:00Z" }, "calendar/oversize-uid");
|
|
885
|
+
var okUid = new Array(1025).join("u"); // exactly 1024 chars
|
|
886
|
+
var rv = b.calendar.validate({ "@type": "Event", uid: okUid, updated: "2026-05-21T10:00:00Z" });
|
|
887
|
+
check("uid == 1024 bytes accepted", rv && rv.uid.length === 1024);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
function testValidateEventBadStart() {
|
|
891
|
+
// Event.start present but not a LocalDateTime.
|
|
892
|
+
_expectValidateCode("Event non-string start refused",
|
|
893
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z", start: 20260522 }, "calendar/bad-start");
|
|
894
|
+
_expectValidateCode("Event malformed start string refused",
|
|
895
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z", start: "2026-05-22 09:00" }, "calendar/bad-start");
|
|
896
|
+
// A UTC-suffixed start is NOT a LocalDateTime (Z is disallowed on start).
|
|
897
|
+
_expectValidateCode("Event start with Z suffix refused (LocalDateTime has no Z)",
|
|
898
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z", start: "2026-05-22T09:00:00Z" }, "calendar/bad-start");
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
function testValidateTaskBadStart() {
|
|
902
|
+
_expectValidateCode("Task non-string start refused",
|
|
903
|
+
{ "@type": "Task", uid: "x", updated: "2026-05-21T10:00:00Z", start: 5 }, "calendar/bad-start");
|
|
904
|
+
_expectValidateCode("Task malformed start refused",
|
|
905
|
+
{ "@type": "Task", uid: "x", updated: "2026-05-21T10:00:00Z", start: "yesterday" }, "calendar/bad-start");
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
function testValidateTaskBadProgressUpdated() {
|
|
909
|
+
// progressUpdated MUST be a UTCDateTime (has the Z suffix).
|
|
910
|
+
_expectValidateCode("Task non-string progressUpdated refused",
|
|
911
|
+
{ "@type": "Task", uid: "x", updated: "2026-05-21T10:00:00Z", progressUpdated: 12345 },
|
|
912
|
+
"calendar/bad-progress-updated");
|
|
913
|
+
_expectValidateCode("Task LocalDateTime progressUpdated refused (needs Z)",
|
|
914
|
+
{ "@type": "Task", uid: "x", updated: "2026-05-21T10:00:00Z", progressUpdated: "2026-05-21T10:00:00" },
|
|
915
|
+
"calendar/bad-progress-updated");
|
|
916
|
+
var rv = b.calendar.validate({
|
|
917
|
+
"@type": "Task", uid: "x", updated: "2026-05-21T10:00:00Z", progressUpdated: "2026-05-21T09:30:00Z",
|
|
918
|
+
});
|
|
919
|
+
check("valid Task progressUpdated accepted", rv && rv.progressUpdated === "2026-05-21T09:30:00Z");
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
function testValidateNoteBadStart() {
|
|
923
|
+
_expectValidateCode("Note non-string start refused",
|
|
924
|
+
{ "@type": "Note", uid: "x", updated: "2026-05-21T10:00:00Z", start: {} }, "calendar/bad-start");
|
|
925
|
+
_expectValidateCode("Note malformed start refused",
|
|
926
|
+
{ "@type": "Note", uid: "x", updated: "2026-05-21T10:00:00Z", start: "2026/05/21" }, "calendar/bad-start");
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
function testValidateGroupEntryNotObject() {
|
|
930
|
+
// Group.entries element that is null / non-object / array → bad-entries
|
|
931
|
+
// via the object-shape guard (distinct from the @type / nesting guard).
|
|
932
|
+
_expectValidateCode("Group entry null refused",
|
|
933
|
+
{ "@type": "Group", uid: "x", updated: "2026-05-21T10:00:00Z", entries: [null] }, "calendar/bad-entries");
|
|
934
|
+
_expectValidateCode("Group entry primitive refused",
|
|
935
|
+
{ "@type": "Group", uid: "x", updated: "2026-05-21T10:00:00Z", entries: [42] }, "calendar/bad-entries");
|
|
936
|
+
_expectValidateCode("Group entry array refused",
|
|
937
|
+
{ "@type": "Group", uid: "x", updated: "2026-05-21T10:00:00Z", entries: [[]] }, "calendar/bad-entries");
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
function testValidateRecurrenceRulesNotArray() {
|
|
941
|
+
// recurrenceRules present on a non-Group but not an array.
|
|
942
|
+
_expectValidateCode("recurrenceRules as string refused",
|
|
943
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z", recurrenceRules: "FREQ=DAILY" },
|
|
944
|
+
"calendar/bad-recurrence");
|
|
945
|
+
_expectValidateCode("recurrenceRules as object refused",
|
|
946
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z", recurrenceRules: { frequency: "daily" } },
|
|
947
|
+
"calendar/bad-recurrence");
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
function testValidateAlertsObjectMap() {
|
|
951
|
+
// The alerts object-map validation path (distinct from the
|
|
952
|
+
// "alerts must be an object" refusal an array triggers).
|
|
953
|
+
var rv = b.calendar.validate({
|
|
954
|
+
"@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z",
|
|
955
|
+
alerts: {
|
|
956
|
+
a1: { "@type": "Alert", action: "display" },
|
|
957
|
+
a2: { "@type": "Alert", action: "email" },
|
|
958
|
+
a3: { "@type": "Alert" }, // action optional
|
|
959
|
+
},
|
|
960
|
+
});
|
|
961
|
+
check("valid alerts object map accepted", rv && rv["@type"] === "Event");
|
|
962
|
+
_expectValidateCode("alert with wrong @type refused",
|
|
963
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z",
|
|
964
|
+
alerts: { a1: { "@type": "Reminder", action: "display" } } }, "calendar/bad-alerts");
|
|
965
|
+
_expectValidateCode("alert with null value refused",
|
|
966
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z",
|
|
967
|
+
alerts: { a1: null } }, "calendar/bad-alerts");
|
|
968
|
+
_expectValidateCode("alert with unknown action refused",
|
|
969
|
+
{ "@type": "Event", uid: "x", updated: "2026-05-21T10:00:00Z",
|
|
970
|
+
alerts: { a1: { "@type": "Alert", action: "vibrate" } } }, "calendar/bad-alerts");
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
function testFromIcalTzidParamPreservedAsString() {
|
|
974
|
+
// A DTSTART;TZID=<zone> parameter must map to JSCalendar
|
|
975
|
+
// `timeZone` as a STRING (RFC 8984 §4.7.1 TimeZoneId is a String),
|
|
976
|
+
// not the raw multi-valued parameter array safeIcal exposes.
|
|
977
|
+
var ical =
|
|
978
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
979
|
+
"BEGIN:VEVENT\r\nUID:tz@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
980
|
+
"DTSTART;TZID=America/New_York:20260522T090000\r\nDURATION:PT1H\r\nSUMMARY:tz\r\n" +
|
|
981
|
+
"END:VEVENT\r\nEND:VCALENDAR\r\n";
|
|
982
|
+
var ev = b.calendar.fromIcal(ical);
|
|
983
|
+
check("VEVENT TZID → timeZone is a string", typeof ev.timeZone === "string");
|
|
984
|
+
check("VEVENT TZID → timeZone value", ev.timeZone === "America/New_York");
|
|
985
|
+
// Round-trips back to a TZID-parameterized DTSTART.
|
|
986
|
+
var back = b.calendar.toIcal(ev);
|
|
987
|
+
check("toIcal re-emits DTSTART;TZID from a named zone",
|
|
988
|
+
/DTSTART;TZID=America\/New_York:20260522T090000/.test(back));
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
function testToIcalNamedTimeZoneEmitsTzid() {
|
|
992
|
+
// Event with a named (non-UTC) timeZone → DTSTART;TZID=<zone>.
|
|
993
|
+
var ev = {
|
|
994
|
+
"@type": "Event",
|
|
995
|
+
uid: "named-tz",
|
|
996
|
+
updated: "2026-05-21T10:00:00Z",
|
|
997
|
+
title: "Standup",
|
|
998
|
+
start: "2026-05-22T09:00:00",
|
|
999
|
+
duration: "PT1H",
|
|
1000
|
+
timeZone: "Europe/Berlin",
|
|
1001
|
+
};
|
|
1002
|
+
var ical = b.calendar.toIcal(ev);
|
|
1003
|
+
check("named timeZone emits DTSTART;TZID", /DTSTART;TZID=Europe\/Berlin:20260522T090000/.test(ical));
|
|
1004
|
+
check("named timeZone does NOT emit a Z-suffixed DTSTART", !/DTSTART:20260522T090000Z/.test(ical));
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
function testToIcalTaskDueTimeZones() {
|
|
1008
|
+
// VTODO DUE property honours the same UTC / TZID / floating handling
|
|
1009
|
+
// as DTSTART.
|
|
1010
|
+
var utcTask = {
|
|
1011
|
+
"@type": "Task",
|
|
1012
|
+
uid: "due-utc",
|
|
1013
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1014
|
+
title: "Ship",
|
|
1015
|
+
due: "2026-05-22T17:00:00",
|
|
1016
|
+
timeZone: "Etc/UTC",
|
|
1017
|
+
};
|
|
1018
|
+
var utcIcal = b.calendar.toIcal(utcTask);
|
|
1019
|
+
check("VTODO DUE with Etc/UTC emits Z suffix", /DUE:20260522T170000Z/.test(utcIcal));
|
|
1020
|
+
|
|
1021
|
+
var tzTask = {
|
|
1022
|
+
"@type": "Task",
|
|
1023
|
+
uid: "due-tz",
|
|
1024
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1025
|
+
title: "Ship",
|
|
1026
|
+
due: "2026-05-22T17:00:00",
|
|
1027
|
+
timeZone: "America/Chicago",
|
|
1028
|
+
};
|
|
1029
|
+
var tzIcal = b.calendar.toIcal(tzTask);
|
|
1030
|
+
check("VTODO DUE with named zone emits TZID", /DUE;TZID=America\/Chicago:20260522T170000/.test(tzIcal));
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
function testToIcalEmitsRruleWithAllParts() {
|
|
1034
|
+
// toIcal serializes recurrenceRules → RRULE, exercising the full
|
|
1035
|
+
// _recurrenceRuleToIcal serializer (INTERVAL / COUNT / UNTIL / BYDAY /
|
|
1036
|
+
// BYMONTH / BYMONTHDAY).
|
|
1037
|
+
var ev = {
|
|
1038
|
+
"@type": "Event",
|
|
1039
|
+
uid: "rrule-out",
|
|
1040
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1041
|
+
title: "Cadence",
|
|
1042
|
+
start: "2026-05-22T09:00:00",
|
|
1043
|
+
timeZone: "Etc/UTC",
|
|
1044
|
+
recurrenceRules: [{
|
|
1045
|
+
"@type": "RecurrenceRule",
|
|
1046
|
+
frequency: "monthly",
|
|
1047
|
+
interval: 2,
|
|
1048
|
+
count: 6,
|
|
1049
|
+
until: "2027-01-01T00:00:00Z",
|
|
1050
|
+
byDay: [{ "@type": "NDay", day: "mo" }, { "@type": "NDay", day: "we" }],
|
|
1051
|
+
byMonth: [3, 6, 9, 12],
|
|
1052
|
+
byMonthDay: [1, 15],
|
|
1053
|
+
}],
|
|
1054
|
+
};
|
|
1055
|
+
var ical = b.calendar.toIcal(ev);
|
|
1056
|
+
var rruleLine = ical.split("\r\n").filter(function (l) { return l.indexOf("RRULE:") === 0; })[0] || "";
|
|
1057
|
+
check("toIcal emits an RRULE line", rruleLine.indexOf("FREQ=MONTHLY") !== -1);
|
|
1058
|
+
check("RRULE carries INTERVAL", rruleLine.indexOf("INTERVAL=2") !== -1);
|
|
1059
|
+
check("RRULE carries COUNT", rruleLine.indexOf("COUNT=6") !== -1);
|
|
1060
|
+
check("RRULE carries UNTIL", rruleLine.indexOf("UNTIL=20270101T000000Z") !== -1);
|
|
1061
|
+
check("RRULE carries BYDAY upper", rruleLine.indexOf("BYDAY=MO,WE") !== -1);
|
|
1062
|
+
check("RRULE carries BYMONTH", rruleLine.indexOf("BYMONTH=3,6,9,12") !== -1);
|
|
1063
|
+
check("RRULE carries BYMONTHDAY", rruleLine.indexOf("BYMONTHDAY=1,15") !== -1);
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
function testExpandRecurrenceNoRules() {
|
|
1067
|
+
// No recurrenceRules → a single-instance (the start) or empty set.
|
|
1068
|
+
var withStart = b.calendar.expandRecurrence(
|
|
1069
|
+
{ "@type": "Event", uid: "single", updated: "2026-05-21T10:00:00Z", start: "2026-05-22T09:00:00" }, {});
|
|
1070
|
+
check("no rules + start → single instance", withStart.length === 1 && withStart[0] === "2026-05-22T09:00:00Z");
|
|
1071
|
+
var noStart = b.calendar.expandRecurrence(
|
|
1072
|
+
{ "@type": "Event", uid: "empty", updated: "2026-05-21T10:00:00Z" }, {});
|
|
1073
|
+
check("no rules + no start → empty set", Array.isArray(noStart) && noStart.length === 0);
|
|
1074
|
+
// Also exercised when recurrenceRules is an empty array.
|
|
1075
|
+
var emptyRules = b.calendar.expandRecurrence(
|
|
1076
|
+
{ "@type": "Event", uid: "emptyrr", updated: "2026-05-21T10:00:00Z",
|
|
1077
|
+
start: "2026-05-22T09:00:00", recurrenceRules: [] }, {});
|
|
1078
|
+
check("empty recurrenceRules array → single instance", emptyRules.length === 1);
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
function testExpandWindowToBeforeFrom() {
|
|
1082
|
+
var ev = {
|
|
1083
|
+
"@type": "Event",
|
|
1084
|
+
uid: "bad-window",
|
|
1085
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1086
|
+
start: "2026-05-22T09:00:00",
|
|
1087
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "daily", count: 5 }],
|
|
1088
|
+
};
|
|
1089
|
+
var threw = null;
|
|
1090
|
+
try { b.calendar.expandRecurrence(ev, { from: "2026-06-01T00:00:00Z", to: "2026-05-01T00:00:00Z" }); }
|
|
1091
|
+
catch (e) { threw = e; }
|
|
1092
|
+
check("expand with to < from refused",
|
|
1093
|
+
threw && (threw.code || "").indexOf("calendar/bad-expansion-window") !== -1);
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
function testExpandRecurrenceRulesButNoStart() {
|
|
1097
|
+
// recurrenceRules present but no start → the start becomes unparseable
|
|
1098
|
+
// and expansion fails closed with calendar/bad-start.
|
|
1099
|
+
var ev = {
|
|
1100
|
+
"@type": "Event",
|
|
1101
|
+
uid: "rules-no-start",
|
|
1102
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1103
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "daily", count: 3 }],
|
|
1104
|
+
};
|
|
1105
|
+
var threw = null;
|
|
1106
|
+
try { b.calendar.expandRecurrence(ev, { from: "2026-05-22T00:00:00Z", to: "2026-06-01T00:00:00Z" }); }
|
|
1107
|
+
catch (e) { threw = e; }
|
|
1108
|
+
check("expand with rules but no start refused",
|
|
1109
|
+
threw && (threw.code || "").indexOf("calendar/bad-start") !== -1);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
function testExpandRecurrenceByMonthDay() {
|
|
1113
|
+
// FREQ=DAILY;BYMONTHDAY=1,15 — only the 1st and 15th of each month fire.
|
|
1114
|
+
var ev = {
|
|
1115
|
+
"@type": "Event",
|
|
1116
|
+
uid: "bymonthday",
|
|
1117
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1118
|
+
start: "2026-05-01T09:00:00",
|
|
1119
|
+
timeZone: "Etc/UTC",
|
|
1120
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "daily",
|
|
1121
|
+
byMonthDay: [1, 15], count: 4 }],
|
|
1122
|
+
};
|
|
1123
|
+
var insts = b.calendar.expandRecurrence(ev, { from: "2026-05-01T00:00:00Z", to: "2026-08-01T00:00:00Z" });
|
|
1124
|
+
check("BYMONTHDAY=1,15 emits 4 instances", insts.length === 4);
|
|
1125
|
+
check("first is May 1", insts[0] === "2026-05-01T09:00:00Z");
|
|
1126
|
+
check("second is May 15", insts[1] === "2026-05-15T09:00:00Z");
|
|
1127
|
+
check("third is Jun 1", insts[2] === "2026-06-01T09:00:00Z");
|
|
1128
|
+
check("every instance is a 1st or 15th",
|
|
1129
|
+
insts.every(function (s) { return /-(01|15)T/.test(s); }));
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
function testBysetposWeeklyPeriod() {
|
|
1133
|
+
// BYSETPOS with FREQ=WEEKLY exercises the weekly period-anchoring
|
|
1134
|
+
// branch of _periodForIndex (WKST=Monday alignment).
|
|
1135
|
+
var ev = {
|
|
1136
|
+
"@type": "Event",
|
|
1137
|
+
uid: "weekly-setpos",
|
|
1138
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1139
|
+
start: "2026-05-04T09:00:00", // Monday
|
|
1140
|
+
timeZone: "Etc/UTC",
|
|
1141
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "weekly",
|
|
1142
|
+
byDay: ["MO", "TU", "WE", "TH", "FR"], bySetPos: [1], count: 3 }],
|
|
1143
|
+
};
|
|
1144
|
+
var insts = b.calendar.expandRecurrence(ev, { from: "2026-05-01T00:00:00Z", to: "2026-06-15T00:00:00Z" });
|
|
1145
|
+
check("weekly BYSETPOS=1 emits 3 instances", insts.length === 3);
|
|
1146
|
+
check("first weekday of week 1 (Mon May 4)", insts[0] === "2026-05-04T09:00:00Z");
|
|
1147
|
+
check("first weekday of week 2 (Mon May 11)", insts[1] === "2026-05-11T09:00:00Z");
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
function testFromIcalVtodoTzidLocationAndRrule() {
|
|
1151
|
+
// VTODO carrying a TZID param, a LOCATION, and an RRULE.
|
|
1152
|
+
var ical =
|
|
1153
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1154
|
+
"BEGIN:VTODO\r\nUID:vt-tz@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
1155
|
+
"DTSTART;TZID=Asia/Tokyo:20260522T090000\r\nDUE;TZID=Asia/Tokyo:20260522T170000\r\n" +
|
|
1156
|
+
"LOCATION:HQ Floor 3\r\nRRULE:FREQ=WEEKLY;COUNT=4\r\nSUMMARY:Standup task\r\n" +
|
|
1157
|
+
"END:VTODO\r\nEND:VCALENDAR\r\n";
|
|
1158
|
+
var task = b.calendar.fromIcal(ical);
|
|
1159
|
+
check("VTODO TZID → timeZone string", task.timeZone === "Asia/Tokyo");
|
|
1160
|
+
check("VTODO LOCATION → locations[]", task.locations && task.locations.L1 &&
|
|
1161
|
+
task.locations.L1.name === "HQ Floor 3");
|
|
1162
|
+
check("VTODO RRULE → recurrenceRules", Array.isArray(task.recurrenceRules) &&
|
|
1163
|
+
task.recurrenceRules[0].frequency === "weekly");
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
function testFromIcalVtodoUtcSuffix() {
|
|
1167
|
+
// VTODO with a Z-suffixed DTSTART (no TZID) → timeZone "Etc/UTC".
|
|
1168
|
+
var ical =
|
|
1169
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1170
|
+
"BEGIN:VTODO\r\nUID:vt-utc@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
1171
|
+
"DTSTART:20260522T090000Z\r\nSUMMARY:UTC task\r\n" +
|
|
1172
|
+
"END:VTODO\r\nEND:VCALENDAR\r\n";
|
|
1173
|
+
var task = b.calendar.fromIcal(ical);
|
|
1174
|
+
check("VTODO Z-suffix DTSTART → Etc/UTC", task.timeZone === "Etc/UTC");
|
|
1175
|
+
check("VTODO start LocalDateTime stripped of Z", task.start === "2026-05-22T09:00:00");
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
function testFromIcalVjournalTzidLocationAndRrule() {
|
|
1179
|
+
// VJOURNAL carrying a TZID param, a LOCATION, and an RRULE.
|
|
1180
|
+
var ical =
|
|
1181
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1182
|
+
"BEGIN:VJOURNAL\r\nUID:vj-tz@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
1183
|
+
"DTSTART;TZID=Europe/Paris:20260521T120000\r\nLOCATION:Paris Office\r\n" +
|
|
1184
|
+
"RRULE:FREQ=MONTHLY;COUNT=3\r\nSUMMARY:Journal\r\n" +
|
|
1185
|
+
"END:VJOURNAL\r\nEND:VCALENDAR\r\n";
|
|
1186
|
+
var note = b.calendar.fromIcal(ical);
|
|
1187
|
+
check("VJOURNAL TZID → timeZone string", note.timeZone === "Europe/Paris");
|
|
1188
|
+
check("VJOURNAL LOCATION → locations[]", note.locations && note.locations.L1 &&
|
|
1189
|
+
note.locations.L1.name === "Paris Office");
|
|
1190
|
+
check("VJOURNAL RRULE → recurrenceRules", Array.isArray(note.recurrenceRules) &&
|
|
1191
|
+
note.recurrenceRules[0].frequency === "monthly");
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
function testFromIcalVjournalNoDescription() {
|
|
1195
|
+
// VJOURNAL with no DESCRIPTION property → description stays unset
|
|
1196
|
+
// (exercises the empty-values branch of the description join).
|
|
1197
|
+
var ical =
|
|
1198
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1199
|
+
"BEGIN:VJOURNAL\r\nUID:vj-nodesc@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
1200
|
+
"SUMMARY:Titled but empty\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n";
|
|
1201
|
+
var note = b.calendar.fromIcal(ical);
|
|
1202
|
+
check("VJOURNAL without DESCRIPTION has no description", note.description === undefined);
|
|
1203
|
+
check("VJOURNAL title preserved", note.title === "Titled but empty");
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
function testFromIcalRruleByMonthDay() {
|
|
1207
|
+
// The ical→jscal RRULE parser maps BYMONTHDAY to integers.
|
|
1208
|
+
var ical =
|
|
1209
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1210
|
+
"BEGIN:VEVENT\r\nUID:rr-bmd@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
1211
|
+
"DTSTART:20260501T090000\r\nRRULE:FREQ=MONTHLY;BYMONTHDAY=1,15,-1\r\nSUMMARY:Payroll\r\n" +
|
|
1212
|
+
"END:VEVENT\r\nEND:VCALENDAR\r\n";
|
|
1213
|
+
var ev = b.calendar.fromIcal(ical);
|
|
1214
|
+
check("RRULE BYMONTHDAY parsed to integer array",
|
|
1215
|
+
Array.isArray(ev.recurrenceRules[0].byMonthDay) &&
|
|
1216
|
+
ev.recurrenceRules[0].byMonthDay[0] === 1 &&
|
|
1217
|
+
ev.recurrenceRules[0].byMonthDay[2] === -1);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
function testToIcalFoldsLongLine() {
|
|
1221
|
+
// RFC 5545 §3.1 line folding — a >75-octet UID is folded with
|
|
1222
|
+
// CRLF + a leading space.
|
|
1223
|
+
var longUid = new Array(101).join("u") + "@example.com"; // 112 chars
|
|
1224
|
+
var ev = { "@type": "Event", uid: longUid, updated: "2026-05-21T10:00:00Z", title: "x" };
|
|
1225
|
+
var ical = b.calendar.toIcal(ev);
|
|
1226
|
+
var uidRegion = ical.slice(ical.indexOf("UID:"));
|
|
1227
|
+
check("long UID line is folded (CRLF + space continuation)", /\r\n /.test(uidRegion));
|
|
1228
|
+
// Reconstruct: strip the CRLF-space fold sequences and read the UID line.
|
|
1229
|
+
var joined = ical.replace(/\r\n /g, "");
|
|
1230
|
+
var uidLine = joined.split("\r\n").filter(function (l) { return l.indexOf("UID:") === 0; })[0];
|
|
1231
|
+
check("unfolded UID matches original", uidLine === "UID:" + longUid);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
function testToIcalLocationsAsArray() {
|
|
1235
|
+
// toIcal accepts `locations` as an ARRAY (not only the object map
|
|
1236
|
+
// fromIcal produces), emitting one LOCATION per named entry.
|
|
1237
|
+
var ev = {
|
|
1238
|
+
"@type": "Event",
|
|
1239
|
+
uid: "loc-array",
|
|
1240
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1241
|
+
title: "Offsite",
|
|
1242
|
+
start: "2026-05-22T09:00:00",
|
|
1243
|
+
locations: [
|
|
1244
|
+
{ "@type": "Location", name: "Room A" },
|
|
1245
|
+
{ "@type": "Location", name: "Room B" },
|
|
1246
|
+
{ "@type": "Location" }, // no name → skipped
|
|
1247
|
+
],
|
|
1248
|
+
};
|
|
1249
|
+
var ical = b.calendar.toIcal(ev);
|
|
1250
|
+
check("locations array emits first LOCATION", ical.indexOf("LOCATION:Room A") !== -1);
|
|
1251
|
+
check("locations array emits second LOCATION", ical.indexOf("LOCATION:Room B") !== -1);
|
|
1252
|
+
check("nameless location entry is skipped", (ical.match(/LOCATION:/g) || []).length === 2);
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
function testFromIcalBareComponentDefaults() {
|
|
1256
|
+
// A VEVENT lacking UID and DTSTAMP still parses; the missing
|
|
1257
|
+
// required properties default to empty strings (the `|| ""` guards).
|
|
1258
|
+
var ical =
|
|
1259
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1260
|
+
"BEGIN:VEVENT\r\nSUMMARY:Bare event\r\nEND:VEVENT\r\nEND:VCALENDAR\r\n";
|
|
1261
|
+
var ev = b.calendar.fromIcal(ical);
|
|
1262
|
+
check("bare VEVENT uid defaults to empty string", ev.uid === "");
|
|
1263
|
+
check("bare VEVENT updated defaults to empty string", ev.updated === "");
|
|
1264
|
+
check("bare VEVENT title preserved", ev.title === "Bare event");
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
function testExpandRecurrenceDefaultOpts() {
|
|
1268
|
+
// expandRecurrence called with NO opts argument — opts defaults to {},
|
|
1269
|
+
// no from/to window, count bounds the set.
|
|
1270
|
+
var ev = {
|
|
1271
|
+
"@type": "Event",
|
|
1272
|
+
uid: "no-opts",
|
|
1273
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1274
|
+
start: "2026-05-22T09:00:00",
|
|
1275
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "daily", count: 3 }],
|
|
1276
|
+
};
|
|
1277
|
+
var insts = b.calendar.expandRecurrence(ev);
|
|
1278
|
+
check("expand with no opts uses defaults + count", insts.length === 3);
|
|
1279
|
+
check("expand with no opts first instance at start", insts[0] === "2026-05-22T09:00:00Z");
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
function testFromIcalMalformedRruleSegmentSkipped() {
|
|
1283
|
+
// A RRULE segment without an '=' (e.g. a stray token) is skipped
|
|
1284
|
+
// rather than corrupting the parsed rule.
|
|
1285
|
+
var ical =
|
|
1286
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1287
|
+
"BEGIN:VEVENT\r\nUID:rr-junk@x\r\nDTSTAMP:20260521T100000Z\r\n" +
|
|
1288
|
+
"DTSTART:20260501T090000\r\nRRULE:FREQ=WEEKLY;GARBAGE;COUNT=3\r\nSUMMARY:x\r\n" +
|
|
1289
|
+
"END:VEVENT\r\nEND:VCALENDAR\r\n";
|
|
1290
|
+
var ev = b.calendar.fromIcal(ical);
|
|
1291
|
+
check("malformed RRULE segment skipped; freq parsed", ev.recurrenceRules[0].frequency === "weekly");
|
|
1292
|
+
check("malformed RRULE segment skipped; count parsed", ev.recurrenceRules[0].count === 3);
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
function testFromIcalBareVtodoAndVjournalDefaults() {
|
|
1296
|
+
// Bare VTODO / VJOURNAL (no UID / DTSTAMP) still parse, defaulting the
|
|
1297
|
+
// required properties to empty strings.
|
|
1298
|
+
var vtodoIcal =
|
|
1299
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1300
|
+
"BEGIN:VTODO\r\nSUMMARY:Bare task\r\nEND:VTODO\r\nEND:VCALENDAR\r\n";
|
|
1301
|
+
var task = b.calendar.fromIcal(vtodoIcal);
|
|
1302
|
+
check("bare VTODO uid defaults to empty string", task.uid === "");
|
|
1303
|
+
check("bare VTODO updated defaults to empty string", task.updated === "");
|
|
1304
|
+
check("bare VTODO @type Task", task["@type"] === "Task");
|
|
1305
|
+
|
|
1306
|
+
var vjournalIcal =
|
|
1307
|
+
"BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//x//EN\r\n" +
|
|
1308
|
+
"BEGIN:VJOURNAL\r\nSUMMARY:Bare note\r\nEND:VJOURNAL\r\nEND:VCALENDAR\r\n";
|
|
1309
|
+
var note = b.calendar.fromIcal(vjournalIcal);
|
|
1310
|
+
check("bare VJOURNAL uid defaults to empty string", note.uid === "");
|
|
1311
|
+
check("bare VJOURNAL updated defaults to empty string", note.updated === "");
|
|
1312
|
+
check("bare VJOURNAL @type Note", note["@type"] === "Note");
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
function testBysetposWeeklySundayAnchor() {
|
|
1316
|
+
// A weekly BYSETPOS rule whose start falls on a Sunday exercises the
|
|
1317
|
+
// WKST-Monday period anchor's Sunday (getUTCDay() === 0 → 7) branch.
|
|
1318
|
+
var ev = {
|
|
1319
|
+
"@type": "Event",
|
|
1320
|
+
uid: "weekly-sunday",
|
|
1321
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1322
|
+
start: "2026-05-03T09:00:00", // 2026-05-03 is a Sunday
|
|
1323
|
+
timeZone: "Etc/UTC",
|
|
1324
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "weekly",
|
|
1325
|
+
byDay: ["SU"], bySetPos: [1], count: 2 }],
|
|
1326
|
+
};
|
|
1327
|
+
var insts = b.calendar.expandRecurrence(ev, { from: "2026-05-01T00:00:00Z", to: "2026-06-01T00:00:00Z" });
|
|
1328
|
+
check("weekly Sunday-anchored BYSETPOS emits 2", insts.length === 2);
|
|
1329
|
+
check("first Sunday is the start (May 3)", insts[0] === "2026-05-03T09:00:00Z");
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
function testBysetposUnboundedIntervalTerminates() {
|
|
1333
|
+
// Adversarial DoS — a BYSETPOS rule whose FREQ interval is large
|
|
1334
|
+
// enough that the SECOND period's Date.UTC overflows to NaN (year
|
|
1335
|
+
// 2026 + 300000 is beyond the representable ECMAScript date range).
|
|
1336
|
+
// A NaN period runs the day-enumeration loop zero times, so it never
|
|
1337
|
+
// decrements the shared step budget, and the untilMs / toMs window
|
|
1338
|
+
// breaks are NaN-comparison no-ops — the BYSETPOS expander would
|
|
1339
|
+
// otherwise spin forever. Every accepted recurrenceRule MUST make
|
|
1340
|
+
// expandRecurrence terminate. Driven in a child process with a hard
|
|
1341
|
+
// wall-clock kill so a regression manifests as a killed child rather
|
|
1342
|
+
// than hanging this suite.
|
|
1343
|
+
var childProc = require("child_process");
|
|
1344
|
+
var fs = require("fs");
|
|
1345
|
+
var os = require("os");
|
|
1346
|
+
var path = require("path");
|
|
1347
|
+
var calPath = path.resolve(__dirname, "../../lib/calendar");
|
|
1348
|
+
var ev = {
|
|
1349
|
+
"@type": "Event",
|
|
1350
|
+
uid: "bysetpos-dos",
|
|
1351
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1352
|
+
start: "2026-06-15T09:00:00",
|
|
1353
|
+
timeZone: "Etc/UTC",
|
|
1354
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "yearly",
|
|
1355
|
+
interval: 300000, byDay: ["FR"], bySetPos: [1] }], // allow:raw-byte-literal — interval large enough to overflow Date.UTC on period 2
|
|
1356
|
+
};
|
|
1357
|
+
var target = path.join(os.tmpdir(),
|
|
1358
|
+
"blamejs-cal-bysetpos-dos-" + process.pid + "-" + Date.now() + ".js");
|
|
1359
|
+
var src =
|
|
1360
|
+
"\"use strict\";\n" +
|
|
1361
|
+
"var cal = require(" + JSON.stringify(calPath) + ");\n" +
|
|
1362
|
+
"cal.expandRecurrence(" + JSON.stringify(ev) + ", {});\n" +
|
|
1363
|
+
"process.stdout.write(\"DONE\");\n";
|
|
1364
|
+
fs.writeFileSync(target, src);
|
|
1365
|
+
var r;
|
|
1366
|
+
try {
|
|
1367
|
+
r = childProc.spawnSync(process.execPath, [target],
|
|
1368
|
+
{ timeout: 5000, killSignal: "SIGKILL", encoding: "utf8" }); // allow:raw-byte-literal — child wall-clock kill budget; a fixed tree returns in <100ms
|
|
1369
|
+
} finally {
|
|
1370
|
+
try { fs.unlinkSync(target); } catch (_e) { /* best-effort cleanup */ }
|
|
1371
|
+
}
|
|
1372
|
+
check("BYSETPOS + unbounded interval terminates (no infinite loop)",
|
|
1373
|
+
r.status === 0 && !r.signal && /DONE/.test(r.stdout || ""));
|
|
1374
|
+
|
|
1375
|
+
// Same root, non-BYSETPOS manifestation: the plain step loop does not
|
|
1376
|
+
// hang (it decrements the budget every iteration) but a large interval
|
|
1377
|
+
// makes _advance overflow to NaN, which _msToIsoZ then throws on
|
|
1378
|
+
// (uncaught TimeError → the request crashes). This runs in-process
|
|
1379
|
+
// because it terminates; it must return a bounded array, not throw.
|
|
1380
|
+
var evPlain = {
|
|
1381
|
+
"@type": "Event",
|
|
1382
|
+
uid: "interval-dos",
|
|
1383
|
+
updated: "2026-05-21T10:00:00Z",
|
|
1384
|
+
start: "2026-06-15T09:00:00",
|
|
1385
|
+
timeZone: "Etc/UTC",
|
|
1386
|
+
recurrenceRules: [{ "@type": "RecurrenceRule", frequency: "yearly",
|
|
1387
|
+
interval: 300000 }], // allow:raw-byte-literal — interval large enough to overflow Date.UTC on the first advance
|
|
1388
|
+
};
|
|
1389
|
+
var threwPlain = null, instsPlain = null;
|
|
1390
|
+
try { instsPlain = b.calendar.expandRecurrence(evPlain, {}); }
|
|
1391
|
+
catch (e) { threwPlain = e; }
|
|
1392
|
+
check("unbounded interval does not crash the expander (no NaN date throw)",
|
|
1393
|
+
threwPlain === null && Array.isArray(instsPlain));
|
|
1394
|
+
}
|
|
1395
|
+
|
|
870
1396
|
function run() {
|
|
871
1397
|
testSurface();
|
|
872
1398
|
testValidateHappyPath();
|
|
@@ -914,6 +1440,37 @@ function run() {
|
|
|
914
1440
|
testBysetposRefusesDailyFrequency();
|
|
915
1441
|
testMixedVcalendarReturnsArray();
|
|
916
1442
|
testJmapCatalogueCarriesCalendarMethods();
|
|
1443
|
+
// Uncovered error / adversarial / defensive / option-default branches.
|
|
1444
|
+
testValidateOversizeUid();
|
|
1445
|
+
testValidateEventBadStart();
|
|
1446
|
+
testValidateTaskBadStart();
|
|
1447
|
+
testValidateTaskBadProgressUpdated();
|
|
1448
|
+
testValidateNoteBadStart();
|
|
1449
|
+
testValidateGroupEntryNotObject();
|
|
1450
|
+
testValidateRecurrenceRulesNotArray();
|
|
1451
|
+
testValidateAlertsObjectMap();
|
|
1452
|
+
testFromIcalTzidParamPreservedAsString();
|
|
1453
|
+
testToIcalNamedTimeZoneEmitsTzid();
|
|
1454
|
+
testToIcalTaskDueTimeZones();
|
|
1455
|
+
testToIcalEmitsRruleWithAllParts();
|
|
1456
|
+
testExpandRecurrenceNoRules();
|
|
1457
|
+
testExpandWindowToBeforeFrom();
|
|
1458
|
+
testExpandRecurrenceRulesButNoStart();
|
|
1459
|
+
testExpandRecurrenceByMonthDay();
|
|
1460
|
+
testBysetposWeeklyPeriod();
|
|
1461
|
+
testFromIcalVtodoTzidLocationAndRrule();
|
|
1462
|
+
testFromIcalVtodoUtcSuffix();
|
|
1463
|
+
testFromIcalVjournalTzidLocationAndRrule();
|
|
1464
|
+
testFromIcalVjournalNoDescription();
|
|
1465
|
+
testFromIcalRruleByMonthDay();
|
|
1466
|
+
testToIcalFoldsLongLine();
|
|
1467
|
+
testToIcalLocationsAsArray();
|
|
1468
|
+
testFromIcalBareComponentDefaults();
|
|
1469
|
+
testExpandRecurrenceDefaultOpts();
|
|
1470
|
+
testFromIcalMalformedRruleSegmentSkipped();
|
|
1471
|
+
testFromIcalBareVtodoAndVjournalDefaults();
|
|
1472
|
+
testBysetposWeeklySundayAnchor();
|
|
1473
|
+
testBysetposUnboundedIntervalTerminates();
|
|
917
1474
|
}
|
|
918
1475
|
|
|
919
1476
|
module.exports = { run: run };
|