@backblaze-labs/b2-sdk 0.3.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 +45 -1
- package/README.md +18 -5
- package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
- package/dist/_virtual/_b2-sdk-version-json.js +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/raw.cjs +37 -15
- package/dist/backup/raw.cjs.map +1 -1
- package/dist/backup/raw.d.cts +2 -2
- package/dist/backup/raw.d.cts.map +1 -1
- package/dist/backup/raw.d.ts +2 -2
- package/dist/backup/raw.d.ts.map +1 -1
- package/dist/backup/raw.js +37 -15
- package/dist/backup/raw.js.map +1 -1
- 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 +123 -73
- 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 +123 -73
- 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/download/single.cjs +38 -13
- 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 +38 -13
- package/dist/download/single.js.map +1 -1
- package/dist/errors/index.cjs +27 -4
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +15 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +15 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +27 -5
- 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/transport.cjs +9 -8
- package/dist/http/transport.cjs.map +1 -1
- package/dist/http/transport.d.cts +5 -0
- package/dist/http/transport.d.cts.map +1 -1
- package/dist/http/transport.d.ts +5 -0
- package/dist/http/transport.d.ts.map +1 -1
- package/dist/http/transport.js +9 -8
- 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 +25 -0
- package/dist/index.d.cts +10 -9
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +10 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- 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 +12 -1
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.cts +7 -1
- package/dist/object.d.cts.map +1 -1
- package/dist/object.d.ts +7 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +12 -1
- package/dist/object.js.map +1 -1
- package/dist/partner/auth-core.cjs +4 -23
- package/dist/partner/auth-core.cjs.map +1 -1
- package/dist/partner/auth-core.d.cts +1 -1
- package/dist/partner/auth-core.d.cts.map +1 -1
- package/dist/partner/auth-core.d.ts +1 -1
- package/dist/partner/auth-core.d.ts.map +1 -1
- package/dist/partner/auth-core.js +5 -24
- package/dist/partner/auth-core.js.map +1 -1
- package/dist/partner/client.cjs +25 -10
- package/dist/partner/client.cjs.map +1 -1
- package/dist/partner/client.d.cts +32 -10
- package/dist/partner/client.d.cts.map +1 -1
- package/dist/partner/client.d.ts +32 -10
- package/dist/partner/client.d.ts.map +1 -1
- package/dist/partner/client.js +25 -10
- package/dist/partner/client.js.map +1 -1
- package/dist/partner/endpoint-url.cjs +1 -0
- package/dist/partner/endpoint-url.cjs.map +1 -1
- package/dist/partner/endpoint-url.d.cts +2 -0
- package/dist/partner/endpoint-url.d.cts.map +1 -1
- package/dist/partner/endpoint-url.d.ts +2 -0
- package/dist/partner/endpoint-url.d.ts.map +1 -1
- package/dist/partner/endpoint-url.js +1 -0
- package/dist/partner/endpoint-url.js.map +1 -1
- package/dist/partner/in-memory.cjs.map +1 -1
- package/dist/partner/in-memory.js.map +1 -1
- package/dist/partner/index.cjs +9 -0
- package/dist/partner/index.d.cts +11 -2
- package/dist/partner/index.d.cts.map +1 -1
- package/dist/partner/index.d.ts +11 -2
- package/dist/partner/index.d.ts.map +1 -1
- package/dist/partner/index.js +3 -1
- package/dist/partner/raw.cjs +52 -44
- package/dist/partner/raw.cjs.map +1 -1
- package/dist/partner/raw.d.cts +16 -19
- package/dist/partner/raw.d.cts.map +1 -1
- package/dist/partner/raw.d.ts +16 -19
- package/dist/partner/raw.d.ts.map +1 -1
- package/dist/partner/raw.js +52 -44
- package/dist/partner/raw.js.map +1 -1
- package/dist/partner/redaction.cjs +133 -108
- package/dist/partner/redaction.cjs.map +1 -1
- package/dist/partner/redaction.d.cts +47 -13
- package/dist/partner/redaction.d.cts.map +1 -1
- package/dist/partner/redaction.d.ts +47 -13
- package/dist/partner/redaction.d.ts.map +1 -1
- package/dist/partner/redaction.js +133 -109
- package/dist/partner/redaction.js.map +1 -1
- 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 +64 -39
- package/dist/raw/index.cjs.map +1 -1
- package/dist/raw/index.d.cts +21 -19
- package/dist/raw/index.d.cts.map +1 -1
- package/dist/raw/index.d.ts +21 -19
- package/dist/raw/index.d.ts.map +1 -1
- package/dist/raw/index.js +47 -40
- package/dist/raw/index.js.map +1 -1
- package/dist/raw/url.cjs.map +1 -1
- package/dist/raw/url.d.cts +3 -3
- package/dist/raw/url.d.ts +3 -3
- package/dist/raw/url.js.map +1 -1
- package/dist/simulator/index.cjs +456 -125
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.cts +16 -1
- package/dist/simulator/index.d.cts.map +1 -1
- package/dist/simulator/index.d.ts +16 -1
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +449 -130
- 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 +55 -61
- package/dist/simulator/partner.cjs.map +1 -1
- package/dist/simulator/partner.d.cts +5 -2
- package/dist/simulator/partner.d.cts.map +1 -1
- package/dist/simulator/partner.d.ts +5 -2
- package/dist/simulator/partner.d.ts.map +1 -1
- package/dist/simulator/partner.js +56 -61
- package/dist/simulator/partner.js.map +1 -1
- package/dist/simulator/validation.cjs +160 -30
- package/dist/simulator/validation.cjs.map +1 -1
- package/dist/simulator/validation.d.cts +28 -6
- package/dist/simulator/validation.d.cts.map +1 -1
- package/dist/simulator/validation.d.ts +28 -6
- package/dist/simulator/validation.d.ts.map +1 -1
- package/dist/simulator/validation.js +148 -31
- package/dist/simulator/validation.js.map +1 -1
- package/dist/streams/file-source.cjs +1 -1
- package/dist/streams/file-source.cjs.map +1 -1
- package/dist/streams/file-source.js +1 -1
- 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 +2 -0
- 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 +2 -2
- 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/sync/download-staging.cjs +147 -35
- package/dist/sync/download-staging.cjs.map +1 -1
- package/dist/sync/download-staging.d.cts +25 -2
- package/dist/sync/download-staging.d.cts.map +1 -1
- package/dist/sync/download-staging.d.ts +25 -2
- package/dist/sync/download-staging.d.ts.map +1 -1
- package/dist/sync/download-staging.js +146 -36
- package/dist/sync/download-staging.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 +5 -1
- package/dist/sync/local-file-io.cjs.map +1 -1
- package/dist/sync/local-file-io.d.cts +2 -0
- package/dist/sync/local-file-io.d.cts.map +1 -1
- package/dist/sync/local-file-io.d.ts +2 -0
- package/dist/sync/local-file-io.d.ts.map +1 -1
- package/dist/sync/local-file-io.js +5 -1
- package/dist/sync/local-file-io.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/scanners/b2.cjs +2 -0
- 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 +2 -0
- 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 +76 -29
- 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 +76 -29
- 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/backup.d.cts +6 -1
- package/dist/types/backup.d.cts.map +1 -1
- package/dist/types/backup.d.ts +6 -1
- package/dist/types/backup.d.ts.map +1 -1
- package/dist/types/bucket.cjs +81 -11
- package/dist/types/bucket.cjs.map +1 -1
- package/dist/types/bucket.d.cts +190 -39
- package/dist/types/bucket.d.cts.map +1 -1
- package/dist/types/bucket.d.ts +190 -39
- 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.map +1 -1
- package/dist/types/download.d.cts +3 -17
- package/dist/types/download.d.cts.map +1 -1
- package/dist/types/download.d.ts +3 -17
- package/dist/types/download.d.ts.map +1 -1
- package/dist/types/download.js.map +1 -1
- package/dist/types/encryption.cjs +18 -0
- package/dist/types/encryption.cjs.map +1 -1
- package/dist/types/encryption.d.cts +21 -11
- package/dist/types/encryption.d.cts.map +1 -1
- package/dist/types/encryption.d.ts +21 -11
- package/dist/types/encryption.d.ts.map +1 -1
- package/dist/types/encryption.js +18 -0
- package/dist/types/encryption.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 +125 -16
- package/dist/types/file.d.cts.map +1 -1
- package/dist/types/file.d.ts +125 -16
- 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/index.d.cts +7 -7
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +7 -7
- 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/notifications.cjs +30 -0
- package/dist/types/notifications.cjs.map +1 -1
- package/dist/types/notifications.d.cts +26 -1
- package/dist/types/notifications.d.cts.map +1 -1
- package/dist/types/notifications.d.ts +26 -1
- package/dist/types/notifications.d.ts.map +1 -1
- package/dist/types/notifications.js +29 -1
- package/dist/types/notifications.js.map +1 -1
- package/dist/types/partner.cjs.map +1 -1
- package/dist/types/partner.d.cts +28 -36
- package/dist/types/partner.d.cts.map +1 -1
- package/dist/types/partner.d.ts +28 -36
- package/dist/types/partner.d.ts.map +1 -1
- package/dist/types/partner.js.map +1 -1
- package/dist/types/upload.d.cts +4 -0
- package/dist/types/upload.d.cts.map +1 -1
- package/dist/types/upload.d.ts +4 -0
- package/dist/types/upload.d.ts.map +1 -1
- package/dist/upload/large.cjs +10 -7
- package/dist/upload/large.cjs.map +1 -1
- package/dist/upload/large.d.cts +15 -6
- package/dist/upload/large.d.cts.map +1 -1
- package/dist/upload/large.d.ts +15 -6
- package/dist/upload/large.d.ts.map +1 -1
- package/dist/upload/large.js +10 -7
- package/dist/upload/large.js.map +1 -1
- package/dist/upload/options.cjs.map +1 -1
- package/dist/upload/options.d.cts +12 -0
- package/dist/upload/options.d.cts.map +1 -1
- package/dist/upload/options.d.ts +12 -0
- package/dist/upload/options.d.ts.map +1 -1
- package/dist/upload/options.js.map +1 -1
- package/dist/upload/resume.cjs +4 -3
- package/dist/upload/resume.cjs.map +1 -1
- package/dist/upload/resume.d.cts +6 -4
- package/dist/upload/resume.d.cts.map +1 -1
- package/dist/upload/resume.d.ts +6 -4
- package/dist/upload/resume.d.ts.map +1 -1
- package/dist/upload/resume.js +4 -3
- package/dist/upload/resume.js.map +1 -1
- package/dist/upload/retry.cjs +17 -10
- 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 +17 -10
- package/dist/upload/retry.js.map +1 -1
- package/dist/upload/single.cjs +35 -31
- package/dist/upload/single.cjs.map +1 -1
- package/dist/upload/single.d.cts +6 -0
- package/dist/upload/single.d.cts.map +1 -1
- package/dist/upload/single.d.ts +6 -0
- package/dist/upload/single.d.ts.map +1 -1
- package/dist/upload/single.js +35 -31
- package/dist/upload/single.js.map +1 -1
- package/dist/upload/stream.cjs +12 -1
- package/dist/upload/stream.cjs.map +1 -1
- package/dist/upload/stream.d.cts +6 -0
- package/dist/upload/stream.d.cts.map +1 -1
- package/dist/upload/stream.d.ts +6 -0
- package/dist/upload/stream.d.ts.map +1 -1
- package/dist/upload/stream.js +12 -1
- package/dist/upload/stream.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 +11 -4
package/dist/simulator/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FileAction } from "../types/file.js";
|
|
1
|
+
import { FileAction, HIDE_MARKER_CONTENT_TYPE } from "../types/file.js";
|
|
2
2
|
import { accountId, bucketId, fileId } from "../types/ids.js";
|
|
3
3
|
import { utf8Decoder, utf8Encoder } from "../util/text-codec.js";
|
|
4
4
|
import { encodeFileName } from "../raw/encoding.js";
|
|
@@ -8,14 +8,15 @@ import { EncryptionAlgorithm, EncryptionMode } from "../types/encryption.js";
|
|
|
8
8
|
import { LegalHoldValue, RetentionMode } from "../types/lock.js";
|
|
9
9
|
import { hexEncode, hmacSha256 } from "../util/crypto.js";
|
|
10
10
|
import { sha1Hex } from "../streams/hash.js";
|
|
11
|
-
import { BucketRetentionMode } from "../types/bucket.js";
|
|
11
|
+
import { BUCKET_INFO_KEY_MAX_BYTES, BUCKET_INFO_KEY_MIN_BYTES, BUCKET_INFO_KEY_PATTERN, BUCKET_INFO_RESERVED_PREFIX, BUCKET_INFO_VALUES_MAX_BYTES, BucketRetentionMode, CORS_MAX_AGE_SECONDS_MAX, CORS_RULES_MAX_COUNT, CORS_RULE_MAX_BYTES, CORS_RULE_NAME_MAX_LENGTH, CORS_RULE_NAME_MIN_LENGTH, CORS_RULE_NAME_PATTERN, CORS_RULE_NAME_RESERVED_PREFIX } from "../types/bucket.js";
|
|
12
12
|
import { toError } from "../util/to-error.js";
|
|
13
13
|
import { b2Url, isB2ApiVersion } from "../raw/url.js";
|
|
14
14
|
import { Capability } from "../types/auth.js";
|
|
15
|
-
import {
|
|
15
|
+
import { PartnerEndpoint } from "./partner-capabilities.js";
|
|
16
|
+
import { PartnerSimulator } from "./partner.js";
|
|
16
17
|
import { missingCapabilitiesFor } from "./capabilities.js";
|
|
17
18
|
import { BUCKET_NAME_MAX, BUCKET_NAME_MIN, FILE_NAME_MAX_BYTES } from "../internal/b2-naming.js";
|
|
18
|
-
import { BUCKET_INFO_MAX_KEYS, BUCKET_INFO_VALUE_MAX, DOWNLOAD_AUTH_DURATION_MAX_SECONDS, DOWNLOAD_AUTH_DURATION_MIN_SECONDS, FILE_INFO_TOTAL_MAX, FILE_INFO_VALUE_MAX, KEY_NAME_MAX, KEY_NAME_MIN, LIST_ENDPOINT_CAPS, normalizeCreateKeyCapabilities, validateBucketInfo, validateBucketName, validateBucketTypes, validateCorsRules, validateCreateKeyCapabilities, validateCreateKeyName, validateDefaultRetention, validateDownloadAuthorizationDuration, validateDownloadAuthorizationPrefix, validateFileInfo, validateFileName, validateLifecycleRules, validateMaxCount, validateNotificationRules, validateReplicationConfiguration } from "./validation.js";
|
|
19
|
+
import { BUCKET_INFO_MAX_KEYS, BUCKET_INFO_VALUE_MAX, DOWNLOAD_AUTH_DURATION_MAX_SECONDS, DOWNLOAD_AUTH_DURATION_MIN_SECONDS, FILE_INFO_TOTAL_MAX, FILE_INFO_VALUE_MAX, KEY_NAME_MAX, KEY_NAME_MIN, LIST_ENDPOINT_CAPS, normalizeCreateKeyCapabilities, validateBucketInfo, validateBucketName, validateBucketType, validateBucketTypes, validateCorsRules, validateCreateKeyCapabilities, validateCreateKeyName, validateDefaultRetention, validateDownloadAuthorizationDuration, validateDownloadAuthorizationPrefix, validateFileInfo, validateFileName, validateLifecycleRules, validateMaxCount, validateNotificationRules, validateReplicationConfiguration } from "./validation.js";
|
|
19
20
|
//#region src/simulator/index.ts
|
|
20
21
|
var UPLOAD_TOKEN_SIGNING_KEY = [
|
|
21
22
|
"b2 sdk typescript",
|
|
@@ -55,9 +56,22 @@ var SIMULATOR_MASTER_CAPABILITIES = [
|
|
|
55
56
|
function apiPathParts(path) {
|
|
56
57
|
const segments = path.split("/").filter((segment) => segment.length > 0);
|
|
57
58
|
const candidate = segments.at(-2);
|
|
59
|
+
const endpoint = segments.at(-1) ?? "";
|
|
60
|
+
const isB2ApiPath = segments.at(-3) === "b2api";
|
|
61
|
+
if (candidate !== void 0 && isB2ApiVersion(candidate)) {
|
|
62
|
+
if (candidate === "v3" || candidate === "v4") return {
|
|
63
|
+
endpoint,
|
|
64
|
+
version: candidate
|
|
65
|
+
};
|
|
66
|
+
if (isB2ApiPath) return {
|
|
67
|
+
endpoint,
|
|
68
|
+
version: "v3",
|
|
69
|
+
unsupportedVersion: candidate
|
|
70
|
+
};
|
|
71
|
+
}
|
|
58
72
|
return {
|
|
59
|
-
endpoint
|
|
60
|
-
version:
|
|
73
|
+
endpoint,
|
|
74
|
+
version: "v3"
|
|
61
75
|
};
|
|
62
76
|
}
|
|
63
77
|
function parseBasicAuthorizationHeader(authzHeader) {
|
|
@@ -190,6 +204,11 @@ function compareB2FileNames(a, b) {
|
|
|
190
204
|
if (a > b) return 1;
|
|
191
205
|
return 0;
|
|
192
206
|
}
|
|
207
|
+
function compareFileVersionListEntries(a, b) {
|
|
208
|
+
const nameCmp = compareB2FileNames(a.fileName, b.fileName);
|
|
209
|
+
if (nameCmp !== 0) return nameCmp;
|
|
210
|
+
return b.uploadTimestamp - a.uploadTimestamp;
|
|
211
|
+
}
|
|
193
212
|
var DOWNLOAD_AUTH_TOKEN_BYTES = 32;
|
|
194
213
|
var DOWNLOAD_AUTH_TOKEN_PREFIX = "sim_dl_auth_";
|
|
195
214
|
var DOWNLOAD_AUTH_PURGE_BATCH_SIZE = 128;
|
|
@@ -283,6 +302,44 @@ function normalizeReplicationConfiguration(config) {
|
|
|
283
302
|
asReplicationDestination: config.asReplicationDestination ?? null
|
|
284
303
|
};
|
|
285
304
|
}
|
|
305
|
+
function wrapReplicationConfiguration(config) {
|
|
306
|
+
if (config === void 0) return {
|
|
307
|
+
isClientAuthorizedToRead: true,
|
|
308
|
+
value: null
|
|
309
|
+
};
|
|
310
|
+
const normalized = normalizeReplicationConfiguration(config);
|
|
311
|
+
return {
|
|
312
|
+
isClientAuthorizedToRead: true,
|
|
313
|
+
value: normalized.asReplicationSource === null && normalized.asReplicationDestination === null ? null : normalized
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function filterReadableReplicationConfiguration(config, canRead) {
|
|
317
|
+
return canRead ? {
|
|
318
|
+
isClientAuthorizedToRead: true,
|
|
319
|
+
value: config.value
|
|
320
|
+
} : {
|
|
321
|
+
isClientAuthorizedToRead: false,
|
|
322
|
+
value: null
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
function readableFileRetention(value, canRead) {
|
|
326
|
+
return canRead ? {
|
|
327
|
+
isClientAuthorizedToRead: true,
|
|
328
|
+
value
|
|
329
|
+
} : {
|
|
330
|
+
isClientAuthorizedToRead: false,
|
|
331
|
+
value: null
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
function readableLegalHold(value, canRead) {
|
|
335
|
+
return canRead ? {
|
|
336
|
+
isClientAuthorizedToRead: true,
|
|
337
|
+
value
|
|
338
|
+
} : {
|
|
339
|
+
isClientAuthorizedToRead: false,
|
|
340
|
+
value: null
|
|
341
|
+
};
|
|
342
|
+
}
|
|
286
343
|
function validateBucketConfigurationFields(fields, options) {
|
|
287
344
|
if (fields.bucketInfo !== void 0) {
|
|
288
345
|
const infoError = validateBucketInfo(fields.bucketInfo);
|
|
@@ -296,6 +353,10 @@ function validateBucketConfigurationFields(fields, options) {
|
|
|
296
353
|
const lifecycleError = validateLifecycleRules(fields.lifecycleRules);
|
|
297
354
|
if (lifecycleError) return lifecycleError;
|
|
298
355
|
}
|
|
356
|
+
if (fields.defaultServerSideEncryption !== void 0) {
|
|
357
|
+
const encryptionError = validateBucketDefaultServerSideEncryption(fields.defaultServerSideEncryption);
|
|
358
|
+
if (encryptionError) return encryptionError;
|
|
359
|
+
}
|
|
299
360
|
if (fields.replicationConfiguration !== void 0) {
|
|
300
361
|
const replicationError = validateReplicationConfiguration(fields.replicationConfiguration);
|
|
301
362
|
if (replicationError) return replicationError;
|
|
@@ -310,6 +371,34 @@ function validateBucketConfigurationFields(fields, options) {
|
|
|
310
371
|
}
|
|
311
372
|
return null;
|
|
312
373
|
}
|
|
374
|
+
function validateBucketDefaultServerSideEncryption(encryption) {
|
|
375
|
+
const runtimeEncryption = requestRecord(encryption);
|
|
376
|
+
if (runtimeEncryption === null) return {
|
|
377
|
+
code: "bad_request",
|
|
378
|
+
message: "defaultServerSideEncryption must be an object"
|
|
379
|
+
};
|
|
380
|
+
if (hasCustomerEncryptionFields(runtimeEncryption)) return {
|
|
381
|
+
code: "bad_request",
|
|
382
|
+
message: "Bucket default server-side encryption cannot use SSE-C"
|
|
383
|
+
};
|
|
384
|
+
const mode = runtimeEncryption["mode"];
|
|
385
|
+
if (mode === EncryptionMode.None) return null;
|
|
386
|
+
if (mode === EncryptionMode.SseB2) {
|
|
387
|
+
if (runtimeEncryption["algorithm"] !== EncryptionAlgorithm.Aes256) return {
|
|
388
|
+
code: "bad_request",
|
|
389
|
+
message: "SSE-B2 algorithm must be AES256"
|
|
390
|
+
};
|
|
391
|
+
return null;
|
|
392
|
+
}
|
|
393
|
+
if (mode === EncryptionMode.SseC) return {
|
|
394
|
+
code: "bad_request",
|
|
395
|
+
message: "Bucket default server-side encryption cannot use SSE-C"
|
|
396
|
+
};
|
|
397
|
+
return {
|
|
398
|
+
code: "bad_request",
|
|
399
|
+
message: `Unsupported bucket default server-side encryption mode: ${String(mode)}`
|
|
400
|
+
};
|
|
401
|
+
}
|
|
313
402
|
function nextObjectLockEnabled(current, requested) {
|
|
314
403
|
if (requested === void 0) return current;
|
|
315
404
|
if (typeof requested !== "boolean") return {
|
|
@@ -352,59 +441,188 @@ function fileNames(...names) {
|
|
|
352
441
|
const present = names.filter((name) => name !== void 0);
|
|
353
442
|
return present.length > 0 ? present : void 0;
|
|
354
443
|
}
|
|
355
|
-
function queryParamsBody(params) {
|
|
444
|
+
function queryParamsBody(params, endpoint) {
|
|
445
|
+
const metadata = jsonEndpointMetadata(endpoint);
|
|
446
|
+
const queryFields = new Set(metadata?.queryFields ?? []);
|
|
447
|
+
const numericFields = new Set(metadata?.numericQueryFields ?? []);
|
|
356
448
|
const body = Object.create(null);
|
|
357
|
-
let hasParams = false;
|
|
358
449
|
for (const [key, value] of params) {
|
|
450
|
+
if (!queryFields.has(key)) continue;
|
|
359
451
|
if (body[key] !== void 0) continue;
|
|
360
|
-
body[key] = value;
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
]
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
]
|
|
452
|
+
body[key] = queryParamValue(value, numericFields.has(key));
|
|
453
|
+
}
|
|
454
|
+
return body;
|
|
455
|
+
}
|
|
456
|
+
function queryParamValue(value, numeric) {
|
|
457
|
+
if (!numeric || !/^-?\d+$/.test(value)) return value;
|
|
458
|
+
const numericValue = Number(value);
|
|
459
|
+
return Number.isSafeInteger(numericValue) ? numericValue : value;
|
|
460
|
+
}
|
|
461
|
+
var JSON_ENDPOINTS = {
|
|
462
|
+
b2_authorize_account: { methods: ["GET"] },
|
|
463
|
+
[PartnerEndpoint.ListGroups]: {
|
|
464
|
+
methods: ["GET"],
|
|
465
|
+
queryFields: [
|
|
466
|
+
"adminAccountId",
|
|
467
|
+
"groupName",
|
|
468
|
+
"startGroupId",
|
|
469
|
+
"maxGroupCount"
|
|
470
|
+
],
|
|
471
|
+
numericQueryFields: ["maxGroupCount"]
|
|
472
|
+
},
|
|
473
|
+
[PartnerEndpoint.ListGroupMembers]: {
|
|
474
|
+
methods: ["GET"],
|
|
475
|
+
queryFields: [
|
|
476
|
+
"adminAccountId",
|
|
477
|
+
"groupId",
|
|
478
|
+
"startEmail",
|
|
479
|
+
"maxMemberCount"
|
|
480
|
+
],
|
|
481
|
+
numericQueryFields: ["maxMemberCount"]
|
|
482
|
+
},
|
|
483
|
+
[PartnerEndpoint.ListComputers]: {
|
|
484
|
+
methods: ["GET"],
|
|
485
|
+
queryFields: [
|
|
486
|
+
"accountId",
|
|
487
|
+
"startComputerId",
|
|
488
|
+
"maxComputerCount"
|
|
489
|
+
],
|
|
490
|
+
numericQueryFields: ["maxComputerCount"]
|
|
491
|
+
},
|
|
492
|
+
b2_get_upload_url: {
|
|
493
|
+
methods: ["GET", "POST"],
|
|
494
|
+
queryFields: ["bucketId"]
|
|
495
|
+
},
|
|
496
|
+
b2_list_file_names: {
|
|
497
|
+
methods: ["GET", "POST"],
|
|
498
|
+
queryFields: [
|
|
499
|
+
"bucketId",
|
|
500
|
+
"delimiter",
|
|
501
|
+
"maxFileCount",
|
|
502
|
+
"prefix",
|
|
503
|
+
"startFileName"
|
|
504
|
+
],
|
|
505
|
+
numericQueryFields: ["maxFileCount"]
|
|
506
|
+
},
|
|
507
|
+
b2_list_file_versions: {
|
|
508
|
+
methods: ["GET", "POST"],
|
|
509
|
+
queryFields: [
|
|
510
|
+
"bucketId",
|
|
511
|
+
"delimiter",
|
|
512
|
+
"maxFileCount",
|
|
513
|
+
"prefix",
|
|
514
|
+
"startFileName",
|
|
515
|
+
"startFileId"
|
|
516
|
+
],
|
|
517
|
+
numericQueryFields: ["maxFileCount"]
|
|
518
|
+
},
|
|
519
|
+
b2_get_file_info: {
|
|
520
|
+
methods: ["GET", "POST"],
|
|
521
|
+
queryFields: ["fileId"]
|
|
522
|
+
},
|
|
523
|
+
b2_copy_file: {
|
|
524
|
+
methods: ["GET", "POST"],
|
|
525
|
+
queryFields: [
|
|
526
|
+
"sourceFileId",
|
|
527
|
+
"fileName",
|
|
528
|
+
"destinationBucketId",
|
|
529
|
+
"range",
|
|
530
|
+
"metadataDirective",
|
|
531
|
+
"contentType"
|
|
532
|
+
]
|
|
533
|
+
},
|
|
534
|
+
b2_get_upload_part_url: {
|
|
535
|
+
methods: ["GET", "POST"],
|
|
536
|
+
queryFields: ["fileId"]
|
|
537
|
+
},
|
|
538
|
+
b2_list_unfinished_large_files: {
|
|
539
|
+
methods: ["GET", "POST"],
|
|
540
|
+
queryFields: [
|
|
541
|
+
"bucketId",
|
|
542
|
+
"namePrefix",
|
|
543
|
+
"startFileId",
|
|
544
|
+
"maxFileCount"
|
|
545
|
+
],
|
|
546
|
+
numericQueryFields: ["maxFileCount"]
|
|
547
|
+
},
|
|
548
|
+
b2_list_parts: {
|
|
549
|
+
methods: ["GET", "POST"],
|
|
550
|
+
queryFields: [
|
|
551
|
+
"fileId",
|
|
552
|
+
"startPartNumber",
|
|
553
|
+
"maxPartCount"
|
|
554
|
+
],
|
|
555
|
+
numericQueryFields: ["startPartNumber", "maxPartCount"]
|
|
556
|
+
},
|
|
557
|
+
b2_copy_part: {
|
|
558
|
+
methods: ["GET", "POST"],
|
|
559
|
+
queryFields: [
|
|
560
|
+
"sourceFileId",
|
|
561
|
+
"largeFileId",
|
|
562
|
+
"partNumber",
|
|
563
|
+
"range"
|
|
564
|
+
],
|
|
565
|
+
numericQueryFields: ["partNumber"]
|
|
566
|
+
},
|
|
567
|
+
b2_get_download_authorization: {
|
|
568
|
+
methods: ["GET", "POST"],
|
|
569
|
+
queryFields: [
|
|
570
|
+
"bucketId",
|
|
571
|
+
"fileNamePrefix",
|
|
572
|
+
"validDurationInSeconds",
|
|
573
|
+
"b2ContentDisposition",
|
|
574
|
+
"b2ContentLanguage",
|
|
575
|
+
"b2ContentEncoding",
|
|
576
|
+
"b2ContentType",
|
|
577
|
+
"b2CacheControl",
|
|
578
|
+
"b2Expires"
|
|
579
|
+
],
|
|
580
|
+
numericQueryFields: ["validDurationInSeconds"]
|
|
581
|
+
},
|
|
582
|
+
b2_list_keys: {
|
|
583
|
+
methods: ["GET", "POST"],
|
|
584
|
+
queryFields: [
|
|
585
|
+
"accountId",
|
|
586
|
+
"maxKeyCount",
|
|
587
|
+
"startApplicationKeyId"
|
|
588
|
+
],
|
|
589
|
+
numericQueryFields: ["maxKeyCount"]
|
|
590
|
+
},
|
|
591
|
+
b2_get_bucket_notification_rules: {
|
|
592
|
+
methods: ["GET", "POST"],
|
|
593
|
+
queryFields: ["bucketId"]
|
|
594
|
+
},
|
|
595
|
+
[PartnerEndpoint.CreateGroupMember]: { methods: ["POST"] },
|
|
596
|
+
[PartnerEndpoint.EjectGroupMember]: { methods: ["POST"] },
|
|
597
|
+
[PartnerEndpoint.ReserveTrialCreateAccount]: { methods: ["POST"] },
|
|
598
|
+
[PartnerEndpoint.DeleteComputer]: { methods: ["POST"] },
|
|
599
|
+
b2_create_bucket: { methods: ["POST"] },
|
|
600
|
+
b2_list_buckets: { methods: ["POST"] },
|
|
601
|
+
b2_delete_bucket: { methods: ["POST"] },
|
|
602
|
+
b2_update_bucket: { methods: ["POST"] },
|
|
603
|
+
b2_hide_file: { methods: ["POST"] },
|
|
604
|
+
b2_delete_file_version: { methods: ["POST"] },
|
|
605
|
+
b2_start_large_file: { methods: ["POST"] },
|
|
606
|
+
b2_finish_large_file: { methods: ["POST"] },
|
|
607
|
+
b2_cancel_large_file: { methods: ["POST"] },
|
|
608
|
+
b2_create_key: { methods: ["POST"] },
|
|
609
|
+
b2_delete_key: { methods: ["POST"] },
|
|
610
|
+
b2_update_file_retention: { methods: ["POST"] },
|
|
611
|
+
b2_update_file_legal_hold: { methods: ["POST"] },
|
|
612
|
+
b2_set_bucket_notification_rules: { methods: ["POST"] }
|
|
613
|
+
};
|
|
614
|
+
function jsonEndpointMetadata(endpoint) {
|
|
615
|
+
return JSON_ENDPOINTS[endpoint];
|
|
616
|
+
}
|
|
403
617
|
function jsonEndpointAllowsMethod(method, endpoint) {
|
|
618
|
+
const metadata = jsonEndpointMetadata(endpoint);
|
|
619
|
+
if (metadata === void 0) return true;
|
|
404
620
|
const normalizedMethod = method.toUpperCase();
|
|
405
|
-
if (
|
|
406
|
-
|
|
407
|
-
|
|
621
|
+
if (normalizedMethod !== "GET" && normalizedMethod !== "POST") return false;
|
|
622
|
+
return metadata.methods.includes(normalizedMethod);
|
|
623
|
+
}
|
|
624
|
+
function isJsonQueryEndpoint(endpoint) {
|
|
625
|
+
return jsonEndpointMetadata(endpoint)?.queryFields !== void 0;
|
|
408
626
|
}
|
|
409
627
|
function notificationRulePrefixes(body) {
|
|
410
628
|
if (typeof body !== "object" || body === null) return void 0;
|
|
@@ -440,6 +658,30 @@ function publicServerSideEncryption(encryption) {
|
|
|
440
658
|
};
|
|
441
659
|
return encryption;
|
|
442
660
|
}
|
|
661
|
+
function publicBucketDefaultServerSideEncryption(encryption) {
|
|
662
|
+
return {
|
|
663
|
+
isClientAuthorizedToRead: true,
|
|
664
|
+
value: publicBucketDefaultServerSideEncryptionValue(encryption)
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function publicBucketDefaultServerSideEncryptionValue(encryption) {
|
|
668
|
+
if (encryption?.mode === EncryptionMode.SseB2) return encryption;
|
|
669
|
+
return {
|
|
670
|
+
mode: null,
|
|
671
|
+
algorithm: null
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function bucketDefaultServerSideEncryptionForStorage(info) {
|
|
675
|
+
const encryption = info.defaultServerSideEncryption;
|
|
676
|
+
if (!encryption.isClientAuthorizedToRead) return {
|
|
677
|
+
mode: null,
|
|
678
|
+
algorithm: null
|
|
679
|
+
};
|
|
680
|
+
return encryption.value ?? {
|
|
681
|
+
mode: null,
|
|
682
|
+
algorithm: null
|
|
683
|
+
};
|
|
684
|
+
}
|
|
443
685
|
function customerKeyDigest(customerKey) {
|
|
444
686
|
let first = 2166136261;
|
|
445
687
|
let second = 668265261;
|
|
@@ -494,13 +736,21 @@ function hasCustomerEncryptionFields(encryption) {
|
|
|
494
736
|
function hasCustomerEncryptionHeaders(headers) {
|
|
495
737
|
return headers["x-bz-server-side-encryption-customer-algorithm"] !== void 0 || headers["x-bz-server-side-encryption-customer-key"] !== void 0 || headers["x-bz-server-side-encryption-customer-key-md5"] !== void 0;
|
|
496
738
|
}
|
|
739
|
+
function isExactNoEncryptionWireSetting(encryption) {
|
|
740
|
+
return encryption["mode"] === null && encryption["algorithm"] === null && Object.keys(encryption).length === 2;
|
|
741
|
+
}
|
|
497
742
|
async function storedServerSideEncryption(encryption) {
|
|
498
743
|
const runtimeEncryption = encryption;
|
|
744
|
+
if (encryption.mode === null) {
|
|
745
|
+
if (isExactNoEncryptionWireSetting(runtimeEncryption)) return { mode: EncryptionMode.None };
|
|
746
|
+
if (hasCustomerEncryptionFields(runtimeEncryption)) return encryptionValidationError("No-encryption settings must not include SSE-C customer keys");
|
|
747
|
+
return encryptionValidationError("No-encryption wire settings must be exactly { mode: null, algorithm: null }");
|
|
748
|
+
}
|
|
499
749
|
if (encryption.mode === EncryptionMode.SseC) {
|
|
500
750
|
if (runtimeEncryption["algorithm"] === void 0) return encryptionValidationError("SSE-C customer algorithm is required");
|
|
501
751
|
if (encryption.algorithm !== EncryptionAlgorithm.Aes256) return encryptionValidationError("SSE-C customer algorithm must be AES256");
|
|
502
|
-
const customerKey = encryption.customerKey;
|
|
503
|
-
const customerKeyMd5 = encryption.customerKeyMd5;
|
|
752
|
+
const customerKey = "customerKey" in encryption ? encryption.customerKey : void 0;
|
|
753
|
+
const customerKeyMd5 = "customerKeyMd5" in encryption ? encryption.customerKeyMd5 : void 0;
|
|
504
754
|
if (typeof customerKey !== "string" || customerKey === "") return encryptionValidationError("SSE-C customer key is required");
|
|
505
755
|
if (typeof customerKeyMd5 !== "string" || customerKeyMd5 === "") return encryptionValidationError("SSE-C customer key MD5 is required");
|
|
506
756
|
const customerKeyBytes = base64ToBytes(customerKey, 32);
|
|
@@ -555,7 +805,22 @@ async function uploadServerSideEncryption(headers, fallback) {
|
|
|
555
805
|
}
|
|
556
806
|
return await storedServerSideEncryption(fallback);
|
|
557
807
|
}
|
|
808
|
+
function noBucketDefaultRetention() {
|
|
809
|
+
return {
|
|
810
|
+
mode: null,
|
|
811
|
+
period: null
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
function bucketDefaultRetentionForResponse(policy) {
|
|
815
|
+
if (policy === void 0 || policy.mode === BucketRetentionMode.None) return noBucketDefaultRetention();
|
|
816
|
+
return policy;
|
|
817
|
+
}
|
|
818
|
+
function bucketDefaultRetention(info) {
|
|
819
|
+
return info.fileLockConfiguration.value?.defaultRetention;
|
|
820
|
+
}
|
|
558
821
|
function defaultFileRetention(policy, uploadTimestamp) {
|
|
822
|
+
if (policy === void 0) return null;
|
|
823
|
+
if (policy.mode === null) return null;
|
|
559
824
|
if (policy.mode === BucketRetentionMode.None || policy.period === null) return null;
|
|
560
825
|
const retainUntilTimestamp = uploadTimestamp + (policy.period.unit === "days" ? policy.period.duration : policy.period.duration * 365) * MS_PER_DAY;
|
|
561
826
|
if (!isValidRetentionTimestamp(retainUntilTimestamp, uploadTimestamp)) return null;
|
|
@@ -1024,6 +1289,16 @@ var B2Simulator = class {
|
|
|
1024
1289
|
if (authToken === void 0) return false;
|
|
1025
1290
|
return this.issuedTokens.get(authToken)?.capabilities.includes(capability) === true;
|
|
1026
1291
|
}
|
|
1292
|
+
bucketInfoForResponse(info, authToken) {
|
|
1293
|
+
return {
|
|
1294
|
+
...info,
|
|
1295
|
+
defaultServerSideEncryption: this.requestHasCapability(authToken, Capability.ReadBucketEncryption) ? info.defaultServerSideEncryption : {
|
|
1296
|
+
isClientAuthorizedToRead: false,
|
|
1297
|
+
value: null
|
|
1298
|
+
},
|
|
1299
|
+
replicationConfiguration: filterReadableReplicationConfiguration(info.replicationConfiguration, this.requestHasCapability(authToken, Capability.ReadBucketReplications))
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1027
1302
|
requireFileLockEnabled(bucket) {
|
|
1028
1303
|
if (bucket.info.fileLockConfiguration.value?.isFileLockEnabled === true) return null;
|
|
1029
1304
|
return this.error(400, "file_lock_not_enabled", "Bucket does not have file lock enabled");
|
|
@@ -1050,7 +1325,7 @@ var B2Simulator = class {
|
|
|
1050
1325
|
for (const rule of rules) {
|
|
1051
1326
|
const destinationBucketId = requestRecord(rule)?.["destinationBucketId"];
|
|
1052
1327
|
if (typeof destinationBucketId !== "string") continue;
|
|
1053
|
-
const destinationApplicationKeyId = this.buckets.get(destinationBucketId)?.info.replicationConfiguration.asReplicationDestination?.sourceToDestinationKeyMapping[sourceApplicationKeyId];
|
|
1328
|
+
const destinationApplicationKeyId = this.buckets.get(destinationBucketId)?.info.replicationConfiguration.value?.asReplicationDestination?.sourceToDestinationKeyMapping[sourceApplicationKeyId];
|
|
1054
1329
|
if (destinationApplicationKeyId === void 0) return this.invalidReplicationDestinationBucket();
|
|
1055
1330
|
const destinationKeyError = this.validateReplicationApplicationKey(destinationApplicationKeyId, [Capability.WriteFiles], {
|
|
1056
1331
|
bucketId: destinationBucketId,
|
|
@@ -1479,7 +1754,8 @@ var B2Simulator = class {
|
|
|
1479
1754
|
* @returns An object with HTTP status and JSON response body.
|
|
1480
1755
|
*/
|
|
1481
1756
|
async handleRequest(method, origin, path, headers, body) {
|
|
1482
|
-
const { endpoint, version } = apiPathParts(path);
|
|
1757
|
+
const { endpoint, version, unsupportedVersion } = apiPathParts(path);
|
|
1758
|
+
if (unsupportedVersion !== void 0) return this.error(400, "unsupported_api_version", `B2 API version ${unsupportedVersion} is not supported by the simulator; use v4 or v3`);
|
|
1483
1759
|
if (!jsonEndpointAllowsMethod(method, endpoint)) return this.error(405, "method_not_allowed", `${endpoint} does not support ${method.toUpperCase()}`);
|
|
1484
1760
|
if (this.strictAuth && !this.partner.isEndpoint(endpoint)) {
|
|
1485
1761
|
const authError = this.authorizeRequest(headers["authorization"], endpoint, this.requestScope(endpoint, body));
|
|
@@ -1489,17 +1765,17 @@ var B2Simulator = class {
|
|
|
1489
1765
|
case "b2_authorize_account":
|
|
1490
1766
|
if (version === "v3" && this.partner.isAuthorizeEnabled()) return this.partner.authorize(headers["authorization"], origin);
|
|
1491
1767
|
return this.authorize(headers["authorization"], origin);
|
|
1492
|
-
case
|
|
1493
|
-
case
|
|
1494
|
-
case
|
|
1495
|
-
case
|
|
1496
|
-
case
|
|
1497
|
-
case
|
|
1498
|
-
case
|
|
1499
|
-
case "b2_create_bucket": return this.createBucket(body);
|
|
1500
|
-
case "b2_list_buckets": return this.listBuckets(body);
|
|
1501
|
-
case "b2_delete_bucket": return this.deleteBucket(body);
|
|
1502
|
-
case "b2_update_bucket": return this.updateBucket(body);
|
|
1768
|
+
case PartnerEndpoint.CreateGroupMember: return this.partner.createGroupMember(body, headers["authorization"]);
|
|
1769
|
+
case PartnerEndpoint.EjectGroupMember: return this.partner.ejectGroupMember(body, headers["authorization"]);
|
|
1770
|
+
case PartnerEndpoint.ListGroups: return this.partner.listGroups(body, headers["authorization"]);
|
|
1771
|
+
case PartnerEndpoint.ListGroupMembers: return this.partner.listGroupMembers(body, headers["authorization"]);
|
|
1772
|
+
case PartnerEndpoint.ReserveTrialCreateAccount: return this.partner.reserveTrialCreateAccount(body, headers["authorization"]);
|
|
1773
|
+
case PartnerEndpoint.ListComputers: return this.partner.listComputers(body, headers["authorization"]);
|
|
1774
|
+
case PartnerEndpoint.DeleteComputer: return this.partner.deleteComputer(body, headers["authorization"]);
|
|
1775
|
+
case "b2_create_bucket": return this.createBucket(body, headers["authorization"]);
|
|
1776
|
+
case "b2_list_buckets": return this.listBuckets(body, headers["authorization"]);
|
|
1777
|
+
case "b2_delete_bucket": return this.deleteBucket(body, headers["authorization"]);
|
|
1778
|
+
case "b2_update_bucket": return this.updateBucket(body, headers["authorization"]);
|
|
1503
1779
|
case "b2_get_upload_url": return await this.getUploadUrl(body, headers["authorization"]);
|
|
1504
1780
|
case "b2_list_file_names": return this.listFileNames(body);
|
|
1505
1781
|
case "b2_list_file_versions": return this.listFileVersions(body);
|
|
@@ -1507,11 +1783,11 @@ var B2Simulator = class {
|
|
|
1507
1783
|
case "b2_hide_file": return this.hideFile(body);
|
|
1508
1784
|
case "b2_delete_file_version": return this.deleteFileVersion(body, headers["authorization"]);
|
|
1509
1785
|
case "b2_copy_file": return await this.copyFile(body);
|
|
1510
|
-
case "b2_start_large_file": return await this.startLargeFile(body);
|
|
1786
|
+
case "b2_start_large_file": return await this.startLargeFile(body, headers["authorization"]);
|
|
1511
1787
|
case "b2_get_upload_part_url": return await this.getUploadPartUrl(body, headers["authorization"]);
|
|
1512
1788
|
case "b2_finish_large_file": return this.finishLargeFile(body);
|
|
1513
1789
|
case "b2_cancel_large_file": return this.cancelLargeFile(body);
|
|
1514
|
-
case "b2_list_unfinished_large_files": return this.listUnfinishedLargeFiles(body);
|
|
1790
|
+
case "b2_list_unfinished_large_files": return this.listUnfinishedLargeFiles(body, headers["authorization"]);
|
|
1515
1791
|
case "b2_list_parts": return this.listParts(body);
|
|
1516
1792
|
case "b2_copy_part": return await this.copyPart(body);
|
|
1517
1793
|
case "b2_get_download_authorization": return this.getDownloadAuthorization(body);
|
|
@@ -1667,7 +1943,7 @@ var B2Simulator = class {
|
|
|
1667
1943
|
const resolved = await this.resolveUploadSha1(headers["x-bz-content-sha1"], data);
|
|
1668
1944
|
if ("status" in resolved) return resolved;
|
|
1669
1945
|
const { sha1: contentSha1, data: storedData } = resolved;
|
|
1670
|
-
const serverSideEncryption = await uploadServerSideEncryption(headers, bucket.info
|
|
1946
|
+
const serverSideEncryption = await uploadServerSideEncryption(headers, bucketDefaultServerSideEncryptionForStorage(bucket.info));
|
|
1671
1947
|
if ("status" in serverSideEncryption) return serverSideEncryption;
|
|
1672
1948
|
const customUploadTimestamp = this.parseCustomUploadTimestamp(requestHeaderValue(headers, "x-bz-custom-upload-timestamp"));
|
|
1673
1949
|
if ("status" in customUploadTimestamp) return customUploadTimestamp;
|
|
@@ -1844,7 +2120,7 @@ var B2Simulator = class {
|
|
|
1844
2120
|
}
|
|
1845
2121
|
async resolveCopyDestinationEncryption(destinationBucket, requested) {
|
|
1846
2122
|
if (requested !== void 0) return await storedServerSideEncryption(requested);
|
|
1847
|
-
return await storedServerSideEncryption(destinationBucket.info
|
|
2123
|
+
return await storedServerSideEncryption(bucketDefaultServerSideEncryptionForStorage(destinationBucket.info));
|
|
1848
2124
|
}
|
|
1849
2125
|
async validateCopyPartDestinationEncryption(large, encryption) {
|
|
1850
2126
|
if (encryption === void 0) return large.serverSideEncryption.mode === EncryptionMode.SseC ? this.error(400, "bad_request", "SSE-C destination copies require customer encryption") : null;
|
|
@@ -1972,9 +2248,11 @@ var B2Simulator = class {
|
|
|
1972
2248
|
}
|
|
1973
2249
|
};
|
|
1974
2250
|
}
|
|
1975
|
-
createBucket(req) {
|
|
2251
|
+
createBucket(req, authToken) {
|
|
1976
2252
|
const nameError = validateBucketName(req.bucketName);
|
|
1977
2253
|
if (nameError) return this.error(400, nameError.code, nameError.message);
|
|
2254
|
+
const bucketTypeError = validateBucketType(req.bucketType);
|
|
2255
|
+
if (bucketTypeError) return this.error(400, bucketTypeError.code, bucketTypeError.message);
|
|
1978
2256
|
const objectLockEnabled = nextObjectLockEnabled(false, req.fileLockEnabled);
|
|
1979
2257
|
if (typeof objectLockEnabled !== "boolean") return this.error(400, objectLockEnabled.code, objectLockEnabled.message);
|
|
1980
2258
|
const configError = validateBucketConfigurationFields(req, { objectLockEnabled });
|
|
@@ -1983,10 +2261,7 @@ var B2Simulator = class {
|
|
|
1983
2261
|
if (replicationKeyError !== null) return replicationKeyError;
|
|
1984
2262
|
for (const b of this.buckets.values()) if (b.info.bucketName === req.bucketName) return this.error(400, "duplicate_bucket_name", "Bucket name already in use");
|
|
1985
2263
|
const bid = bucketId(this.genId("b2_bucket"));
|
|
1986
|
-
const defaultRetention = req.defaultRetention
|
|
1987
|
-
mode: BucketRetentionMode.None,
|
|
1988
|
-
period: null
|
|
1989
|
-
};
|
|
2264
|
+
const defaultRetention = bucketDefaultRetentionForResponse(req.defaultRetention);
|
|
1990
2265
|
const info = {
|
|
1991
2266
|
accountId: accountId(req.accountId),
|
|
1992
2267
|
bucketId: bid,
|
|
@@ -1994,7 +2269,7 @@ var B2Simulator = class {
|
|
|
1994
2269
|
bucketType: req.bucketType,
|
|
1995
2270
|
bucketInfo: req.bucketInfo ?? {},
|
|
1996
2271
|
corsRules: req.corsRules ?? [],
|
|
1997
|
-
defaultServerSideEncryption: req.defaultServerSideEncryption
|
|
2272
|
+
defaultServerSideEncryption: publicBucketDefaultServerSideEncryption(req.defaultServerSideEncryption),
|
|
1998
2273
|
fileLockConfiguration: {
|
|
1999
2274
|
isClientAuthorizedToRead: true,
|
|
2000
2275
|
value: {
|
|
@@ -2005,11 +2280,7 @@ var B2Simulator = class {
|
|
|
2005
2280
|
lifecycleRules: req.lifecycleRules ?? [],
|
|
2006
2281
|
options: [],
|
|
2007
2282
|
revision: 1,
|
|
2008
|
-
|
|
2009
|
-
replicationConfiguration: req.replicationConfiguration === void 0 ? {
|
|
2010
|
-
asReplicationSource: null,
|
|
2011
|
-
asReplicationDestination: null
|
|
2012
|
-
} : normalizeReplicationConfiguration(req.replicationConfiguration)
|
|
2283
|
+
replicationConfiguration: wrapReplicationConfiguration(req.replicationConfiguration)
|
|
2013
2284
|
};
|
|
2014
2285
|
this.buckets.set(bid, {
|
|
2015
2286
|
info,
|
|
@@ -2017,25 +2288,25 @@ var B2Simulator = class {
|
|
|
2017
2288
|
});
|
|
2018
2289
|
return {
|
|
2019
2290
|
status: 200,
|
|
2020
|
-
body: info
|
|
2291
|
+
body: this.bucketInfoForResponse(info, authToken)
|
|
2021
2292
|
};
|
|
2022
2293
|
}
|
|
2023
|
-
listBuckets(req) {
|
|
2294
|
+
listBuckets(req, authToken) {
|
|
2024
2295
|
const bucketTypesError = validateBucketTypes(req.bucketTypes);
|
|
2025
2296
|
if (bucketTypesError) return this.error(400, bucketTypesError.code, bucketTypesError.message);
|
|
2026
2297
|
return {
|
|
2027
2298
|
status: 200,
|
|
2028
|
-
body: { buckets: [...this.buckets.values()].map((b) => b.info).filter((bucket) => req.bucketId === void 0 || bucket.bucketId === req.bucketId).filter((bucket) => req.bucketName === void 0 || bucket.bucketName === req.bucketName).filter((bucket) => req.bucketTypes === void 0 || req.bucketTypes.
|
|
2299
|
+
body: { buckets: [...this.buckets.values()].map((b) => b.info).filter((bucket) => req.bucketId === void 0 || bucket.bucketId === req.bucketId).filter((bucket) => req.bucketName === void 0 || bucket.bucketName === req.bucketName).filter((bucket) => req.bucketTypes === void 0 || req.bucketTypes[0] === "all" || req.bucketTypes.some((bucketType) => bucketType === bucket.bucketType)).map((bucket) => this.bucketInfoForResponse(bucket, authToken)) }
|
|
2029
2300
|
};
|
|
2030
2301
|
}
|
|
2031
|
-
deleteBucket(req) {
|
|
2302
|
+
deleteBucket(req, authToken) {
|
|
2032
2303
|
const bucket = this.buckets.get(req.bucketId);
|
|
2033
2304
|
if (!bucket) return this.error(400, "bad_bucket_id", "Bucket not found");
|
|
2034
2305
|
if (this.bucketHasContents(bucket)) return this.error(400, "cannot_delete_non_empty_bucket", "Bucket is not empty and cannot be deleted");
|
|
2035
2306
|
this.buckets.delete(req.bucketId);
|
|
2036
2307
|
return {
|
|
2037
2308
|
status: 200,
|
|
2038
|
-
body: bucket.info
|
|
2309
|
+
body: this.bucketInfoForResponse(bucket.info, authToken)
|
|
2039
2310
|
};
|
|
2040
2311
|
}
|
|
2041
2312
|
bucketHasContents(bucket) {
|
|
@@ -2043,7 +2314,7 @@ var B2Simulator = class {
|
|
|
2043
2314
|
for (const large of this.largeFiles.values()) if (large.bucketId === bucket.info.bucketId) return true;
|
|
2044
2315
|
return false;
|
|
2045
2316
|
}
|
|
2046
|
-
updateBucket(req) {
|
|
2317
|
+
updateBucket(req, authToken) {
|
|
2047
2318
|
const bucket = this.buckets.get(req["bucketId"]);
|
|
2048
2319
|
if (!bucket) return this.error(400, "bad_bucket_id", "Bucket not found");
|
|
2049
2320
|
const revisionGuard = req["ifRevisionIs"];
|
|
@@ -2053,9 +2324,14 @@ var B2Simulator = class {
|
|
|
2053
2324
|
}
|
|
2054
2325
|
const objectLockEnabled = nextObjectLockEnabled(bucket.info.fileLockConfiguration.value?.isFileLockEnabled ?? false, req["fileLockEnabled"]);
|
|
2055
2326
|
if (typeof objectLockEnabled !== "boolean") return this.error(400, objectLockEnabled.code, objectLockEnabled.message);
|
|
2327
|
+
if (req["bucketType"] !== void 0) {
|
|
2328
|
+
const bucketTypeError = validateBucketType(req["bucketType"]);
|
|
2329
|
+
if (bucketTypeError) return this.error(400, bucketTypeError.code, bucketTypeError.message);
|
|
2330
|
+
}
|
|
2056
2331
|
const configError = validateBucketConfigurationFields({
|
|
2057
2332
|
bucketInfo: req["bucketInfo"],
|
|
2058
2333
|
corsRules: req["corsRules"],
|
|
2334
|
+
defaultServerSideEncryption: req["defaultServerSideEncryption"],
|
|
2059
2335
|
defaultRetention: req["defaultRetention"],
|
|
2060
2336
|
lifecycleRules: req["lifecycleRules"],
|
|
2061
2337
|
replicationConfiguration: req["replicationConfiguration"]
|
|
@@ -2069,25 +2345,22 @@ var B2Simulator = class {
|
|
|
2069
2345
|
...req["bucketInfo"] !== void 0 ? { bucketInfo: req["bucketInfo"] } : {},
|
|
2070
2346
|
...req["lifecycleRules"] !== void 0 ? { lifecycleRules: req["lifecycleRules"] } : {},
|
|
2071
2347
|
...req["corsRules"] !== void 0 ? { corsRules: req["corsRules"] } : {},
|
|
2072
|
-
...req["replicationConfiguration"] !== void 0 ? { replicationConfiguration:
|
|
2073
|
-
...req["defaultRetention"] !== void 0 ? {
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
isFileLockEnabled: objectLockEnabled,
|
|
2079
|
-
defaultRetention: req["defaultRetention"]
|
|
2080
|
-
}
|
|
2348
|
+
...req["replicationConfiguration"] !== void 0 ? { replicationConfiguration: wrapReplicationConfiguration(req["replicationConfiguration"]) } : {},
|
|
2349
|
+
...req["defaultRetention"] !== void 0 ? { fileLockConfiguration: {
|
|
2350
|
+
isClientAuthorizedToRead: true,
|
|
2351
|
+
value: {
|
|
2352
|
+
isFileLockEnabled: objectLockEnabled,
|
|
2353
|
+
defaultRetention: bucketDefaultRetentionForResponse(req["defaultRetention"])
|
|
2081
2354
|
}
|
|
2082
|
-
} : {},
|
|
2355
|
+
} } : {},
|
|
2083
2356
|
...req["fileLockEnabled"] !== void 0 && req["defaultRetention"] === void 0 ? { fileLockConfiguration: {
|
|
2084
2357
|
isClientAuthorizedToRead: true,
|
|
2085
2358
|
value: {
|
|
2086
2359
|
isFileLockEnabled: objectLockEnabled,
|
|
2087
|
-
defaultRetention: bucket.info
|
|
2360
|
+
defaultRetention: bucketDefaultRetention(bucket.info) ?? noBucketDefaultRetention()
|
|
2088
2361
|
}
|
|
2089
2362
|
} } : {},
|
|
2090
|
-
...req["defaultServerSideEncryption"] !== void 0 ? { defaultServerSideEncryption: req["defaultServerSideEncryption"] } : {},
|
|
2363
|
+
...req["defaultServerSideEncryption"] !== void 0 ? { defaultServerSideEncryption: publicBucketDefaultServerSideEncryption(req["defaultServerSideEncryption"]) } : {},
|
|
2091
2364
|
revision: bucket.info.revision + 1
|
|
2092
2365
|
};
|
|
2093
2366
|
this.buckets.set(req["bucketId"], {
|
|
@@ -2096,7 +2369,7 @@ var B2Simulator = class {
|
|
|
2096
2369
|
});
|
|
2097
2370
|
return {
|
|
2098
2371
|
status: 200,
|
|
2099
|
-
body: updated
|
|
2372
|
+
body: this.bucketInfoForResponse(updated, authToken)
|
|
2100
2373
|
};
|
|
2101
2374
|
}
|
|
2102
2375
|
async getUploadUrl(req, authToken) {
|
|
@@ -2122,7 +2395,13 @@ var B2Simulator = class {
|
|
|
2122
2395
|
if (countError) return this.error(400, countError.code, countError.message);
|
|
2123
2396
|
const max = req.maxFileCount ?? 1e3;
|
|
2124
2397
|
const prefix = req.prefix ?? "";
|
|
2125
|
-
|
|
2398
|
+
const currentVersions = [...bucket.files.entries()].filter(([name]) => name.startsWith(prefix)).map(([_, versions]) => versions[versions.length - 1]).filter((v) => v !== void 0).map((v) => v.fileVersion).filter((v) => v.action !== FileAction.Hide).sort((a, b) => compareB2FileNames(a.fileName, b.fileName));
|
|
2399
|
+
let allFiles = this.applyListDelimiter({
|
|
2400
|
+
bucketId: req.bucketId,
|
|
2401
|
+
delimiter: req.delimiter,
|
|
2402
|
+
entries: currentVersions,
|
|
2403
|
+
prefix
|
|
2404
|
+
});
|
|
2126
2405
|
if (req.startFileName) {
|
|
2127
2406
|
const start = req.startFileName;
|
|
2128
2407
|
allFiles = allFiles.filter((f) => f.fileName >= start);
|
|
@@ -2142,11 +2421,17 @@ var B2Simulator = class {
|
|
|
2142
2421
|
if (countError) return this.error(400, countError.code, countError.message);
|
|
2143
2422
|
const max = req.maxFileCount ?? 1e3;
|
|
2144
2423
|
const prefix = req.prefix ?? "";
|
|
2145
|
-
const
|
|
2424
|
+
const versions = [...bucket.files.entries()].filter(([name]) => name.startsWith(prefix)).flatMap(([_, versions]) => versions.map((v) => v.fileVersion)).sort((a, b) => {
|
|
2146
2425
|
const nameCmp = compareB2FileNames(a.fileName, b.fileName);
|
|
2147
2426
|
if (nameCmp !== 0) return nameCmp;
|
|
2148
2427
|
return b.uploadTimestamp - a.uploadTimestamp;
|
|
2149
2428
|
});
|
|
2429
|
+
const allVersions = this.applyListDelimiter({
|
|
2430
|
+
bucketId: req.bucketId,
|
|
2431
|
+
delimiter: req.delimiter,
|
|
2432
|
+
entries: versions,
|
|
2433
|
+
prefix
|
|
2434
|
+
});
|
|
2150
2435
|
let startIdx = 0;
|
|
2151
2436
|
if (req.startFileName !== void 0) {
|
|
2152
2437
|
const startName = req.startFileName;
|
|
@@ -2169,6 +2454,48 @@ var B2Simulator = class {
|
|
|
2169
2454
|
}
|
|
2170
2455
|
};
|
|
2171
2456
|
}
|
|
2457
|
+
applyListDelimiter(params) {
|
|
2458
|
+
if (params.delimiter === void 0 || params.delimiter === "") return params.entries.map((entry) => this.toListEntry(entry));
|
|
2459
|
+
const grouped = [];
|
|
2460
|
+
const seenFolders = /* @__PURE__ */ new Set();
|
|
2461
|
+
for (const entry of params.entries) {
|
|
2462
|
+
const delimiterIndex = entry.fileName.indexOf(params.delimiter, params.prefix.length);
|
|
2463
|
+
if (delimiterIndex === -1) {
|
|
2464
|
+
grouped.push(this.toListEntry(entry));
|
|
2465
|
+
continue;
|
|
2466
|
+
}
|
|
2467
|
+
const folderName = entry.fileName.slice(0, delimiterIndex + params.delimiter.length);
|
|
2468
|
+
if (!seenFolders.has(folderName)) {
|
|
2469
|
+
seenFolders.add(folderName);
|
|
2470
|
+
grouped.push(this.makeFolderListEntry(params.bucketId, folderName));
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
return grouped.sort(compareFileVersionListEntries);
|
|
2474
|
+
}
|
|
2475
|
+
toListEntry(entry) {
|
|
2476
|
+
if (entry.action !== FileAction.Hide) return entry;
|
|
2477
|
+
const { contentType: _contentType, fileRetention, legalHold, serverSideEncryption, ...listed } = entry;
|
|
2478
|
+
return {
|
|
2479
|
+
...listed,
|
|
2480
|
+
action: FileAction.Hide,
|
|
2481
|
+
contentType: HIDE_MARKER_CONTENT_TYPE
|
|
2482
|
+
};
|
|
2483
|
+
}
|
|
2484
|
+
makeFolderListEntry(bucketId$1, fileName) {
|
|
2485
|
+
return {
|
|
2486
|
+
accountId: accountId(this.accountId),
|
|
2487
|
+
action: FileAction.Folder,
|
|
2488
|
+
bucketId: bucketId(bucketId$1),
|
|
2489
|
+
contentLength: 0,
|
|
2490
|
+
contentMd5: null,
|
|
2491
|
+
contentSha1: null,
|
|
2492
|
+
contentType: null,
|
|
2493
|
+
fileId: null,
|
|
2494
|
+
fileInfo: {},
|
|
2495
|
+
fileName,
|
|
2496
|
+
uploadTimestamp: 0
|
|
2497
|
+
};
|
|
2498
|
+
}
|
|
2172
2499
|
getFileInfo(req) {
|
|
2173
2500
|
const found = this.findFile(req.fileId);
|
|
2174
2501
|
if (found === null) return this.error(404, "file_not_present", "File not found");
|
|
@@ -2185,7 +2512,7 @@ var B2Simulator = class {
|
|
|
2185
2512
|
const fileVersion = this.makeFileVersion({
|
|
2186
2513
|
bucketId: req.bucketId,
|
|
2187
2514
|
fileName: req.fileName,
|
|
2188
|
-
contentType:
|
|
2515
|
+
contentType: HIDE_MARKER_CONTENT_TYPE,
|
|
2189
2516
|
contentLength: 0,
|
|
2190
2517
|
contentSha1: "none",
|
|
2191
2518
|
action: FileAction.Hide
|
|
@@ -2289,7 +2616,7 @@ var B2Simulator = class {
|
|
|
2289
2616
|
body: fileVersion
|
|
2290
2617
|
};
|
|
2291
2618
|
}
|
|
2292
|
-
async startLargeFile(req) {
|
|
2619
|
+
async startLargeFile(req, authToken) {
|
|
2293
2620
|
const bucket = this.buckets.get(req.bucketId);
|
|
2294
2621
|
if (!bucket) return this.error(400, "bad_bucket_id", "Bucket not found");
|
|
2295
2622
|
const nameError = validateFileName(req.fileName);
|
|
@@ -2302,7 +2629,7 @@ var B2Simulator = class {
|
|
|
2302
2629
|
if ("status" in customUploadTimestamp) return customUploadTimestamp;
|
|
2303
2630
|
const fid = this.genId("4_z");
|
|
2304
2631
|
const uploadTimestamp = customUploadTimestamp.timestamp ?? this.monotonicTimestamp();
|
|
2305
|
-
const serverSideEncryption = await storedServerSideEncryption(req.serverSideEncryption ?? bucket.info
|
|
2632
|
+
const serverSideEncryption = await storedServerSideEncryption(req.serverSideEncryption ?? bucketDefaultServerSideEncryptionForStorage(bucket.info));
|
|
2306
2633
|
if ("status" in serverSideEncryption) return serverSideEncryption;
|
|
2307
2634
|
const replicationStatus = this.replicationStatusForNewFile(req.bucketId, req.fileName);
|
|
2308
2635
|
const large = {
|
|
@@ -2311,7 +2638,7 @@ var B2Simulator = class {
|
|
|
2311
2638
|
fileName: req.fileName,
|
|
2312
2639
|
contentType: req.contentType,
|
|
2313
2640
|
fileInfo: req.fileInfo ?? {},
|
|
2314
|
-
fileRetention: req.fileRetention ?? defaultFileRetention(bucket.info
|
|
2641
|
+
fileRetention: req.fileRetention ?? defaultFileRetention(bucketDefaultRetention(bucket.info), uploadTimestamp),
|
|
2315
2642
|
legalHold: req.legalHold ?? null,
|
|
2316
2643
|
...this.replicationStatusMetadataFor(replicationStatus),
|
|
2317
2644
|
serverSideEncryption,
|
|
@@ -2332,14 +2659,8 @@ var B2Simulator = class {
|
|
|
2332
2659
|
contentLength: 0,
|
|
2333
2660
|
contentSha1: "none",
|
|
2334
2661
|
contentMd5: null,
|
|
2335
|
-
fileRetention:
|
|
2336
|
-
|
|
2337
|
-
value: large.fileRetention
|
|
2338
|
-
},
|
|
2339
|
-
legalHold: {
|
|
2340
|
-
isClientAuthorizedToRead: true,
|
|
2341
|
-
value: large.legalHold
|
|
2342
|
-
},
|
|
2662
|
+
fileRetention: readableFileRetention(large.fileRetention, this.requestHasCapability(authToken, Capability.ReadFileRetentions)),
|
|
2663
|
+
legalHold: readableLegalHold(large.legalHold, this.requestHasCapability(authToken, Capability.ReadFileLegalHolds)),
|
|
2343
2664
|
...this.replicationStatusMetadataFor(large.replicationStatus),
|
|
2344
2665
|
serverSideEncryption: publicServerSideEncryption(large.serverSideEncryption),
|
|
2345
2666
|
uploadTimestamp: large.uploadTimestamp
|
|
@@ -2426,7 +2747,7 @@ var B2Simulator = class {
|
|
|
2426
2747
|
}
|
|
2427
2748
|
};
|
|
2428
2749
|
}
|
|
2429
|
-
listUnfinishedLargeFiles(req) {
|
|
2750
|
+
listUnfinishedLargeFiles(req, authToken) {
|
|
2430
2751
|
const countError = validateMaxCount(req.maxFileCount, "b2_list_unfinished_large_files");
|
|
2431
2752
|
if (countError) return this.error(400, countError.code, countError.message);
|
|
2432
2753
|
const prefix = req.namePrefix ?? "";
|
|
@@ -2437,10 +2758,13 @@ var B2Simulator = class {
|
|
|
2437
2758
|
const found = candidates.findIndex((f) => f.fileId === req.startFileId);
|
|
2438
2759
|
startIndex = found >= 0 ? found : 0;
|
|
2439
2760
|
}
|
|
2761
|
+
const slice = candidates.slice(startIndex, startIndex + max);
|
|
2762
|
+
const canReadFileRetentions = this.requestHasCapability(authToken, Capability.ReadFileRetentions);
|
|
2763
|
+
const canReadFileLegalHolds = this.requestHasCapability(authToken, Capability.ReadFileLegalHolds);
|
|
2440
2764
|
return {
|
|
2441
2765
|
status: 200,
|
|
2442
2766
|
body: {
|
|
2443
|
-
files:
|
|
2767
|
+
files: slice.map((f) => ({
|
|
2444
2768
|
fileId: f.fileId,
|
|
2445
2769
|
fileName: f.fileName,
|
|
2446
2770
|
accountId: this.accountId,
|
|
@@ -2451,14 +2775,8 @@ var B2Simulator = class {
|
|
|
2451
2775
|
contentSha1: "none",
|
|
2452
2776
|
contentMd5: null,
|
|
2453
2777
|
fileInfo: f.fileInfo,
|
|
2454
|
-
fileRetention:
|
|
2455
|
-
|
|
2456
|
-
value: f.fileRetention
|
|
2457
|
-
},
|
|
2458
|
-
legalHold: {
|
|
2459
|
-
isClientAuthorizedToRead: true,
|
|
2460
|
-
value: f.legalHold
|
|
2461
|
-
},
|
|
2778
|
+
fileRetention: readableFileRetention(f.fileRetention, canReadFileRetentions),
|
|
2779
|
+
legalHold: readableLegalHold(f.legalHold, canReadFileLegalHolds),
|
|
2462
2780
|
...this.replicationStatusMetadataFor(f.replicationStatus),
|
|
2463
2781
|
serverSideEncryption: publicServerSideEncryption(f.serverSideEncryption),
|
|
2464
2782
|
uploadTimestamp: f.uploadTimestamp
|
|
@@ -2813,7 +3131,7 @@ var B2Simulator = class {
|
|
|
2813
3131
|
return this.matchingEnabledReplicationRules(bucketId, fileName).length > 0 ? "PENDING" : void 0;
|
|
2814
3132
|
}
|
|
2815
3133
|
matchingEnabledReplicationRules(bucketId, fileName) {
|
|
2816
|
-
return (this.buckets.get(bucketId)?.info.replicationConfiguration.asReplicationSource?.replicationRules)?.filter((rule) => rule.isEnabled && fileName.startsWith(rule.fileNamePrefix)) ?? [];
|
|
3134
|
+
return (this.buckets.get(bucketId)?.info.replicationConfiguration.value?.asReplicationSource?.replicationRules)?.filter((rule) => rule.isEnabled && fileName.startsWith(rule.fileNamePrefix)) ?? [];
|
|
2817
3135
|
}
|
|
2818
3136
|
error(status, code, message) {
|
|
2819
3137
|
return {
|
|
@@ -3082,6 +3400,7 @@ var SimulatorTransport = class {
|
|
|
3082
3400
|
result = "error" in uploadBody ? uploadBody.error : await this.sim.handleUpload(url, headers, uploadBody.data);
|
|
3083
3401
|
}
|
|
3084
3402
|
} else {
|
|
3403
|
+
const requestPath = apiPathParts(parsedUrl.pathname);
|
|
3085
3404
|
let body = null;
|
|
3086
3405
|
if (request.body) {
|
|
3087
3406
|
const text = typeof request.body === "string" ? request.body : await new Response(request.body).text();
|
|
@@ -3090,7 +3409,7 @@ var SimulatorTransport = class {
|
|
|
3090
3409
|
} catch {
|
|
3091
3410
|
body = text;
|
|
3092
3411
|
}
|
|
3093
|
-
} else if (request.method.toUpperCase() === "GET" &&
|
|
3412
|
+
} else if (request.method.toUpperCase() === "GET" && isJsonQueryEndpoint(requestPath.endpoint)) body = queryParamsBody(parsedUrl.searchParams, requestPath.endpoint);
|
|
3094
3413
|
result = await this.sim.handleRequest(request.method, parsedUrl.origin, parsedUrl.pathname, headers, body);
|
|
3095
3414
|
}
|
|
3096
3415
|
const responseBody = JSON.stringify(result.body);
|
|
@@ -3108,6 +3427,6 @@ var SimulatorTransport = class {
|
|
|
3108
3427
|
}
|
|
3109
3428
|
};
|
|
3110
3429
|
//#endregion
|
|
3111
|
-
export { B2Simulator, BUCKET_INFO_MAX_KEYS, BUCKET_INFO_VALUE_MAX, BUCKET_NAME_MAX, BUCKET_NAME_MIN, DOWNLOAD_AUTH_DURATION_MAX_SECONDS, DOWNLOAD_AUTH_DURATION_MIN_SECONDS, FILE_INFO_TOTAL_MAX, FILE_INFO_VALUE_MAX, FILE_NAME_MAX_BYTES, KEY_NAME_MAX, KEY_NAME_MIN, LIST_ENDPOINT_CAPS };
|
|
3430
|
+
export { B2Simulator, BUCKET_INFO_KEY_MAX_BYTES, BUCKET_INFO_KEY_MIN_BYTES, BUCKET_INFO_KEY_PATTERN, BUCKET_INFO_MAX_KEYS, BUCKET_INFO_RESERVED_PREFIX, BUCKET_INFO_VALUES_MAX_BYTES, BUCKET_INFO_VALUE_MAX, BUCKET_NAME_MAX, BUCKET_NAME_MIN, CORS_MAX_AGE_SECONDS_MAX, CORS_RULES_MAX_COUNT, CORS_RULE_MAX_BYTES, CORS_RULE_NAME_MAX_LENGTH, CORS_RULE_NAME_MIN_LENGTH, CORS_RULE_NAME_PATTERN, CORS_RULE_NAME_RESERVED_PREFIX, DOWNLOAD_AUTH_DURATION_MAX_SECONDS, DOWNLOAD_AUTH_DURATION_MIN_SECONDS, FILE_INFO_TOTAL_MAX, FILE_INFO_VALUE_MAX, FILE_NAME_MAX_BYTES, KEY_NAME_MAX, KEY_NAME_MIN, LIST_ENDPOINT_CAPS };
|
|
3112
3431
|
|
|
3113
3432
|
//# sourceMappingURL=index.js.map
|