@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner.cjs","names":[],"sources":["../../src/simulator/partner.ts"],"sourcesContent":["import { Capability } from '../types/auth.ts'\nimport type { ComputerBackup } from '../types/backup.ts'\nimport type { BucketInfo, BucketType } from '../types/bucket.ts'\nimport {\n accountId as accountIdOf,\n applicationKeyId as applicationKeyIdOf,\n computerId as computerIdOf,\n groupId as groupIdOf,\n} from '../types/ids.ts'\nimport {\n type CreateGroupMemberRequest,\n type CreateGroupMemberResult,\n type EjectGroupMemberRequest,\n type EjectGroupMemberResponse,\n type ListedGroupMember,\n type ListGroupMembersRequest,\n type ListGroupMembersResult,\n type ListGroupsResult,\n type PartnerB2Stats,\n PartnerCapability,\n type PartnerGroup,\n type PartnerGroupMember,\n Region,\n type ReserveTrialCreateAccountRequestEntry,\n type ReserveTrialCreateAccountResult,\n} from '../types/partner.ts'\nimport type { B2SimulatorOptions, SimulatorJsonResponse } from './index.ts'\n\nconst DAY_MS = 24 * 60 * 60 * 1000\nconst PARTNER_REGIONS = new Set<string>(Object.values(Region))\nconst PARTNER_API_ENDPOINTS = new Set<string>([\n 'b2_create_group_member',\n 'b2_eject_group_member',\n 'b2_list_groups',\n 'b2_list_group_members',\n 'b2_reserve_trial_create_account',\n 'bz_list_computers',\n 'bz_delete_computer',\n])\nconst DEFAULT_GROUP_COUNT = 3\nconst MAX_GROUPS_PER_ADMIN = 500\nconst DEFAULT_MAX_GROUP_COUNT = 100 // Default group page size.\nconst MAX_GROUP_COUNT = 100 // Maximum accepted group page size.\nconst MAX_AUTO_PROVISIONED_ADMINS = 100\nconst MAX_GROUP_MEMBERS = 5000\nconst DEFAULT_MAX_MEMBER_COUNT = 100\nconst MAX_MEMBER_COUNT = 1000\nconst DEFAULT_MAX_COMPUTER_COUNT = 100\nconst MIN_COMPUTER_COUNT = 1\nconst MAX_COMPUTER_COUNT = 500\nconst DEFAULT_COMPUTER_COUNT = 3\nconst MAX_AUTO_PROVISIONED_BACKUP_ACCOUNTS = 100\nconst PARTNER_CREATED_STORAGE_KEY_CAPABILITIES = Object.freeze([\n Capability.ListBuckets,\n Capability.ReadBuckets,\n Capability.WriteBuckets,\n Capability.ListFiles,\n Capability.ReadFiles,\n Capability.WriteFiles,\n Capability.DeleteFiles,\n])\n\nfunction isPartnerApiEndpoint(endpoint: string): boolean {\n return PARTNER_API_ENDPOINTS.has(endpoint)\n}\n\nconst PARTNER_QUERY_ENDPOINTS = new Set<string>([\n 'b2_list_groups',\n 'b2_list_group_members',\n 'bz_list_computers',\n])\n\n/**\n * Checks whether a JSON API endpoint can safely receive GET query parameters.\n *\n * @param endpoint - Endpoint name parsed from the request path.\n *\n * @returns `true` for Partner/Backup list endpoints that document GET query requests.\n */\nexport function isPartnerQueryEndpoint(endpoint: string): boolean {\n return PARTNER_QUERY_ENDPOINTS.has(endpoint)\n}\n\nfunction utcDateString(ms: number): string {\n return new Date(ms).toISOString().slice(0, 10)\n}\n\nfunction utcDayStartMs(ms: number): number {\n const date = new Date(ms)\n return Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())\n}\n\ninterface IssuedPartnerToken {\n readonly accountId: string\n readonly expiresAt: number\n}\n\ninterface AuthorizedPartnerRequest {\n readonly accountId: string | null\n}\n\ninterface StoredPartnerGroup {\n readonly adminAccountId: string\n readonly groupId: string\n readonly groupName: string\n readonly groupProducts: readonly string[]\n readonly createdTimestamp: number\n deleted: boolean\n}\n\ninterface StoredPartnerGroupMember {\n readonly accountId: string\n email: string\n normalizedEmail: string\n readonly groupId: string\n readonly groupName: string\n readonly region: Region\n readonly s3Endpoint: string\n readonly applicationKeyId: string\n readonly applicationKey: string\n readonly createdTimestamp: number\n ejected: boolean\n}\n\ninterface StoredComputerBackup {\n readonly accountId: string\n readonly computerId: string\n readonly computerName: string\n readonly lastFileUploadedTimestamp: number\n deleted: boolean\n}\n\nfunction requestObject(body: unknown): Record<string, unknown> {\n return typeof body === 'object' && body !== null ? (body as Record<string, unknown>) : {}\n}\n\nfunction normalizeEmail(email: string): string {\n return email.trim().toLowerCase()\n}\n\nfunction isValidEmailAddress(email: string): boolean {\n const trimmed = email.trim()\n if (trimmed !== email || trimmed.length < 3 || trimmed.length > 254) return false\n const at = trimmed.indexOf('@')\n if (at <= 0 || at !== trimmed.lastIndexOf('@') || at === trimmed.length - 1) return false\n const domain = trimmed.slice(at + 1)\n if (!domain.includes('.') || domain.startsWith('.') || domain.endsWith('.')) return false\n return !/\\s/.test(trimmed)\n}\n\nfunction compareStrings(left: string, right: string): number {\n if (left < right) return -1\n if (left > right) return 1\n return 0\n}\n\nexport interface PartnerStoredKey {\n readonly applicationKeyId: string\n readonly keyName: string\n readonly capabilities: readonly Capability[]\n readonly accountId: string\n readonly applicationKey: string\n readonly bucketIds: readonly string[] | null\n readonly namePrefix: string | null\n readonly expirationTimestamp: number | null\n}\n\nexport interface PartnerSimulatorHost {\n readonly accountId: string\n readonly authTokenTtlMs: number\n readonly minimumPartSize: number\n readonly recommendedPartSize: number\n canAuthorize(authzHeader: string | undefined): boolean\n createBucket(req: {\n bucketName: string\n bucketType: BucketType\n accountId: string\n }): SimulatorJsonResponse\n error(status: number, code: string, message: string): SimulatorJsonResponse\n genId(prefix: string): string\n monotonicTimestamp(): number\n now(): number\n storeKey(key: PartnerStoredKey): void\n}\n\n/**\n * Handles Partner and Computer Backup simulator state and endpoint logic.\n *\n * B2Simulator owns dispatch and shared storage primitives. This collaborator\n * intentionally keeps both Partner and Backup surfaces together because one\n * Partner token authorizes both products. Product-specific state remains split\n * by map: groups/trials/members for Partner, computers for Backup.\n *\n * Auth has two modes:\n *\n * - default `new B2Simulator()` endpoint tests are permissive and accept any\n * non-empty Partner token without binding request account IDs;\n * - `partnerAuthorize: true` or `strictAuth: true` turns on issued-token\n * validation so client auth-error tests can still exercise 401 responses.\n */\nexport class PartnerSimulator {\n private readonly issuedTokens = new Map<string, IssuedPartnerToken>()\n private readonly knownEmails = new Set<string>()\n private readonly groups = new Map<string, StoredPartnerGroup>()\n private readonly groupsByAdmin = new Map<string, string[]>()\n private readonly groupMembers = new Map<string, Map<string, StoredPartnerGroupMember>>()\n private readonly groupMembersByAccountId = new Map<string, StoredPartnerGroupMember>()\n private readonly computersByAccount = new Map<string, Map<string, StoredComputerBackup>>()\n private readonly authorizeEnabled: boolean\n private readonly validateIssuedTokens: boolean\n private readonly apiEnabled: boolean\n private readonly accountHasValidPhone: boolean\n private readonly accountInGoodStanding: boolean\n\n /**\n * Creates the Partner/Backup simulator facade.\n *\n * @param host - Narrow callbacks into the parent B2 simulator.\n * @param options - Parent simulator options relevant to Partner behavior.\n */\n constructor(\n private readonly host: PartnerSimulatorHost,\n options: B2SimulatorOptions,\n ) {\n this.authorizeEnabled = options.partnerAuthorize ?? false\n this.validateIssuedTokens = this.authorizeEnabled || (options.strictAuth ?? false)\n this.apiEnabled = options.partnerApiEnabled ?? true\n this.accountHasValidPhone = options.partnerAccountHasValidPhone ?? true\n this.accountInGoodStanding = options.partnerAccountInGoodStanding ?? true\n }\n\n /**\n * Reports whether v3 authorize should return Partner/Backup suites.\n *\n * @returns `true` when Partner authorization is enabled.\n */\n isAuthorizeEnabled(): boolean {\n return this.authorizeEnabled\n }\n\n /**\n * Checks whether an endpoint name belongs to Partner or Backup APIs.\n *\n * @param endpoint - Endpoint name parsed from the request path.\n *\n * @returns `true` when this simulator should handle the endpoint.\n */\n isEndpoint(endpoint: string): boolean {\n return isPartnerApiEndpoint(endpoint)\n }\n\n /**\n * Authorizes a Partner administrator and mints a Partner token.\n *\n * @param authzHeader - Basic authorization header from b2_authorize_account.\n * @param origin - Request origin used to build simulator endpoint URLs.\n *\n * @returns JSON response with Partner, Backup, and storage API information.\n */\n authorize(authzHeader: string | undefined, origin = 'http://localhost:0'): SimulatorJsonResponse {\n if (!this.host.canAuthorize(authzHeader)) {\n return this.host.error(\n 401,\n 'bad_auth_token',\n 'missing or invalid Partner authorize credentials',\n )\n }\n\n const tokenStr = this.host.genId('sim_partner_auth_token')\n this.issuedTokens.set(tokenStr, {\n accountId: this.host.accountId,\n expiresAt: this.host.now() + this.host.authTokenTtlMs,\n })\n return {\n status: 200,\n body: {\n accountId: accountIdOf(this.host.accountId),\n authorizationToken: tokenStr,\n apiInfo: {\n storageApi: {\n absoluteMinimumPartSize: this.host.minimumPartSize,\n apiUrl: origin,\n bucketId: null,\n bucketName: null,\n capabilities: [\n Capability.ListBuckets,\n Capability.ReadBuckets,\n Capability.WriteBuckets,\n Capability.DeleteBuckets,\n Capability.ListFiles,\n Capability.ReadFiles,\n Capability.WriteFiles,\n Capability.DeleteFiles,\n ],\n downloadUrl: origin,\n infoType: 'storageApi',\n namePrefix: null,\n recommendedPartSize: this.host.recommendedPartSize,\n s3ApiUrl: origin,\n },\n groupsApi: {\n capabilities: [PartnerCapability.All],\n groupsApiUrl: `${origin}/partner`,\n infoType: 'groupsApi',\n },\n backupApi: {\n backupApiUrl: `${origin}/backup`,\n capabilities: [PartnerCapability.All],\n infoType: 'backupApi',\n },\n },\n applicationKeyExpirationTimestamp: null,\n },\n }\n }\n\n /**\n * Handles b2_reserve_trial_create_account.\n *\n * @param body - Parsed JSON array request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n reserveTrialCreateAccount(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken)\n if ('status' in auth) return auth\n if (!Array.isArray(body)) {\n return this.host.error(400, 'bad_request', 'request body must be an array')\n }\n if (body.length === 0) {\n return this.host.error(400, 'bad_request', 'request body must include at least one account')\n }\n\n const entries: {\n readonly entry: ReserveTrialCreateAccountRequestEntry\n readonly normalizedEmail: string\n }[] = []\n const requestEmails = new Set<string>()\n for (const item of body) {\n const parsed = this.parseReserveTrialCreateAccountEntry(item, requestEmails)\n if (parsed.error !== null) return parsed.error\n entries.push(parsed)\n }\n\n const startDayMs = utcDayStartMs(this.host.now())\n const results = entries.map(({ entry, normalizedEmail }) =>\n this.createReserveTrialAccount(entry, normalizedEmail, startDayMs),\n )\n return { status: 200, body: results }\n }\n\n /**\n * Handles b2_create_group_member.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n createGroupMember(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken, { checkPhone: false })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const request = this.parseCreateGroupMemberRequest(record)\n if ('error' in request) return request.error\n const accountError = this.authorizeAccount(auth, request.adminAccountId)\n if (accountError !== null) return accountError\n\n const group = this.activeGroup(request.groupId, request.adminAccountId)\n if (group === null) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n if (!this.accountHasValidPhone) {\n return this.host.error(401, 'invalid_sms_phone', 'account is missing a valid SMS phone')\n }\n\n const normalizedEmail = normalizeEmail(request.memberEmail)\n if (!isValidEmailAddress(request.memberEmail) || this.knownEmails.has(normalizedEmail)) {\n return this.host.error(401, 'invalid_email', 'email address is invalid or already exists')\n }\n\n const members = this.membersForGroup(group.groupId)\n if (this.activeMembersForGroup(group.groupId).length >= MAX_GROUP_MEMBERS) {\n return this.host.error(401, 'too_many_members', 'group member count limit exceeded')\n }\n\n const accountId = accountIdOf(this.host.genId('sim_group_member_account'))\n const applicationKeyId = applicationKeyIdOf(this.host.genId('sim_key'))\n const applicationKey = this.host.genId('sim_secret')\n const region = request.region ?? Region.UsWest\n const stored: StoredPartnerGroupMember = {\n accountId,\n email: request.memberEmail,\n normalizedEmail,\n groupId: group.groupId,\n groupName: group.groupName,\n region,\n s3Endpoint: `s3.${region}-001.backblazeb2.com`,\n applicationKeyId,\n applicationKey,\n createdTimestamp: this.host.monotonicTimestamp(),\n ejected: false,\n }\n members.set(normalizedEmail, stored)\n this.groupMembersByAccountId.set(accountId, stored)\n this.knownEmails.add(normalizedEmail)\n this.host.storeKey({\n applicationKeyId,\n keyName: `group-member-${accountId}`,\n capabilities: PARTNER_CREATED_STORAGE_KEY_CAPABILITIES,\n accountId,\n applicationKey,\n bucketIds: null,\n namePrefix: null,\n expirationTimestamp: null,\n })\n\n const result: CreateGroupMemberResult = {\n applicationKeyId,\n applicationKey,\n groupMember: this.publicGroupMember(stored),\n }\n return { status: 200, body: [result] }\n }\n\n /**\n * Handles b2_eject_group_member.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n ejectGroupMember(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken)\n if ('status' in auth) return auth\n const record = requestObject(body)\n const request = this.parseEjectGroupMemberRequest(record)\n if ('error' in request) return request.error\n const accountError = this.authorizeAccount(auth, request.adminAccountId)\n if (accountError !== null) return accountError\n\n const group = this.activeGroup(request.groupId, request.adminAccountId)\n if (group === null) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n\n const member = this.groupMembersByAccountId.get(request.memberAccountId)\n if (member === undefined || member.ejected || member.groupId !== group.groupId) {\n return this.host.error(401, 'invalid_member_account_id', 'group member account ID is invalid')\n }\n\n const previousNormalizedEmail = member.normalizedEmail\n if (request.email !== undefined && request.email !== null) {\n const normalizedEmail = normalizeEmail(request.email)\n const keepsSameEmail = normalizedEmail === previousNormalizedEmail\n if (\n !isValidEmailAddress(request.email) ||\n (!keepsSameEmail && this.knownEmails.has(normalizedEmail))\n ) {\n return this.host.error(401, 'invalid_email', 'email address is invalid or already exists')\n }\n if (!keepsSameEmail) {\n this.knownEmails.delete(previousNormalizedEmail)\n this.knownEmails.add(normalizedEmail)\n }\n member.email = request.email\n member.normalizedEmail = normalizedEmail\n }\n\n member.ejected = true\n this.groupMembers.get(group.groupId)?.delete(previousNormalizedEmail)\n const response: EjectGroupMemberResponse = this.publicGroupMember(member)\n return { status: 200, body: response }\n }\n\n /**\n * Handles b2_list_groups.\n *\n * @param body - Parsed GET query parameters or JSON body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n listGroups(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken, { checkPhone: false })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId.error\n const accountError = this.authorizeAccount(auth, adminAccountId.value)\n if (accountError !== null) return accountError\n const maxGroupCount = this.optionalInteger(\n record,\n 'maxGroupCount',\n DEFAULT_MAX_GROUP_COUNT,\n 1,\n MAX_GROUP_COUNT,\n 401,\n 'out_of_range',\n )\n if ('error' in maxGroupCount) return maxGroupCount.error\n\n const groupSeedError = this.ensureGroupsForAdmin(adminAccountId.value)\n if (groupSeedError !== null) return groupSeedError\n const groupNameValue = record['groupName']\n const groupName = typeof groupNameValue === 'string' ? groupNameValue : undefined\n const startGroupIdValue = record['startGroupId']\n const startGroupId = typeof startGroupIdValue === 'string' ? startGroupIdValue : undefined\n if (\n startGroupId !== undefined &&\n this.activeGroup(startGroupId, adminAccountId.value) === null\n ) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n\n const allGroups = this.activeGroupsForAdmin(adminAccountId.value)\n .filter((group) => groupName === undefined || group.groupName === groupName)\n .sort((left, right) => compareStrings(left.groupId, right.groupId))\n const startIndex =\n startGroupId === undefined ? 0 : allGroups.findIndex((group) => group.groupId >= startGroupId)\n const normalizedStartIndex = startIndex === -1 ? allGroups.length : startIndex\n const page = allGroups.slice(normalizedStartIndex, normalizedStartIndex + maxGroupCount.value)\n const next = allGroups[normalizedStartIndex + maxGroupCount.value]\n const response: ListGroupsResult = {\n accountId: accountIdOf(adminAccountId.value),\n groups: page.map((group) => this.publicGroup(group)),\n nextGroupId: next === undefined ? null : groupIdOf(next.groupId),\n }\n return { status: 200, body: response }\n }\n\n /**\n * Handles b2_list_group_members.\n *\n * @param body - Parsed GET query parameters or JSON body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n listGroupMembers(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken, { checkPhone: false })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const request = this.parseListGroupMembersRequest(record)\n if ('error' in request) return request.error\n const accountError = this.authorizeAccount(auth, request.adminAccountId)\n if (accountError !== null) return accountError\n\n const group = this.activeGroup(request.groupId, request.adminAccountId)\n if (group === null) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n\n const members = this.activeMembersForGroup(group.groupId).sort((left, right) =>\n compareStrings(left.normalizedEmail, right.normalizedEmail),\n )\n const startEmail =\n request.startEmail === undefined ? undefined : normalizeEmail(request.startEmail)\n const startIndex =\n startEmail === undefined\n ? 0\n : members.findIndex((member) => member.normalizedEmail >= startEmail)\n const normalizedStartIndex = startIndex === -1 ? members.length : startIndex\n const page = members.slice(normalizedStartIndex, normalizedStartIndex + request.maxMemberCount)\n const next = members[normalizedStartIndex + request.maxMemberCount]\n const response: ListGroupMembersResult = {\n groupId: groupIdOf(group.groupId),\n groupName: group.groupName,\n groupMembers: page.map((member) => this.publicListedGroupMember(member)),\n nextEmail: next === undefined ? null : next.email,\n }\n return { status: 200, body: [response] }\n }\n\n /**\n * Handles bz_list_computers.\n *\n * @param body - Parsed GET query parameters or JSON body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n listComputers(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken, { checkPhone: false })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const accountId = this.requiredString(record, 'accountId', 400, 'invalid_account_id')\n if ('error' in accountId) return accountId.error\n const accountError = this.authorizeAccount(auth, accountId.value)\n if (accountError !== null) return accountError\n const maxComputerCount = this.optionalInteger(\n record,\n 'maxComputerCount',\n DEFAULT_MAX_COMPUTER_COUNT,\n MIN_COMPUTER_COUNT,\n MAX_COMPUTER_COUNT,\n 400,\n 'out_of_range',\n )\n if ('error' in maxComputerCount) return maxComputerCount.error\n\n const computers = this.ensureComputersForAccount(accountId.value)\n if ('status' in computers) return computers\n const startComputerIdValue = record['startComputerId']\n const startComputerId =\n typeof startComputerIdValue === 'string' ? startComputerIdValue : undefined\n if (startComputerId !== undefined) {\n const start = computers.get(startComputerId)\n if (start === undefined || start.deleted) {\n // Backup API invalid computer identifiers are validation failures.\n return this.host.error(400, 'invalid_computer_id', 'computer ID is invalid or deleted')\n }\n }\n\n const activeComputers = [...computers.values()]\n .filter((computer) => !computer.deleted)\n .sort((left, right) => compareStrings(left.computerId, right.computerId))\n const startIndex =\n startComputerId === undefined\n ? 0\n : activeComputers.findIndex((computer) => computer.computerId >= startComputerId)\n const normalizedStartIndex = startIndex === -1 ? activeComputers.length : startIndex\n const page = activeComputers.slice(\n normalizedStartIndex,\n normalizedStartIndex + maxComputerCount.value,\n )\n const next = activeComputers[normalizedStartIndex + maxComputerCount.value]\n return {\n status: 200,\n body: {\n nextComputerId: next === undefined ? null : next.computerId,\n computers: page.map((computer) => this.publicComputer(computer)),\n },\n }\n }\n\n /**\n * Handles bz_delete_computer.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n deleteComputer(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(authToken, { checkPhone: false })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const accountId = this.requiredString(record, 'accountId', 400, 'invalid_account_id')\n if ('error' in accountId) return accountId.error\n const computerId = this.requiredString(record, 'computerId', 400, 'invalid_computer_id')\n if ('error' in computerId) return computerId.error\n const accountError = this.authorizeAccount(auth, accountId.value)\n if (accountError !== null) return accountError\n\n const computers = this.computersByAccount.get(accountId.value)\n const computer = computers?.get(computerId.value)\n if (computer === undefined || computer.deleted) {\n return this.host.error(400, 'invalid_computer_id', 'computer ID is invalid or deleted')\n }\n computer.deleted = true\n return { status: 200, body: [this.publicComputer(computer)] }\n }\n\n private authorizeRequest(\n authToken: string | undefined,\n options: { readonly checkPhone?: boolean } = {},\n ): AuthorizedPartnerRequest | SimulatorJsonResponse {\n if (authToken === undefined || authToken.trim() === '' || /\\s/.test(authToken)) {\n return this.host.error(\n 403,\n 'access_denied',\n 'missing or malformed Partner API Authorization header',\n )\n }\n\n if (!this.validateIssuedTokens) {\n if (!this.apiEnabled) {\n return this.host.error(403, 'access_denied', 'account is not enabled for Partner API')\n }\n if (options.checkPhone !== false && !this.accountHasValidPhone) {\n return this.host.error(403, 'access_denied', 'account does not have a valid phone number')\n }\n if (!this.accountInGoodStanding) {\n return this.host.error(403, 'access_denied', 'account is not in good standing')\n }\n return { accountId: null }\n }\n\n const token = this.issuedTokens.get(authToken)\n if (token === undefined || this.host.now() > token.expiresAt) {\n return this.host.error(401, 'unauthorized', 'invalid Partner API authorization token')\n }\n if (!this.apiEnabled) {\n return this.host.error(403, 'access_denied', 'account is not enabled for Partner API')\n }\n if (options.checkPhone !== false && !this.accountHasValidPhone) {\n return this.host.error(403, 'access_denied', 'account does not have a valid phone number')\n }\n if (!this.accountInGoodStanding) {\n return this.host.error(403, 'access_denied', 'account is not in good standing')\n }\n return { accountId: token.accountId }\n }\n\n private authorizeAccount(\n auth: AuthorizedPartnerRequest,\n requestedAccountId: string,\n ): SimulatorJsonResponse | null {\n if (auth.accountId === null) return null\n if (auth.accountId === requestedAccountId) return null\n return this.host.error(\n 403,\n 'unauthorized',\n 'Partner token is not authorized for requested account',\n )\n }\n\n private parseReserveTrialCreateAccountEntry(\n value: unknown,\n requestEmails: Set<string>,\n ):\n | {\n readonly entry: ReserveTrialCreateAccountRequestEntry\n readonly normalizedEmail: string\n readonly error: null\n }\n | {\n readonly error: SimulatorJsonResponse\n } {\n if (typeof value !== 'object' || value === null) {\n return {\n error: this.host.error(400, 'bad_request', 'trial account request must be an object'),\n }\n }\n const record = value as Record<string, unknown>\n const email = record['email']\n if (typeof email !== 'string') {\n return { error: this.host.error(400, 'bad_request', 'email is required') }\n }\n if (!isValidEmailAddress(email)) {\n return { error: this.host.error(400, 'bad_request', 'email address is invalid') }\n }\n const normalizedEmail = normalizeEmail(email)\n if (this.knownEmails.has(normalizedEmail) || requestEmails.has(normalizedEmail)) {\n return {\n error: this.host.error(\n 400,\n 'bad_request',\n 'email must not already exist as a Backblaze account',\n ),\n }\n }\n const term = record['term']\n if (typeof term !== 'number' || !Number.isInteger(term) || term < 7 || term > 30) {\n return { error: this.host.error(400, 'bad_request', 'term must be between 7 and 30 days') }\n }\n const storage = record['storage']\n if (typeof storage !== 'number' || !Number.isInteger(storage) || storage < 1 || storage > 50) {\n return { error: this.host.error(400, 'bad_request', 'storage must be between 1 and 50 TB') }\n }\n const region = record['region']\n if (\n region !== undefined &&\n region !== null &&\n (typeof region !== 'string' || !PARTNER_REGIONS.has(region))\n ) {\n return { error: this.host.error(400, 'bad_request', 'region is not supported') }\n }\n\n requestEmails.add(normalizedEmail)\n return {\n entry: {\n email,\n term,\n storage,\n ...(region !== undefined ? { region: region as Region | null } : {}),\n },\n normalizedEmail,\n error: null,\n }\n }\n\n private createReserveTrialAccount(\n request: ReserveTrialCreateAccountRequestEntry,\n normalizedEmail: string,\n startDayMs: number,\n ): ReserveTrialCreateAccountResult {\n const accountId = accountIdOf(this.host.genId('sim_trial_account'))\n const bucketName = `trial-${this.host.genId('bucket').slice(-8)}`\n const bucketResponse = this.host.createBucket({\n accountId,\n bucketName,\n bucketType: 'allPrivate',\n })\n if (bucketResponse.status !== 200) {\n throw new Error('failed to create simulator reserve trial bucket')\n }\n const bucket = bucketResponse.body as BucketInfo\n const keyId = applicationKeyIdOf(this.host.genId('sim_key'))\n const applicationKey = this.host.genId('sim_secret')\n this.host.storeKey({\n applicationKeyId: keyId,\n keyName: `reserve-trial-${bucketName}`,\n capabilities: PARTNER_CREATED_STORAGE_KEY_CAPABILITIES,\n accountId,\n applicationKey,\n bucketIds: [bucket.bucketId],\n namePrefix: null,\n expirationTimestamp: null,\n })\n this.knownEmails.add(normalizedEmail)\n const region = request.region ?? Region.UsWest\n const account: ReserveTrialCreateAccountResult = {\n accountId,\n applicationKey,\n applicationKeyId: keyId,\n s3Endpoint: `s3.${region}-001.backblazeb2.com`,\n startDate: utcDateString(startDayMs),\n endDate: utcDateString(startDayMs + request.term * DAY_MS),\n email: request.email,\n bucketName: bucket.bucketName,\n bucketId: bucket.bucketId,\n }\n return account\n }\n\n private parseCreateGroupMemberRequest(\n record: Record<string, unknown>,\n ): CreateGroupMemberRequest | { readonly error: SimulatorJsonResponse } {\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId\n const groupId = this.requiredString(record, 'groupId', 401, 'invalid_group_id')\n if ('error' in groupId) return groupId\n const memberEmail = this.requiredString(record, 'memberEmail', 401, 'invalid_email')\n if ('error' in memberEmail) return memberEmail\n const regionValue = record['region']\n if (\n regionValue !== undefined &&\n regionValue !== null &&\n (typeof regionValue !== 'string' || !PARTNER_REGIONS.has(regionValue))\n ) {\n return { error: this.host.error(401, 'invalid_region', 'region is invalid') }\n }\n return {\n adminAccountId: accountIdOf(adminAccountId.value),\n groupId: groupIdOf(groupId.value),\n memberEmail: memberEmail.value,\n ...(regionValue !== undefined ? { region: regionValue as Region | null } : {}),\n }\n }\n\n private parseEjectGroupMemberRequest(\n record: Record<string, unknown>,\n ): EjectGroupMemberRequest | { readonly error: SimulatorJsonResponse } {\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId\n const groupId = this.requiredString(record, 'groupId', 401, 'invalid_group_id')\n if ('error' in groupId) return groupId\n const memberAccountId = this.requiredString(\n record,\n 'memberAccountId',\n 401,\n 'invalid_member_account_id',\n )\n if ('error' in memberAccountId) return memberAccountId\n const email = record['email']\n if (email !== undefined && email !== null && typeof email !== 'string') {\n return { error: this.host.error(401, 'invalid_email', 'email address is invalid') }\n }\n return {\n adminAccountId: accountIdOf(adminAccountId.value),\n groupId: groupIdOf(groupId.value),\n memberAccountId: accountIdOf(memberAccountId.value),\n ...(email !== undefined ? { email: email as string | null } : {}),\n }\n }\n\n private parseListGroupMembersRequest(\n record: Record<string, unknown>,\n ):\n | (ListGroupMembersRequest & { readonly maxMemberCount: number })\n | { readonly error: SimulatorJsonResponse } {\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId\n const groupId = this.requiredString(record, 'groupId', 401, 'invalid_group_id')\n if ('error' in groupId) return groupId\n const maxMemberCount = this.optionalInteger(\n record,\n 'maxMemberCount',\n DEFAULT_MAX_MEMBER_COUNT,\n 1,\n MAX_MEMBER_COUNT,\n 401,\n 'out_of_range',\n { zeroUsesDefault: true },\n )\n if ('error' in maxMemberCount) return maxMemberCount\n const startEmail = record['startEmail']\n if (startEmail !== undefined && typeof startEmail !== 'string') {\n return { error: this.host.error(400, 'bad_request', 'startEmail must be a string') }\n }\n return {\n adminAccountId: accountIdOf(adminAccountId.value),\n groupId: groupIdOf(groupId.value),\n ...(startEmail !== undefined ? { startEmail } : {}),\n maxMemberCount: maxMemberCount.value,\n }\n }\n\n private requiredString(\n record: Record<string, unknown>,\n field: string,\n status: number,\n code: string,\n ): { readonly value: string } | { readonly error: SimulatorJsonResponse } {\n const value = record[field]\n if (typeof value !== 'string' || value === '') {\n return { error: this.host.error(status, code, `${field} is required`) }\n }\n return { value }\n }\n\n private optionalInteger(\n record: Record<string, unknown>,\n field: string,\n defaultValue: number,\n min: number,\n max: number,\n status: number,\n code: string,\n options: { readonly zeroUsesDefault?: boolean } = {},\n ): { readonly value: number } | { readonly error: SimulatorJsonResponse } {\n const raw = record[field]\n if (raw === undefined) return { value: defaultValue }\n const value =\n typeof raw === 'number'\n ? raw\n : typeof raw === 'string' && raw !== ''\n ? Number(raw)\n : Number.NaN\n if (options.zeroUsesDefault === true && value === 0) return { value: defaultValue }\n if (!Number.isInteger(value) || value < min || value > max) {\n return { error: this.host.error(status, code, `${field} must be between ${min} and ${max}`) }\n }\n return { value }\n }\n\n private ensureGroupsForAdmin(adminAccountId: string): SimulatorJsonResponse | null {\n if (this.groupsByAdmin.has(adminAccountId)) return null\n if (this.groupsByAdmin.size >= MAX_AUTO_PROVISIONED_ADMINS) {\n return this.host.error(\n 400,\n 'too_many_accounts',\n 'simulator Partner account auto-provisioning cap exceeded',\n )\n }\n this.groupsByAdmin.set(adminAccountId, [])\n for (let index = 1; index <= DEFAULT_GROUP_COUNT; index += 1) {\n this.createGroup(adminAccountId, `Simulator Group ${index}`)\n }\n return null\n }\n\n private createGroup(adminAccountId: string, groupName: string): StoredPartnerGroup {\n const existingGroupIds = this.groupsByAdmin.get(adminAccountId) ?? []\n if (existingGroupIds.length >= MAX_GROUPS_PER_ADMIN) {\n throw new Error('simulator Partner group cap exceeded')\n }\n const group: StoredPartnerGroup = {\n adminAccountId,\n groupId: this.host.genId('sim_group'),\n groupName,\n groupProducts: ['STORAGE', 'BACKUP'],\n createdTimestamp: this.host.monotonicTimestamp(),\n deleted: false,\n }\n this.groups.set(group.groupId, group)\n existingGroupIds.push(group.groupId)\n this.groupsByAdmin.set(adminAccountId, existingGroupIds)\n this.groupMembers.set(group.groupId, new Map())\n return group\n }\n\n private activeGroup(groupId: string, adminAccountId: string): StoredPartnerGroup | null {\n const group = this.groups.get(groupId)\n if (group === undefined || group.deleted || group.adminAccountId !== adminAccountId) return null\n return group\n }\n\n private activeGroupsForAdmin(adminAccountId: string): StoredPartnerGroup[] {\n const groupIds = this.groupsByAdmin.get(adminAccountId) ?? []\n return groupIds\n .map((groupId) => this.groups.get(groupId))\n .filter((group): group is StoredPartnerGroup => group !== undefined && !group.deleted)\n }\n\n private membersForGroup(groupId: string): Map<string, StoredPartnerGroupMember> {\n const existing = this.groupMembers.get(groupId)\n if (existing !== undefined) return existing\n const created = new Map<string, StoredPartnerGroupMember>()\n this.groupMembers.set(groupId, created)\n return created\n }\n\n private activeMembersForGroup(groupId: string): StoredPartnerGroupMember[] {\n return [...(this.groupMembers.get(groupId)?.values() ?? [])].filter((member) => !member.ejected)\n }\n\n private ensureComputersForAccount(\n accountId: string,\n ): Map<string, StoredComputerBackup> | SimulatorJsonResponse {\n const existing = this.computersByAccount.get(accountId)\n if (existing !== undefined) return existing\n if (this.computersByAccount.size >= MAX_AUTO_PROVISIONED_BACKUP_ACCOUNTS) {\n return this.host.error(\n 400,\n 'too_many_accounts',\n 'simulator Backup account auto-provisioning cap exceeded',\n )\n }\n const computers = new Map<string, StoredComputerBackup>()\n for (let index = 1; index <= DEFAULT_COMPUTER_COUNT; index += 1) {\n const computer: StoredComputerBackup = {\n accountId,\n computerId: this.host.genId('sim_computer'),\n computerName: `sim-computer-${index}`,\n lastFileUploadedTimestamp: this.host.monotonicTimestamp(),\n deleted: false,\n }\n computers.set(computer.computerId, computer)\n }\n this.computersByAccount.set(accountId, computers)\n return computers\n }\n\n private publicGroup(group: StoredPartnerGroup): PartnerGroup {\n const timestamp = new Date(group.createdTimestamp).toISOString()\n return {\n accountStandingDetails: { state: 'good_standing' },\n b2Stats: this.emptyB2Stats(group.createdTimestamp),\n groupId: groupIdOf(group.groupId),\n groupName: group.groupName,\n groupProducts: group.groupProducts,\n groupStats: {\n createdTimestamp: timestamp,\n groupStatsAsOfTimestamp: timestamp,\n memberCount: this.activeMembersForGroup(group.groupId).length,\n },\n }\n }\n\n private publicGroupMember(member: StoredPartnerGroupMember): PartnerGroupMember {\n return {\n accountId: accountIdOf(member.accountId),\n email: member.email,\n groupId: groupIdOf(member.groupId),\n groupName: member.groupName,\n region: member.region,\n s3Endpoint: member.s3Endpoint,\n }\n }\n\n private publicListedGroupMember(member: StoredPartnerGroupMember): ListedGroupMember {\n return {\n ...this.publicGroupMember(member),\n b2Stats: this.emptyB2Stats(member.createdTimestamp),\n }\n }\n\n private publicComputer(computer: StoredComputerBackup): ComputerBackup {\n return {\n computerId: computerIdOf(computer.computerId),\n computerName: computer.computerName,\n lastFileUploadedTimestamp: computer.lastFileUploadedTimestamp,\n }\n }\n\n private emptyB2Stats(timestamp: number): PartnerB2Stats {\n return {\n b2BytesStoredCount: '0',\n b2FilesStoredCount: '0',\n b2StatsAsOfTimestamp: new Date(timestamp).toISOString(),\n bucketCount: '0',\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"partner.cjs","names":[],"sources":["../../src/simulator/partner.ts"],"sourcesContent":["import { Capability } from '../types/auth.ts'\nimport type { ComputerBackup } from '../types/backup.ts'\nimport type { BucketInfo, BucketType } from '../types/bucket.ts'\nimport {\n accountId as accountIdOf,\n applicationKeyId as applicationKeyIdOf,\n computerId as computerIdOf,\n groupId as groupIdOf,\n} from '../types/ids.ts'\nimport {\n type CreateGroupMemberRequest,\n type CreateGroupMemberResult,\n type EjectGroupMemberRequest,\n type EjectGroupMemberResponse,\n type ListedGroupMember,\n type ListGroupMembersRequest,\n type ListGroupMembersResult,\n type ListGroupsResult,\n type PartnerB2Stats,\n PartnerCapability,\n type PartnerGroup,\n type PartnerGroupMember,\n Region,\n type ReserveTrialCreateAccountRequestEntry,\n type ReserveTrialCreateAccountResult,\n} from '../types/partner.ts'\nimport type { B2SimulatorOptions, SimulatorJsonResponse } from './index.ts'\nimport {\n missingPartnerCapabilities,\n PARTNER_ENDPOINT_NAMES,\n PartnerEndpoint,\n partnerEndpointCapabilityRequirementFor,\n} from './partner-capabilities.ts'\n\nconst DAY_MS = 24 * 60 * 60 * 1000\nconst PARTNER_REGIONS = new Set<string>(Object.values(Region))\nconst PARTNER_API_ENDPOINTS = new Set<PartnerEndpoint>(PARTNER_ENDPOINT_NAMES)\nconst DEFAULT_GROUP_COUNT = 3\nconst MAX_GROUPS_PER_ADMIN = 500\nconst DEFAULT_MAX_GROUP_COUNT = 100 // Default group page size.\nconst MAX_GROUP_COUNT = 100 // Maximum accepted group page size.\nconst MAX_AUTO_PROVISIONED_ADMINS = 100\nconst MAX_GROUP_MEMBERS = 5000\nconst DEFAULT_MAX_MEMBER_COUNT = 100\nconst MAX_MEMBER_COUNT = 1000\nconst DEFAULT_MAX_COMPUTER_COUNT = 100\nconst MIN_COMPUTER_COUNT = 1\nconst MAX_COMPUTER_COUNT = 500\nconst DEFAULT_COMPUTER_COUNT = 3\nconst MAX_AUTO_PROVISIONED_BACKUP_ACCOUNTS = 100\nconst PARTNER_CREATED_STORAGE_KEY_CAPABILITIES = Object.freeze([\n Capability.ListBuckets,\n Capability.ReadBuckets,\n Capability.WriteBuckets,\n Capability.ListFiles,\n Capability.ReadFiles,\n Capability.WriteFiles,\n Capability.DeleteFiles,\n])\n\nfunction isPartnerApiEndpoint(endpoint: string): endpoint is PartnerEndpoint {\n return PARTNER_API_ENDPOINTS.has(endpoint as PartnerEndpoint)\n}\n\nconst PARTNER_QUERY_ENDPOINTS = new Set<PartnerEndpoint>([\n PartnerEndpoint.ListGroups,\n PartnerEndpoint.ListGroupMembers,\n PartnerEndpoint.ListComputers,\n])\n\n/**\n * Checks whether a JSON API endpoint can safely receive GET query parameters.\n *\n * @param endpoint - Endpoint name parsed from the request path.\n *\n * @returns `true` for Partner/Backup list endpoints that document GET query requests.\n */\nexport function isPartnerQueryEndpoint(endpoint: string): boolean {\n return PARTNER_QUERY_ENDPOINTS.has(endpoint as PartnerEndpoint)\n}\n\nfunction utcDateString(ms: number): string {\n return new Date(ms).toISOString().slice(0, 10)\n}\n\n// B2 Partner API timestamps are `dYYYYMMDD_mHHMMSS` (UTC), not ISO 8601.\nfunction b2FriendlyTimestamp(ms: number): string {\n const date = new Date(ms)\n const pad = (n: number, width = 2): string => String(n).padStart(width, '0')\n const day = `${pad(date.getUTCFullYear(), 4)}${pad(date.getUTCMonth() + 1)}${pad(date.getUTCDate())}`\n const time = `${pad(date.getUTCHours())}${pad(date.getUTCMinutes())}${pad(date.getUTCSeconds())}`\n return `d${day}_m${time}`\n}\n\nfunction utcDayStartMs(ms: number): number {\n const date = new Date(ms)\n return Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate())\n}\n\ninterface IssuedPartnerToken {\n readonly accountId: string\n readonly backupCapabilities: readonly PartnerCapability[]\n readonly expiresAt: number\n readonly groupsCapabilities: readonly PartnerCapability[]\n}\n\ninterface AuthorizedPartnerRequest {\n readonly accountId: string | null\n}\n\ninterface StoredPartnerGroup {\n readonly adminAccountId: string\n readonly groupId: string\n readonly groupName: string\n readonly groupProducts: readonly string[]\n readonly createdTimestamp: number\n deleted: boolean\n}\n\ninterface StoredPartnerGroupMember {\n readonly accountId: string\n email: string\n normalizedEmail: string\n readonly groupId: string\n readonly groupName: string\n readonly region: Region\n readonly s3Endpoint: string\n readonly applicationKeyId: string\n readonly applicationKey: string\n readonly createdTimestamp: number\n ejected: boolean\n}\n\ninterface StoredComputerBackup {\n readonly accountId: string\n readonly computerId: string\n readonly computerName: string\n readonly lastFileUploadedTimestamp: number\n deleted: boolean\n}\n\nfunction requestObject(body: unknown): Record<string, unknown> {\n return typeof body === 'object' && body !== null ? (body as Record<string, unknown>) : {}\n}\n\nfunction normalizeEmail(email: string): string {\n return email.trim().toLowerCase()\n}\n\nfunction isValidEmailAddress(email: string): boolean {\n const trimmed = email.trim()\n if (trimmed !== email || trimmed.length < 3 || trimmed.length > 254) return false\n const at = trimmed.indexOf('@')\n if (at <= 0 || at !== trimmed.lastIndexOf('@') || at === trimmed.length - 1) return false\n const domain = trimmed.slice(at + 1)\n if (!domain.includes('.') || domain.startsWith('.') || domain.endsWith('.')) return false\n return !/\\s/.test(trimmed)\n}\n\nfunction compareStrings(left: string, right: string): number {\n if (left < right) return -1\n if (left > right) return 1\n return 0\n}\n\nfunction clonePartnerCapabilities(\n capabilities: readonly PartnerCapability[],\n): readonly PartnerCapability[] {\n return Object.freeze([...capabilities])\n}\n\nexport interface PartnerStoredKey {\n readonly applicationKeyId: string\n readonly keyName: string\n readonly capabilities: readonly Capability[]\n readonly accountId: string\n readonly applicationKey: string\n readonly bucketIds: readonly string[] | null\n readonly namePrefix: string | null\n readonly expirationTimestamp: number | null\n}\n\nexport interface PartnerSimulatorHost {\n readonly accountId: string\n readonly authTokenTtlMs: number\n readonly minimumPartSize: number\n readonly recommendedPartSize: number\n canAuthorize(authzHeader: string | undefined): boolean\n createBucket(req: {\n bucketName: string\n bucketType: BucketType\n accountId: string\n }): SimulatorJsonResponse\n error(status: number, code: string, message: string): SimulatorJsonResponse\n genId(prefix: string): string\n monotonicTimestamp(): number\n now(): number\n storeKey(key: PartnerStoredKey): void\n}\n\n/**\n * Handles Partner and Computer Backup simulator state and endpoint logic.\n *\n * B2Simulator owns dispatch and shared storage primitives. This collaborator\n * intentionally keeps both Partner and Backup surfaces together because one\n * Partner token authorizes both products. Product-specific state remains split\n * by map: groups/trials/members for Partner, computers for Backup.\n *\n * Auth has two modes:\n *\n * - default `new B2Simulator()` endpoint tests are permissive and accept any\n * non-empty Partner token without binding request account IDs;\n * - `partnerAuthorize: true` or `strictAuth: true` turns on issued-token\n * validation so client auth-error tests can still exercise 401 responses.\n */\nexport class PartnerSimulator {\n private readonly issuedTokens = new Map<string, IssuedPartnerToken>()\n private readonly knownEmails = new Set<string>()\n private readonly groups = new Map<string, StoredPartnerGroup>()\n private readonly groupsByAdmin = new Map<string, string[]>()\n private readonly groupMembers = new Map<string, Map<string, StoredPartnerGroupMember>>()\n private readonly groupMembersByAccountId = new Map<string, StoredPartnerGroupMember>()\n private readonly computersByAccount = new Map<string, Map<string, StoredComputerBackup>>()\n private readonly authorizeEnabled: boolean\n private readonly validateIssuedTokens: boolean\n private readonly apiEnabled: boolean\n private readonly accountHasValidPhone: boolean\n private readonly accountInGoodStanding: boolean\n private readonly groupsCapabilities: readonly PartnerCapability[]\n private readonly backupCapabilities: readonly PartnerCapability[]\n\n /**\n * Creates the Partner/Backup simulator facade.\n *\n * @param host - Narrow callbacks into the parent B2 simulator.\n * @param options - Parent simulator options relevant to Partner behavior.\n */\n constructor(\n private readonly host: PartnerSimulatorHost,\n options: B2SimulatorOptions,\n ) {\n this.authorizeEnabled = options.partnerAuthorize ?? false\n this.validateIssuedTokens = this.authorizeEnabled || (options.strictAuth ?? false)\n this.apiEnabled = options.partnerApiEnabled ?? true\n this.accountHasValidPhone = options.partnerAccountHasValidPhone ?? true\n this.accountInGoodStanding = options.partnerAccountInGoodStanding ?? true\n this.groupsCapabilities = clonePartnerCapabilities(\n options.partnerGroupsCapabilities ?? [PartnerCapability.All],\n )\n this.backupCapabilities = clonePartnerCapabilities(\n options.partnerBackupCapabilities ?? [PartnerCapability.All],\n )\n }\n\n /**\n * Reports whether v3 authorize should return Partner/Backup suites.\n *\n * @returns `true` when Partner authorization is enabled.\n */\n isAuthorizeEnabled(): boolean {\n return this.authorizeEnabled\n }\n\n /**\n * Checks whether an endpoint name belongs to Partner or Backup APIs.\n *\n * @param endpoint - Endpoint name parsed from the request path.\n *\n * @returns `true` when this simulator should handle the endpoint.\n */\n isEndpoint(endpoint: string): boolean {\n return isPartnerApiEndpoint(endpoint)\n }\n\n /**\n * Authorizes a Partner administrator and mints a Partner token.\n *\n * @param authzHeader - Basic authorization header from b2_authorize_account.\n * @param origin - Request origin used to build simulator endpoint URLs.\n *\n * @returns JSON response with Partner, Backup, and storage API information.\n */\n authorize(authzHeader: string | undefined, origin = 'http://localhost:0'): SimulatorJsonResponse {\n if (!this.host.canAuthorize(authzHeader)) {\n return this.host.error(\n 401,\n 'bad_auth_token',\n 'missing or invalid Partner authorize credentials',\n )\n }\n\n const tokenStr = this.host.genId('sim_partner_auth_token')\n this.issuedTokens.set(tokenStr, {\n accountId: this.host.accountId,\n backupCapabilities: this.backupCapabilities,\n expiresAt: this.host.now() + this.host.authTokenTtlMs,\n groupsCapabilities: this.groupsCapabilities,\n })\n return {\n status: 200,\n body: {\n accountId: accountIdOf(this.host.accountId),\n authorizationToken: tokenStr,\n apiInfo: {\n storageApi: {\n absoluteMinimumPartSize: this.host.minimumPartSize,\n apiUrl: origin,\n bucketId: null,\n bucketName: null,\n capabilities: [\n Capability.ListBuckets,\n Capability.ReadBuckets,\n Capability.WriteBuckets,\n Capability.DeleteBuckets,\n Capability.ListFiles,\n Capability.ReadFiles,\n Capability.WriteFiles,\n Capability.DeleteFiles,\n ],\n downloadUrl: origin,\n infoType: 'storageApi',\n namePrefix: null,\n recommendedPartSize: this.host.recommendedPartSize,\n s3ApiUrl: origin,\n },\n groupsApi: {\n capabilities: this.groupsCapabilities,\n groupsApiUrl: `${origin}/partner`,\n infoType: 'groupsApi',\n },\n backupApi: {\n backupApiUrl: `${origin}/backup`,\n capabilities: this.backupCapabilities,\n infoType: 'backupApi',\n },\n },\n applicationKeyExpirationTimestamp: null,\n },\n }\n }\n\n /**\n * Handles b2_reserve_trial_create_account.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n reserveTrialCreateAccount(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.ReserveTrialCreateAccount, authToken)\n if ('status' in auth) return auth\n const parsed = this.parseReserveTrialCreateAccountRequest(body)\n if (parsed.error !== null) return parsed.error\n\n const startDayMs = utcDayStartMs(this.host.now())\n const result = this.createReserveTrialAccount(parsed.entry, parsed.normalizedEmail, startDayMs)\n return { status: 200, body: result }\n }\n\n /**\n * Handles b2_create_group_member.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n createGroupMember(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.CreateGroupMember, authToken, {\n checkPhone: false,\n })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const request = this.parseCreateGroupMemberRequest(record)\n if ('error' in request) return request.error\n const accountError = this.authorizeAccount(auth, request.adminAccountId)\n if (accountError !== null) return accountError\n\n const group = this.activeGroup(request.groupId, request.adminAccountId)\n if (group === null) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n if (!this.accountHasValidPhone) {\n return this.host.error(401, 'invalid_sms_phone', 'account is missing a valid SMS phone')\n }\n\n const normalizedEmail = normalizeEmail(request.memberEmail)\n if (!isValidEmailAddress(request.memberEmail) || this.knownEmails.has(normalizedEmail)) {\n return this.host.error(401, 'invalid_email', 'email address is invalid or already exists')\n }\n\n const members = this.membersForGroup(group.groupId)\n if (this.activeMembersForGroup(group.groupId).length >= MAX_GROUP_MEMBERS) {\n return this.host.error(401, 'too_many_members', 'group member count limit exceeded')\n }\n\n const accountId = accountIdOf(this.host.genId('sim_group_member_account'))\n const applicationKeyId = applicationKeyIdOf(this.host.genId('sim_key'))\n const applicationKey = this.host.genId('sim_secret')\n const region = request.region ?? Region.UsWest\n const stored: StoredPartnerGroupMember = {\n accountId,\n email: request.memberEmail,\n normalizedEmail,\n groupId: group.groupId,\n groupName: group.groupName,\n region,\n s3Endpoint: `s3.${region}-001.backblazeb2.com`,\n applicationKeyId,\n applicationKey,\n createdTimestamp: this.host.monotonicTimestamp(),\n ejected: false,\n }\n members.set(normalizedEmail, stored)\n this.groupMembersByAccountId.set(accountId, stored)\n this.knownEmails.add(normalizedEmail)\n this.host.storeKey({\n applicationKeyId,\n keyName: `group-member-${accountId}`,\n capabilities: PARTNER_CREATED_STORAGE_KEY_CAPABILITIES,\n accountId,\n applicationKey,\n bucketIds: null,\n namePrefix: null,\n expirationTimestamp: null,\n })\n\n const result: CreateGroupMemberResult = {\n applicationKeyId,\n applicationKey,\n groupMember: this.publicGroupMember(stored),\n }\n return { status: 200, body: result }\n }\n\n /**\n * Handles b2_eject_group_member.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n ejectGroupMember(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.EjectGroupMember, authToken)\n if ('status' in auth) return auth\n const record = requestObject(body)\n const request = this.parseEjectGroupMemberRequest(record)\n if ('error' in request) return request.error\n const accountError = this.authorizeAccount(auth, request.adminAccountId)\n if (accountError !== null) return accountError\n\n const group = this.activeGroup(request.groupId, request.adminAccountId)\n if (group === null) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n\n const member = this.groupMembersByAccountId.get(request.memberAccountId)\n if (member === undefined || member.ejected || member.groupId !== group.groupId) {\n return this.host.error(401, 'invalid_member_account_id', 'group member account ID is invalid')\n }\n\n const previousNormalizedEmail = member.normalizedEmail\n if (request.email !== undefined && request.email !== null) {\n const normalizedEmail = normalizeEmail(request.email)\n const keepsSameEmail = normalizedEmail === previousNormalizedEmail\n if (\n !isValidEmailAddress(request.email) ||\n (!keepsSameEmail && this.knownEmails.has(normalizedEmail))\n ) {\n return this.host.error(401, 'invalid_email', 'email address is invalid or already exists')\n }\n if (!keepsSameEmail) {\n this.knownEmails.delete(previousNormalizedEmail)\n this.knownEmails.add(normalizedEmail)\n }\n member.email = request.email\n member.normalizedEmail = normalizedEmail\n }\n\n member.ejected = true\n this.groupMembers.get(group.groupId)?.delete(previousNormalizedEmail)\n const response: EjectGroupMemberResponse = this.publicGroupMember(member)\n return { status: 200, body: response }\n }\n\n /**\n * Handles b2_list_groups.\n *\n * @param body - Parsed GET query parameters or JSON body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n listGroups(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.ListGroups, authToken, {\n checkPhone: false,\n })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId.error\n const accountError = this.authorizeAccount(auth, adminAccountId.value)\n if (accountError !== null) return accountError\n const maxGroupCount = this.optionalInteger(\n record,\n 'maxGroupCount',\n DEFAULT_MAX_GROUP_COUNT,\n 1,\n MAX_GROUP_COUNT,\n 401,\n 'out_of_range',\n )\n if ('error' in maxGroupCount) return maxGroupCount.error\n\n const groupSeedError = this.ensureGroupsForAdmin(adminAccountId.value)\n if (groupSeedError !== null) return groupSeedError\n const groupNameValue = record['groupName']\n const groupName = typeof groupNameValue === 'string' ? groupNameValue : undefined\n const startGroupIdValue = record['startGroupId']\n const startGroupId = typeof startGroupIdValue === 'string' ? startGroupIdValue : undefined\n if (\n startGroupId !== undefined &&\n this.activeGroup(startGroupId, adminAccountId.value) === null\n ) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n\n const allGroups = this.activeGroupsForAdmin(adminAccountId.value)\n .filter((group) => groupName === undefined || group.groupName === groupName)\n .sort((left, right) => compareStrings(left.groupId, right.groupId))\n const startIndex =\n startGroupId === undefined ? 0 : allGroups.findIndex((group) => group.groupId >= startGroupId)\n const normalizedStartIndex = startIndex === -1 ? allGroups.length : startIndex\n const page = allGroups.slice(normalizedStartIndex, normalizedStartIndex + maxGroupCount.value)\n const next = allGroups[normalizedStartIndex + maxGroupCount.value]\n const response: ListGroupsResult = {\n accountId: accountIdOf(adminAccountId.value),\n groups: page.map((group) => this.publicGroup(group)),\n nextGroupId: next === undefined ? null : groupIdOf(next.groupId),\n }\n return { status: 200, body: response }\n }\n\n /**\n * Handles b2_list_group_members.\n *\n * @param body - Parsed GET query parameters or JSON body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n listGroupMembers(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.ListGroupMembers, authToken, {\n checkPhone: false,\n })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const request = this.parseListGroupMembersRequest(record)\n if ('error' in request) return request.error\n const accountError = this.authorizeAccount(auth, request.adminAccountId)\n if (accountError !== null) return accountError\n\n const group = this.activeGroup(request.groupId, request.adminAccountId)\n if (group === null) {\n return this.host.error(401, 'invalid_group_id', 'group ID is invalid or deleted')\n }\n\n const members = this.activeMembersForGroup(group.groupId).sort((left, right) =>\n compareStrings(left.normalizedEmail, right.normalizedEmail),\n )\n const startEmail =\n request.startEmail === undefined ? undefined : normalizeEmail(request.startEmail)\n const startIndex =\n startEmail === undefined\n ? 0\n : members.findIndex((member) => member.normalizedEmail >= startEmail)\n const normalizedStartIndex = startIndex === -1 ? members.length : startIndex\n const page = members.slice(normalizedStartIndex, normalizedStartIndex + request.maxMemberCount)\n const next = members[normalizedStartIndex + request.maxMemberCount]\n const response: ListGroupMembersResult = {\n groupId: groupIdOf(group.groupId),\n groupName: group.groupName,\n groupMembers: page.map((member) => this.publicListedGroupMember(member)),\n nextEmail: next === undefined ? null : next.email,\n }\n return { status: 200, body: response }\n }\n\n /**\n * Handles bz_list_computers.\n *\n * @param body - Parsed GET query parameters or JSON body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n listComputers(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.ListComputers, authToken, {\n checkPhone: false,\n })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const accountId = this.requiredString(record, 'accountId', 400, 'invalid_account_id')\n if ('error' in accountId) return accountId.error\n const accountError = this.authorizeAccount(auth, accountId.value)\n if (accountError !== null) return accountError\n const maxComputerCount = this.optionalInteger(\n record,\n 'maxComputerCount',\n DEFAULT_MAX_COMPUTER_COUNT,\n MIN_COMPUTER_COUNT,\n MAX_COMPUTER_COUNT,\n 400,\n 'out_of_range',\n )\n if ('error' in maxComputerCount) return maxComputerCount.error\n\n const computers = this.ensureComputersForAccount(accountId.value)\n if ('status' in computers) return computers\n const startComputerIdValue = record['startComputerId']\n const startComputerId =\n typeof startComputerIdValue === 'string' ? startComputerIdValue : undefined\n if (startComputerId !== undefined) {\n const start = computers.get(startComputerId)\n if (start === undefined || start.deleted) {\n // Backup API invalid computer identifiers are validation failures.\n return this.host.error(400, 'invalid_computer_id', 'computer ID is invalid or deleted')\n }\n }\n\n const activeComputers = [...computers.values()]\n .filter((computer) => !computer.deleted)\n .sort((left, right) => compareStrings(left.computerId, right.computerId))\n const startIndex =\n startComputerId === undefined\n ? 0\n : activeComputers.findIndex((computer) => computer.computerId >= startComputerId)\n const normalizedStartIndex = startIndex === -1 ? activeComputers.length : startIndex\n const page = activeComputers.slice(\n normalizedStartIndex,\n normalizedStartIndex + maxComputerCount.value,\n )\n const next = activeComputers[normalizedStartIndex + maxComputerCount.value]\n return {\n status: 200,\n body: {\n nextComputerId: next === undefined ? null : next.computerId,\n computers: page.map((computer) => this.publicComputer(computer)),\n },\n }\n }\n\n /**\n * Handles bz_delete_computer.\n *\n * @param body - Parsed JSON request body.\n * @param authToken - Partner authorization token.\n *\n * @returns Simulator JSON response.\n */\n deleteComputer(body: unknown, authToken?: string): SimulatorJsonResponse {\n const auth = this.authorizeRequest(PartnerEndpoint.DeleteComputer, authToken, {\n checkPhone: false,\n })\n if ('status' in auth) return auth\n const record = requestObject(body)\n const accountId = this.requiredString(record, 'accountId', 400, 'invalid_account_id')\n if ('error' in accountId) return accountId.error\n const computerId = this.requiredString(record, 'computerId', 400, 'invalid_computer_id')\n if ('error' in computerId) return computerId.error\n const accountError = this.authorizeAccount(auth, accountId.value)\n if (accountError !== null) return accountError\n\n const computers = this.computersByAccount.get(accountId.value)\n const computer = computers?.get(computerId.value)\n if (computer === undefined || computer.deleted) {\n return this.host.error(400, 'invalid_computer_id', 'computer ID is invalid or deleted')\n }\n computer.deleted = true\n return { status: 200, body: [this.publicComputer(computer)] }\n }\n\n private authorizeRequest(\n endpoint: PartnerEndpoint,\n authToken: string | undefined,\n options: { readonly checkPhone?: boolean } = {},\n ): AuthorizedPartnerRequest | SimulatorJsonResponse {\n if (authToken === undefined || authToken.trim() === '' || /\\s/.test(authToken)) {\n return this.host.error(\n 403,\n 'access_denied',\n 'missing or malformed Partner API Authorization header',\n )\n }\n\n if (!this.validateIssuedTokens) {\n if (!this.apiEnabled) {\n return this.host.error(403, 'access_denied', 'account is not enabled for Partner API')\n }\n if (options.checkPhone !== false && !this.accountHasValidPhone) {\n return this.host.error(403, 'access_denied', 'account does not have a valid phone number')\n }\n if (!this.accountInGoodStanding) {\n return this.host.error(403, 'access_denied', 'account is not in good standing')\n }\n return { accountId: null }\n }\n\n const token = this.issuedTokens.get(authToken)\n if (token === undefined || this.host.now() > token.expiresAt) {\n return this.host.error(401, 'unauthorized', 'invalid Partner API authorization token')\n }\n if (!this.apiEnabled) {\n return this.host.error(403, 'access_denied', 'account is not enabled for Partner API')\n }\n if (options.checkPhone !== false && !this.accountHasValidPhone) {\n return this.host.error(403, 'access_denied', 'account does not have a valid phone number')\n }\n if (!this.accountInGoodStanding) {\n return this.host.error(403, 'access_denied', 'account is not in good standing')\n }\n const capabilityError = this.authorizeEndpointCapabilities(endpoint, token)\n if (capabilityError !== null) return capabilityError\n return { accountId: token.accountId }\n }\n\n private authorizeEndpointCapabilities(\n endpoint: PartnerEndpoint,\n token: IssuedPartnerToken,\n ): SimulatorJsonResponse | null {\n const requirement = partnerEndpointCapabilityRequirementFor(endpoint)\n if (requirement === null) {\n return this.host.error(401, 'unauthorized', `no Partner capability policy for ${endpoint}`)\n }\n const granted =\n requirement.suite === 'groups' ? token.groupsCapabilities : token.backupCapabilities\n const missing = missingPartnerCapabilities(requirement.capabilities, granted)\n if (missing.length === 0) return null\n return this.host.error(\n 401,\n 'unauthorized',\n `Partner token lacks required capabilities: ${missing.join(', ')}`,\n )\n }\n\n private authorizeAccount(\n auth: AuthorizedPartnerRequest,\n requestedAccountId: string,\n ): SimulatorJsonResponse | null {\n if (auth.accountId === null) return null\n if (auth.accountId === requestedAccountId) return null\n return this.host.error(\n 403,\n 'unauthorized',\n 'Partner token is not authorized for requested account',\n )\n }\n\n private parseReserveTrialCreateAccountRequest(value: unknown):\n | {\n readonly entry: ReserveTrialCreateAccountRequestEntry\n readonly normalizedEmail: string\n readonly error: null\n }\n | {\n readonly error: SimulatorJsonResponse\n } {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return {\n error: this.host.error(400, 'bad_request', 'trial account request must be an object'),\n }\n }\n const record = value as Record<string, unknown>\n const email = record['email']\n if (typeof email !== 'string') {\n return { error: this.host.error(400, 'bad_request', 'email is required') }\n }\n if (!isValidEmailAddress(email)) {\n return { error: this.host.error(400, 'bad_request', 'email address is invalid') }\n }\n const normalizedEmail = normalizeEmail(email)\n if (this.knownEmails.has(normalizedEmail)) {\n return {\n error: this.host.error(\n 400,\n 'bad_request',\n 'email must not already exist as a Backblaze account',\n ),\n }\n }\n const term = record['term']\n if (typeof term !== 'number' || !Number.isInteger(term) || term < 7 || term > 30) {\n return { error: this.host.error(400, 'bad_request', 'term must be between 7 and 30 days') }\n }\n const storage = record['storage']\n if (typeof storage !== 'number' || !Number.isInteger(storage) || storage < 1 || storage > 50) {\n return { error: this.host.error(400, 'bad_request', 'storage must be between 1 and 50 TB') }\n }\n const region = record['region']\n if (\n region !== undefined &&\n region !== null &&\n (typeof region !== 'string' || !PARTNER_REGIONS.has(region))\n ) {\n return { error: this.host.error(400, 'bad_request', 'region is not supported') }\n }\n\n return {\n entry: {\n email,\n term,\n storage,\n ...(region !== undefined ? { region: region as Region | null } : {}),\n },\n normalizedEmail,\n error: null,\n }\n }\n\n private createReserveTrialAccount(\n request: ReserveTrialCreateAccountRequestEntry,\n normalizedEmail: string,\n startDayMs: number,\n ): ReserveTrialCreateAccountResult {\n const accountId = accountIdOf(this.host.genId('sim_trial_account'))\n const bucketName = `trial-${this.host.genId('bucket').slice(-8)}`\n const bucketResponse = this.host.createBucket({\n accountId,\n bucketName,\n bucketType: 'allPrivate',\n })\n if (bucketResponse.status !== 200) {\n throw new Error('failed to create simulator reserve trial bucket')\n }\n const bucket = bucketResponse.body as BucketInfo\n const keyId = applicationKeyIdOf(this.host.genId('sim_key'))\n const applicationKey = this.host.genId('sim_secret')\n this.host.storeKey({\n applicationKeyId: keyId,\n keyName: `reserve-trial-${bucketName}`,\n capabilities: PARTNER_CREATED_STORAGE_KEY_CAPABILITIES,\n accountId,\n applicationKey,\n bucketIds: [bucket.bucketId],\n namePrefix: null,\n expirationTimestamp: null,\n })\n this.knownEmails.add(normalizedEmail)\n const region = request.region ?? Region.UsWest\n const account: ReserveTrialCreateAccountResult = {\n accountId,\n applicationKey,\n applicationKeyId: keyId,\n s3Endpoint: `s3.${region}-001.backblazeb2.com`,\n startDate: utcDateString(startDayMs),\n endDate: utcDateString(startDayMs + request.term * DAY_MS),\n email: request.email,\n bucketName: bucket.bucketName,\n bucketId: bucket.bucketId,\n }\n return account\n }\n\n private parseCreateGroupMemberRequest(\n record: Record<string, unknown>,\n ): CreateGroupMemberRequest | { readonly error: SimulatorJsonResponse } {\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId\n const groupId = this.requiredString(record, 'groupId', 401, 'invalid_group_id')\n if ('error' in groupId) return groupId\n const memberEmail = this.requiredString(record, 'memberEmail', 401, 'invalid_email')\n if ('error' in memberEmail) return memberEmail\n const regionValue = record['region']\n if (\n regionValue !== undefined &&\n regionValue !== null &&\n (typeof regionValue !== 'string' || !PARTNER_REGIONS.has(regionValue))\n ) {\n return { error: this.host.error(401, 'invalid_region', 'region is invalid') }\n }\n return {\n adminAccountId: accountIdOf(adminAccountId.value),\n groupId: groupIdOf(groupId.value),\n memberEmail: memberEmail.value,\n ...(regionValue !== undefined ? { region: regionValue as Region | null } : {}),\n }\n }\n\n private parseEjectGroupMemberRequest(\n record: Record<string, unknown>,\n ): EjectGroupMemberRequest | { readonly error: SimulatorJsonResponse } {\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId\n const groupId = this.requiredString(record, 'groupId', 401, 'invalid_group_id')\n if ('error' in groupId) return groupId\n const memberAccountId = this.requiredString(\n record,\n 'memberAccountId',\n 401,\n 'invalid_member_account_id',\n )\n if ('error' in memberAccountId) return memberAccountId\n const email = record['email']\n if (email !== undefined && email !== null && typeof email !== 'string') {\n return { error: this.host.error(401, 'invalid_email', 'email address is invalid') }\n }\n return {\n adminAccountId: accountIdOf(adminAccountId.value),\n groupId: groupIdOf(groupId.value),\n memberAccountId: accountIdOf(memberAccountId.value),\n ...(email !== undefined ? { email: email as string | null } : {}),\n }\n }\n\n private parseListGroupMembersRequest(\n record: Record<string, unknown>,\n ):\n | (ListGroupMembersRequest & { readonly maxMemberCount: number })\n | { readonly error: SimulatorJsonResponse } {\n const adminAccountId = this.requiredString(record, 'adminAccountId', 400, 'bad_request')\n if ('error' in adminAccountId) return adminAccountId\n const groupId = this.requiredString(record, 'groupId', 401, 'invalid_group_id')\n if ('error' in groupId) return groupId\n const maxMemberCount = this.optionalInteger(\n record,\n 'maxMemberCount',\n DEFAULT_MAX_MEMBER_COUNT,\n 1,\n MAX_MEMBER_COUNT,\n 401,\n 'out_of_range',\n { zeroUsesDefault: true },\n )\n if ('error' in maxMemberCount) return maxMemberCount\n const startEmail = record['startEmail']\n if (startEmail !== undefined && typeof startEmail !== 'string') {\n return { error: this.host.error(400, 'bad_request', 'startEmail must be a string') }\n }\n return {\n adminAccountId: accountIdOf(adminAccountId.value),\n groupId: groupIdOf(groupId.value),\n ...(startEmail !== undefined ? { startEmail } : {}),\n maxMemberCount: maxMemberCount.value,\n }\n }\n\n private requiredString(\n record: Record<string, unknown>,\n field: string,\n status: number,\n code: string,\n ): { readonly value: string } | { readonly error: SimulatorJsonResponse } {\n const value = record[field]\n if (typeof value !== 'string' || value === '') {\n return { error: this.host.error(status, code, `${field} is required`) }\n }\n return { value }\n }\n\n private optionalInteger(\n record: Record<string, unknown>,\n field: string,\n defaultValue: number,\n min: number,\n max: number,\n status: number,\n code: string,\n options: { readonly zeroUsesDefault?: boolean } = {},\n ): { readonly value: number } | { readonly error: SimulatorJsonResponse } {\n const raw = record[field]\n if (raw === undefined) return { value: defaultValue }\n const value =\n typeof raw === 'number'\n ? raw\n : typeof raw === 'string' && raw !== ''\n ? Number(raw)\n : Number.NaN\n if (options.zeroUsesDefault === true && value === 0) return { value: defaultValue }\n if (!Number.isInteger(value) || value < min || value > max) {\n return { error: this.host.error(status, code, `${field} must be between ${min} and ${max}`) }\n }\n return { value }\n }\n\n private ensureGroupsForAdmin(adminAccountId: string): SimulatorJsonResponse | null {\n if (this.groupsByAdmin.has(adminAccountId)) return null\n if (this.groupsByAdmin.size >= MAX_AUTO_PROVISIONED_ADMINS) {\n return this.host.error(\n 400,\n 'too_many_accounts',\n 'simulator Partner account auto-provisioning cap exceeded',\n )\n }\n this.groupsByAdmin.set(adminAccountId, [])\n for (let index = 1; index <= DEFAULT_GROUP_COUNT; index += 1) {\n this.createGroup(adminAccountId, `Simulator Group ${index}`)\n }\n return null\n }\n\n private createGroup(adminAccountId: string, groupName: string): StoredPartnerGroup {\n const existingGroupIds = this.groupsByAdmin.get(adminAccountId) ?? []\n if (existingGroupIds.length >= MAX_GROUPS_PER_ADMIN) {\n throw new Error('simulator Partner group cap exceeded')\n }\n const group: StoredPartnerGroup = {\n adminAccountId,\n groupId: this.host.genId('sim_group'),\n groupName,\n groupProducts: ['STORAGE', 'BACKUP'],\n createdTimestamp: this.host.monotonicTimestamp(),\n deleted: false,\n }\n this.groups.set(group.groupId, group)\n existingGroupIds.push(group.groupId)\n this.groupsByAdmin.set(adminAccountId, existingGroupIds)\n this.groupMembers.set(group.groupId, new Map())\n return group\n }\n\n private activeGroup(groupId: string, adminAccountId: string): StoredPartnerGroup | null {\n const group = this.groups.get(groupId)\n if (group === undefined || group.deleted || group.adminAccountId !== adminAccountId) return null\n return group\n }\n\n private activeGroupsForAdmin(adminAccountId: string): StoredPartnerGroup[] {\n const groupIds = this.groupsByAdmin.get(adminAccountId) ?? []\n return groupIds\n .map((groupId) => this.groups.get(groupId))\n .filter((group): group is StoredPartnerGroup => group !== undefined && !group.deleted)\n }\n\n private membersForGroup(groupId: string): Map<string, StoredPartnerGroupMember> {\n const existing = this.groupMembers.get(groupId)\n if (existing !== undefined) return existing\n const created = new Map<string, StoredPartnerGroupMember>()\n this.groupMembers.set(groupId, created)\n return created\n }\n\n private activeMembersForGroup(groupId: string): StoredPartnerGroupMember[] {\n return [...(this.groupMembers.get(groupId)?.values() ?? [])].filter((member) => !member.ejected)\n }\n\n private ensureComputersForAccount(\n accountId: string,\n ): Map<string, StoredComputerBackup> | SimulatorJsonResponse {\n const existing = this.computersByAccount.get(accountId)\n if (existing !== undefined) return existing\n if (this.computersByAccount.size >= MAX_AUTO_PROVISIONED_BACKUP_ACCOUNTS) {\n return this.host.error(\n 400,\n 'too_many_accounts',\n 'simulator Backup account auto-provisioning cap exceeded',\n )\n }\n const computers = new Map<string, StoredComputerBackup>()\n for (let index = 1; index <= DEFAULT_COMPUTER_COUNT; index += 1) {\n const computer: StoredComputerBackup = {\n accountId,\n computerId: this.host.genId('sim_computer'),\n computerName: `sim-computer-${index}`,\n lastFileUploadedTimestamp: this.host.monotonicTimestamp(),\n deleted: false,\n }\n computers.set(computer.computerId, computer)\n }\n this.computersByAccount.set(accountId, computers)\n return computers\n }\n\n private publicGroup(group: StoredPartnerGroup): PartnerGroup {\n const timestamp = b2FriendlyTimestamp(group.createdTimestamp)\n return {\n accountStandingDetails: { state: 'B2_GOOD_STANDING' },\n b2Stats: this.emptyB2Stats(group.createdTimestamp),\n groupId: groupIdOf(group.groupId),\n groupName: group.groupName,\n groupProducts: group.groupProducts,\n groupStats: {\n createdTimestamp: timestamp,\n groupStatsAsOfTimestamp: timestamp,\n memberCount: this.activeMembersForGroup(group.groupId).length,\n },\n }\n }\n\n private publicGroupMember(member: StoredPartnerGroupMember): PartnerGroupMember {\n return {\n accountId: accountIdOf(member.accountId),\n email: member.email,\n groupId: groupIdOf(member.groupId),\n groupName: member.groupName,\n region: member.region,\n s3Endpoint: member.s3Endpoint,\n }\n }\n\n private publicListedGroupMember(member: StoredPartnerGroupMember): ListedGroupMember {\n return {\n ...this.publicGroupMember(member),\n b2Stats: this.emptyB2Stats(member.createdTimestamp),\n }\n }\n\n private publicComputer(computer: StoredComputerBackup): ComputerBackup {\n return {\n computerId: computerIdOf(computer.computerId),\n computerName: computer.computerName,\n lastFileUploadedTimestamp: computer.lastFileUploadedTimestamp,\n }\n }\n\n private emptyB2Stats(timestamp: number): PartnerB2Stats {\n return {\n b2BytesStoredCount: 0,\n b2FilesStoredCount: 0,\n b2StatsAsOfTimestamp: b2FriendlyTimestamp(timestamp),\n bucketCount: 0,\n }\n }\n}\n"],"mappings":";;;;;AAkCA,IAAM,SAAS;AACf,IAAM,kBAAkB,IAAI,IAAY,OAAO,OAAO,gBAAA,MAAM,CAAC;AAC7D,IAAM,wBAAwB,IAAI,IAAqB,6BAAA,sBAAsB;AAC7E,IAAM,sBAAsB;AAC5B,IAAM,uBAAuB;AAC7B,IAAM,0BAA0B;AAChC,IAAM,kBAAkB;AACxB,IAAM,8BAA8B;AACpC,IAAM,oBAAoB;AAC1B,IAAM,2BAA2B;AACjC,IAAM,mBAAmB;AACzB,IAAM,6BAA6B;AACnC,IAAM,qBAAqB;AAC3B,IAAM,qBAAqB;AAC3B,IAAM,yBAAyB;AAC/B,IAAM,uCAAuC;AAC7C,IAAM,2CAA2C,OAAO,OAAO;CAC7D,aAAA,WAAW;CACX,aAAA,WAAW;CACX,aAAA,WAAW;CACX,aAAA,WAAW;CACX,aAAA,WAAW;CACX,aAAA,WAAW;CACX,aAAA,WAAW;AACb,CAAC;AAED,SAAS,qBAAqB,UAA+C;CAC3E,OAAO,sBAAsB,IAAI,QAA2B;AAC9D;AAGE,6BAAA,gBAAgB,YAChB,6BAAA,gBAAgB,kBAChB,6BAAA,gBAAgB;AAclB,SAAS,cAAc,IAAoB;CACzC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,GAAG,EAAE;AAC/C;AAGA,SAAS,oBAAoB,IAAoB;CAC/C,MAAM,OAAO,IAAI,KAAK,EAAE;CACxB,MAAM,OAAO,GAAW,QAAQ,MAAc,OAAO,CAAC,CAAC,CAAC,SAAS,OAAO,GAAG;CAG3E,OAAO,IAAI,GAFI,IAAI,KAAK,eAAe,GAAG,CAAC,IAAI,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,IAAI,KAAK,WAAW,CAAC,IAEnF,IAAI,GADH,IAAI,KAAK,YAAY,CAAC,IAAI,IAAI,KAAK,cAAc,CAAC,IAAI,IAAI,KAAK,cAAc,CAAC;AAEhG;AAEA,SAAS,cAAc,IAAoB;CACzC,MAAM,OAAO,IAAI,KAAK,EAAE;CACxB,OAAO,KAAK,IAAI,KAAK,eAAe,GAAG,KAAK,YAAY,GAAG,KAAK,WAAW,CAAC;AAC9E;AA4CA,SAAS,cAAc,MAAwC;CAC7D,OAAO,OAAO,SAAS,YAAY,SAAS,OAAQ,OAAmC,CAAC;AAC1F;AAEA,SAAS,eAAe,OAAuB;CAC7C,OAAO,MAAM,KAAK,CAAC,CAAC,YAAY;AAClC;AAEA,SAAS,oBAAoB,OAAwB;CACnD,MAAM,UAAU,MAAM,KAAK;CAC3B,IAAI,YAAY,SAAS,QAAQ,SAAS,KAAK,QAAQ,SAAS,KAAK,OAAO;CAC5E,MAAM,KAAK,QAAQ,QAAQ,GAAG;CAC9B,IAAI,MAAM,KAAK,OAAO,QAAQ,YAAY,GAAG,KAAK,OAAO,QAAQ,SAAS,GAAG,OAAO;CACpF,MAAM,SAAS,QAAQ,MAAM,KAAK,CAAC;CACnC,IAAI,CAAC,OAAO,SAAS,GAAG,KAAK,OAAO,WAAW,GAAG,KAAK,OAAO,SAAS,GAAG,GAAG,OAAO;CACpF,OAAO,CAAC,KAAK,KAAK,OAAO;AAC3B;AAEA,SAAS,eAAe,MAAc,OAAuB;CAC3D,IAAI,OAAO,OAAO,OAAO;CACzB,IAAI,OAAO,OAAO,OAAO;CACzB,OAAO;AACT;AAEA,SAAS,yBACP,cAC8B;CAC9B,OAAO,OAAO,OAAO,CAAC,GAAG,YAAY,CAAC;AACxC;;;;;;;;;;;;;;;;AA8CA,IAAa,mBAAb,MAA8B;CAuBT;CAtBnB,+BAAgC,IAAI,IAAgC;CACpE,8BAA+B,IAAI,IAAY;CAC/C,yBAA0B,IAAI,IAAgC;CAC9D,gCAAiC,IAAI,IAAsB;CAC3D,+BAAgC,IAAI,IAAmD;CACvF,0CAA2C,IAAI,IAAsC;CACrF,qCAAsC,IAAI,IAA+C;CACzF;CACA;CACA;CACA;CACA;CACA;CACA;;;;;;;CAQA,YACE,MACA,SACA;EAFiB,KAAA,OAAA;EAGjB,KAAK,mBAAmB,QAAQ,oBAAoB;EACpD,KAAK,uBAAuB,KAAK,qBAAqB,QAAQ,cAAc;EAC5E,KAAK,aAAa,QAAQ,qBAAqB;EAC/C,KAAK,uBAAuB,QAAQ,+BAA+B;EACnE,KAAK,wBAAwB,QAAQ,gCAAgC;EACrE,KAAK,qBAAqB,yBACxB,QAAQ,6BAA6B,CAAC,gBAAA,kBAAkB,GAAG,CAC7D;EACA,KAAK,qBAAqB,yBACxB,QAAQ,6BAA6B,CAAC,gBAAA,kBAAkB,GAAG,CAC7D;CACF;;;;;;CAOA,qBAA8B;EAC5B,OAAO,KAAK;CACd;;;;;;;;CASA,WAAW,UAA2B;EACpC,OAAO,qBAAqB,QAAQ;CACtC;;;;;;;;;CAUA,UAAU,aAAiC,SAAS,sBAA6C;EAC/F,IAAI,CAAC,KAAK,KAAK,aAAa,WAAW,GACrC,OAAO,KAAK,KAAK,MACf,KACA,kBACA,kDACF;EAGF,MAAM,WAAW,KAAK,KAAK,MAAM,wBAAwB;EACzD,KAAK,aAAa,IAAI,UAAU;GAC9B,WAAW,KAAK,KAAK;GACrB,oBAAoB,KAAK;GACzB,WAAW,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK;GACvC,oBAAoB,KAAK;EAC3B,CAAC;EACD,OAAO;GACL,QAAQ;GACR,MAAM;IACJ,WAAW,YAAA,UAAY,KAAK,KAAK,SAAS;IAC1C,oBAAoB;IACpB,SAAS;KACP,YAAY;MACV,yBAAyB,KAAK,KAAK;MACnC,QAAQ;MACR,UAAU;MACV,YAAY;MACZ,cAAc;OACZ,aAAA,WAAW;OACX,aAAA,WAAW;OACX,aAAA,WAAW;OACX,aAAA,WAAW;OACX,aAAA,WAAW;OACX,aAAA,WAAW;OACX,aAAA,WAAW;OACX,aAAA,WAAW;MACb;MACA,aAAa;MACb,UAAU;MACV,YAAY;MACZ,qBAAqB,KAAK,KAAK;MAC/B,UAAU;KACZ;KACA,WAAW;MACT,cAAc,KAAK;MACnB,cAAc,GAAG,OAAO;MACxB,UAAU;KACZ;KACA,WAAW;MACT,cAAc,GAAG,OAAO;MACxB,cAAc,KAAK;MACnB,UAAU;KACZ;IACF;IACA,mCAAmC;GACrC;EACF;CACF;;;;;;;;;CAUA,0BAA0B,MAAe,WAA2C;EAClF,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,2BAA2B,SAAS;EACvF,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,KAAK,sCAAsC,IAAI;EAC9D,IAAI,OAAO,UAAU,MAAM,OAAO,OAAO;EAEzC,MAAM,aAAa,cAAc,KAAK,KAAK,IAAI,CAAC;EAEhD,OAAO;GAAE,QAAQ;GAAK,MADP,KAAK,0BAA0B,OAAO,OAAO,OAAO,iBAAiB,UACxD;EAAO;CACrC;;;;;;;;;CAUA,kBAAkB,MAAe,WAA2C;EAC1E,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,mBAAmB,WAAW,EAC/E,YAAY,MACd,CAAC;EACD,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,cAAc,IAAI;EACjC,MAAM,UAAU,KAAK,8BAA8B,MAAM;EACzD,IAAI,WAAW,SAAS,OAAO,QAAQ;EACvC,MAAM,eAAe,KAAK,iBAAiB,MAAM,QAAQ,cAAc;EACvE,IAAI,iBAAiB,MAAM,OAAO;EAElC,MAAM,QAAQ,KAAK,YAAY,QAAQ,SAAS,QAAQ,cAAc;EACtE,IAAI,UAAU,MACZ,OAAO,KAAK,KAAK,MAAM,KAAK,oBAAoB,gCAAgC;EAElF,IAAI,CAAC,KAAK,sBACR,OAAO,KAAK,KAAK,MAAM,KAAK,qBAAqB,sCAAsC;EAGzF,MAAM,kBAAkB,eAAe,QAAQ,WAAW;EAC1D,IAAI,CAAC,oBAAoB,QAAQ,WAAW,KAAK,KAAK,YAAY,IAAI,eAAe,GACnF,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,4CAA4C;EAG3F,MAAM,UAAU,KAAK,gBAAgB,MAAM,OAAO;EAClD,IAAI,KAAK,sBAAsB,MAAM,OAAO,CAAC,CAAC,UAAU,mBACtD,OAAO,KAAK,KAAK,MAAM,KAAK,oBAAoB,mCAAmC;EAGrF,MAAM,cAAY,YAAA,UAAY,KAAK,KAAK,MAAM,0BAA0B,CAAC;EACzE,MAAM,qBAAmB,YAAA,iBAAmB,KAAK,KAAK,MAAM,SAAS,CAAC;EACtE,MAAM,iBAAiB,KAAK,KAAK,MAAM,YAAY;EACnD,MAAM,SAAS,QAAQ,UAAU,gBAAA,OAAO;EACxC,MAAM,SAAmC;GACvC,WAAA;GACA,OAAO,QAAQ;GACf;GACA,SAAS,MAAM;GACf,WAAW,MAAM;GACjB;GACA,YAAY,MAAM,OAAO;GACzB,kBAAA;GACA;GACA,kBAAkB,KAAK,KAAK,mBAAmB;GAC/C,SAAS;EACX;EACA,QAAQ,IAAI,iBAAiB,MAAM;EACnC,KAAK,wBAAwB,IAAI,aAAW,MAAM;EAClD,KAAK,YAAY,IAAI,eAAe;EACpC,KAAK,KAAK,SAAS;GACjB,kBAAA;GACA,SAAS,gBAAgB;GACzB,cAAc;GACd,WAAA;GACA;GACA,WAAW;GACX,YAAY;GACZ,qBAAqB;EACvB,CAAC;EAOD,OAAO;GAAE,QAAQ;GAAK,MAAM;IAJ1B,kBAAA;IACA;IACA,aAAa,KAAK,kBAAkB,MAAM;GAEhB;EAAO;CACrC;;;;;;;;;CAUA,iBAAiB,MAAe,WAA2C;EACzE,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,kBAAkB,SAAS;EAC9E,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,cAAc,IAAI;EACjC,MAAM,UAAU,KAAK,6BAA6B,MAAM;EACxD,IAAI,WAAW,SAAS,OAAO,QAAQ;EACvC,MAAM,eAAe,KAAK,iBAAiB,MAAM,QAAQ,cAAc;EACvE,IAAI,iBAAiB,MAAM,OAAO;EAElC,MAAM,QAAQ,KAAK,YAAY,QAAQ,SAAS,QAAQ,cAAc;EACtE,IAAI,UAAU,MACZ,OAAO,KAAK,KAAK,MAAM,KAAK,oBAAoB,gCAAgC;EAGlF,MAAM,SAAS,KAAK,wBAAwB,IAAI,QAAQ,eAAe;EACvE,IAAI,WAAW,KAAA,KAAa,OAAO,WAAW,OAAO,YAAY,MAAM,SACrE,OAAO,KAAK,KAAK,MAAM,KAAK,6BAA6B,oCAAoC;EAG/F,MAAM,0BAA0B,OAAO;EACvC,IAAI,QAAQ,UAAU,KAAA,KAAa,QAAQ,UAAU,MAAM;GACzD,MAAM,kBAAkB,eAAe,QAAQ,KAAK;GACpD,MAAM,iBAAiB,oBAAoB;GAC3C,IACE,CAAC,oBAAoB,QAAQ,KAAK,KACjC,CAAC,kBAAkB,KAAK,YAAY,IAAI,eAAe,GAExD,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,4CAA4C;GAE3F,IAAI,CAAC,gBAAgB;IACnB,KAAK,YAAY,OAAO,uBAAuB;IAC/C,KAAK,YAAY,IAAI,eAAe;GACtC;GACA,OAAO,QAAQ,QAAQ;GACvB,OAAO,kBAAkB;EAC3B;EAEA,OAAO,UAAU;EACjB,KAAK,aAAa,IAAI,MAAM,OAAO,CAAC,EAAE,OAAO,uBAAuB;EAEpE,OAAO;GAAE,QAAQ;GAAK,MADqB,KAAK,kBAAkB,MACtC;EAAS;CACvC;;;;;;;;;CAUA,WAAW,MAAe,WAA2C;EACnE,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,YAAY,WAAW,EACxE,YAAY,MACd,CAAC;EACD,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,cAAc,IAAI;EACjC,MAAM,iBAAiB,KAAK,eAAe,QAAQ,kBAAkB,KAAK,aAAa;EACvF,IAAI,WAAW,gBAAgB,OAAO,eAAe;EACrD,MAAM,eAAe,KAAK,iBAAiB,MAAM,eAAe,KAAK;EACrE,IAAI,iBAAiB,MAAM,OAAO;EAClC,MAAM,gBAAgB,KAAK,gBACzB,QACA,iBACA,yBACA,GACA,iBACA,KACA,cACF;EACA,IAAI,WAAW,eAAe,OAAO,cAAc;EAEnD,MAAM,iBAAiB,KAAK,qBAAqB,eAAe,KAAK;EACrE,IAAI,mBAAmB,MAAM,OAAO;EACpC,MAAM,iBAAiB,OAAO;EAC9B,MAAM,YAAY,OAAO,mBAAmB,WAAW,iBAAiB,KAAA;EACxE,MAAM,oBAAoB,OAAO;EACjC,MAAM,eAAe,OAAO,sBAAsB,WAAW,oBAAoB,KAAA;EACjF,IACE,iBAAiB,KAAA,KACjB,KAAK,YAAY,cAAc,eAAe,KAAK,MAAM,MAEzD,OAAO,KAAK,KAAK,MAAM,KAAK,oBAAoB,gCAAgC;EAGlF,MAAM,YAAY,KAAK,qBAAqB,eAAe,KAAK,CAAC,CAC9D,QAAQ,UAAU,cAAc,KAAA,KAAa,MAAM,cAAc,SAAS,CAAC,CAC3E,MAAM,MAAM,UAAU,eAAe,KAAK,SAAS,MAAM,OAAO,CAAC;EACpE,MAAM,aACJ,iBAAiB,KAAA,IAAY,IAAI,UAAU,WAAW,UAAU,MAAM,WAAW,YAAY;EAC/F,MAAM,uBAAuB,eAAe,KAAK,UAAU,SAAS;EACpE,MAAM,OAAO,UAAU,MAAM,sBAAsB,uBAAuB,cAAc,KAAK;EAC7F,MAAM,OAAO,UAAU,uBAAuB,cAAc;EAM5D,OAAO;GAAE,QAAQ;GAAK,MAAM;IAJ1B,WAAW,YAAA,UAAY,eAAe,KAAK;IAC3C,QAAQ,KAAK,KAAK,UAAU,KAAK,YAAY,KAAK,CAAC;IACnD,aAAa,SAAS,KAAA,IAAY,OAAO,YAAA,QAAU,KAAK,OAAO;GAErC;EAAS;CACvC;;;;;;;;;CAUA,iBAAiB,MAAe,WAA2C;EACzE,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,kBAAkB,WAAW,EAC9E,YAAY,MACd,CAAC;EACD,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,cAAc,IAAI;EACjC,MAAM,UAAU,KAAK,6BAA6B,MAAM;EACxD,IAAI,WAAW,SAAS,OAAO,QAAQ;EACvC,MAAM,eAAe,KAAK,iBAAiB,MAAM,QAAQ,cAAc;EACvE,IAAI,iBAAiB,MAAM,OAAO;EAElC,MAAM,QAAQ,KAAK,YAAY,QAAQ,SAAS,QAAQ,cAAc;EACtE,IAAI,UAAU,MACZ,OAAO,KAAK,KAAK,MAAM,KAAK,oBAAoB,gCAAgC;EAGlF,MAAM,UAAU,KAAK,sBAAsB,MAAM,OAAO,CAAC,CAAC,MAAM,MAAM,UACpE,eAAe,KAAK,iBAAiB,MAAM,eAAe,CAC5D;EACA,MAAM,aACJ,QAAQ,eAAe,KAAA,IAAY,KAAA,IAAY,eAAe,QAAQ,UAAU;EAClF,MAAM,aACJ,eAAe,KAAA,IACX,IACA,QAAQ,WAAW,WAAW,OAAO,mBAAmB,UAAU;EACxE,MAAM,uBAAuB,eAAe,KAAK,QAAQ,SAAS;EAClE,MAAM,OAAO,QAAQ,MAAM,sBAAsB,uBAAuB,QAAQ,cAAc;EAC9F,MAAM,OAAO,QAAQ,uBAAuB,QAAQ;EAOpD,OAAO;GAAE,QAAQ;GAAK,MAAM;IAL1B,SAAS,YAAA,QAAU,MAAM,OAAO;IAChC,WAAW,MAAM;IACjB,cAAc,KAAK,KAAK,WAAW,KAAK,wBAAwB,MAAM,CAAC;IACvE,WAAW,SAAS,KAAA,IAAY,OAAO,KAAK;GAElB;EAAS;CACvC;;;;;;;;;CAUA,cAAc,MAAe,WAA2C;EACtE,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,eAAe,WAAW,EAC3E,YAAY,MACd,CAAC;EACD,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,cAAc,IAAI;EACjC,MAAM,YAAY,KAAK,eAAe,QAAQ,aAAa,KAAK,oBAAoB;EACpF,IAAI,WAAW,WAAW,OAAO,UAAU;EAC3C,MAAM,eAAe,KAAK,iBAAiB,MAAM,UAAU,KAAK;EAChE,IAAI,iBAAiB,MAAM,OAAO;EAClC,MAAM,mBAAmB,KAAK,gBAC5B,QACA,oBACA,4BACA,oBACA,oBACA,KACA,cACF;EACA,IAAI,WAAW,kBAAkB,OAAO,iBAAiB;EAEzD,MAAM,YAAY,KAAK,0BAA0B,UAAU,KAAK;EAChE,IAAI,YAAY,WAAW,OAAO;EAClC,MAAM,uBAAuB,OAAO;EACpC,MAAM,kBACJ,OAAO,yBAAyB,WAAW,uBAAuB,KAAA;EACpE,IAAI,oBAAoB,KAAA,GAAW;GACjC,MAAM,QAAQ,UAAU,IAAI,eAAe;GAC3C,IAAI,UAAU,KAAA,KAAa,MAAM,SAE/B,OAAO,KAAK,KAAK,MAAM,KAAK,uBAAuB,mCAAmC;EAE1F;EAEA,MAAM,kBAAkB,CAAC,GAAG,UAAU,OAAO,CAAC,CAAC,CAC5C,QAAQ,aAAa,CAAC,SAAS,OAAO,CAAC,CACvC,MAAM,MAAM,UAAU,eAAe,KAAK,YAAY,MAAM,UAAU,CAAC;EAC1E,MAAM,aACJ,oBAAoB,KAAA,IAChB,IACA,gBAAgB,WAAW,aAAa,SAAS,cAAc,eAAe;EACpF,MAAM,uBAAuB,eAAe,KAAK,gBAAgB,SAAS;EAC1E,MAAM,OAAO,gBAAgB,MAC3B,sBACA,uBAAuB,iBAAiB,KAC1C;EACA,MAAM,OAAO,gBAAgB,uBAAuB,iBAAiB;EACrE,OAAO;GACL,QAAQ;GACR,MAAM;IACJ,gBAAgB,SAAS,KAAA,IAAY,OAAO,KAAK;IACjD,WAAW,KAAK,KAAK,aAAa,KAAK,eAAe,QAAQ,CAAC;GACjE;EACF;CACF;;;;;;;;;CAUA,eAAe,MAAe,WAA2C;EACvE,MAAM,OAAO,KAAK,iBAAiB,6BAAA,gBAAgB,gBAAgB,WAAW,EAC5E,YAAY,MACd,CAAC;EACD,IAAI,YAAY,MAAM,OAAO;EAC7B,MAAM,SAAS,cAAc,IAAI;EACjC,MAAM,YAAY,KAAK,eAAe,QAAQ,aAAa,KAAK,oBAAoB;EACpF,IAAI,WAAW,WAAW,OAAO,UAAU;EAC3C,MAAM,aAAa,KAAK,eAAe,QAAQ,cAAc,KAAK,qBAAqB;EACvF,IAAI,WAAW,YAAY,OAAO,WAAW;EAC7C,MAAM,eAAe,KAAK,iBAAiB,MAAM,UAAU,KAAK;EAChE,IAAI,iBAAiB,MAAM,OAAO;EAGlC,MAAM,WADY,KAAK,mBAAmB,IAAI,UAAU,KACvC,CAAA,EAAW,IAAI,WAAW,KAAK;EAChD,IAAI,aAAa,KAAA,KAAa,SAAS,SACrC,OAAO,KAAK,KAAK,MAAM,KAAK,uBAAuB,mCAAmC;EAExF,SAAS,UAAU;EACnB,OAAO;GAAE,QAAQ;GAAK,MAAM,CAAC,KAAK,eAAe,QAAQ,CAAC;EAAE;CAC9D;CAEA,iBACE,UACA,WACA,UAA6C,CAAC,GACI;EAClD,IAAI,cAAc,KAAA,KAAa,UAAU,KAAK,MAAM,MAAM,KAAK,KAAK,SAAS,GAC3E,OAAO,KAAK,KAAK,MACf,KACA,iBACA,uDACF;EAGF,IAAI,CAAC,KAAK,sBAAsB;GAC9B,IAAI,CAAC,KAAK,YACR,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,wCAAwC;GAEvF,IAAI,QAAQ,eAAe,SAAS,CAAC,KAAK,sBACxC,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,4CAA4C;GAE3F,IAAI,CAAC,KAAK,uBACR,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,iCAAiC;GAEhF,OAAO,EAAE,WAAW,KAAK;EAC3B;EAEA,MAAM,QAAQ,KAAK,aAAa,IAAI,SAAS;EAC7C,IAAI,UAAU,KAAA,KAAa,KAAK,KAAK,IAAI,IAAI,MAAM,WACjD,OAAO,KAAK,KAAK,MAAM,KAAK,gBAAgB,yCAAyC;EAEvF,IAAI,CAAC,KAAK,YACR,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,wCAAwC;EAEvF,IAAI,QAAQ,eAAe,SAAS,CAAC,KAAK,sBACxC,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,4CAA4C;EAE3F,IAAI,CAAC,KAAK,uBACR,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,iCAAiC;EAEhF,MAAM,kBAAkB,KAAK,8BAA8B,UAAU,KAAK;EAC1E,IAAI,oBAAoB,MAAM,OAAO;EACrC,OAAO,EAAE,WAAW,MAAM,UAAU;CACtC;CAEA,8BACE,UACA,OAC8B;EAC9B,MAAM,cAAc,6BAAA,wCAAwC,QAAQ;EACpE,IAAI,gBAAgB,MAClB,OAAO,KAAK,KAAK,MAAM,KAAK,gBAAgB,oCAAoC,UAAU;EAE5F,MAAM,UACJ,YAAY,UAAU,WAAW,MAAM,qBAAqB,MAAM;EACpE,MAAM,UAAU,6BAAA,2BAA2B,YAAY,cAAc,OAAO;EAC5E,IAAI,QAAQ,WAAW,GAAG,OAAO;EACjC,OAAO,KAAK,KAAK,MACf,KACA,gBACA,8CAA8C,QAAQ,KAAK,IAAI,GACjE;CACF;CAEA,iBACE,MACA,oBAC8B;EAC9B,IAAI,KAAK,cAAc,MAAM,OAAO;EACpC,IAAI,KAAK,cAAc,oBAAoB,OAAO;EAClD,OAAO,KAAK,KAAK,MACf,KACA,gBACA,uDACF;CACF;CAEA,sCAA8C,OAQxC;EACJ,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,OAAO,EACL,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,yCAAyC,EACtF;EAEF,MAAM,SAAS;EACf,MAAM,QAAQ,OAAO;EACrB,IAAI,OAAO,UAAU,UACnB,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,mBAAmB,EAAE;EAE3E,IAAI,CAAC,oBAAoB,KAAK,GAC5B,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,0BAA0B,EAAE;EAElF,MAAM,kBAAkB,eAAe,KAAK;EAC5C,IAAI,KAAK,YAAY,IAAI,eAAe,GACtC,OAAO,EACL,OAAO,KAAK,KAAK,MACf,KACA,eACA,qDACF,EACF;EAEF,MAAM,OAAO,OAAO;EACpB,IAAI,OAAO,SAAS,YAAY,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,OAAO,IAC5E,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,oCAAoC,EAAE;EAE5F,MAAM,UAAU,OAAO;EACvB,IAAI,OAAO,YAAY,YAAY,CAAC,OAAO,UAAU,OAAO,KAAK,UAAU,KAAK,UAAU,IACxF,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,qCAAqC,EAAE;EAE7F,MAAM,SAAS,OAAO;EACtB,IACE,WAAW,KAAA,KACX,WAAW,SACV,OAAO,WAAW,YAAY,CAAC,gBAAgB,IAAI,MAAM,IAE1D,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,yBAAyB,EAAE;EAGjF,OAAO;GACL,OAAO;IACL;IACA;IACA;IACA,GAAI,WAAW,KAAA,IAAY,EAAU,OAAwB,IAAI,CAAC;GACpE;GACA;GACA,OAAO;EACT;CACF;CAEA,0BACE,SACA,iBACA,YACiC;EACjC,MAAM,cAAY,YAAA,UAAY,KAAK,KAAK,MAAM,mBAAmB,CAAC;EAClE,MAAM,aAAa,SAAS,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAE;EAC9D,MAAM,iBAAiB,KAAK,KAAK,aAAa;GAC5C,WAAA;GACA;GACA,YAAY;EACd,CAAC;EACD,IAAI,eAAe,WAAW,KAC5B,MAAM,IAAI,MAAM,iDAAiD;EAEnE,MAAM,SAAS,eAAe;EAC9B,MAAM,QAAQ,YAAA,iBAAmB,KAAK,KAAK,MAAM,SAAS,CAAC;EAC3D,MAAM,iBAAiB,KAAK,KAAK,MAAM,YAAY;EACnD,KAAK,KAAK,SAAS;GACjB,kBAAkB;GAClB,SAAS,iBAAiB;GAC1B,cAAc;GACd,WAAA;GACA;GACA,WAAW,CAAC,OAAO,QAAQ;GAC3B,YAAY;GACZ,qBAAqB;EACvB,CAAC;EACD,KAAK,YAAY,IAAI,eAAe;EAapC,OAAO;GAVL,WAAA;GACA;GACA,kBAAkB;GAClB,YAAY,MALC,QAAQ,UAAU,gBAAA,OAAO,OAKb;GACzB,WAAW,cAAc,UAAU;GACnC,SAAS,cAAc,aAAa,QAAQ,OAAO,MAAM;GACzD,OAAO,QAAQ;GACf,YAAY,OAAO;GACnB,UAAU,OAAO;EAEZ;CACT;CAEA,8BACE,QACsE;EACtE,MAAM,iBAAiB,KAAK,eAAe,QAAQ,kBAAkB,KAAK,aAAa;EACvF,IAAI,WAAW,gBAAgB,OAAO;EACtC,MAAM,YAAU,KAAK,eAAe,QAAQ,WAAW,KAAK,kBAAkB;EAC9E,IAAI,WAAW,WAAS,OAAO;EAC/B,MAAM,cAAc,KAAK,eAAe,QAAQ,eAAe,KAAK,eAAe;EACnF,IAAI,WAAW,aAAa,OAAO;EACnC,MAAM,cAAc,OAAO;EAC3B,IACE,gBAAgB,KAAA,KAChB,gBAAgB,SACf,OAAO,gBAAgB,YAAY,CAAC,gBAAgB,IAAI,WAAW,IAEpE,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,kBAAkB,mBAAmB,EAAE;EAE9E,OAAO;GACL,gBAAgB,YAAA,UAAY,eAAe,KAAK;GAChD,SAAS,YAAA,QAAU,UAAQ,KAAK;GAChC,aAAa,YAAY;GACzB,GAAI,gBAAgB,KAAA,IAAY,EAAE,QAAQ,YAA6B,IAAI,CAAC;EAC9E;CACF;CAEA,6BACE,QACqE;EACrE,MAAM,iBAAiB,KAAK,eAAe,QAAQ,kBAAkB,KAAK,aAAa;EACvF,IAAI,WAAW,gBAAgB,OAAO;EACtC,MAAM,YAAU,KAAK,eAAe,QAAQ,WAAW,KAAK,kBAAkB;EAC9E,IAAI,WAAW,WAAS,OAAO;EAC/B,MAAM,kBAAkB,KAAK,eAC3B,QACA,mBACA,KACA,2BACF;EACA,IAAI,WAAW,iBAAiB,OAAO;EACvC,MAAM,QAAQ,OAAO;EACrB,IAAI,UAAU,KAAA,KAAa,UAAU,QAAQ,OAAO,UAAU,UAC5D,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,iBAAiB,0BAA0B,EAAE;EAEpF,OAAO;GACL,gBAAgB,YAAA,UAAY,eAAe,KAAK;GAChD,SAAS,YAAA,QAAU,UAAQ,KAAK;GAChC,iBAAiB,YAAA,UAAY,gBAAgB,KAAK;GAClD,GAAI,UAAU,KAAA,IAAY,EAAS,MAAuB,IAAI,CAAC;EACjE;CACF;CAEA,6BACE,QAG4C;EAC5C,MAAM,iBAAiB,KAAK,eAAe,QAAQ,kBAAkB,KAAK,aAAa;EACvF,IAAI,WAAW,gBAAgB,OAAO;EACtC,MAAM,YAAU,KAAK,eAAe,QAAQ,WAAW,KAAK,kBAAkB;EAC9E,IAAI,WAAW,WAAS,OAAO;EAC/B,MAAM,iBAAiB,KAAK,gBAC1B,QACA,kBACA,0BACA,GACA,kBACA,KACA,gBACA,EAAE,iBAAiB,KAAK,CAC1B;EACA,IAAI,WAAW,gBAAgB,OAAO;EACtC,MAAM,aAAa,OAAO;EAC1B,IAAI,eAAe,KAAA,KAAa,OAAO,eAAe,UACpD,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,KAAK,eAAe,6BAA6B,EAAE;EAErF,OAAO;GACL,gBAAgB,YAAA,UAAY,eAAe,KAAK;GAChD,SAAS,YAAA,QAAU,UAAQ,KAAK;GAChC,GAAI,eAAe,KAAA,IAAY,EAAE,WAAW,IAAI,CAAC;GACjD,gBAAgB,eAAe;EACjC;CACF;CAEA,eACE,QACA,OACA,QACA,MACwE;EACxE,MAAM,QAAQ,OAAO;EACrB,IAAI,OAAO,UAAU,YAAY,UAAU,IACzC,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,QAAQ,MAAM,GAAG,MAAM,aAAa,EAAE;EAExE,OAAO,EAAE,MAAM;CACjB;CAEA,gBACE,QACA,OACA,cACA,KACA,KACA,QACA,MACA,UAAkD,CAAC,GACqB;EACxE,MAAM,MAAM,OAAO;EACnB,IAAI,QAAQ,KAAA,GAAW,OAAO,EAAE,OAAO,aAAa;EACpD,MAAM,QACJ,OAAO,QAAQ,WACX,MACA,OAAO,QAAQ,YAAY,QAAQ,KACjC,OAAO,GAAG,IACV;EACR,IAAI,QAAQ,oBAAoB,QAAQ,UAAU,GAAG,OAAO,EAAE,OAAO,aAAa;EAClF,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,OAAO,QAAQ,KACrD,OAAO,EAAE,OAAO,KAAK,KAAK,MAAM,QAAQ,MAAM,GAAG,MAAM,mBAAmB,IAAI,OAAO,KAAK,EAAE;EAE9F,OAAO,EAAE,MAAM;CACjB;CAEA,qBAA6B,gBAAsD;EACjF,IAAI,KAAK,cAAc,IAAI,cAAc,GAAG,OAAO;EACnD,IAAI,KAAK,cAAc,QAAQ,6BAC7B,OAAO,KAAK,KAAK,MACf,KACA,qBACA,0DACF;EAEF,KAAK,cAAc,IAAI,gBAAgB,CAAC,CAAC;EACzC,KAAK,IAAI,QAAQ,GAAG,SAAS,qBAAqB,SAAS,GACzD,KAAK,YAAY,gBAAgB,mBAAmB,OAAO;EAE7D,OAAO;CACT;CAEA,YAAoB,gBAAwB,WAAuC;EACjF,MAAM,mBAAmB,KAAK,cAAc,IAAI,cAAc,KAAK,CAAC;EACpE,IAAI,iBAAiB,UAAU,sBAC7B,MAAM,IAAI,MAAM,sCAAsC;EAExD,MAAM,QAA4B;GAChC;GACA,SAAS,KAAK,KAAK,MAAM,WAAW;GACpC;GACA,eAAe,CAAC,WAAW,QAAQ;GACnC,kBAAkB,KAAK,KAAK,mBAAmB;GAC/C,SAAS;EACX;EACA,KAAK,OAAO,IAAI,MAAM,SAAS,KAAK;EACpC,iBAAiB,KAAK,MAAM,OAAO;EACnC,KAAK,cAAc,IAAI,gBAAgB,gBAAgB;EACvD,KAAK,aAAa,IAAI,MAAM,yBAAS,IAAI,IAAI,CAAC;EAC9C,OAAO;CACT;CAEA,YAAoB,SAAiB,gBAAmD;EACtF,MAAM,QAAQ,KAAK,OAAO,IAAI,OAAO;EACrC,IAAI,UAAU,KAAA,KAAa,MAAM,WAAW,MAAM,mBAAmB,gBAAgB,OAAO;EAC5F,OAAO;CACT;CAEA,qBAA6B,gBAA8C;EAEzE,QADiB,KAAK,cAAc,IAAI,cAAc,KAAK,CAAC,EAAA,CAEzD,KAAK,YAAY,KAAK,OAAO,IAAI,OAAO,CAAC,CAAC,CAC1C,QAAQ,UAAuC,UAAU,KAAA,KAAa,CAAC,MAAM,OAAO;CACzF;CAEA,gBAAwB,SAAwD;EAC9E,MAAM,WAAW,KAAK,aAAa,IAAI,OAAO;EAC9C,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,0BAAU,IAAI,IAAsC;EAC1D,KAAK,aAAa,IAAI,SAAS,OAAO;EACtC,OAAO;CACT;CAEA,sBAA8B,SAA6C;EACzE,OAAO,CAAC,GAAI,KAAK,aAAa,IAAI,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC,CAAE,CAAC,CAAC,QAAQ,WAAW,CAAC,OAAO,OAAO;CACjG;CAEA,0BACE,WAC2D;EAC3D,MAAM,WAAW,KAAK,mBAAmB,IAAI,SAAS;EACtD,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,IAAI,KAAK,mBAAmB,QAAQ,sCAClC,OAAO,KAAK,KAAK,MACf,KACA,qBACA,yDACF;EAEF,MAAM,4BAAY,IAAI,IAAkC;EACxD,KAAK,IAAI,QAAQ,GAAG,SAAS,wBAAwB,SAAS,GAAG;GAC/D,MAAM,WAAiC;IACrC;IACA,YAAY,KAAK,KAAK,MAAM,cAAc;IAC1C,cAAc,gBAAgB;IAC9B,2BAA2B,KAAK,KAAK,mBAAmB;IACxD,SAAS;GACX;GACA,UAAU,IAAI,SAAS,YAAY,QAAQ;EAC7C;EACA,KAAK,mBAAmB,IAAI,WAAW,SAAS;EAChD,OAAO;CACT;CAEA,YAAoB,OAAyC;EAC3D,MAAM,YAAY,oBAAoB,MAAM,gBAAgB;EAC5D,OAAO;GACL,wBAAwB,EAAE,OAAO,mBAAmB;GACpD,SAAS,KAAK,aAAa,MAAM,gBAAgB;GACjD,SAAS,YAAA,QAAU,MAAM,OAAO;GAChC,WAAW,MAAM;GACjB,eAAe,MAAM;GACrB,YAAY;IACV,kBAAkB;IAClB,yBAAyB;IACzB,aAAa,KAAK,sBAAsB,MAAM,OAAO,CAAC,CAAC;GACzD;EACF;CACF;CAEA,kBAA0B,QAAsD;EAC9E,OAAO;GACL,WAAW,YAAA,UAAY,OAAO,SAAS;GACvC,OAAO,OAAO;GACd,SAAS,YAAA,QAAU,OAAO,OAAO;GACjC,WAAW,OAAO;GAClB,QAAQ,OAAO;GACf,YAAY,OAAO;EACrB;CACF;CAEA,wBAAgC,QAAqD;EACnF,OAAO;GACL,GAAG,KAAK,kBAAkB,MAAM;GAChC,SAAS,KAAK,aAAa,OAAO,gBAAgB;EACpD;CACF;CAEA,eAAuB,UAAgD;EACrE,OAAO;GACL,YAAY,YAAA,WAAa,SAAS,UAAU;GAC5C,cAAc,SAAS;GACvB,2BAA2B,SAAS;EACtC;CACF;CAEA,aAAqB,WAAmC;EACtD,OAAO;GACL,oBAAoB;GACpB,oBAAoB;GACpB,sBAAsB,oBAAoB,SAAS;GACnD,aAAa;EACf;CACF;AACF"}
|
|
@@ -65,6 +65,8 @@ export declare class PartnerSimulator {
|
|
|
65
65
|
private readonly apiEnabled;
|
|
66
66
|
private readonly accountHasValidPhone;
|
|
67
67
|
private readonly accountInGoodStanding;
|
|
68
|
+
private readonly groupsCapabilities;
|
|
69
|
+
private readonly backupCapabilities;
|
|
68
70
|
/**
|
|
69
71
|
* Creates the Partner/Backup simulator facade.
|
|
70
72
|
*
|
|
@@ -98,7 +100,7 @@ export declare class PartnerSimulator {
|
|
|
98
100
|
/**
|
|
99
101
|
* Handles b2_reserve_trial_create_account.
|
|
100
102
|
*
|
|
101
|
-
* @param body - Parsed JSON
|
|
103
|
+
* @param body - Parsed JSON request body.
|
|
102
104
|
* @param authToken - Partner authorization token.
|
|
103
105
|
*
|
|
104
106
|
* @returns Simulator JSON response.
|
|
@@ -159,8 +161,9 @@ export declare class PartnerSimulator {
|
|
|
159
161
|
*/
|
|
160
162
|
deleteComputer(body: unknown, authToken?: string): SimulatorJsonResponse;
|
|
161
163
|
private authorizeRequest;
|
|
164
|
+
private authorizeEndpointCapabilities;
|
|
162
165
|
private authorizeAccount;
|
|
163
|
-
private
|
|
166
|
+
private parseReserveTrialCreateAccountRequest;
|
|
164
167
|
private createReserveTrialAccount;
|
|
165
168
|
private parseCreateGroupMemberRequest;
|
|
166
169
|
private parseEjectGroupMemberRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/simulator/partner.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAwBhE,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/simulator/partner.js"],"names":[],"mappings":"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"}
|
|
@@ -65,6 +65,8 @@ export declare class PartnerSimulator {
|
|
|
65
65
|
private readonly apiEnabled;
|
|
66
66
|
private readonly accountHasValidPhone;
|
|
67
67
|
private readonly accountInGoodStanding;
|
|
68
|
+
private readonly groupsCapabilities;
|
|
69
|
+
private readonly backupCapabilities;
|
|
68
70
|
/**
|
|
69
71
|
* Creates the Partner/Backup simulator facade.
|
|
70
72
|
*
|
|
@@ -98,7 +100,7 @@ export declare class PartnerSimulator {
|
|
|
98
100
|
/**
|
|
99
101
|
* Handles b2_reserve_trial_create_account.
|
|
100
102
|
*
|
|
101
|
-
* @param body - Parsed JSON
|
|
103
|
+
* @param body - Parsed JSON request body.
|
|
102
104
|
* @param authToken - Partner authorization token.
|
|
103
105
|
*
|
|
104
106
|
* @returns Simulator JSON response.
|
|
@@ -159,8 +161,9 @@ export declare class PartnerSimulator {
|
|
|
159
161
|
*/
|
|
160
162
|
deleteComputer(body: unknown, authToken?: string): SimulatorJsonResponse;
|
|
161
163
|
private authorizeRequest;
|
|
164
|
+
private authorizeEndpointCapabilities;
|
|
162
165
|
private authorizeAccount;
|
|
163
|
-
private
|
|
166
|
+
private parseReserveTrialCreateAccountRequest;
|
|
164
167
|
private createReserveTrialAccount;
|
|
165
168
|
private parseCreateGroupMemberRequest;
|
|
166
169
|
private parseEjectGroupMemberRequest;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/simulator/partner.js"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,KAAK,EAAc,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAwBhE,OAAO,KAAK,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"partner.d.ts","sourceRoot":"","sources":["../../src/simulator/partner.js"],"names":[],"mappings":"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"}
|