@backblaze-labs/b2-sdk 0.2.0 → 0.4.0
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 +86 -1
- package/README.md +38 -7
- package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
- package/dist/_virtual/_b2-sdk-version-json.js +1 -1
- package/dist/auth/file.cjs.map +1 -1
- package/dist/auth/reauth-coalescer.cjs +65 -0
- package/dist/auth/reauth-coalescer.cjs.map +1 -0
- package/dist/auth/reauth-coalescer.d.cts +34 -0
- package/dist/auth/reauth-coalescer.d.cts.map +1 -0
- package/dist/auth/reauth-coalescer.d.ts +34 -0
- package/dist/auth/reauth-coalescer.d.ts.map +1 -0
- package/dist/auth/reauth-coalescer.js +65 -0
- package/dist/auth/reauth-coalescer.js.map +1 -0
- package/dist/backup/client.cjs +206 -0
- package/dist/backup/client.cjs.map +1 -0
- package/dist/backup/client.d.cts +238 -0
- package/dist/backup/client.d.cts.map +1 -0
- package/dist/backup/client.d.ts +238 -0
- package/dist/backup/client.d.ts.map +1 -0
- package/dist/backup/client.js +206 -0
- package/dist/backup/client.js.map +1 -0
- package/dist/backup/index.cjs +15 -0
- package/dist/backup/index.d.cts +22 -0
- package/dist/backup/index.d.cts.map +1 -0
- package/dist/backup/index.d.ts +22 -0
- package/dist/backup/index.d.ts.map +1 -0
- package/dist/backup/index.js +7 -0
- package/dist/backup/raw.cjs +168 -0
- package/dist/backup/raw.cjs.map +1 -0
- package/dist/backup/raw.d.cts +122 -0
- package/dist/backup/raw.d.cts.map +1 -0
- package/dist/backup/raw.d.ts +122 -0
- package/dist/backup/raw.d.ts.map +1 -0
- package/dist/backup/raw.js +168 -0
- package/dist/backup/raw.js.map +1 -0
- package/dist/bucket-validation.cjs +111 -0
- package/dist/bucket-validation.cjs.map +1 -0
- package/dist/bucket-validation.d.cts +27 -0
- package/dist/bucket-validation.d.cts.map +1 -0
- package/dist/bucket-validation.d.ts +27 -0
- package/dist/bucket-validation.d.ts.map +1 -0
- package/dist/bucket-validation.js +109 -0
- package/dist/bucket-validation.js.map +1 -0
- package/dist/bucket.cjs +125 -74
- package/dist/bucket.cjs.map +1 -1
- package/dist/bucket.d.cts +156 -61
- package/dist/bucket.d.cts.map +1 -1
- package/dist/bucket.d.ts +156 -61
- package/dist/bucket.d.ts.map +1 -1
- package/dist/bucket.js +125 -74
- package/dist/bucket.js.map +1 -1
- package/dist/client.cjs +29 -8
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +30 -9
- package/dist/client.d.cts.map +1 -1
- package/dist/client.d.ts +30 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +29 -8
- package/dist/client.js.map +1 -1
- package/dist/copy/large.cjs +5 -3
- package/dist/copy/large.cjs.map +1 -1
- package/dist/copy/large.d.cts.map +1 -1
- package/dist/copy/large.d.ts.map +1 -1
- package/dist/copy/large.js +5 -3
- package/dist/copy/large.js.map +1 -1
- package/dist/download/checksum.cjs +6 -2
- package/dist/download/checksum.cjs.map +1 -1
- package/dist/download/checksum.js +6 -2
- package/dist/download/checksum.js.map +1 -1
- package/dist/download/parallel.cjs +52 -15
- package/dist/download/parallel.cjs.map +1 -1
- package/dist/download/parallel.d.cts +8 -1
- package/dist/download/parallel.d.cts.map +1 -1
- package/dist/download/parallel.d.ts +8 -1
- package/dist/download/parallel.d.ts.map +1 -1
- package/dist/download/parallel.js +52 -15
- package/dist/download/parallel.js.map +1 -1
- package/dist/download/single.cjs +179 -19
- package/dist/download/single.cjs.map +1 -1
- package/dist/download/single.d.cts +10 -4
- package/dist/download/single.d.cts.map +1 -1
- package/dist/download/single.d.ts +10 -4
- package/dist/download/single.d.ts.map +1 -1
- package/dist/download/single.js +179 -19
- package/dist/download/single.js.map +1 -1
- package/dist/errors/index.cjs +196 -3
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +134 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +134 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +183 -4
- package/dist/errors/index.js.map +1 -1
- package/dist/http/non-idempotent-mutations.cjs +38 -0
- package/dist/http/non-idempotent-mutations.cjs.map +1 -0
- package/dist/http/non-idempotent-mutations.d.cts +25 -0
- package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
- package/dist/http/non-idempotent-mutations.d.ts +25 -0
- package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
- package/dist/http/non-idempotent-mutations.js +35 -0
- package/dist/http/non-idempotent-mutations.js.map +1 -0
- package/dist/http/retry.cjs +1 -1
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.js +1 -1
- package/dist/http/retry.js.map +1 -1
- package/dist/http/transport.cjs +62 -23
- package/dist/http/transport.cjs.map +1 -1
- package/dist/http/transport.d.cts +30 -3
- package/dist/http/transport.d.cts.map +1 -1
- package/dist/http/transport.d.ts +30 -3
- package/dist/http/transport.d.ts.map +1 -1
- package/dist/http/transport.js +60 -22
- package/dist/http/transport.js.map +1 -1
- package/dist/http/user-agent.cjs +12 -1
- package/dist/http/user-agent.cjs.map +1 -1
- package/dist/http/user-agent.d.cts +8 -0
- package/dist/http/user-agent.d.cts.map +1 -1
- package/dist/http/user-agent.d.ts +8 -0
- package/dist/http/user-agent.d.ts.map +1 -1
- package/dist/http/user-agent.js +13 -3
- package/dist/http/user-agent.js.map +1 -1
- package/dist/index.cjs +50 -2
- package/dist/index.d.cts +15 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -10
- package/dist/notifications/index.cjs +3 -0
- package/dist/notifications/index.d.cts +2 -0
- package/dist/notifications/index.d.cts.map +1 -1
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +2 -1
- package/dist/object.cjs +13 -2
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.cts +11 -3
- package/dist/object.d.cts.map +1 -1
- package/dist/object.d.ts +11 -3
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +13 -2
- package/dist/object.js.map +1 -1
- package/dist/partner/account-info.d.cts +43 -0
- package/dist/partner/account-info.d.cts.map +1 -0
- package/dist/partner/account-info.d.ts +43 -0
- package/dist/partner/account-info.d.ts.map +1 -0
- package/dist/partner/auth-clone.cjs +64 -0
- package/dist/partner/auth-clone.cjs.map +1 -0
- package/dist/partner/auth-clone.d.cts +27 -0
- package/dist/partner/auth-clone.d.cts.map +1 -0
- package/dist/partner/auth-clone.d.ts +27 -0
- package/dist/partner/auth-clone.d.ts.map +1 -0
- package/dist/partner/auth-clone.js +63 -0
- package/dist/partner/auth-clone.js.map +1 -0
- package/dist/partner/auth-core.cjs +156 -0
- package/dist/partner/auth-core.cjs.map +1 -0
- package/dist/partner/auth-core.d.cts +111 -0
- package/dist/partner/auth-core.d.cts.map +1 -0
- package/dist/partner/auth-core.d.ts +111 -0
- package/dist/partner/auth-core.d.ts.map +1 -0
- package/dist/partner/auth-core.js +156 -0
- package/dist/partner/auth-core.js.map +1 -0
- package/dist/partner/auth-shape.cjs +36 -0
- package/dist/partner/auth-shape.cjs.map +1 -0
- package/dist/partner/auth-shape.d.cts +12 -0
- package/dist/partner/auth-shape.d.cts.map +1 -0
- package/dist/partner/auth-shape.d.ts +12 -0
- package/dist/partner/auth-shape.d.ts.map +1 -0
- package/dist/partner/auth-shape.js +36 -0
- package/dist/partner/auth-shape.js.map +1 -0
- package/dist/partner/client.cjs +270 -0
- package/dist/partner/client.cjs.map +1 -0
- package/dist/partner/client.d.cts +357 -0
- package/dist/partner/client.d.cts.map +1 -0
- package/dist/partner/client.d.ts +357 -0
- package/dist/partner/client.d.ts.map +1 -0
- package/dist/partner/client.js +270 -0
- package/dist/partner/client.js.map +1 -0
- package/dist/partner/endpoint-url.cjs +109 -0
- package/dist/partner/endpoint-url.cjs.map +1 -0
- package/dist/partner/endpoint-url.d.cts +74 -0
- package/dist/partner/endpoint-url.d.cts.map +1 -0
- package/dist/partner/endpoint-url.d.ts +74 -0
- package/dist/partner/endpoint-url.d.ts.map +1 -0
- package/dist/partner/endpoint-url.js +106 -0
- package/dist/partner/endpoint-url.js.map +1 -0
- package/dist/partner/in-memory.cjs +135 -0
- package/dist/partner/in-memory.cjs.map +1 -0
- package/dist/partner/in-memory.d.cts +99 -0
- package/dist/partner/in-memory.d.cts.map +1 -0
- package/dist/partner/in-memory.d.ts +99 -0
- package/dist/partner/in-memory.d.ts.map +1 -0
- package/dist/partner/in-memory.js +135 -0
- package/dist/partner/in-memory.js.map +1 -0
- package/dist/partner/index.cjs +27 -0
- package/dist/partner/index.d.cts +32 -0
- package/dist/partner/index.d.cts.map +1 -0
- package/dist/partner/index.d.ts +32 -0
- package/dist/partner/index.d.ts.map +1 -0
- package/dist/partner/index.js +9 -0
- package/dist/partner/raw.cjs +400 -0
- package/dist/partner/raw.cjs.map +1 -0
- package/dist/partner/raw.d.cts +220 -0
- package/dist/partner/raw.d.cts.map +1 -0
- package/dist/partner/raw.d.ts +220 -0
- package/dist/partner/raw.d.ts.map +1 -0
- package/dist/partner/raw.js +398 -0
- package/dist/partner/raw.js.map +1 -0
- package/dist/partner/redaction-placeholders.cjs +10 -0
- package/dist/partner/redaction-placeholders.cjs.map +1 -0
- package/dist/partner/redaction-placeholders.d.cts +5 -0
- package/dist/partner/redaction-placeholders.d.cts.map +1 -0
- package/dist/partner/redaction-placeholders.d.ts +5 -0
- package/dist/partner/redaction-placeholders.d.ts.map +1 -0
- package/dist/partner/redaction-placeholders.js +9 -0
- package/dist/partner/redaction-placeholders.js.map +1 -0
- package/dist/partner/redaction.cjs +292 -0
- package/dist/partner/redaction.cjs.map +1 -0
- package/dist/partner/redaction.d.cts +158 -0
- package/dist/partner/redaction.d.cts.map +1 -0
- package/dist/partner/redaction.d.ts +158 -0
- package/dist/partner/redaction.d.ts.map +1 -0
- package/dist/partner/redaction.js +281 -0
- package/dist/partner/redaction.js.map +1 -0
- package/dist/raw/encoding.cjs +29 -10
- package/dist/raw/encoding.cjs.map +1 -1
- package/dist/raw/encoding.d.cts +3 -2
- package/dist/raw/encoding.d.cts.map +1 -1
- package/dist/raw/encoding.d.ts +3 -2
- package/dist/raw/encoding.d.ts.map +1 -1
- package/dist/raw/encoding.js +29 -10
- package/dist/raw/encoding.js.map +1 -1
- package/dist/raw/index.cjs +131 -44
- package/dist/raw/index.cjs.map +1 -1
- package/dist/raw/index.d.cts +21 -15
- package/dist/raw/index.d.cts.map +1 -1
- package/dist/raw/index.d.ts +21 -15
- package/dist/raw/index.d.ts.map +1 -1
- package/dist/raw/index.js +114 -45
- package/dist/raw/index.js.map +1 -1
- package/dist/raw/url.cjs +111 -0
- package/dist/raw/url.cjs.map +1 -0
- package/dist/raw/url.d.cts +41 -0
- package/dist/raw/url.d.cts.map +1 -0
- package/dist/raw/url.d.ts +41 -0
- package/dist/raw/url.d.ts.map +1 -0
- package/dist/raw/url.js +110 -0
- package/dist/raw/url.js.map +1 -0
- package/dist/s3/sigv4.cjs +15 -10
- package/dist/s3/sigv4.cjs.map +1 -1
- package/dist/s3/sigv4.js +15 -10
- package/dist/s3/sigv4.js.map +1 -1
- package/dist/simulator/index.cjs +1579 -257
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.cts +124 -11
- package/dist/simulator/index.d.cts.map +1 -1
- package/dist/simulator/index.d.ts +124 -11
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +1568 -262
- package/dist/simulator/index.js.map +1 -1
- package/dist/simulator/partner-capabilities.cjs +77 -0
- package/dist/simulator/partner-capabilities.cjs.map +1 -0
- package/dist/simulator/partner-capabilities.d.cts +53 -0
- package/dist/simulator/partner-capabilities.d.cts.map +1 -0
- package/dist/simulator/partner-capabilities.d.ts +53 -0
- package/dist/simulator/partner-capabilities.d.ts.map +1 -0
- package/dist/simulator/partner-capabilities.js +73 -0
- package/dist/simulator/partner-capabilities.js.map +1 -0
- package/dist/simulator/partner.cjs +713 -0
- package/dist/simulator/partner.cjs.map +1 -0
- package/dist/simulator/partner.d.cts +186 -0
- package/dist/simulator/partner.d.cts.map +1 -0
- package/dist/simulator/partner.d.ts +186 -0
- package/dist/simulator/partner.d.ts.map +1 -0
- package/dist/simulator/partner.js +713 -0
- package/dist/simulator/partner.js.map +1 -0
- package/dist/simulator/validation.cjs +732 -25
- package/dist/simulator/validation.cjs.map +1 -1
- package/dist/simulator/validation.d.cts +145 -6
- package/dist/simulator/validation.d.cts.map +1 -1
- package/dist/simulator/validation.d.ts +145 -6
- package/dist/simulator/validation.d.ts.map +1 -1
- package/dist/simulator/validation.js +705 -26
- package/dist/simulator/validation.js.map +1 -1
- package/dist/streams/file-source.cjs +2 -2
- package/dist/streams/file-source.cjs.map +1 -1
- package/dist/streams/file-source.js +2 -2
- package/dist/streams/file-source.js.map +1 -1
- package/dist/streams/hash.cjs +246 -13
- package/dist/streams/hash.cjs.map +1 -1
- package/dist/streams/hash.d.cts +37 -12
- package/dist/streams/hash.d.cts.map +1 -1
- package/dist/streams/hash.d.ts +37 -12
- package/dist/streams/hash.d.ts.map +1 -1
- package/dist/streams/hash.js +246 -15
- package/dist/streams/hash.js.map +1 -1
- package/dist/streams/index.cjs +3 -1
- package/dist/streams/index.d.cts +1 -1
- package/dist/streams/index.d.cts.map +1 -1
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.d.ts.map +1 -1
- package/dist/streams/index.js +3 -3
- package/dist/streams/progress.cjs +63 -4
- package/dist/streams/progress.cjs.map +1 -1
- package/dist/streams/progress.d.cts +28 -2
- package/dist/streams/progress.d.cts.map +1 -1
- package/dist/streams/progress.d.ts +28 -2
- package/dist/streams/progress.d.ts.map +1 -1
- package/dist/streams/progress.js +63 -4
- package/dist/streams/progress.js.map +1 -1
- package/dist/streams/source.cjs +2 -1
- package/dist/streams/source.cjs.map +1 -1
- package/dist/streams/source.js +2 -1
- package/dist/streams/source.js.map +1 -1
- package/dist/sync/b2-sha1-reader.cjs +6 -2
- package/dist/sync/b2-sha1-reader.cjs.map +1 -1
- package/dist/sync/b2-sha1-reader.d.cts.map +1 -1
- package/dist/sync/b2-sha1-reader.d.ts.map +1 -1
- package/dist/sync/b2-sha1-reader.js +6 -2
- package/dist/sync/b2-sha1-reader.js.map +1 -1
- package/dist/sync/download-staging.cjs +156 -43
- package/dist/sync/download-staging.cjs.map +1 -1
- package/dist/sync/download-staging.d.cts +26 -2
- package/dist/sync/download-staging.d.cts.map +1 -1
- package/dist/sync/download-staging.d.ts +26 -2
- package/dist/sync/download-staging.d.ts.map +1 -1
- package/dist/sync/download-staging.js +155 -44
- package/dist/sync/download-staging.js.map +1 -1
- package/dist/sync/filters.cjs.map +1 -1
- package/dist/sync/filters.js.map +1 -1
- package/dist/sync/index.d.cts +1 -1
- package/dist/sync/index.d.cts.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/local-file-io.cjs +15 -6
- package/dist/sync/local-file-io.cjs.map +1 -1
- package/dist/sync/local-file-io.d.cts +3 -0
- package/dist/sync/local-file-io.d.cts.map +1 -1
- package/dist/sync/local-file-io.d.ts +3 -0
- package/dist/sync/local-file-io.d.ts.map +1 -1
- package/dist/sync/local-file-io.js +15 -6
- package/dist/sync/local-file-io.js.map +1 -1
- package/dist/sync/local-sha1.cjs +6 -15
- package/dist/sync/local-sha1.cjs.map +1 -1
- package/dist/sync/local-sha1.d.cts +0 -8
- package/dist/sync/local-sha1.d.cts.map +1 -1
- package/dist/sync/local-sha1.d.ts +0 -8
- package/dist/sync/local-sha1.d.ts.map +1 -1
- package/dist/sync/local-sha1.js +7 -15
- package/dist/sync/local-sha1.js.map +1 -1
- package/dist/sync/pairing.cjs +1 -0
- package/dist/sync/pairing.cjs.map +1 -1
- package/dist/sync/pairing.js +1 -0
- package/dist/sync/pairing.js.map +1 -1
- package/dist/sync/policies/compare.cjs +5 -3
- package/dist/sync/policies/compare.cjs.map +1 -1
- package/dist/sync/policies/compare.d.cts.map +1 -1
- package/dist/sync/policies/compare.d.ts.map +1 -1
- package/dist/sync/policies/compare.js +6 -4
- package/dist/sync/policies/compare.js.map +1 -1
- package/dist/sync/policies/index.cjs +4 -10
- package/dist/sync/policies/index.cjs.map +1 -1
- package/dist/sync/policies/index.js +4 -10
- package/dist/sync/policies/index.js.map +1 -1
- package/dist/sync/scanners/b2.cjs +4 -2
- package/dist/sync/scanners/b2.cjs.map +1 -1
- package/dist/sync/scanners/b2.d.cts.map +1 -1
- package/dist/sync/scanners/b2.d.ts.map +1 -1
- package/dist/sync/scanners/b2.js +4 -2
- package/dist/sync/scanners/b2.js.map +1 -1
- package/dist/sync/scanners/local.cjs +150 -33
- package/dist/sync/scanners/local.cjs.map +1 -1
- package/dist/sync/scanners/local.d.cts +6 -0
- package/dist/sync/scanners/local.d.cts.map +1 -1
- package/dist/sync/scanners/local.d.ts +6 -0
- package/dist/sync/scanners/local.d.ts.map +1 -1
- package/dist/sync/scanners/local.js +150 -33
- package/dist/sync/scanners/local.js.map +1 -1
- package/dist/sync/synchronizer.cjs +79 -31
- package/dist/sync/synchronizer.cjs.map +1 -1
- package/dist/sync/synchronizer.d.cts +1 -0
- package/dist/sync/synchronizer.d.cts.map +1 -1
- package/dist/sync/synchronizer.d.ts +1 -0
- package/dist/sync/synchronizer.d.ts.map +1 -1
- package/dist/sync/synchronizer.js +79 -31
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/sync/types.d.cts +19 -3
- package/dist/sync/types.d.cts.map +1 -1
- package/dist/sync/types.d.ts +19 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types/auth.cjs +4 -0
- package/dist/types/auth.cjs.map +1 -1
- package/dist/types/auth.d.cts +4 -0
- package/dist/types/auth.d.cts.map +1 -1
- package/dist/types/auth.d.ts +4 -0
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js +4 -0
- package/dist/types/auth.js.map +1 -1
- package/dist/types/backup.d.cts +85 -0
- package/dist/types/backup.d.cts.map +1 -0
- package/dist/types/backup.d.ts +85 -0
- package/dist/types/backup.d.ts.map +1 -0
- package/dist/types/bucket.cjs +81 -11
- package/dist/types/bucket.cjs.map +1 -1
- package/dist/types/bucket.d.cts +194 -41
- package/dist/types/bucket.d.cts.map +1 -1
- package/dist/types/bucket.d.ts +194 -41
- package/dist/types/bucket.d.ts.map +1 -1
- package/dist/types/bucket.js +67 -12
- package/dist/types/bucket.js.map +1 -1
- package/dist/types/download.cjs +62 -0
- package/dist/types/download.cjs.map +1 -0
- package/dist/types/download.d.cts +100 -16
- package/dist/types/download.d.cts.map +1 -1
- package/dist/types/download.d.ts +100 -16
- package/dist/types/download.d.ts.map +1 -1
- package/dist/types/download.js +61 -0
- package/dist/types/download.js.map +1 -0
- package/dist/types/encryption.cjs +76 -229
- package/dist/types/encryption.cjs.map +1 -1
- package/dist/types/encryption.d.cts +48 -6
- package/dist/types/encryption.d.cts.map +1 -1
- package/dist/types/encryption.d.ts +48 -6
- package/dist/types/encryption.d.ts.map +1 -1
- package/dist/types/encryption.js +74 -229
- package/dist/types/encryption.js.map +1 -1
- package/dist/types/errors.cjs +9 -0
- package/dist/types/errors.cjs.map +1 -1
- package/dist/types/errors.d.cts +1 -1
- package/dist/types/errors.d.cts.map +1 -1
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +9 -0
- package/dist/types/errors.js.map +1 -1
- package/dist/types/file.cjs +3 -0
- package/dist/types/file.cjs.map +1 -1
- package/dist/types/file.d.cts +140 -18
- package/dist/types/file.d.cts.map +1 -1
- package/dist/types/file.d.ts +140 -18
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/file.js +3 -1
- package/dist/types/file.js.map +1 -1
- package/dist/types/ids.cjs +30 -0
- package/dist/types/ids.cjs.map +1 -1
- package/dist/types/ids.d.cts +32 -0
- package/dist/types/ids.d.cts.map +1 -1
- package/dist/types/ids.d.ts +32 -0
- package/dist/types/ids.d.ts.map +1 -1
- package/dist/types/ids.js +28 -1
- package/dist/types/ids.js.map +1 -1
- package/dist/types/index.d.cts +16 -12
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +16 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/key.d.cts +4 -3
- package/dist/types/key.d.cts.map +1 -1
- package/dist/types/key.d.ts +4 -3
- package/dist/types/key.d.ts.map +1 -1
- package/dist/types/lock.cjs.map +1 -1
- package/dist/types/lock.d.cts +14 -0
- package/dist/types/lock.d.cts.map +1 -1
- package/dist/types/lock.d.ts +14 -0
- package/dist/types/lock.d.ts.map +1 -1
- package/dist/types/lock.js.map +1 -1
- package/dist/types/notifications.cjs +31 -1
- package/dist/types/notifications.cjs.map +1 -1
- package/dist/types/notifications.d.cts +31 -4
- package/dist/types/notifications.d.cts.map +1 -1
- package/dist/types/notifications.d.ts +31 -4
- package/dist/types/notifications.d.ts.map +1 -1
- package/dist/types/notifications.js +30 -2
- package/dist/types/notifications.js.map +1 -1
- package/dist/types/partner.cjs +32 -0
- package/dist/types/partner.cjs.map +1 -0
- package/dist/types/partner.d.cts +386 -0
- package/dist/types/partner.d.cts.map +1 -0
- package/dist/types/partner.d.ts +386 -0
- package/dist/types/partner.d.ts.map +1 -0
- package/dist/types/partner.js +29 -0
- package/dist/types/partner.js.map +1 -0
- package/dist/types/upload.d.cts +35 -18
- package/dist/types/upload.d.cts.map +1 -1
- package/dist/types/upload.d.ts +35 -18
- package/dist/types/upload.d.ts.map +1 -1
- package/dist/upload/abort-scope.cjs +0 -45
- package/dist/upload/abort-scope.cjs.map +1 -1
- package/dist/upload/abort-scope.d.cts +0 -22
- package/dist/upload/abort-scope.d.cts.map +1 -1
- package/dist/upload/abort-scope.d.ts +0 -22
- package/dist/upload/abort-scope.d.ts.map +1 -1
- package/dist/upload/abort-scope.js +1 -44
- package/dist/upload/abort-scope.js.map +1 -1
- package/dist/upload/finish.cjs +3 -8
- package/dist/upload/finish.cjs.map +1 -1
- package/dist/upload/finish.d.cts.map +1 -1
- package/dist/upload/finish.d.ts.map +1 -1
- package/dist/upload/finish.js +1 -6
- package/dist/upload/finish.js.map +1 -1
- package/dist/upload/large.cjs +15 -8
- package/dist/upload/large.cjs.map +1 -1
- package/dist/upload/large.d.cts +31 -8
- package/dist/upload/large.d.cts.map +1 -1
- package/dist/upload/large.d.ts +31 -8
- package/dist/upload/large.d.ts.map +1 -1
- package/dist/upload/large.js +15 -8
- package/dist/upload/large.js.map +1 -1
- package/dist/upload/options.cjs.map +1 -1
- package/dist/upload/options.d.cts +24 -0
- package/dist/upload/options.d.cts.map +1 -1
- package/dist/upload/options.d.ts +24 -0
- package/dist/upload/options.d.ts.map +1 -1
- package/dist/upload/options.js.map +1 -1
- package/dist/upload/resume.cjs +6 -4
- package/dist/upload/resume.cjs.map +1 -1
- package/dist/upload/resume.d.cts +9 -5
- package/dist/upload/resume.d.cts.map +1 -1
- package/dist/upload/resume.d.ts +9 -5
- package/dist/upload/resume.d.ts.map +1 -1
- package/dist/upload/resume.js +6 -4
- package/dist/upload/resume.js.map +1 -1
- package/dist/upload/retry.cjs +25 -13
- package/dist/upload/retry.cjs.map +1 -1
- package/dist/upload/retry.d.cts.map +1 -1
- package/dist/upload/retry.d.ts.map +1 -1
- package/dist/upload/retry.js +25 -13
- package/dist/upload/retry.js.map +1 -1
- package/dist/upload/single.cjs +35 -30
- package/dist/upload/single.cjs.map +1 -1
- package/dist/upload/single.d.cts +12 -0
- package/dist/upload/single.d.cts.map +1 -1
- package/dist/upload/single.d.ts +12 -0
- package/dist/upload/single.d.ts.map +1 -1
- package/dist/upload/single.js +35 -30
- package/dist/upload/single.js.map +1 -1
- package/dist/upload/stream.cjs +18 -5
- package/dist/upload/stream.cjs.map +1 -1
- package/dist/upload/stream.d.cts +12 -0
- package/dist/upload/stream.d.cts.map +1 -1
- package/dist/upload/stream.d.ts +12 -0
- package/dist/upload/stream.d.ts.map +1 -1
- package/dist/upload/stream.js +15 -2
- package/dist/upload/stream.js.map +1 -1
- package/dist/util/abort.cjs +114 -0
- package/dist/util/abort.cjs.map +1 -0
- package/dist/util/abort.d.cts +65 -0
- package/dist/util/abort.d.cts.map +1 -0
- package/dist/util/abort.d.ts +65 -0
- package/dist/util/abort.d.ts.map +1 -0
- package/dist/util/abort.js +109 -0
- package/dist/util/abort.js.map +1 -0
- package/dist/util/defaults.cjs +3 -0
- package/dist/util/defaults.cjs.map +1 -1
- package/dist/util/defaults.d.cts +2 -0
- package/dist/util/defaults.d.cts.map +1 -1
- package/dist/util/defaults.d.ts +2 -0
- package/dist/util/defaults.d.ts.map +1 -1
- package/dist/util/defaults.js +3 -1
- package/dist/util/defaults.js.map +1 -1
- package/dist/util/md5.cjs +211 -0
- package/dist/util/md5.cjs.map +1 -0
- package/dist/util/md5.d.cts +43 -0
- package/dist/util/md5.d.cts.map +1 -0
- package/dist/util/md5.d.ts +43 -0
- package/dist/util/md5.d.ts.map +1 -0
- package/dist/util/md5.js +209 -0
- package/dist/util/md5.js.map +1 -0
- package/dist/util/normalize.cjs +5 -5
- package/dist/util/normalize.cjs.map +1 -1
- package/dist/util/normalize.d.cts +7 -7
- package/dist/util/normalize.d.cts.map +1 -1
- package/dist/util/normalize.d.ts +7 -7
- package/dist/util/normalize.d.ts.map +1 -1
- package/dist/util/normalize.js +5 -5
- package/dist/util/normalize.js.map +1 -1
- package/dist/util/paginator.cjs +7 -1
- package/dist/util/paginator.cjs.map +1 -1
- package/dist/util/paginator.d.cts +3 -1
- package/dist/util/paginator.d.cts.map +1 -1
- package/dist/util/paginator.d.ts +3 -1
- package/dist/util/paginator.d.ts.map +1 -1
- package/dist/util/paginator.js +7 -1
- package/dist/util/paginator.js.map +1 -1
- package/dist/version.cjs +56 -4
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +53 -4
- package/dist/version.d.cts.map +1 -1
- package/dist/version.d.ts +53 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +52 -5
- package/dist/version.js.map +1 -1
- package/package.json +47 -18
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../src/partner/redaction.js"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,yBAAyB,EACzB,uBAAuB,EAEvB,wBAAwB,EAKxB,iCAAiC,EACjC,+BAA+B,EAChC,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,6BAA6B,CAAA;AAEpC;;;GAGG;AACH,MAAM,WAAW,oCACf,SAAQ,IAAI,CAAC,wBAAwB,EAAE,oBAAoB,CAAC;IAC5D,wDAAwD;IACxD,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAA;CACpC;AAED;;;;;GAKG;AACH,MAAM,MAAM,mCAAmC,GAAG,IAAI,CACpD,uBAAuB,EACvB,gBAAgB,CACjB,GAAG;IACF,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,qCAAqC,GAAG,mCAAmC,CAAA;AAEvF;;;;;GAKG;AACH,MAAM,MAAM,2CAA2C,GAAG,IAAI,CAC5D,+BAA+B,EAC/B,gBAAgB,CACjB,GAAG;IACF,mDAAmD;IACnD,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAChC,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,6CAA6C,GACvD,2CAA2C,CAAA;AAiK7C;;;;;;GAMG;AACH,wBAAgB,sCAAsC,CACpD,IAAI,EAAE,wBAAwB,GAC7B,oCAAoC,CAgBtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,uBAAuB,GAC9B,mCAAmC,CAMrC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,yBAAyB,GAClC,qCAAqC,CAEvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,6CAA6C,CAC3D,MAAM,EAAE,+BAA+B,GACtC,2CAA2C,CAY7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,+CAA+C,CAC7D,QAAQ,EAAE,iCAAiC,GAC1C,6CAA6C,CAE/C;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,wBAAwB,GAC7B,wBAAwB,CAqB1B;AAED;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,uBAAuB,GAC9B,uBAAuB,CAMzB;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,yBAAyB,GAClC,yBAAyB,CAiB3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qCAAqC,CACnD,MAAM,EAAE,+BAA+B,GACtC,+BAA+B,CAMjC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,iCAAiC,GAC1C,iCAAiC,CAiBnC"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { B2PartnerAuthorizationError } from "../errors/index.js";
|
|
2
|
+
import { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED } from "./redaction-placeholders.js";
|
|
3
|
+
//#region src/partner/redaction.ts
|
|
4
|
+
var inspectSymbol = Symbol.for("nodejs.util.inspect.custom");
|
|
5
|
+
function partnerGroupsApiInfoToRedactedJson(info) {
|
|
6
|
+
return {
|
|
7
|
+
capabilities: [...info.capabilities],
|
|
8
|
+
groupsApiUrl: info.groupsApiUrl,
|
|
9
|
+
infoType: info.infoType
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function partnerBackupApiInfoToRedactedJson(info) {
|
|
13
|
+
return {
|
|
14
|
+
capabilities: [...info.capabilities],
|
|
15
|
+
backupApiUrl: info.backupApiUrl,
|
|
16
|
+
infoType: info.infoType
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function partnerStorageApiInfoToRedactedJson(info) {
|
|
20
|
+
return {
|
|
21
|
+
absoluteMinimumPartSize: info.absoluteMinimumPartSize,
|
|
22
|
+
apiUrl: info.apiUrl,
|
|
23
|
+
bucketId: info.bucketId,
|
|
24
|
+
bucketName: info.bucketName,
|
|
25
|
+
capabilities: [...info.capabilities],
|
|
26
|
+
downloadUrl: info.downloadUrl,
|
|
27
|
+
infoType: info.infoType,
|
|
28
|
+
namePrefix: info.namePrefix,
|
|
29
|
+
recommendedPartSize: info.recommendedPartSize,
|
|
30
|
+
s3ApiUrl: info.s3ApiUrl
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function partnerApiInfoToRedactedJson(apiInfo) {
|
|
34
|
+
const redacted = {};
|
|
35
|
+
if (apiInfo.storageApi !== void 0) redacted.storageApi = partnerStorageApiInfoToRedactedJson(apiInfo.storageApi);
|
|
36
|
+
if (apiInfo.groupsApi !== void 0) redacted.groupsApi = partnerGroupsApiInfoToRedactedJson(apiInfo.groupsApi);
|
|
37
|
+
if (apiInfo.backupApi !== void 0) redacted.backupApi = partnerBackupApiInfoToRedactedJson(apiInfo.backupApi);
|
|
38
|
+
return redacted;
|
|
39
|
+
}
|
|
40
|
+
function partnerGroupMemberToRedactedJson(groupMember) {
|
|
41
|
+
return {
|
|
42
|
+
accountId: groupMember.accountId,
|
|
43
|
+
email: groupMember.email,
|
|
44
|
+
groupId: groupMember.groupId,
|
|
45
|
+
groupName: groupMember.groupName,
|
|
46
|
+
region: groupMember.region,
|
|
47
|
+
s3Endpoint: groupMember.s3Endpoint
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function isSingleJsonObject(value) {
|
|
51
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
52
|
+
}
|
|
53
|
+
function isCredentialBearing(response) {
|
|
54
|
+
return isSingleJsonObject(response) && typeof response["applicationKey"] === "string" && typeof response["applicationKeyId"] === "string";
|
|
55
|
+
}
|
|
56
|
+
function matchesGroupMemberShape(groupMember) {
|
|
57
|
+
return isSingleJsonObject(groupMember) && typeof groupMember["accountId"] === "string" && typeof groupMember["email"] === "string" && typeof groupMember["groupId"] === "string" && typeof groupMember["groupName"] === "string" && typeof groupMember["region"] === "string" && typeof groupMember["s3Endpoint"] === "string";
|
|
58
|
+
}
|
|
59
|
+
function matchesReserveTrialAccountShape(response) {
|
|
60
|
+
return typeof response.accountId === "string" && typeof response.s3Endpoint === "string" && typeof response.startDate === "string" && typeof response.endDate === "string" && typeof response.email === "string" && typeof response.bucketName === "string" && typeof response.bucketId === "string";
|
|
61
|
+
}
|
|
62
|
+
function redactApplicationKeyShallow(target) {
|
|
63
|
+
return {
|
|
64
|
+
...target,
|
|
65
|
+
applicationKey: APPLICATION_KEY_REDACTED
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function installPortableJsonHook(target, toJson) {
|
|
69
|
+
const originalPrototype = Object.getPrototypeOf(target);
|
|
70
|
+
const redactionPrototype = Object.create(originalPrototype);
|
|
71
|
+
Object.defineProperty(redactionPrototype, "toJSON", {
|
|
72
|
+
value: toJson,
|
|
73
|
+
enumerable: false,
|
|
74
|
+
configurable: true
|
|
75
|
+
});
|
|
76
|
+
Object.setPrototypeOf(target, redactionPrototype);
|
|
77
|
+
Object.defineProperty(target, "toJSON", {
|
|
78
|
+
value: toJson,
|
|
79
|
+
enumerable: false,
|
|
80
|
+
configurable: true
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function redactWithHooks(value, toRedactedJsonForTarget, toRedactedString) {
|
|
84
|
+
const target = Object.isExtensible(value) ? value : { ...value };
|
|
85
|
+
const toRedactedJson = () => toRedactedJsonForTarget(target);
|
|
86
|
+
installPortableJsonHook(target, toRedactedJson);
|
|
87
|
+
Object.defineProperties(target, {
|
|
88
|
+
toString: {
|
|
89
|
+
value: toRedactedString,
|
|
90
|
+
enumerable: false,
|
|
91
|
+
configurable: true
|
|
92
|
+
},
|
|
93
|
+
[inspectSymbol]: {
|
|
94
|
+
value: toRedactedJson,
|
|
95
|
+
enumerable: false,
|
|
96
|
+
configurable: true
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return target;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns a redacted copy for log serializers that intentionally hide tokens.
|
|
103
|
+
*
|
|
104
|
+
* @param auth - Partner authorization response to render safely.
|
|
105
|
+
*
|
|
106
|
+
* @returns A plain object with the Partner token replaced by a placeholder.
|
|
107
|
+
*/
|
|
108
|
+
function partnerAuthorizeResponseToRedactedJson(auth) {
|
|
109
|
+
const redacted = {
|
|
110
|
+
accountId: auth.accountId,
|
|
111
|
+
authorizationToken: PARTNER_TOKEN_REDACTED,
|
|
112
|
+
apiInfo: partnerApiInfoToRedactedJson(auth.apiInfo),
|
|
113
|
+
applicationKeyExpirationTimestamp: auth.applicationKeyExpirationTimestamp
|
|
114
|
+
};
|
|
115
|
+
if (auth.groupsApiUrl !== void 0) redacted.groupsApiUrl = auth.groupsApiUrl;
|
|
116
|
+
if (auth.backupApiUrl !== void 0) redacted.backupApiUrl = auth.backupApiUrl;
|
|
117
|
+
if (auth.groupsCapabilities !== void 0) redacted.groupsCapabilities = [...auth.groupsCapabilities];
|
|
118
|
+
if (auth.backupCapabilities !== void 0) redacted.backupCapabilities = [...auth.backupCapabilities];
|
|
119
|
+
return redacted;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Returns a redacted copy for log serializers that intentionally hide group-member keys.
|
|
123
|
+
*
|
|
124
|
+
* @param result - Create group member result to render safely.
|
|
125
|
+
*
|
|
126
|
+
* @returns A plain object with the application key secret replaced by a placeholder.
|
|
127
|
+
*
|
|
128
|
+
* @experimental Partner API surface; shape may change as the Partner API docs evolve.
|
|
129
|
+
*/
|
|
130
|
+
function createGroupMemberResultToRedactedJson(result) {
|
|
131
|
+
return {
|
|
132
|
+
applicationKeyId: result.applicationKeyId,
|
|
133
|
+
applicationKey: APPLICATION_KEY_REDACTED,
|
|
134
|
+
groupMember: partnerGroupMemberToRedactedJson(result.groupMember)
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Returns a redacted copy for log serializers that intentionally hide group-member keys.
|
|
139
|
+
*
|
|
140
|
+
* @param response - Create group member response to render safely.
|
|
141
|
+
*
|
|
142
|
+
* @returns A plain object with the application key secret replaced by a placeholder.
|
|
143
|
+
*
|
|
144
|
+
* @experimental Partner API surface; shape may change as the Partner API docs evolve.
|
|
145
|
+
*/
|
|
146
|
+
function createGroupMemberResponseToRedactedJson(response) {
|
|
147
|
+
return createGroupMemberResultToRedactedJson(response);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Returns a redacted copy for log serializers that intentionally hide trial account keys.
|
|
151
|
+
*
|
|
152
|
+
* @param result - Reserve trial account result to render safely.
|
|
153
|
+
*
|
|
154
|
+
* @returns A plain object with the application key secret replaced by a placeholder.
|
|
155
|
+
*
|
|
156
|
+
* @experimental Partner API surface; shape may change as the Partner API docs evolve.
|
|
157
|
+
*/
|
|
158
|
+
function reserveTrialCreateAccountResultToRedactedJson(result) {
|
|
159
|
+
return {
|
|
160
|
+
accountId: result.accountId,
|
|
161
|
+
applicationKey: APPLICATION_KEY_REDACTED,
|
|
162
|
+
applicationKeyId: result.applicationKeyId,
|
|
163
|
+
s3Endpoint: result.s3Endpoint,
|
|
164
|
+
startDate: result.startDate,
|
|
165
|
+
endDate: result.endDate,
|
|
166
|
+
email: result.email,
|
|
167
|
+
bucketName: result.bucketName,
|
|
168
|
+
bucketId: result.bucketId
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Returns a redacted copy for log serializers that intentionally hide trial account keys.
|
|
173
|
+
*
|
|
174
|
+
* @param response - Reserve trial account response to render safely.
|
|
175
|
+
*
|
|
176
|
+
* @returns A plain object with the application key secret replaced by a placeholder.
|
|
177
|
+
*
|
|
178
|
+
* @experimental Partner API surface; shape may change as the Partner API docs evolve.
|
|
179
|
+
*/
|
|
180
|
+
function reserveTrialCreateAccountResponseToRedactedJson(response) {
|
|
181
|
+
return reserveTrialCreateAccountResultToRedactedJson(response);
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Adds non-enumerable serialization and inspection hooks that redact the
|
|
185
|
+
* Partner token through `JSON.stringify`, `toString`, and Node `util.inspect`
|
|
186
|
+
* while preserving direct property access.
|
|
187
|
+
*
|
|
188
|
+
* `JSON.stringify` no longer round-trips `authorizationToken` from protected
|
|
189
|
+
* authorize responses. Persist trusted auth caches with
|
|
190
|
+
* `partnerAuthorizeResponseForPersistence(auth)` only into encrypted or
|
|
191
|
+
* otherwise credential-grade storage, or read `authorizationToken` directly
|
|
192
|
+
* into secure storage before serializing.
|
|
193
|
+
*
|
|
194
|
+
* This does not make the object universally log-safe: object spread,
|
|
195
|
+
* `Object.assign`, `Object.entries`, `structuredClone`, and serializers that
|
|
196
|
+
* walk enumerable properties can still expose the raw token.
|
|
197
|
+
*
|
|
198
|
+
* @param auth - Partner authorization response to protect from accidental inspection.
|
|
199
|
+
*
|
|
200
|
+
* @returns The same auth object with inspection hooks installed when possible.
|
|
201
|
+
*/
|
|
202
|
+
function redactPartnerAuthorizeResponse(auth) {
|
|
203
|
+
const target = Object.isExtensible(auth) ? auth : { ...auth };
|
|
204
|
+
const toRedactedJson = () => partnerAuthorizeResponseToRedactedJson(target);
|
|
205
|
+
const toRedactedString = () => `[PartnerAuthorizeResponse ${PARTNER_TOKEN_REDACTED}]`;
|
|
206
|
+
installPortableJsonHook(target, toRedactedJson);
|
|
207
|
+
Object.defineProperties(target, {
|
|
208
|
+
toString: {
|
|
209
|
+
value: toRedactedString,
|
|
210
|
+
enumerable: false,
|
|
211
|
+
configurable: true
|
|
212
|
+
},
|
|
213
|
+
[inspectSymbol]: {
|
|
214
|
+
value: toRedactedJson,
|
|
215
|
+
enumerable: false,
|
|
216
|
+
configurable: true
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
return target;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Adds non-enumerable serialization and inspection hooks that redact the
|
|
223
|
+
* application key secret while preserving direct property access.
|
|
224
|
+
*
|
|
225
|
+
* @param result - Create group member result to protect from accidental logging.
|
|
226
|
+
*
|
|
227
|
+
* @returns The same result object with redaction hooks installed when possible.
|
|
228
|
+
*/
|
|
229
|
+
function redactCreateGroupMemberResult(result) {
|
|
230
|
+
return redactWithHooks(result, createGroupMemberResultToRedactedJson, () => `[CreateGroupMemberResult ${APPLICATION_KEY_REDACTED}]`);
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Adds non-enumerable serialization and inspection hooks that redact the
|
|
234
|
+
* create-group-member application key secret while preserving direct access.
|
|
235
|
+
*
|
|
236
|
+
* @param response - Create group member response to protect from accidental logging.
|
|
237
|
+
*
|
|
238
|
+
* @returns The same response object with redaction hooks installed when possible.
|
|
239
|
+
*
|
|
240
|
+
* @throws B2PartnerAuthorizationError if the response carries no usable application key.
|
|
241
|
+
*/
|
|
242
|
+
function redactCreateGroupMemberResponse(response) {
|
|
243
|
+
if (!isCredentialBearing(response)) throw new B2PartnerAuthorizationError("b2_create_group_member response did not contain a usable application key");
|
|
244
|
+
if (matchesGroupMemberShape(response.groupMember)) return redactCreateGroupMemberResult(response);
|
|
245
|
+
return redactWithHooks(response, redactApplicationKeyShallow, () => `[CreateGroupMemberResponse ${APPLICATION_KEY_REDACTED}]`);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Adds non-enumerable serialization and inspection hooks that redact the
|
|
249
|
+
* application key secret while preserving direct property access.
|
|
250
|
+
*
|
|
251
|
+
* `JSON.stringify` redacts because the response contains newly minted
|
|
252
|
+
* application key secrets that are commonly logged with responses. Callers
|
|
253
|
+
* that need to persist the key should read `applicationKey` directly into
|
|
254
|
+
* secure storage before serializing the object.
|
|
255
|
+
*
|
|
256
|
+
* @param result - Reserve trial account result to protect from accidental logging.
|
|
257
|
+
*
|
|
258
|
+
* @returns The same result object with redaction hooks installed when possible.
|
|
259
|
+
*/
|
|
260
|
+
function redactReserveTrialCreateAccountResult(result) {
|
|
261
|
+
return redactWithHooks(result, reserveTrialCreateAccountResultToRedactedJson, () => `[ReserveTrialCreateAccountResult ${APPLICATION_KEY_REDACTED}]`);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Adds non-enumerable serialization and inspection hooks that redact the
|
|
265
|
+
* reserve-trial application key secret while preserving direct property access.
|
|
266
|
+
*
|
|
267
|
+
* @param response - Reserve trial account response to protect from accidental logging.
|
|
268
|
+
*
|
|
269
|
+
* @returns The same response object with redaction hooks installed when possible.
|
|
270
|
+
*
|
|
271
|
+
* @throws B2PartnerAuthorizationError if the response carries no usable application key.
|
|
272
|
+
*/
|
|
273
|
+
function redactReserveTrialCreateAccountResponse(response) {
|
|
274
|
+
if (!isCredentialBearing(response)) throw new B2PartnerAuthorizationError("b2_reserve_trial_create_account response did not contain a usable application key");
|
|
275
|
+
if (matchesReserveTrialAccountShape(response)) return redactReserveTrialCreateAccountResult(response);
|
|
276
|
+
return redactWithHooks(response, redactApplicationKeyShallow, () => `[ReserveTrialCreateAccountResponse ${APPLICATION_KEY_REDACTED}]`);
|
|
277
|
+
}
|
|
278
|
+
//#endregion
|
|
279
|
+
export { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED, createGroupMemberResponseToRedactedJson, createGroupMemberResultToRedactedJson, partnerAuthorizeResponseToRedactedJson, redactCreateGroupMemberResponse, redactCreateGroupMemberResult, redactPartnerAuthorizeResponse, redactReserveTrialCreateAccountResponse, redactReserveTrialCreateAccountResult, reserveTrialCreateAccountResponseToRedactedJson, reserveTrialCreateAccountResultToRedactedJson };
|
|
280
|
+
|
|
281
|
+
//# sourceMappingURL=redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.js","names":[],"sources":["../../src/partner/redaction.ts"],"sourcesContent":["import { B2PartnerAuthorizationError } from '../errors/index.ts'\nimport type {\n CreateGroupMemberResponse,\n CreateGroupMemberResult,\n PartnerApiInfo,\n PartnerAuthorizeResponse,\n PartnerBackupApiInfo,\n PartnerGroupMember,\n PartnerGroupsApiInfo,\n PartnerStorageApiInfo,\n ReserveTrialCreateAccountResponse,\n ReserveTrialCreateAccountResult,\n} from '../types/partner.ts'\nimport { APPLICATION_KEY_REDACTED, PARTNER_TOKEN_REDACTED } from './redaction-placeholders.ts'\n\nexport {\n APPLICATION_KEY_REDACTED,\n PARTNER_TOKEN_REDACTED,\n} from './redaction-placeholders.ts'\n\n/**\n * JSON-safe Partner authorize response with the Partner token replaced by a\n * placeholder string.\n */\nexport interface RedactedPartnerAuthorizeResponseJson\n extends Omit<PartnerAuthorizeResponse, 'authorizationToken'> {\n /** Redacted Partner authorization token placeholder. */\n readonly authorizationToken: string\n}\n\n/**\n * JSON-safe create-group-member result with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedCreateGroupMemberResultJson = Omit<\n CreateGroupMemberResult,\n 'applicationKey'\n> & {\n /** Redacted application key secret placeholder. */\n readonly applicationKey: string\n}\n\n/**\n * JSON-safe create-group-member response with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedCreateGroupMemberResponseJson = RedactedCreateGroupMemberResultJson\n\n/**\n * JSON-safe reserve-trial account result with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedReserveTrialCreateAccountResultJson = Omit<\n ReserveTrialCreateAccountResult,\n 'applicationKey'\n> & {\n /** Redacted application key secret placeholder. */\n readonly applicationKey: string\n}\n\n/**\n * JSON-safe reserve-trial account response with the one-time application key\n * secret replaced by a placeholder string.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport type RedactedReserveTrialCreateAccountResponseJson =\n RedactedReserveTrialCreateAccountResultJson\n\nconst inspectSymbol = Symbol.for('nodejs.util.inspect.custom')\n\ntype Writable<T> = { -readonly [K in keyof T]: T[K] }\n\nfunction partnerGroupsApiInfoToRedactedJson(info: PartnerGroupsApiInfo): PartnerGroupsApiInfo {\n return {\n capabilities: [...info.capabilities],\n groupsApiUrl: info.groupsApiUrl,\n infoType: info.infoType,\n }\n}\n\nfunction partnerBackupApiInfoToRedactedJson(info: PartnerBackupApiInfo): PartnerBackupApiInfo {\n return {\n capabilities: [...info.capabilities],\n backupApiUrl: info.backupApiUrl,\n infoType: info.infoType,\n }\n}\n\nfunction partnerStorageApiInfoToRedactedJson(info: PartnerStorageApiInfo): PartnerStorageApiInfo {\n return {\n absoluteMinimumPartSize: info.absoluteMinimumPartSize,\n apiUrl: info.apiUrl,\n bucketId: info.bucketId,\n bucketName: info.bucketName,\n capabilities: [...info.capabilities],\n downloadUrl: info.downloadUrl,\n infoType: info.infoType,\n namePrefix: info.namePrefix,\n recommendedPartSize: info.recommendedPartSize,\n s3ApiUrl: info.s3ApiUrl,\n }\n}\n\nfunction partnerApiInfoToRedactedJson(apiInfo: PartnerApiInfo): PartnerApiInfo {\n const redacted: Writable<PartnerApiInfo> = {}\n if (apiInfo.storageApi !== undefined) {\n redacted.storageApi = partnerStorageApiInfoToRedactedJson(apiInfo.storageApi)\n }\n if (apiInfo.groupsApi !== undefined) {\n redacted.groupsApi = partnerGroupsApiInfoToRedactedJson(apiInfo.groupsApi)\n }\n if (apiInfo.backupApi !== undefined) {\n redacted.backupApi = partnerBackupApiInfoToRedactedJson(apiInfo.backupApi)\n }\n return redacted\n}\n\nfunction partnerGroupMemberToRedactedJson(groupMember: PartnerGroupMember): PartnerGroupMember {\n return {\n accountId: groupMember.accountId,\n email: groupMember.email,\n groupId: groupMember.groupId,\n groupName: groupMember.groupName,\n region: groupMember.region,\n s3Endpoint: groupMember.s3Endpoint,\n }\n}\n\nfunction isSingleJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n// The one invariant a create/reserve redaction wrapper must never violate: a\n// usable one-time credential must survive. B2 mints the application key exactly\n// once, after the (non-deletable) account already exists, so throwing the\n// response away over an unexpected *non-credential* field would destroy an\n// unrecoverable secret — the core hazard of #280. We hard-fail only when there\n// is no usable credential to preserve (nothing is lost in that case).\nfunction isCredentialBearing(\n response: unknown,\n): response is { applicationKey: string; applicationKeyId: string } {\n return (\n isSingleJsonObject(response) &&\n typeof response['applicationKey'] === 'string' &&\n typeof response['applicationKeyId'] === 'string'\n )\n}\n\n// True when `groupMember` matches every documented field type, so the\n// field-specific (allowlist) redaction copies the full shape without dropping\n// unexpected fields. A partial/variant object falls back to shallow redaction.\nfunction matchesGroupMemberShape(groupMember: unknown): groupMember is PartnerGroupMember {\n return (\n isSingleJsonObject(groupMember) &&\n typeof groupMember['accountId'] === 'string' &&\n typeof groupMember['email'] === 'string' &&\n typeof groupMember['groupId'] === 'string' &&\n typeof groupMember['groupName'] === 'string' &&\n typeof groupMember['region'] === 'string' &&\n typeof groupMember['s3Endpoint'] === 'string'\n )\n}\n\n// True when the reserve-trial response also matches every documented\n// non-credential field, so the field-specific (allowlist) redaction is exact.\nfunction matchesReserveTrialAccountShape(response: ReserveTrialCreateAccountResponse): boolean {\n return (\n typeof response.accountId === 'string' &&\n typeof response.s3Endpoint === 'string' &&\n typeof response.startDate === 'string' &&\n typeof response.endDate === 'string' &&\n typeof response.email === 'string' &&\n typeof response.bucketName === 'string' &&\n typeof response.bucketId === 'string'\n )\n}\n\n// Redaction hook for a credential-bearing response whose surrounding shape is\n// unexpected: shallow-copy every field the server sent and redact only the\n// one-time secret, so the response is never discarded and never logs the key.\nfunction redactApplicationKeyShallow<T extends object>(target: T): unknown {\n return { ...target, applicationKey: APPLICATION_KEY_REDACTED }\n}\n\n// Bun/WebKit only honor object toJSON hooks when they are inherited, while Node\n// honors own hooks. Install both shapes so SDK safe serialization is portable.\nfunction installPortableJsonHook<T extends object>(target: T, toJson: () => unknown): void {\n const originalPrototype = Object.getPrototypeOf(target)\n const redactionPrototype = Object.create(originalPrototype) as object\n Object.defineProperty(redactionPrototype, 'toJSON', {\n value: toJson,\n enumerable: false,\n configurable: true,\n })\n Object.setPrototypeOf(target, redactionPrototype)\n Object.defineProperty(target, 'toJSON', {\n value: toJson,\n enumerable: false,\n configurable: true,\n })\n}\n\nfunction redactWithHooks<T extends object>(\n value: T,\n toRedactedJsonForTarget: (target: T) => unknown,\n toRedactedString: () => string,\n): T {\n const target = Object.isExtensible(value) ? value : ({ ...value } as T)\n const toRedactedJson = (): unknown => toRedactedJsonForTarget(target)\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide tokens.\n *\n * @param auth - Partner authorization response to render safely.\n *\n * @returns A plain object with the Partner token replaced by a placeholder.\n */\nexport function partnerAuthorizeResponseToRedactedJson(\n auth: PartnerAuthorizeResponse,\n): RedactedPartnerAuthorizeResponseJson {\n const redacted: Writable<RedactedPartnerAuthorizeResponseJson> = {\n accountId: auth.accountId,\n authorizationToken: PARTNER_TOKEN_REDACTED,\n apiInfo: partnerApiInfoToRedactedJson(auth.apiInfo),\n applicationKeyExpirationTimestamp: auth.applicationKeyExpirationTimestamp,\n }\n if (auth.groupsApiUrl !== undefined) redacted.groupsApiUrl = auth.groupsApiUrl\n if (auth.backupApiUrl !== undefined) redacted.backupApiUrl = auth.backupApiUrl\n if (auth.groupsCapabilities !== undefined) {\n redacted.groupsCapabilities = [...auth.groupsCapabilities]\n }\n if (auth.backupCapabilities !== undefined) {\n redacted.backupCapabilities = [...auth.backupCapabilities]\n }\n return redacted\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide group-member keys.\n *\n * @param result - Create group member result to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function createGroupMemberResultToRedactedJson(\n result: CreateGroupMemberResult,\n): RedactedCreateGroupMemberResultJson {\n return {\n applicationKeyId: result.applicationKeyId,\n applicationKey: APPLICATION_KEY_REDACTED,\n groupMember: partnerGroupMemberToRedactedJson(result.groupMember),\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide group-member keys.\n *\n * @param response - Create group member response to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function createGroupMemberResponseToRedactedJson(\n response: CreateGroupMemberResponse,\n): RedactedCreateGroupMemberResponseJson {\n return createGroupMemberResultToRedactedJson(response)\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide trial account keys.\n *\n * @param result - Reserve trial account result to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function reserveTrialCreateAccountResultToRedactedJson(\n result: ReserveTrialCreateAccountResult,\n): RedactedReserveTrialCreateAccountResultJson {\n return {\n accountId: result.accountId,\n applicationKey: APPLICATION_KEY_REDACTED,\n applicationKeyId: result.applicationKeyId,\n s3Endpoint: result.s3Endpoint,\n startDate: result.startDate,\n endDate: result.endDate,\n email: result.email,\n bucketName: result.bucketName,\n bucketId: result.bucketId,\n }\n}\n\n/**\n * Returns a redacted copy for log serializers that intentionally hide trial account keys.\n *\n * @param response - Reserve trial account response to render safely.\n *\n * @returns A plain object with the application key secret replaced by a placeholder.\n *\n * @experimental Partner API surface; shape may change as the Partner API docs evolve.\n */\nexport function reserveTrialCreateAccountResponseToRedactedJson(\n response: ReserveTrialCreateAccountResponse,\n): RedactedReserveTrialCreateAccountResponseJson {\n return reserveTrialCreateAccountResultToRedactedJson(response)\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * Partner token through `JSON.stringify`, `toString`, and Node `util.inspect`\n * while preserving direct property access.\n *\n * `JSON.stringify` no longer round-trips `authorizationToken` from protected\n * authorize responses. Persist trusted auth caches with\n * `partnerAuthorizeResponseForPersistence(auth)` only into encrypted or\n * otherwise credential-grade storage, or read `authorizationToken` directly\n * into secure storage before serializing.\n *\n * This does not make the object universally log-safe: object spread,\n * `Object.assign`, `Object.entries`, `structuredClone`, and serializers that\n * walk enumerable properties can still expose the raw token.\n *\n * @param auth - Partner authorization response to protect from accidental inspection.\n *\n * @returns The same auth object with inspection hooks installed when possible.\n */\nexport function redactPartnerAuthorizeResponse(\n auth: PartnerAuthorizeResponse,\n): PartnerAuthorizeResponse {\n const target = Object.isExtensible(auth) ? auth : { ...auth }\n const toRedactedJson = (): RedactedPartnerAuthorizeResponseJson =>\n partnerAuthorizeResponseToRedactedJson(target)\n const toRedactedString = (): string => `[PartnerAuthorizeResponse ${PARTNER_TOKEN_REDACTED}]`\n\n installPortableJsonHook(target, toRedactedJson)\n Object.defineProperties(target, {\n toString: {\n value: toRedactedString,\n enumerable: false,\n configurable: true,\n },\n [inspectSymbol]: {\n value: toRedactedJson,\n enumerable: false,\n configurable: true,\n },\n })\n\n return target\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * application key secret while preserving direct property access.\n *\n * @param result - Create group member result to protect from accidental logging.\n *\n * @returns The same result object with redaction hooks installed when possible.\n */\nexport function redactCreateGroupMemberResult(\n result: CreateGroupMemberResult,\n): CreateGroupMemberResult {\n return redactWithHooks(\n result,\n createGroupMemberResultToRedactedJson,\n () => `[CreateGroupMemberResult ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * create-group-member application key secret while preserving direct access.\n *\n * @param response - Create group member response to protect from accidental logging.\n *\n * @returns The same response object with redaction hooks installed when possible.\n *\n * @throws B2PartnerAuthorizationError if the response carries no usable application key.\n */\nexport function redactCreateGroupMemberResponse(\n response: CreateGroupMemberResponse,\n): CreateGroupMemberResponse {\n if (!isCredentialBearing(response)) {\n throw new B2PartnerAuthorizationError(\n 'b2_create_group_member response did not contain a usable application key',\n )\n }\n // Full documented shape → field-specific (allowlist) redaction.\n if (matchesGroupMemberShape(response.groupMember)) {\n return redactCreateGroupMemberResult(response)\n }\n // Credential present but the surrounding shape is unexpected: never discard a\n // provisioned one-time key. Return it with only the secret redacted for logs.\n return redactWithHooks(\n response,\n redactApplicationKeyShallow,\n () => `[CreateGroupMemberResponse ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * application key secret while preserving direct property access.\n *\n * `JSON.stringify` redacts because the response contains newly minted\n * application key secrets that are commonly logged with responses. Callers\n * that need to persist the key should read `applicationKey` directly into\n * secure storage before serializing the object.\n *\n * @param result - Reserve trial account result to protect from accidental logging.\n *\n * @returns The same result object with redaction hooks installed when possible.\n */\nexport function redactReserveTrialCreateAccountResult(\n result: ReserveTrialCreateAccountResult,\n): ReserveTrialCreateAccountResult {\n return redactWithHooks(\n result,\n reserveTrialCreateAccountResultToRedactedJson,\n () => `[ReserveTrialCreateAccountResult ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n\n/**\n * Adds non-enumerable serialization and inspection hooks that redact the\n * reserve-trial application key secret while preserving direct property access.\n *\n * @param response - Reserve trial account response to protect from accidental logging.\n *\n * @returns The same response object with redaction hooks installed when possible.\n *\n * @throws B2PartnerAuthorizationError if the response carries no usable application key.\n */\nexport function redactReserveTrialCreateAccountResponse(\n response: ReserveTrialCreateAccountResponse,\n): ReserveTrialCreateAccountResponse {\n if (!isCredentialBearing(response)) {\n throw new B2PartnerAuthorizationError(\n 'b2_reserve_trial_create_account response did not contain a usable application key',\n )\n }\n // Full documented shape → field-specific (allowlist) redaction.\n if (matchesReserveTrialAccountShape(response)) {\n return redactReserveTrialCreateAccountResult(response)\n }\n // Credential present but the surrounding shape is unexpected: never discard a\n // provisioned one-time key. Return it with only the secret redacted for logs.\n return redactWithHooks(\n response,\n redactApplicationKeyShallow,\n () => `[ReserveTrialCreateAccountResponse ${APPLICATION_KEY_REDACTED}]`,\n )\n}\n"],"mappings":"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"}
|
package/dist/raw/encoding.cjs
CHANGED
|
@@ -7,6 +7,16 @@ const require_text_codec = require("../util/text-codec.cjs");
|
|
|
7
7
|
* must be percent-encoded using UTF-8 byte values.
|
|
8
8
|
*/
|
|
9
9
|
var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/".split(""));
|
|
10
|
+
var FILE_INFO_VALUE_SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split(""));
|
|
11
|
+
function encodeWithSafeChars(value, safeChars) {
|
|
12
|
+
const encoded = [];
|
|
13
|
+
for (const char of value) if (safeChars.has(char)) encoded.push(char);
|
|
14
|
+
else {
|
|
15
|
+
const bytes = require_text_codec.utf8Encoder.encode(char);
|
|
16
|
+
for (const byte of bytes) encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, "0")}`);
|
|
17
|
+
}
|
|
18
|
+
return encoded.join("");
|
|
19
|
+
}
|
|
10
20
|
/**
|
|
11
21
|
* Percent-encodes a file name using the B2-specific encoding rules.
|
|
12
22
|
*
|
|
@@ -19,13 +29,21 @@ var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01
|
|
|
19
29
|
* @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.
|
|
20
30
|
*/
|
|
21
31
|
function encodeFileName(name) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
return encodeWithSafeChars(name, SAFE_CHARS);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Percent-encodes a file-info value using the stricter B2 metadata value rules.
|
|
36
|
+
*
|
|
37
|
+
* File-info values must be decoded by B2 before storage. Live B2 rejects comma
|
|
38
|
+
* and other RFC punctuation when left raw in these values, so only RFC 3986
|
|
39
|
+
* unreserved characters are passed through.
|
|
40
|
+
*
|
|
41
|
+
* @param value - The raw (unencoded) file-info value.
|
|
42
|
+
*
|
|
43
|
+
* @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.
|
|
44
|
+
*/
|
|
45
|
+
function encodeFileInfoValue(value) {
|
|
46
|
+
return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS);
|
|
29
47
|
}
|
|
30
48
|
/**
|
|
31
49
|
* Decodes a B2 percent-encoded file name back to a plain string.
|
|
@@ -43,8 +61,9 @@ function decodeFileName(encoded) {
|
|
|
43
61
|
/**
|
|
44
62
|
* Converts a file-info map into `X-Bz-Info-*` HTTP headers.
|
|
45
63
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
64
|
+
* Keys use B2 file-name encoding. Values use stricter B2 file-info value
|
|
65
|
+
* encoding so punctuation such as commas is percent-encoded before B2 decodes
|
|
66
|
+
* and validates stored metadata.
|
|
48
67
|
*
|
|
49
68
|
* @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
|
|
50
69
|
*
|
|
@@ -53,7 +72,7 @@ function decodeFileName(encoded) {
|
|
|
53
72
|
function buildFileInfoHeaders(fileInfo) {
|
|
54
73
|
if (!fileInfo) return {};
|
|
55
74
|
const headers = {};
|
|
56
|
-
for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] =
|
|
75
|
+
for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value);
|
|
57
76
|
return headers;
|
|
58
77
|
}
|
|
59
78
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.cjs","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n
|
|
1
|
+
{"version":3,"file":"encoding.cjs","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\nconst FILE_INFO_VALUE_SAFE_CHARS = new Set(\n 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.split(''),\n)\n\nfunction encodeWithSafeChars(value: string, safeChars: ReadonlySet<string>): string {\n const encoded: string[] = []\n for (const char of value) {\n if (safeChars.has(char)) {\n encoded.push(char)\n } else {\n const bytes = utf8Encoder.encode(char)\n for (const byte of bytes) {\n encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, '0')}`)\n }\n }\n }\n return encoded.join('')\n}\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n return encodeWithSafeChars(name, SAFE_CHARS)\n}\n\n/**\n * Percent-encodes a file-info value using the stricter B2 metadata value rules.\n *\n * File-info values must be decoded by B2 before storage. Live B2 rejects comma\n * and other RFC punctuation when left raw in these values, so only RFC 3986\n * unreserved characters are passed through.\n *\n * @param value - The raw (unencoded) file-info value.\n *\n * @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.\n */\nfunction encodeFileInfoValue(value: string): string {\n return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS)\n}\n\n/**\n * Decodes a B2 percent-encoded file name back to a plain string.\n *\n * B2 percent-encoding is compatible with standard `decodeURIComponent`,\n * so this is a thin wrapper.\n *\n * @param encoded - The percent-encoded file name from B2.\n *\n * @returns The decoded file name.\n */\nexport function decodeFileName(encoded: string): string {\n return decodeURIComponent(encoded)\n}\n\n/**\n * Converts a file-info map into `X-Bz-Info-*` HTTP headers.\n *\n * Keys use B2 file-name encoding. Values use stricter B2 file-info value\n * encoding so punctuation such as commas is percent-encoded before B2 decodes\n * and validates stored metadata.\n *\n * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.\n *\n * @returns A record of header name/value pairs (empty if `fileInfo` is `undefined`).\n */\nexport function buildFileInfoHeaders(\n fileInfo: Record<string, string> | undefined,\n): Record<string, string> {\n if (!fileInfo) return {}\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(fileInfo)) {\n headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value)\n }\n return headers\n}\n\n/**\n * Extracts custom file-info key/value pairs from B2 response headers.\n *\n * Scans for headers prefixed with `x-bz-info-` and decodes both the\n * key suffix and value using {@link decodeFileName}.\n *\n * @param headers - The HTTP response headers from a B2 download or file-info call.\n *\n * @returns A record of decoded file-info key/value pairs.\n */\nexport function parseFileInfoHeaders(headers: Headers): Record<string, string> {\n const info: Record<string, string> = {}\n headers.forEach((value, key) => {\n const lower = key.toLowerCase()\n if (lower.startsWith('x-bz-info-')) {\n const infoKey = decodeFileName(lower.slice('x-bz-info-'.length))\n info[infoKey] = decodeFileName(value)\n }\n })\n return info\n}\n"],"mappings":";;;;;;;;AAQA,IAAM,aAAa,IAAI,IACrB,mFAAmF,MAAM,EAAE,CAC7F;AAEA,IAAM,6BAA6B,IAAI,IACrC,qEAAqE,MAAM,EAAE,CAC/E;AAEA,SAAS,oBAAoB,OAAe,WAAwC;CAClF,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,OACjB,IAAI,UAAU,IAAI,IAAI,GACpB,QAAQ,KAAK,IAAI;MACZ;EACL,MAAM,QAAQ,mBAAA,YAAY,OAAO,IAAI;EACrC,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;CAEvE;CAEF,OAAO,QAAQ,KAAK,EAAE;AACxB;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAsB;CACnD,OAAO,oBAAoB,MAAM,UAAU;AAC7C;;;;;;;;;;;;AAaA,SAAS,oBAAoB,OAAuB;CAClD,OAAO,oBAAoB,OAAO,0BAA0B;AAC9D;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,mBAAmB,OAAO;AACnC;;;;;;;;;;;;AAaA,SAAgB,qBACd,UACwB;CACxB,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,QAAQ,aAAa,eAAe,GAAG,OAAO,oBAAoB,KAAK;CAEzE,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAA0C;CAC7E,MAAM,OAA+B,CAAC;CACtC,QAAQ,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI,MAAM,WAAW,YAAY,GAAG;GAClC,MAAM,UAAU,eAAe,MAAM,MAAM,EAAmB,CAAC;GAC/D,KAAK,WAAW,eAAe,KAAK;EACtC;CACF,CAAC;CACD,OAAO;AACT"}
|
package/dist/raw/encoding.d.cts
CHANGED
|
@@ -24,8 +24,9 @@ export declare function decodeFileName(encoded: string): string;
|
|
|
24
24
|
/**
|
|
25
25
|
* Converts a file-info map into `X-Bz-Info-*` HTTP headers.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* Keys use B2 file-name encoding. Values use stricter B2 file-info value
|
|
28
|
+
* encoding so punctuation such as commas is percent-encoded before B2 decodes
|
|
29
|
+
* and validates stored metadata.
|
|
29
30
|
*
|
|
30
31
|
* @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
|
|
31
32
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E"}
|
package/dist/raw/encoding.d.ts
CHANGED
|
@@ -24,8 +24,9 @@ export declare function decodeFileName(encoded: string): string;
|
|
|
24
24
|
/**
|
|
25
25
|
* Converts a file-info map into `X-Bz-Info-*` HTTP headers.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
27
|
+
* Keys use B2 file-name encoding. Values use stricter B2 file-info value
|
|
28
|
+
* encoding so punctuation such as commas is percent-encoded before B2 decodes
|
|
29
|
+
* and validates stored metadata.
|
|
29
30
|
*
|
|
30
31
|
* @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
|
|
31
32
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/raw/encoding.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAC3C,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAU7E"}
|
package/dist/raw/encoding.js
CHANGED
|
@@ -7,6 +7,16 @@ import { utf8Encoder } from "../util/text-codec.js";
|
|
|
7
7
|
* must be percent-encoded using UTF-8 byte values.
|
|
8
8
|
*/
|
|
9
9
|
var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/".split(""));
|
|
10
|
+
var FILE_INFO_VALUE_SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~".split(""));
|
|
11
|
+
function encodeWithSafeChars(value, safeChars) {
|
|
12
|
+
const encoded = [];
|
|
13
|
+
for (const char of value) if (safeChars.has(char)) encoded.push(char);
|
|
14
|
+
else {
|
|
15
|
+
const bytes = utf8Encoder.encode(char);
|
|
16
|
+
for (const byte of bytes) encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, "0")}`);
|
|
17
|
+
}
|
|
18
|
+
return encoded.join("");
|
|
19
|
+
}
|
|
10
20
|
/**
|
|
11
21
|
* Percent-encodes a file name using the B2-specific encoding rules.
|
|
12
22
|
*
|
|
@@ -19,13 +29,21 @@ var SAFE_CHARS = new Set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01
|
|
|
19
29
|
* @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.
|
|
20
30
|
*/
|
|
21
31
|
function encodeFileName(name) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
return encodeWithSafeChars(name, SAFE_CHARS);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Percent-encodes a file-info value using the stricter B2 metadata value rules.
|
|
36
|
+
*
|
|
37
|
+
* File-info values must be decoded by B2 before storage. Live B2 rejects comma
|
|
38
|
+
* and other RFC punctuation when left raw in these values, so only RFC 3986
|
|
39
|
+
* unreserved characters are passed through.
|
|
40
|
+
*
|
|
41
|
+
* @param value - The raw (unencoded) file-info value.
|
|
42
|
+
*
|
|
43
|
+
* @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.
|
|
44
|
+
*/
|
|
45
|
+
function encodeFileInfoValue(value) {
|
|
46
|
+
return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS);
|
|
29
47
|
}
|
|
30
48
|
/**
|
|
31
49
|
* Decodes a B2 percent-encoded file name back to a plain string.
|
|
@@ -43,8 +61,9 @@ function decodeFileName(encoded) {
|
|
|
43
61
|
/**
|
|
44
62
|
* Converts a file-info map into `X-Bz-Info-*` HTTP headers.
|
|
45
63
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
64
|
+
* Keys use B2 file-name encoding. Values use stricter B2 file-info value
|
|
65
|
+
* encoding so punctuation such as commas is percent-encoded before B2 decodes
|
|
66
|
+
* and validates stored metadata.
|
|
48
67
|
*
|
|
49
68
|
* @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.
|
|
50
69
|
*
|
|
@@ -53,7 +72,7 @@ function decodeFileName(encoded) {
|
|
|
53
72
|
function buildFileInfoHeaders(fileInfo) {
|
|
54
73
|
if (!fileInfo) return {};
|
|
55
74
|
const headers = {};
|
|
56
|
-
for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] =
|
|
75
|
+
for (const [key, value] of Object.entries(fileInfo)) headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value);
|
|
57
76
|
return headers;
|
|
58
77
|
}
|
|
59
78
|
/**
|
package/dist/raw/encoding.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.js","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n
|
|
1
|
+
{"version":3,"file":"encoding.js","names":[],"sources":["../../src/raw/encoding.ts"],"sourcesContent":["import { utf8Encoder } from '../util/text-codec.ts'\n\n/**\n * Characters that B2 treats as safe (not percent-encoded) in file names.\n *\n * Per the B2 docs, everything except `a-z A-Z 0-9 - . _ ~ / ! $ & ' ( ) * + , ; = : @`\n * must be percent-encoded using UTF-8 byte values.\n */\nconst SAFE_CHARS = new Set(\n \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@/\".split(''),\n)\n\nconst FILE_INFO_VALUE_SAFE_CHARS = new Set(\n 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'.split(''),\n)\n\nfunction encodeWithSafeChars(value: string, safeChars: ReadonlySet<string>): string {\n const encoded: string[] = []\n for (const char of value) {\n if (safeChars.has(char)) {\n encoded.push(char)\n } else {\n const bytes = utf8Encoder.encode(char)\n for (const byte of bytes) {\n encoded.push(`%${byte.toString(16).toUpperCase().padStart(2, '0')}`)\n }\n }\n }\n return encoded.join('')\n}\n\n/**\n * Percent-encodes a file name using the B2-specific encoding rules.\n *\n * Unlike standard `encodeURIComponent`, B2 keeps `/` and several other\n * characters unencoded while encoding all other non-ASCII and special\n * characters as uppercase percent-encoded UTF-8 bytes.\n *\n * @param name - The raw (unencoded) file name.\n *\n * @returns The percent-encoded file name suitable for `X-Bz-File-Name` headers.\n */\nexport function encodeFileName(name: string): string {\n return encodeWithSafeChars(name, SAFE_CHARS)\n}\n\n/**\n * Percent-encodes a file-info value using the stricter B2 metadata value rules.\n *\n * File-info values must be decoded by B2 before storage. Live B2 rejects comma\n * and other RFC punctuation when left raw in these values, so only RFC 3986\n * unreserved characters are passed through.\n *\n * @param value - The raw (unencoded) file-info value.\n *\n * @returns The percent-encoded value suitable for `X-Bz-Info-*` header values.\n */\nfunction encodeFileInfoValue(value: string): string {\n return encodeWithSafeChars(value, FILE_INFO_VALUE_SAFE_CHARS)\n}\n\n/**\n * Decodes a B2 percent-encoded file name back to a plain string.\n *\n * B2 percent-encoding is compatible with standard `decodeURIComponent`,\n * so this is a thin wrapper.\n *\n * @param encoded - The percent-encoded file name from B2.\n *\n * @returns The decoded file name.\n */\nexport function decodeFileName(encoded: string): string {\n return decodeURIComponent(encoded)\n}\n\n/**\n * Converts a file-info map into `X-Bz-Info-*` HTTP headers.\n *\n * Keys use B2 file-name encoding. Values use stricter B2 file-info value\n * encoding so punctuation such as commas is percent-encoded before B2 decodes\n * and validates stored metadata.\n *\n * @param fileInfo - Key/value pairs to attach as custom file info, or `undefined`.\n *\n * @returns A record of header name/value pairs (empty if `fileInfo` is `undefined`).\n */\nexport function buildFileInfoHeaders(\n fileInfo: Record<string, string> | undefined,\n): Record<string, string> {\n if (!fileInfo) return {}\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(fileInfo)) {\n headers[`X-Bz-Info-${encodeFileName(key)}`] = encodeFileInfoValue(value)\n }\n return headers\n}\n\n/**\n * Extracts custom file-info key/value pairs from B2 response headers.\n *\n * Scans for headers prefixed with `x-bz-info-` and decodes both the\n * key suffix and value using {@link decodeFileName}.\n *\n * @param headers - The HTTP response headers from a B2 download or file-info call.\n *\n * @returns A record of decoded file-info key/value pairs.\n */\nexport function parseFileInfoHeaders(headers: Headers): Record<string, string> {\n const info: Record<string, string> = {}\n headers.forEach((value, key) => {\n const lower = key.toLowerCase()\n if (lower.startsWith('x-bz-info-')) {\n const infoKey = decodeFileName(lower.slice('x-bz-info-'.length))\n info[infoKey] = decodeFileName(value)\n }\n })\n return info\n}\n"],"mappings":";;;;;;;;AAQA,IAAM,aAAa,IAAI,IACrB,mFAAmF,MAAM,EAAE,CAC7F;AAEA,IAAM,6BAA6B,IAAI,IACrC,qEAAqE,MAAM,EAAE,CAC/E;AAEA,SAAS,oBAAoB,OAAe,WAAwC;CAClF,MAAM,UAAoB,CAAC;CAC3B,KAAK,MAAM,QAAQ,OACjB,IAAI,UAAU,IAAI,IAAI,GACpB,QAAQ,KAAK,IAAI;MACZ;EACL,MAAM,QAAQ,YAAY,OAAO,IAAI;EACrC,KAAK,MAAM,QAAQ,OACjB,QAAQ,KAAK,IAAI,KAAK,SAAS,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG;CAEvE;CAEF,OAAO,QAAQ,KAAK,EAAE;AACxB;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAsB;CACnD,OAAO,oBAAoB,MAAM,UAAU;AAC7C;;;;;;;;;;;;AAaA,SAAS,oBAAoB,OAAuB;CAClD,OAAO,oBAAoB,OAAO,0BAA0B;AAC9D;;;;;;;;;;;AAYA,SAAgB,eAAe,SAAyB;CACtD,OAAO,mBAAmB,OAAO;AACnC;;;;;;;;;;;;AAaA,SAAgB,qBACd,UACwB;CACxB,IAAI,CAAC,UAAU,OAAO,CAAC;CACvB,MAAM,UAAkC,CAAC;CACzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,QAAQ,aAAa,eAAe,GAAG,OAAO,oBAAoB,KAAK;CAEzE,OAAO;AACT;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAA0C;CAC7E,MAAM,OAA+B,CAAC;CACtC,QAAQ,SAAS,OAAO,QAAQ;EAC9B,MAAM,QAAQ,IAAI,YAAY;EAC9B,IAAI,MAAM,WAAW,YAAY,GAAG;GAClC,MAAM,UAAU,eAAe,MAAM,MAAM,EAAmB,CAAC;GAC/D,KAAK,WAAW,eAAe,KAAK;EACtC;CACF,CAAC;CACD,OAAO;AACT"}
|