@scality/data-browser-library 1.0.0-preview.9 → 1.0.3
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/dist/components/DataBrowserUI.d.ts +12 -0
- package/dist/components/DataBrowserUI.js +99 -0
- package/dist/components/Editor.d.ts +1 -1
- package/dist/components/Editor.js +3 -3
- package/dist/components/__tests__/BucketAccessor.test.js +214 -0
- package/dist/components/__tests__/BucketCorsPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketCorsPage.test.js +263 -0
- package/dist/components/__tests__/BucketCreate.test.js +271 -105
- package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
- package/dist/components/__tests__/BucketDetails.test.js +421 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +13 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.js +178 -178
- package/dist/components/__tests__/BucketLifecycleList.test.js +85 -85
- package/dist/components/__tests__/BucketList.test.js +463 -239
- package/dist/components/__tests__/BucketNotificationFormPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketNotificationFormPage.test.js +348 -0
- package/dist/components/__tests__/BucketNotificationList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketNotificationList.test.js +379 -0
- package/dist/components/__tests__/BucketOverview.test.js +281 -266
- package/dist/components/__tests__/BucketPolicyPage.test.js +151 -99
- package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +15 -0
- package/dist/components/__tests__/BucketReplicationFormPage.test.js +544 -544
- package/dist/components/__tests__/BucketReplicationList.test.js +106 -106
- package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
- package/dist/components/__tests__/DeleteBucketButton.test.js +64 -64
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +47 -47
- package/dist/components/__tests__/DeleteObjectButton.test.js +64 -64
- package/dist/components/__tests__/EmptyBucketButton.test.js +59 -59
- package/dist/components/__tests__/MetadataSearch.test.js +65 -65
- package/dist/components/__tests__/ObjectList.test.js +741 -240
- package/dist/components/__tests__/UploadButton.test.js +45 -45
- package/dist/components/breadcrumb/Breadcrumb.d.ts +6 -0
- package/dist/components/breadcrumb/Breadcrumb.js +37 -0
- package/dist/components/breadcrumb/DataBrowserBreadcrumb.d.ts +1 -0
- package/dist/components/breadcrumb/DataBrowserBreadcrumb.js +10 -0
- package/dist/components/breadcrumb/__tests__/Breadcrumb.test.d.ts +1 -0
- package/dist/components/breadcrumb/__tests__/Breadcrumb.test.js +196 -0
- package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.d.ts +1 -0
- package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.js +153 -0
- package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.d.ts +1 -0
- package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.js +134 -0
- package/dist/components/breadcrumb/index.d.ts +8 -0
- package/dist/components/breadcrumb/index.js +4 -0
- package/dist/components/breadcrumb/useBreadcrumbPaths.d.ts +2 -0
- package/dist/components/breadcrumb/useBreadcrumbPaths.js +82 -0
- package/dist/components/buckets/BucketAccessor.d.ts +2 -0
- package/dist/components/buckets/BucketAccessor.js +125 -0
- package/dist/components/buckets/BucketConfigEditButton.d.ts +8 -0
- package/dist/components/buckets/{BucketPolicyButton.js → BucketConfigEditButton.js} +9 -5
- package/dist/components/buckets/BucketCorsPage.d.ts +1 -0
- package/dist/components/buckets/BucketCorsPage.js +234 -0
- package/dist/components/buckets/BucketCreate.d.ts +3 -2
- package/dist/components/buckets/BucketCreate.js +93 -47
- package/dist/components/buckets/BucketDetails.d.ts +42 -0
- package/dist/components/buckets/BucketDetails.js +249 -85
- package/dist/components/buckets/BucketLifecycleFormPage.js +225 -191
- package/dist/components/buckets/BucketLifecycleList.d.ts +2 -2
- package/dist/components/buckets/BucketLifecycleList.js +59 -61
- package/dist/components/buckets/BucketList.d.ts +7 -8
- package/dist/components/buckets/BucketList.js +158 -101
- package/dist/components/buckets/BucketLocation.js +4 -4
- package/dist/components/buckets/BucketOverview.d.ts +22 -2
- package/dist/components/buckets/BucketOverview.js +394 -187
- package/dist/components/buckets/BucketPage.js +43 -21
- package/dist/components/buckets/BucketPolicyPage.js +155 -127
- package/dist/components/buckets/BucketReplicationFormPage.js +134 -133
- package/dist/components/buckets/BucketReplicationList.d.ts +2 -2
- package/dist/components/buckets/BucketReplicationList.js +48 -45
- package/dist/components/buckets/BucketVersioning.d.ts +4 -0
- package/dist/components/buckets/BucketVersioning.js +76 -0
- package/dist/components/buckets/DeleteBucketButton.js +8 -8
- package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +2 -2
- package/dist/components/buckets/DeleteBucketConfigRuleButton.js +2 -2
- package/dist/components/buckets/EmptyBucketButton.js +24 -24
- package/dist/components/buckets/EmptyBucketSummary.d.ts +2 -2
- package/dist/components/buckets/EmptyBucketSummary.js +1 -1
- package/dist/components/buckets/EmptyBucketSummaryList.d.ts +1 -1
- package/dist/components/buckets/EmptyBucketSummaryList.js +22 -22
- package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
- package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
- package/dist/components/buckets/notifications/BucketNotificationFormPage.d.ts +1 -0
- package/dist/components/buckets/notifications/BucketNotificationFormPage.js +316 -0
- package/dist/components/buckets/notifications/BucketNotificationList.d.ts +10 -0
- package/dist/components/buckets/notifications/BucketNotificationList.js +267 -0
- package/dist/components/buckets/notifications/EventsSection.js +145 -29
- package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
- package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
- package/dist/components/buckets/notifications/events.d.ts +71 -7
- package/dist/components/buckets/notifications/events.js +98 -16
- package/dist/components/index.d.ts +27 -20
- package/dist/components/index.js +17 -10
- package/dist/components/layouts/ArrowNavigation.d.ts +3 -0
- package/dist/components/layouts/ArrowNavigation.js +28 -0
- package/dist/components/layouts/BrowserPageLayout.d.ts +5 -1
- package/dist/components/layouts/BrowserPageLayout.js +10 -5
- package/dist/components/objects/CreateFolderButton.d.ts +2 -2
- package/dist/components/objects/CreateFolderButton.js +12 -12
- package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
- package/dist/components/objects/DeleteObjectButton.js +19 -21
- package/dist/components/objects/GetPresignedUrlButton.d.ts +7 -0
- package/dist/components/objects/GetPresignedUrlButton.js +255 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -2
- package/dist/components/objects/ObjectDetails/ObjectMetadata.js +289 -230
- package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +2 -2
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +540 -138
- package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +2 -2
- package/dist/components/objects/ObjectDetails/ObjectTags.js +103 -123
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
- package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +1064 -0
- package/dist/components/objects/ObjectDetails/formUtils.d.ts +15 -0
- package/dist/components/objects/ObjectDetails/formUtils.js +7 -0
- package/dist/components/objects/ObjectDetails/index.d.ts +18 -2
- package/dist/components/objects/ObjectDetails/index.js +152 -40
- package/dist/components/objects/ObjectList.d.ts +12 -10
- package/dist/components/objects/ObjectList.js +590 -263
- package/dist/components/objects/ObjectLock/EditRetentionButton.js +4 -4
- package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +15 -15
- package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +1 -1
- package/dist/components/objects/ObjectLock/ObjectLockSettings.js +32 -31
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +1 -1
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +6 -6
- package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +51 -51
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +78 -78
- package/dist/components/objects/ObjectPage.js +12 -8
- package/dist/components/objects/UploadButton.d.ts +3 -3
- package/dist/components/objects/UploadButton.js +10 -10
- package/dist/components/objects/__tests__/GetPresignedUrlButton.test.d.ts +1 -0
- package/dist/components/objects/__tests__/GetPresignedUrlButton.test.js +531 -0
- package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
- package/dist/components/providers/DataBrowserProvider.js +60 -38
- package/dist/components/providers/QueryProvider.d.ts +9 -0
- package/dist/components/providers/QueryProvider.js +21 -0
- package/dist/components/search/MetadataSearch.js +29 -28
- package/dist/components/search/SearchHints.js +1 -1
- package/dist/components/ui/ArrayFieldActions.js +12 -7
- package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +2 -2
- package/dist/components/ui/ConfirmDeleteRuleModal.js +6 -1
- package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
- package/dist/components/ui/DeleteObjectModalContent.js +12 -12
- package/dist/components/ui/FilterFormSection.d.ts +2 -2
- package/dist/components/ui/FilterFormSection.js +29 -29
- package/dist/components/ui/Search.elements.d.ts +2 -2
- package/dist/components/ui/Search.elements.js +7 -7
- package/dist/components/ui/Table.elements.d.ts +2 -1
- package/dist/components/ui/Table.elements.js +18 -12
- package/dist/config/__tests__/factory.test.d.ts +1 -0
- package/dist/config/__tests__/factory.test.js +311 -0
- package/dist/config/factory.d.ts +10 -56
- package/dist/config/factory.js +23 -71
- package/dist/config/types.d.ts +212 -34
- package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
- package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
- package/dist/hooks/__tests__/useAccessibleBuckets.test.d.ts +1 -0
- package/dist/hooks/__tests__/useAccessibleBuckets.test.js +145 -0
- package/dist/hooks/__tests__/useISVBucketDetection.test.js +45 -45
- package/dist/hooks/__tests__/useIsBucketEmpty.test.js +27 -27
- package/dist/hooks/__tests__/useLoginMutation.test.d.ts +1 -0
- package/dist/hooks/__tests__/useLoginMutation.test.js +194 -0
- package/dist/hooks/bucketConfiguration.d.ts +8 -1
- package/dist/hooks/bucketConfiguration.js +52 -51
- package/dist/hooks/bucketOperations.d.ts +10 -1
- package/dist/hooks/bucketOperations.js +10 -9
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +80 -80
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +80 -80
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +44 -44
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +63 -63
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +65 -65
- package/dist/hooks/factories/index.d.ts +4 -4
- package/dist/hooks/factories/index.js +2 -2
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +16 -13
- package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3LoginHook.js +1 -1
- package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
- package/dist/hooks/factories/useCreateS3MutationHook.js +7 -2
- package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
- package/dist/hooks/factories/useCreateS3QueryHook.js +11 -6
- package/dist/hooks/index.d.ts +19 -12
- package/dist/hooks/index.js +16 -9
- package/dist/hooks/loginOperations.d.ts +1 -1
- package/dist/hooks/loginOperations.js +1 -1
- package/dist/hooks/objectOperations.d.ts +2 -2
- package/dist/hooks/objectOperations.js +50 -49
- package/dist/hooks/presignedOperations.d.ts +4 -4
- package/dist/hooks/presignedOperations.js +5 -5
- package/dist/hooks/useAccessibleBuckets.d.ts +11 -0
- package/dist/hooks/useAccessibleBuckets.js +115 -0
- package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
- package/dist/hooks/useBatchObjectLegalHold.js +48 -0
- package/dist/hooks/useBucketConfigEditor.d.ts +31 -0
- package/dist/hooks/useBucketConfigEditor.js +82 -0
- package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
- package/dist/hooks/useDataBrowserNavigate.js +24 -0
- package/dist/hooks/useDeleteBucketConfigRule.d.ts +2 -2
- package/dist/hooks/useDeleteBucketConfigRule.js +4 -4
- package/dist/hooks/useEmptyBucket.js +11 -11
- package/dist/hooks/useFeatures.d.ts +7 -0
- package/dist/hooks/useFeatures.js +8 -0
- package/dist/hooks/useISVBucketDetection.js +6 -6
- package/dist/hooks/useIsBucketEmpty.js +4 -4
- package/dist/hooks/useLimitedAccessFlow.d.ts +48 -0
- package/dist/hooks/useLimitedAccessFlow.js +23 -0
- package/dist/hooks/useS3Client.d.ts +6 -0
- package/dist/hooks/useS3Client.js +3 -2
- package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
- package/dist/hooks/useS3ConfigSwitch.js +37 -0
- package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
- package/dist/hooks/useSupportedNotificationEvents.js +8 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +2 -2
- package/dist/schemas/bucketPolicySchema.json +3 -13
- package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
- package/dist/test/msw/handlers/deleteBucket.js +20 -10
- package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
- package/dist/test/msw/handlers/getBucketAcl.js +29 -17
- package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
- package/dist/test/msw/handlers/getBucketLocation.js +29 -15
- package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
- package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
- package/dist/test/msw/handlers/headObject.d.ts +1 -1
- package/dist/test/msw/handlers/headObject.js +31 -13
- package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
- package/dist/test/msw/handlers/listBuckets.js +5 -3
- package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
- package/dist/test/msw/handlers/listObjectVersions.js +38 -26
- package/dist/test/msw/handlers/listObjects.d.ts +1 -1
- package/dist/test/msw/handlers/listObjects.js +35 -23
- package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
- package/dist/test/msw/handlers/objectLegalHold.js +32 -17
- package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
- package/dist/test/msw/handlers/objectRetention.js +31 -17
- package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
- package/dist/test/msw/handlers/putBucketAcl.js +29 -14
- package/dist/test/msw/handlers/putObject.d.ts +1 -1
- package/dist/test/msw/handlers/putObject.js +27 -12
- package/dist/test/msw/handlers.d.ts +3 -3
- package/dist/test/msw/handlers.js +77 -54
- package/dist/test/msw/index.d.ts +2 -2
- package/dist/test/msw/index.js +1 -1
- package/dist/test/msw/server.d.ts +1 -1
- package/dist/test/msw/server.js +1 -1
- package/dist/test/msw/utils.js +2 -2
- package/dist/test/setup.d.ts +1 -1
- package/dist/test/setup.js +13 -30
- package/dist/test/testUtils.d.ts +85 -33
- package/dist/test/testUtils.js +176 -111
- package/dist/test/utils/errorHandling.test.js +119 -119
- package/dist/types/index.d.ts +50 -37
- package/dist/types/monaco.d.ts +13 -0
- package/dist/types/monaco.js +0 -0
- package/dist/utils/__tests__/proxyMiddleware.test.d.ts +1 -0
- package/dist/utils/__tests__/proxyMiddleware.test.js +579 -0
- package/dist/utils/__tests__/s3Client.test.d.ts +1 -0
- package/dist/utils/__tests__/s3Client.test.js +340 -0
- package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
- package/dist/utils/__tests__/s3ConfigIdentifier.test.js +437 -0
- package/dist/utils/constants.d.ts +10 -0
- package/dist/utils/constants.js +19 -9
- package/dist/utils/deletion/index.d.ts +2 -2
- package/dist/utils/deletion/index.js +1 -1
- package/dist/utils/deletion/messages.d.ts +1 -1
- package/dist/utils/deletion/messages.js +4 -4
- package/dist/utils/errorHandling.d.ts +3 -3
- package/dist/utils/errorHandling.js +6 -6
- package/dist/utils/hooks.js +8 -8
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.js +4 -2
- package/dist/utils/proxyMiddleware.d.ts +32 -13
- package/dist/utils/proxyMiddleware.js +90 -36
- package/dist/utils/s3Client.d.ts +14 -4
- package/dist/utils/s3Client.js +5 -26
- package/dist/utils/s3ConfigIdentifier.d.ts +79 -0
- package/dist/utils/s3ConfigIdentifier.js +57 -0
- package/dist/utils/s3RuleUtils.d.ts +5 -5
- package/dist/utils/s3RuleUtils.js +17 -17
- package/package.json +10 -8
- package/dist/components/__tests__/BucketNotificationCreatePage.test.js +0 -316
- package/dist/components/buckets/BucketPolicyButton.d.ts +0 -7
- package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +0 -1
- package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +0 -234
- package/dist/hooks/useLoginMutation.d.ts +0 -21
- package/dist/hooks/useLoginMutation.js +0 -9
- package/dist/utils/useFeatures.d.ts +0 -1
- package/dist/utils/useFeatures.js +0 -7
- /package/dist/components/__tests__/{BucketNotificationCreatePage.test.d.ts → BucketAccessor.test.d.ts} +0 -0
|
@@ -0,0 +1,437 @@
|
|
|
1
|
+
import { computeS3ConfigIdentifier, hashSessionToken, normalizeEndpoint, normalizeRegion } from "../s3ConfigIdentifier.js";
|
|
2
|
+
describe('hashSessionToken', ()=>{
|
|
3
|
+
it('should return a 16-character hex string', ()=>{
|
|
4
|
+
const hash = hashSessionToken('test-token');
|
|
5
|
+
expect(hash).toHaveLength(16);
|
|
6
|
+
expect(hash).toMatch(/^[0-9a-f]{16}$/);
|
|
7
|
+
});
|
|
8
|
+
it('should be deterministic - same input produces same output', ()=>{
|
|
9
|
+
const input = 'test-session-token';
|
|
10
|
+
const hash1 = hashSessionToken(input);
|
|
11
|
+
const hash2 = hashSessionToken(input);
|
|
12
|
+
expect(hash1).toBe(hash2);
|
|
13
|
+
});
|
|
14
|
+
it('should handle empty string', ()=>{
|
|
15
|
+
const hash = hashSessionToken('');
|
|
16
|
+
expect(hash).toHaveLength(16);
|
|
17
|
+
expect(hash).toBe('cbf29ce484222325');
|
|
18
|
+
});
|
|
19
|
+
it('should handle ASCII strings', ()=>{
|
|
20
|
+
const hash = hashSessionToken('test-session-token');
|
|
21
|
+
expect(hash).toBe('2b7823aacbaafc48');
|
|
22
|
+
});
|
|
23
|
+
it('should handle emoji and multi-byte Unicode characters', ()=>{
|
|
24
|
+
const hash1 = hashSessionToken('test🔥token');
|
|
25
|
+
const hash2 = hashSessionToken('hello-world-multibyte');
|
|
26
|
+
expect(hash1).toHaveLength(16);
|
|
27
|
+
expect(hash2).toHaveLength(16);
|
|
28
|
+
expect(hash1).not.toBe(hash2);
|
|
29
|
+
});
|
|
30
|
+
it('should handle very long strings', ()=>{
|
|
31
|
+
const longString = 'a'.repeat(10000);
|
|
32
|
+
const hash = hashSessionToken(longString);
|
|
33
|
+
expect(hash).toHaveLength(16);
|
|
34
|
+
expect(hash).toMatch(/^[0-9a-f]{16}$/);
|
|
35
|
+
});
|
|
36
|
+
it('should produce different hashes for different inputs', ()=>{
|
|
37
|
+
const hash1 = hashSessionToken('token1');
|
|
38
|
+
const hash2 = hashSessionToken('token2');
|
|
39
|
+
expect(hash1).not.toBe(hash2);
|
|
40
|
+
});
|
|
41
|
+
it('should produce different hashes for similar strings', ()=>{
|
|
42
|
+
const hash1 = hashSessionToken('test-session-token');
|
|
43
|
+
const hash2 = hashSessionToken('test-session-token1');
|
|
44
|
+
const hash3 = hashSessionToken('test-session-token2');
|
|
45
|
+
expect(hash1).not.toBe(hash2);
|
|
46
|
+
expect(hash2).not.toBe(hash3);
|
|
47
|
+
expect(hash1).not.toBe(hash3);
|
|
48
|
+
});
|
|
49
|
+
it('should handle special characters', ()=>{
|
|
50
|
+
const hash = hashSessionToken("!@#$%^&*()_+-=[]{}|;:',.<>?/~`");
|
|
51
|
+
expect(hash).toHaveLength(16);
|
|
52
|
+
expect(hash).toMatch(/^[0-9a-f]{16}$/);
|
|
53
|
+
});
|
|
54
|
+
it('should handle whitespace', ()=>{
|
|
55
|
+
const hash1 = hashSessionToken('token with spaces');
|
|
56
|
+
const hash2 = hashSessionToken('token\twith\ttabs');
|
|
57
|
+
const hash3 = hashSessionToken('token\nwith\nnewlines');
|
|
58
|
+
expect(hash1).not.toBe(hash2);
|
|
59
|
+
expect(hash2).not.toBe(hash3);
|
|
60
|
+
});
|
|
61
|
+
it('should have low collision rate for similar strings', ()=>{
|
|
62
|
+
const hashes = new Set();
|
|
63
|
+
const inputs = Array.from({
|
|
64
|
+
length: 1000
|
|
65
|
+
}, (_, i)=>`session-token-${i}`);
|
|
66
|
+
inputs.forEach((input)=>{
|
|
67
|
+
hashes.add(hashSessionToken(input));
|
|
68
|
+
});
|
|
69
|
+
expect(hashes.size).toBe(1000);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('normalizeRegion', ()=>{
|
|
73
|
+
it('should convert to lowercase', ()=>{
|
|
74
|
+
expect(normalizeRegion('US-EAST-1')).toBe('us-east-1');
|
|
75
|
+
expect(normalizeRegion('EU-WEST-1')).toBe('eu-west-1');
|
|
76
|
+
});
|
|
77
|
+
it('should trim whitespace', ()=>{
|
|
78
|
+
expect(normalizeRegion(' us-east-1 ')).toBe('us-east-1');
|
|
79
|
+
expect(normalizeRegion('\tus-east-1\n')).toBe('us-east-1');
|
|
80
|
+
});
|
|
81
|
+
it('should handle already normalized input', ()=>{
|
|
82
|
+
expect(normalizeRegion('us-east-1')).toBe('us-east-1');
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('normalizeEndpoint', ()=>{
|
|
86
|
+
it('should lowercase protocol and hostname', ()=>{
|
|
87
|
+
expect(normalizeEndpoint('HTTPS://S3.AMAZONAWS.COM')).toBe('https://s3.amazonaws.com');
|
|
88
|
+
});
|
|
89
|
+
it('should remove default HTTPS port (443)', ()=>{
|
|
90
|
+
expect(normalizeEndpoint('https://s3.amazonaws.com:443')).toBe('https://s3.amazonaws.com');
|
|
91
|
+
});
|
|
92
|
+
it('should remove default HTTP port (80)', ()=>{
|
|
93
|
+
expect(normalizeEndpoint('http://localhost:80')).toBe('http://localhost');
|
|
94
|
+
});
|
|
95
|
+
it('should keep non-default ports', ()=>{
|
|
96
|
+
expect(normalizeEndpoint('http://localhost:9000')).toBe('http://localhost:9000');
|
|
97
|
+
expect(normalizeEndpoint('https://api.example.com:8443')).toBe('https://api.example.com:8443');
|
|
98
|
+
});
|
|
99
|
+
it('should remove trailing slashes', ()=>{
|
|
100
|
+
expect(normalizeEndpoint('https://s3.amazonaws.com/')).toBe('https://s3.amazonaws.com');
|
|
101
|
+
expect(normalizeEndpoint('https://s3.amazonaws.com///')).toBe('https://s3.amazonaws.com');
|
|
102
|
+
});
|
|
103
|
+
it('should preserve pathname', ()=>{
|
|
104
|
+
expect(normalizeEndpoint('https://s3.amazonaws.com/path/to/api')).toBe('https://s3.amazonaws.com/path/to/api');
|
|
105
|
+
});
|
|
106
|
+
it('should remove trailing slash from pathname', ()=>{
|
|
107
|
+
expect(normalizeEndpoint('https://s3.amazonaws.com/path/')).toBe('https://s3.amazonaws.com/path');
|
|
108
|
+
});
|
|
109
|
+
it('should normalize equivalent URLs identically', ()=>{
|
|
110
|
+
const url1 = normalizeEndpoint('HTTPS://S3.AMAZONAWS.COM:443/');
|
|
111
|
+
const url2 = normalizeEndpoint('https://s3.amazonaws.com');
|
|
112
|
+
expect(url1).toBe(url2);
|
|
113
|
+
});
|
|
114
|
+
it('should handle invalid URLs with fallback', ()=>{
|
|
115
|
+
expect(normalizeEndpoint('not-a-url')).toBe('not-a-url');
|
|
116
|
+
expect(normalizeEndpoint('ftp://example.com')).toBe('ftp://example.com');
|
|
117
|
+
});
|
|
118
|
+
it('should trim whitespace', ()=>{
|
|
119
|
+
expect(normalizeEndpoint(' https://s3.amazonaws.com ')).toBe('https://s3.amazonaws.com');
|
|
120
|
+
});
|
|
121
|
+
it('should handle IPv6 addresses', ()=>{
|
|
122
|
+
expect(normalizeEndpoint('http://[::1]:9000')).toBe('http://[::1]:9000');
|
|
123
|
+
expect(normalizeEndpoint('http://[::1]:80')).toBe('http://[::1]');
|
|
124
|
+
});
|
|
125
|
+
it('should ignore query strings and fragments', ()=>{
|
|
126
|
+
expect(normalizeEndpoint('https://s3.amazonaws.com?query=1#frag')).toBe('https://s3.amazonaws.com');
|
|
127
|
+
});
|
|
128
|
+
it('should handle URLs with user credentials', ()=>{
|
|
129
|
+
expect(normalizeEndpoint('https://user:pass@s3.amazonaws.com')).toBe('https://s3.amazonaws.com');
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
describe('computeS3ConfigIdentifier', ()=>{
|
|
133
|
+
const mockConfig = (overrides = {})=>({
|
|
134
|
+
region: '',
|
|
135
|
+
endpoint: '',
|
|
136
|
+
...overrides,
|
|
137
|
+
credentials: {
|
|
138
|
+
accessKeyId: '',
|
|
139
|
+
secretAccessKey: '',
|
|
140
|
+
...overrides.credentials || {}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
describe('Cache Key', ()=>{
|
|
144
|
+
it('should use cacheKey as primary identifier', ()=>{
|
|
145
|
+
const config = mockConfig({
|
|
146
|
+
cacheKey: 'my-cache-key'
|
|
147
|
+
});
|
|
148
|
+
const id = computeS3ConfigIdentifier(config);
|
|
149
|
+
expect(id).toContain('my-cache-key');
|
|
150
|
+
});
|
|
151
|
+
it('should trim cacheKey whitespace', ()=>{
|
|
152
|
+
const config = mockConfig({
|
|
153
|
+
cacheKey: ' my-cache-key '
|
|
154
|
+
});
|
|
155
|
+
const id = computeS3ConfigIdentifier(config);
|
|
156
|
+
expect(id).toContain('my-cache-key');
|
|
157
|
+
expect(id).not.toContain(' ');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
describe('Access Key ID', ()=>{
|
|
161
|
+
it('should use accessKeyId', ()=>{
|
|
162
|
+
const config = mockConfig({
|
|
163
|
+
credentials: {
|
|
164
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
const id = computeS3ConfigIdentifier(config);
|
|
168
|
+
expect(id).toBe('AKIAIOSFODNN7EXAMPLE');
|
|
169
|
+
});
|
|
170
|
+
it('should trim accessKeyId whitespace', ()=>{
|
|
171
|
+
const config = mockConfig({
|
|
172
|
+
credentials: {
|
|
173
|
+
accessKeyId: ' AKIAIOSFODNN7EXAMPLE '
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
const id = computeS3ConfigIdentifier(config);
|
|
177
|
+
expect(id).toBe('AKIAIOSFODNN7EXAMPLE');
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('Session Token', ()=>{
|
|
181
|
+
it('should hash session token when present', ()=>{
|
|
182
|
+
const config = mockConfig({
|
|
183
|
+
credentials: {
|
|
184
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
|
185
|
+
sessionToken: 'test-session-token'
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const id = computeS3ConfigIdentifier(config);
|
|
189
|
+
expect(id).toContain('AKIAIOSFODNN7EXAMPLE');
|
|
190
|
+
expect(id).toContain('session:');
|
|
191
|
+
expect(id).toContain('2b7823aacbaafc48');
|
|
192
|
+
});
|
|
193
|
+
it('should not include session token if only whitespace', ()=>{
|
|
194
|
+
const config = mockConfig({
|
|
195
|
+
credentials: {
|
|
196
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
|
197
|
+
sessionToken: ' '
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
const id = computeS3ConfigIdentifier(config);
|
|
201
|
+
expect(id).toBe('AKIAIOSFODNN7EXAMPLE');
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
describe('Region', ()=>{
|
|
205
|
+
it('should include region', ()=>{
|
|
206
|
+
const config = mockConfig({
|
|
207
|
+
credentials: {
|
|
208
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
209
|
+
},
|
|
210
|
+
region: 'us-east-1'
|
|
211
|
+
});
|
|
212
|
+
const id = computeS3ConfigIdentifier(config);
|
|
213
|
+
expect(id).toBe('AKIAIOSFODNN7EXAMPLE||region:us-east-1');
|
|
214
|
+
});
|
|
215
|
+
it('should normalize region to lowercase', ()=>{
|
|
216
|
+
const config = mockConfig({
|
|
217
|
+
credentials: {
|
|
218
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
219
|
+
},
|
|
220
|
+
region: 'US-EAST-1'
|
|
221
|
+
});
|
|
222
|
+
const id = computeS3ConfigIdentifier(config);
|
|
223
|
+
expect(id).toContain('region:us-east-1');
|
|
224
|
+
});
|
|
225
|
+
it('should trim region whitespace', ()=>{
|
|
226
|
+
const config = mockConfig({
|
|
227
|
+
credentials: {
|
|
228
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
229
|
+
},
|
|
230
|
+
region: ' us-east-1 '
|
|
231
|
+
});
|
|
232
|
+
const id = computeS3ConfigIdentifier(config);
|
|
233
|
+
expect(id).toContain('region:us-east-1');
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
describe('Endpoint', ()=>{
|
|
237
|
+
it('should normalize endpoint URL', ()=>{
|
|
238
|
+
const config = mockConfig({
|
|
239
|
+
credentials: {
|
|
240
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
241
|
+
},
|
|
242
|
+
endpoint: 'HTTPS://S3.AMAZONAWS.COM'
|
|
243
|
+
});
|
|
244
|
+
const id = computeS3ConfigIdentifier(config);
|
|
245
|
+
expect(id).toContain('endpoint:https://s3.amazonaws.com');
|
|
246
|
+
});
|
|
247
|
+
it('should remove default HTTPS port', ()=>{
|
|
248
|
+
const config = mockConfig({
|
|
249
|
+
credentials: {
|
|
250
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
251
|
+
},
|
|
252
|
+
endpoint: 'https://s3.amazonaws.com:443'
|
|
253
|
+
});
|
|
254
|
+
const id = computeS3ConfigIdentifier(config);
|
|
255
|
+
expect(id).toContain('endpoint:https://s3.amazonaws.com');
|
|
256
|
+
expect(id).not.toContain(':443');
|
|
257
|
+
});
|
|
258
|
+
it('should remove default HTTP port', ()=>{
|
|
259
|
+
const config = mockConfig({
|
|
260
|
+
credentials: {
|
|
261
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
262
|
+
},
|
|
263
|
+
endpoint: 'http://localhost:80'
|
|
264
|
+
});
|
|
265
|
+
const id = computeS3ConfigIdentifier(config);
|
|
266
|
+
expect(id).toContain('endpoint:http://localhost');
|
|
267
|
+
expect(id).not.toContain(':80');
|
|
268
|
+
});
|
|
269
|
+
it('should keep non-default ports', ()=>{
|
|
270
|
+
const config = mockConfig({
|
|
271
|
+
credentials: {
|
|
272
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
273
|
+
},
|
|
274
|
+
endpoint: 'http://localhost:9000'
|
|
275
|
+
});
|
|
276
|
+
const id = computeS3ConfigIdentifier(config);
|
|
277
|
+
expect(id).toContain('endpoint:http://localhost:9000');
|
|
278
|
+
});
|
|
279
|
+
it('should remove trailing slashes', ()=>{
|
|
280
|
+
const config = mockConfig({
|
|
281
|
+
credentials: {
|
|
282
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
283
|
+
},
|
|
284
|
+
endpoint: 'https://s3.amazonaws.com/'
|
|
285
|
+
});
|
|
286
|
+
const id = computeS3ConfigIdentifier(config);
|
|
287
|
+
expect(id).toContain('endpoint:https://s3.amazonaws.com');
|
|
288
|
+
expect(id).not.toMatch(/\/$/);
|
|
289
|
+
});
|
|
290
|
+
it('should handle invalid URL format with fallback', ()=>{
|
|
291
|
+
const config = mockConfig({
|
|
292
|
+
credentials: {
|
|
293
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE'
|
|
294
|
+
},
|
|
295
|
+
endpoint: 'not-a-valid-url'
|
|
296
|
+
});
|
|
297
|
+
const id = computeS3ConfigIdentifier(config);
|
|
298
|
+
expect(id).toContain('endpoint:not-a-valid-url');
|
|
299
|
+
});
|
|
300
|
+
it('should normalize equivalent URLs identically', ()=>{
|
|
301
|
+
const config1 = mockConfig({
|
|
302
|
+
credentials: {
|
|
303
|
+
accessKeyId: 'KEY'
|
|
304
|
+
},
|
|
305
|
+
endpoint: 'HTTPS://S3.AMAZONAWS.COM:443/'
|
|
306
|
+
});
|
|
307
|
+
const config2 = mockConfig({
|
|
308
|
+
credentials: {
|
|
309
|
+
accessKeyId: 'KEY'
|
|
310
|
+
},
|
|
311
|
+
endpoint: 'https://s3.amazonaws.com'
|
|
312
|
+
});
|
|
313
|
+
const id1 = computeS3ConfigIdentifier(config1);
|
|
314
|
+
const id2 = computeS3ConfigIdentifier(config2);
|
|
315
|
+
expect(id1).toBe(id2);
|
|
316
|
+
});
|
|
317
|
+
it('should preserve pathname in endpoint', ()=>{
|
|
318
|
+
const config = mockConfig({
|
|
319
|
+
credentials: {
|
|
320
|
+
accessKeyId: 'KEY'
|
|
321
|
+
},
|
|
322
|
+
endpoint: 'https://s3.amazonaws.com/my-path/api'
|
|
323
|
+
});
|
|
324
|
+
const id = computeS3ConfigIdentifier(config);
|
|
325
|
+
expect(id).toContain('endpoint:https://s3.amazonaws.com/my-path/api');
|
|
326
|
+
});
|
|
327
|
+
it('should remove trailing slash from pathname', ()=>{
|
|
328
|
+
const config = mockConfig({
|
|
329
|
+
credentials: {
|
|
330
|
+
accessKeyId: 'KEY'
|
|
331
|
+
},
|
|
332
|
+
endpoint: 'https://s3.amazonaws.com/my-path/'
|
|
333
|
+
});
|
|
334
|
+
const id = computeS3ConfigIdentifier(config);
|
|
335
|
+
expect(id).toContain('endpoint:https://s3.amazonaws.com/my-path');
|
|
336
|
+
expect(id).not.toMatch(/\/$/);
|
|
337
|
+
});
|
|
338
|
+
});
|
|
339
|
+
describe('Combined identifiers', ()=>{
|
|
340
|
+
it('should use cacheKey only when present (ignoring accessKeyId/sessionToken)', ()=>{
|
|
341
|
+
const config = mockConfig({
|
|
342
|
+
cacheKey: 'my-cache-key',
|
|
343
|
+
credentials: {
|
|
344
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
|
345
|
+
sessionToken: 'token'
|
|
346
|
+
},
|
|
347
|
+
region: 'us-east-1',
|
|
348
|
+
endpoint: 'https://s3.amazonaws.com'
|
|
349
|
+
});
|
|
350
|
+
const id = computeS3ConfigIdentifier(config);
|
|
351
|
+
const parts = id.split('||');
|
|
352
|
+
expect(parts).toContain('my-cache-key');
|
|
353
|
+
expect(parts).not.toContain('AKIAIOSFODNN7EXAMPLE');
|
|
354
|
+
expect(parts.some((p)=>p.startsWith('session:'))).toBe(false);
|
|
355
|
+
expect(parts).toContain('region:us-east-1');
|
|
356
|
+
expect(parts).toContain('endpoint:https://s3.amazonaws.com');
|
|
357
|
+
});
|
|
358
|
+
it('should use accessKeyId and sessionToken when no cacheKey', ()=>{
|
|
359
|
+
const config = mockConfig({
|
|
360
|
+
credentials: {
|
|
361
|
+
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
|
|
362
|
+
sessionToken: 'token'
|
|
363
|
+
},
|
|
364
|
+
region: 'us-east-1',
|
|
365
|
+
endpoint: 'https://s3.amazonaws.com'
|
|
366
|
+
});
|
|
367
|
+
const id = computeS3ConfigIdentifier(config);
|
|
368
|
+
const parts = id.split('||');
|
|
369
|
+
expect(parts).toContain('AKIAIOSFODNN7EXAMPLE');
|
|
370
|
+
expect(parts.some((p)=>p.startsWith('session:'))).toBe(true);
|
|
371
|
+
expect(parts).toContain('region:us-east-1');
|
|
372
|
+
expect(parts).toContain('endpoint:https://s3.amazonaws.com');
|
|
373
|
+
});
|
|
374
|
+
it('should handle cacheKey with special characters', ()=>{
|
|
375
|
+
const config = mockConfig({
|
|
376
|
+
cacheKey: 'arn:aws:iam::123456789012:role/MyRole'
|
|
377
|
+
});
|
|
378
|
+
const id = computeS3ConfigIdentifier(config);
|
|
379
|
+
expect(id).toBe('arn:aws:iam::123456789012:role/MyRole');
|
|
380
|
+
const parts = id.split('||');
|
|
381
|
+
expect(parts).toHaveLength(1);
|
|
382
|
+
expect(parts[0]).toBe('arn:aws:iam::123456789012:role/MyRole');
|
|
383
|
+
});
|
|
384
|
+
it('should handle cacheKey with region and endpoint', ()=>{
|
|
385
|
+
const config = mockConfig({
|
|
386
|
+
cacheKey: 'my-cache-key',
|
|
387
|
+
region: 'us-east-1',
|
|
388
|
+
endpoint: 'https://s3.example.com:9000'
|
|
389
|
+
});
|
|
390
|
+
const id = computeS3ConfigIdentifier(config);
|
|
391
|
+
const parts = id.split('||');
|
|
392
|
+
expect(parts).toHaveLength(3);
|
|
393
|
+
expect(parts[0]).toBe('my-cache-key');
|
|
394
|
+
expect(parts[1]).toBe('region:us-east-1');
|
|
395
|
+
expect(parts[2]).toBe('endpoint:https://s3.example.com:9000');
|
|
396
|
+
});
|
|
397
|
+
});
|
|
398
|
+
describe('Fallback identifier', ()=>{
|
|
399
|
+
it('should return fallback when no config parts available', ()=>{
|
|
400
|
+
const config = mockConfig();
|
|
401
|
+
const id = computeS3ConfigIdentifier(config, 'test-fallback');
|
|
402
|
+
expect(id).toBe('test-fallback');
|
|
403
|
+
});
|
|
404
|
+
it('should use default fallback if not provided', ()=>{
|
|
405
|
+
const config = mockConfig();
|
|
406
|
+
const id = computeS3ConfigIdentifier(config);
|
|
407
|
+
expect(id).toBe('anonymous-s3-config');
|
|
408
|
+
});
|
|
409
|
+
it('should return fallback for null/undefined config', ()=>{
|
|
410
|
+
const id1 = computeS3ConfigIdentifier(null, 'fallback');
|
|
411
|
+
const id2 = computeS3ConfigIdentifier(void 0, 'fallback');
|
|
412
|
+
expect(id1).toBe('fallback');
|
|
413
|
+
expect(id2).toBe('fallback');
|
|
414
|
+
});
|
|
415
|
+
});
|
|
416
|
+
describe('Edge cases', ()=>{
|
|
417
|
+
it('should handle config with only whitespace values', ()=>{
|
|
418
|
+
const config = mockConfig({
|
|
419
|
+
credentials: {
|
|
420
|
+
accessKeyId: ' ',
|
|
421
|
+
sessionToken: ' '
|
|
422
|
+
},
|
|
423
|
+
region: ' ',
|
|
424
|
+
endpoint: ' '
|
|
425
|
+
});
|
|
426
|
+
const id = computeS3ConfigIdentifier(config, 'fallback');
|
|
427
|
+
expect(id).toBe('fallback');
|
|
428
|
+
});
|
|
429
|
+
it('should handle missing credentials object', ()=>{
|
|
430
|
+
const config = {
|
|
431
|
+
region: 'us-east-1'
|
|
432
|
+
};
|
|
433
|
+
const id = computeS3ConfigIdentifier(config);
|
|
434
|
+
expect(id).toBe('region:us-east-1');
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
});
|
|
@@ -10,3 +10,13 @@ export declare const VEEAM_OFFICE_365 = "Veeam Backup for Microsoft 365 (v6, v7)
|
|
|
10
10
|
export declare const VEEAM_OFFICE_365_V8 = "Veeam Backup for Microsoft 365 (v8+)";
|
|
11
11
|
/** Generic identifier for Commvault */
|
|
12
12
|
export declare const COMMVAULT_APPLICATION = "Commvault";
|
|
13
|
+
export declare const BUCKET_ROUTES: {
|
|
14
|
+
readonly bucketPolicy: (bucketName: string) => string;
|
|
15
|
+
readonly bucketCors: (bucketName: string) => string;
|
|
16
|
+
readonly lifecycleCreate: (bucketName: string) => string;
|
|
17
|
+
readonly lifecycleEdit: (bucketName: string, ruleId: string) => string;
|
|
18
|
+
readonly replicationCreate: (bucketName: string) => string;
|
|
19
|
+
readonly replicationEdit: (bucketName: string, ruleId: string) => string;
|
|
20
|
+
readonly notificationCreate: (bucketName: string) => string;
|
|
21
|
+
readonly notificationEdit: (bucketName: string, ruleId: string) => string;
|
|
22
|
+
};
|
package/dist/utils/constants.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
const BUCKET_TAG_VEEAM_APPLICATION =
|
|
2
|
-
const BUCKET_TAG_APPLICATION =
|
|
3
|
-
const VEEAM_BACKUP_REPLICATION =
|
|
4
|
-
const VEEAM_IMMUTABLE_POLICY_NAME =
|
|
5
|
-
const VEEAM_VBO_APPLICATION =
|
|
6
|
-
const VEEAM_OFFICE_365 =
|
|
7
|
-
const VEEAM_OFFICE_365_V8 =
|
|
8
|
-
const COMMVAULT_APPLICATION =
|
|
9
|
-
|
|
1
|
+
const BUCKET_TAG_VEEAM_APPLICATION = 'X-Scality-Veeam-Application';
|
|
2
|
+
const BUCKET_TAG_APPLICATION = 'X-Scality-Application';
|
|
3
|
+
const VEEAM_BACKUP_REPLICATION = 'Veeam Backup & Replication';
|
|
4
|
+
const VEEAM_IMMUTABLE_POLICY_NAME = 'Scality-Veeam-Immutable-Policy';
|
|
5
|
+
const VEEAM_VBO_APPLICATION = 'Veeam Backup for Microsoft 365';
|
|
6
|
+
const VEEAM_OFFICE_365 = 'Veeam Backup for Microsoft 365 (v6, v7)';
|
|
7
|
+
const VEEAM_OFFICE_365_V8 = 'Veeam Backup for Microsoft 365 (v8+)';
|
|
8
|
+
const COMMVAULT_APPLICATION = 'Commvault';
|
|
9
|
+
const BUCKET_ROUTES = {
|
|
10
|
+
bucketPolicy: (bucketName)=>`/buckets/${bucketName}/policy`,
|
|
11
|
+
bucketCors: (bucketName)=>`/buckets/${bucketName}/cors`,
|
|
12
|
+
lifecycleCreate: (bucketName)=>`/buckets/${bucketName}/lifecycle/create`,
|
|
13
|
+
lifecycleEdit: (bucketName, ruleId)=>`/buckets/${bucketName}/lifecycle/edit/${encodeURIComponent(ruleId)}`,
|
|
14
|
+
replicationCreate: (bucketName)=>`/buckets/${bucketName}/replication/create`,
|
|
15
|
+
replicationEdit: (bucketName, ruleId)=>`/buckets/${bucketName}/replication/edit/${encodeURIComponent(ruleId)}`,
|
|
16
|
+
notificationCreate: (bucketName)=>`/buckets/${bucketName}/notifications/create`,
|
|
17
|
+
notificationEdit: (bucketName, ruleId)=>`/buckets/${bucketName}/notifications/edit/${encodeURIComponent(ruleId)}`
|
|
18
|
+
};
|
|
19
|
+
export { BUCKET_ROUTES, BUCKET_TAG_APPLICATION, BUCKET_TAG_VEEAM_APPLICATION, COMMVAULT_APPLICATION, VEEAM_BACKUP_REPLICATION, VEEAM_IMMUTABLE_POLICY_NAME, VEEAM_OFFICE_365, VEEAM_OFFICE_365_V8, VEEAM_VBO_APPLICATION };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from './messages';
|
|
2
|
+
export * from './types';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const maybePluralize = (count, word, suffix =
|
|
1
|
+
const maybePluralize = (count, word, suffix = 's', includeCount = true)=>{
|
|
2
2
|
const pluralWord = 1 === count ? word : `${word}${suffix}`;
|
|
3
3
|
return includeCount ? `${count} ${pluralWord}` : pluralWord;
|
|
4
4
|
};
|
|
@@ -9,19 +9,19 @@ const getDeletionMessages = (context)=>{
|
|
|
9
9
|
return createSpecificVersionDeletionResult(numberOfObjects);
|
|
10
10
|
};
|
|
11
11
|
const createNonVersionedDeletionResult = (numberOfObjects)=>({
|
|
12
|
-
info: `The selected ${maybePluralize(numberOfObjects,
|
|
12
|
+
info: `The selected ${maybePluralize(numberOfObjects, 'object', 's', false)} will be permanently deleted.`,
|
|
13
13
|
checkboxRequired: true,
|
|
14
14
|
confirmationRequired: false,
|
|
15
15
|
isDeletionPossible: true
|
|
16
16
|
});
|
|
17
17
|
const createDefaultVersionDeletionResult = (numberOfObjects)=>({
|
|
18
|
-
info: `${1 === numberOfObjects ?
|
|
18
|
+
info: `${1 === numberOfObjects ? 'A delete marker' : 'Delete markers'} will be added to the ${maybePluralize(numberOfObjects, 'object', 's', false)}.`,
|
|
19
19
|
checkboxRequired: false,
|
|
20
20
|
confirmationRequired: false,
|
|
21
21
|
isDeletionPossible: true
|
|
22
22
|
});
|
|
23
23
|
const createSpecificVersionDeletionResult = (numberOfObjects)=>({
|
|
24
|
-
info: `The selected ${maybePluralize(numberOfObjects,
|
|
24
|
+
info: `The selected ${maybePluralize(numberOfObjects, 'version', 's', false)} will be permanently deleted.`,
|
|
25
25
|
checkboxRequired: true,
|
|
26
26
|
confirmationRequired: false,
|
|
27
27
|
isDeletionPossible: true
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S3ServiceException } from
|
|
1
|
+
import { type S3ServiceException } from '@aws-sdk/client-s3';
|
|
2
2
|
/**
|
|
3
3
|
* Business-level error categories for S3 operations.
|
|
4
4
|
* Used to determine retry strategy and user messaging.
|
|
@@ -19,10 +19,10 @@ export declare enum ErrorCategory {
|
|
|
19
19
|
export declare class EnhancedS3Error extends Error {
|
|
20
20
|
readonly category: ErrorCategory;
|
|
21
21
|
readonly statusCode?: number;
|
|
22
|
-
readonly metadata?: S3ServiceException[
|
|
22
|
+
readonly metadata?: S3ServiceException['$metadata'];
|
|
23
23
|
readonly originalError: Error;
|
|
24
24
|
readonly context?: Record<string, unknown>;
|
|
25
|
-
constructor(message: string, name: string, category: ErrorCategory, originalError: Error, statusCode?: number, metadata?: S3ServiceException[
|
|
25
|
+
constructor(message: string, name: string, category: ErrorCategory, originalError: Error, statusCode?: number, metadata?: S3ServiceException['$metadata'], context?: Record<string, unknown>);
|
|
26
26
|
/**
|
|
27
27
|
* Determines if this error should be retried based on its category.
|
|
28
28
|
* Only server errors and network issues are retryable.
|
|
@@ -38,13 +38,13 @@ function classifyByStatusCode(statusCode) {
|
|
|
38
38
|
return statusCode >= 500 ? "SERVER_ERROR" : "UNKNOWN";
|
|
39
39
|
}
|
|
40
40
|
function isS3ServiceException(error) {
|
|
41
|
-
return error instanceof Error &&
|
|
41
|
+
return error instanceof Error && '$metadata' in error;
|
|
42
42
|
}
|
|
43
43
|
function isEnhancedS3Error(error) {
|
|
44
44
|
return error instanceof EnhancedS3Error;
|
|
45
45
|
}
|
|
46
46
|
function createS3Error(error, context) {
|
|
47
|
-
if (error instanceof Error &&
|
|
47
|
+
if (error instanceof Error && 'AbortError' === error.name) return new EnhancedS3Error('Operation was cancelled', 'AbortError', "CANCELLATION", error, void 0, void 0, context);
|
|
48
48
|
if (error instanceof NoSuchBucket || error instanceof NoSuchKey || error instanceof NoSuchUpload) return new EnhancedS3Error(error.message, error.name, "NOT_FOUND", error, error.$metadata?.httpStatusCode, error.$metadata, context);
|
|
49
49
|
if (error instanceof InvalidRequest || error instanceof InvalidObjectState || error instanceof InvalidWriteOffset || error instanceof ObjectAlreadyInActiveTierError || error instanceof ObjectNotInActiveTierError) return new EnhancedS3Error(error.message, error.name, "CLIENT_ERROR", error, error.$metadata?.httpStatusCode, error.$metadata, context);
|
|
50
50
|
if (isS3ServiceException(error)) {
|
|
@@ -52,11 +52,11 @@ function createS3Error(error, context) {
|
|
|
52
52
|
return new EnhancedS3Error(error.message, error.name, category, error, error.$metadata?.httpStatusCode, error.$metadata, context);
|
|
53
53
|
}
|
|
54
54
|
if (error instanceof Error) {
|
|
55
|
-
const isNetwork = /network|connection|timeout|dns/i.test(error.message) || error.name.includes(
|
|
55
|
+
const isNetwork = /network|connection|timeout|dns/i.test(error.message) || error.name.includes('Network') || error.name.includes('Timeout');
|
|
56
56
|
return new EnhancedS3Error(error.message, error.name, isNetwork ? "NETWORK_ERROR" : "UNKNOWN", error, void 0, void 0, context);
|
|
57
57
|
}
|
|
58
|
-
const message =
|
|
59
|
-
return new EnhancedS3Error(message,
|
|
58
|
+
const message = 'string' == typeof error ? error : 'Unknown error occurred';
|
|
59
|
+
return new EnhancedS3Error(message, 'UnknownError', "UNKNOWN", new Error(message), void 0, void 0, context);
|
|
60
60
|
}
|
|
61
61
|
function createS3OperationError(error, operation, bucketName, objectKey) {
|
|
62
62
|
const context = {
|
|
@@ -67,7 +67,7 @@ function createS3OperationError(error, operation, bucketName, objectKey) {
|
|
|
67
67
|
};
|
|
68
68
|
const enhancedError = createS3Error(error, context);
|
|
69
69
|
if (!enhancedError.message.includes(operation)) {
|
|
70
|
-
const prefix = bucketName ? `${operation} failed for bucket '${bucketName}'${objectKey ? `, key '${objectKey}'` :
|
|
70
|
+
const prefix = bucketName ? `${operation} failed for bucket '${bucketName}'${objectKey ? `, key '${objectKey}'` : ''}` : `${operation} failed`;
|
|
71
71
|
return new EnhancedS3Error(`${prefix}: ${enhancedError.message}`, enhancedError.name, enhancedError.category, enhancedError.originalError, enhancedError.statusCode, enhancedError.metadata, context);
|
|
72
72
|
}
|
|
73
73
|
return enhancedError;
|
package/dist/utils/hooks.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
|
-
import { useLocation } from "react-router
|
|
2
|
+
import { useLocation } from "react-router";
|
|
3
3
|
const useQueryParams = ()=>{
|
|
4
4
|
const location = useLocation();
|
|
5
5
|
return useMemo(()=>new URLSearchParams(location.search), [
|
|
@@ -9,15 +9,15 @@ const useQueryParams = ()=>{
|
|
|
9
9
|
const usePrefixWithSlash = ()=>{
|
|
10
10
|
const query = useQueryParams();
|
|
11
11
|
return useMemo(()=>{
|
|
12
|
-
const prefix = query.get(
|
|
13
|
-
if (!prefix) return
|
|
14
|
-
if (!prefix ||
|
|
12
|
+
const prefix = query.get('prefix');
|
|
13
|
+
if (!prefix) return '';
|
|
14
|
+
if (!prefix || '/' === prefix.slice(-1)) return prefix;
|
|
15
15
|
{
|
|
16
|
-
const prefixArr = prefix.split(
|
|
16
|
+
const prefixArr = prefix.split('/');
|
|
17
17
|
prefixArr.pop();
|
|
18
|
-
if (!prefixArr.length) return
|
|
19
|
-
const joinedPrefix = prefixArr.join(
|
|
20
|
-
return joinedPrefix ?
|
|
18
|
+
if (!prefixArr.length) return '';
|
|
19
|
+
const joinedPrefix = prefixArr.join('/');
|
|
20
|
+
return joinedPrefix ? '/' !== joinedPrefix.slice(-1) ? `${joinedPrefix}/` : joinedPrefix : '';
|
|
21
21
|
}
|
|
22
22
|
}, [
|
|
23
23
|
query
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export
|
|
1
|
+
export * from './constants';
|
|
2
|
+
export * from './errorHandling';
|
|
3
|
+
export * from './s3Client';
|
|
4
|
+
export { ANONYMOUS_S3_CONFIG_IDENTIFIER, computeS3ConfigIdentifier, hashSessionToken, type S3ConfigIdentifierConfig, } from './s3ConfigIdentifier';
|
|
5
|
+
export * from './s3RuleUtils';
|
package/dist/utils/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
export * from "./errorHandling.js";
|
|
1
|
+
import { ANONYMOUS_S3_CONFIG_IDENTIFIER, computeS3ConfigIdentifier, hashSessionToken } from "./s3ConfigIdentifier.js";
|
|
3
2
|
export * from "./constants.js";
|
|
3
|
+
export * from "./errorHandling.js";
|
|
4
|
+
export * from "./s3Client.js";
|
|
4
5
|
export * from "./s3RuleUtils.js";
|
|
6
|
+
export { ANONYMOUS_S3_CONFIG_IDENTIFIER, computeS3ConfigIdentifier, hashSessionToken };
|