@scality/data-browser-library 1.0.0-preview.7 → 1.0.0-preview.9
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/__tests__/BucketCreate.test.d.ts +1 -0
- package/dist/components/__tests__/BucketCreate.test.js +408 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketLifecycleFormPage.test.js +618 -0
- package/dist/components/__tests__/BucketLifecycleList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketLifecycleList.test.js +325 -0
- package/dist/components/__tests__/BucketList.test.js +190 -0
- package/dist/components/__tests__/BucketOverview.test.js +298 -8
- package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketReplicationFormPage.test.js +1757 -0
- package/dist/components/__tests__/BucketReplicationList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketReplicationList.test.js +344 -0
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +196 -0
- package/dist/components/__tests__/EmptyBucketButton.test.d.ts +1 -0
- package/dist/components/__tests__/EmptyBucketButton.test.js +302 -0
- package/dist/components/buckets/BucketCreate.d.ts +49 -0
- package/dist/components/buckets/BucketCreate.js +237 -0
- package/dist/components/buckets/BucketDetails.js +62 -10
- package/dist/components/buckets/BucketLifecycleFormPage.d.ts +15 -0
- package/dist/components/buckets/BucketLifecycleFormPage.js +1070 -0
- package/dist/components/buckets/BucketLifecycleList.d.ts +10 -0
- package/dist/components/buckets/BucketLifecycleList.js +270 -0
- package/dist/components/buckets/BucketList.d.ts +5 -2
- package/dist/components/buckets/BucketList.js +38 -28
- package/dist/components/buckets/BucketOverview.d.ts +65 -4
- package/dist/components/buckets/BucketOverview.js +261 -179
- package/dist/components/buckets/BucketPage.js +1 -1
- package/dist/components/buckets/BucketReplicationFormPage.d.ts +1 -0
- package/dist/components/buckets/BucketReplicationFormPage.js +834 -0
- package/dist/components/buckets/BucketReplicationList.d.ts +11 -0
- package/dist/components/buckets/BucketReplicationList.js +189 -0
- package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +18 -0
- package/dist/components/buckets/DeleteBucketConfigRuleButton.js +53 -0
- package/dist/components/buckets/EmptyBucketButton.d.ts +5 -0
- package/dist/components/buckets/EmptyBucketButton.js +232 -0
- package/dist/components/buckets/EmptyBucketSummary.d.ts +9 -0
- package/dist/components/buckets/EmptyBucketSummary.js +60 -0
- package/dist/components/buckets/EmptyBucketSummaryList.d.ts +13 -0
- package/dist/components/buckets/EmptyBucketSummaryList.js +140 -0
- package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +8 -8
- package/dist/components/index.d.ts +8 -1
- package/dist/components/index.js +9 -2
- package/dist/components/objects/ObjectLock/EditRetentionButton.d.ts +4 -0
- package/dist/components/objects/ObjectLock/EditRetentionButton.js +32 -0
- package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.d.ts +3 -0
- package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +211 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +9 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettings.js +158 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +8 -0
- package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +39 -0
- package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.d.ts +1 -0
- package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +204 -0
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.d.ts +1 -0
- package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +374 -0
- package/dist/components/ui/ArrayFieldActions.d.ts +36 -0
- package/dist/components/ui/ArrayFieldActions.js +38 -0
- package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +16 -0
- package/dist/components/ui/ConfirmDeleteRuleModal.js +43 -0
- package/dist/components/ui/FilterFormSection.d.ts +44 -0
- package/dist/components/ui/FilterFormSection.js +159 -0
- package/dist/config/factory.d.ts +13 -2
- package/dist/config/factory.js +9 -6
- package/dist/hooks/__tests__/useISVBucketDetection.test.d.ts +1 -0
- package/dist/hooks/__tests__/useISVBucketDetection.test.js +188 -0
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +44 -1
- package/dist/hooks/factories/useCreateS3QueryHook.js +22 -1
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +5 -1
- package/dist/hooks/useDeleteBucketConfigRule.d.ts +26 -0
- package/dist/hooks/useDeleteBucketConfigRule.js +46 -0
- package/dist/hooks/useEmptyBucket.d.ts +27 -0
- package/dist/hooks/useEmptyBucket.js +116 -0
- package/dist/hooks/useISVBucketDetection.d.ts +15 -0
- package/dist/hooks/useISVBucketDetection.js +27 -0
- package/dist/hooks/useTableRowSelection.d.ts +9 -0
- package/dist/hooks/useTableRowSelection.js +45 -0
- package/dist/test/setup.js +8 -0
- package/dist/test/testUtils.d.ts +99 -17
- package/dist/test/testUtils.js +64 -16
- package/dist/test/utils/errorHandling.test.js +39 -1
- package/dist/utils/constants.d.ts +12 -0
- package/dist/utils/constants.js +9 -0
- package/dist/utils/errorHandling.d.ts +9 -0
- package/dist/utils/errorHandling.js +6 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/s3RuleUtils.d.ts +53 -0
- package/dist/utils/s3RuleUtils.js +101 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EnhancedS3Error, ErrorCategory, createS3Error, createS3OperationError, isEnhancedS3Error, isS3ServiceException, shouldRetryError } from "../../utils/errorHandling.js";
|
|
1
|
+
import { EnhancedS3Error, ErrorCategory, createS3Error, createS3OperationError, isEnhancedS3Error, isNotFoundError, isS3ServiceException, shouldRetryError } from "../../utils/errorHandling.js";
|
|
2
2
|
const TEST_CONSTANTS = {
|
|
3
3
|
REQUEST_ID: "test-request-id",
|
|
4
4
|
ATTEMPTS: 1,
|
|
@@ -340,6 +340,44 @@ describe("shouldRetryError", ()=>{
|
|
|
340
340
|
expect(shouldRetryError(retryableError, 3)).toBe(false);
|
|
341
341
|
});
|
|
342
342
|
});
|
|
343
|
+
describe("isNotFoundError", ()=>{
|
|
344
|
+
test("returns true for NOT_FOUND category errors", ()=>{
|
|
345
|
+
expect(isNotFoundError(TestEnhancedErrors.notFound())).toBe(true);
|
|
346
|
+
});
|
|
347
|
+
test("returns true for AWS NOT_FOUND errors", ()=>{
|
|
348
|
+
expect(isNotFoundError(TestErrors.noSuchBucket())).toBe(true);
|
|
349
|
+
expect(isNotFoundError(TestErrors.noSuchKey())).toBe(true);
|
|
350
|
+
});
|
|
351
|
+
test("returns true for 404 status code errors", ()=>{
|
|
352
|
+
const error404 = createMockAWSError("NoSuchLifecycleConfiguration", "The lifecycle configuration does not exist", 404);
|
|
353
|
+
expect(isNotFoundError(error404)).toBe(true);
|
|
354
|
+
});
|
|
355
|
+
test("returns false for other error categories", ()=>{
|
|
356
|
+
expect(isNotFoundError(TestEnhancedErrors.server())).toBe(false);
|
|
357
|
+
expect(isNotFoundError(TestEnhancedErrors.network())).toBe(false);
|
|
358
|
+
expect(isNotFoundError(TestEnhancedErrors.client())).toBe(false);
|
|
359
|
+
expect(isNotFoundError(TestEnhancedErrors.auth())).toBe(false);
|
|
360
|
+
expect(isNotFoundError(TestEnhancedErrors.cancelled())).toBe(false);
|
|
361
|
+
expect(isNotFoundError(TestEnhancedErrors.unknown())).toBe(false);
|
|
362
|
+
});
|
|
363
|
+
test("returns false for non-404 AWS errors", ()=>{
|
|
364
|
+
expect(isNotFoundError(TestErrors.invalidRequest())).toBe(false);
|
|
365
|
+
expect(isNotFoundError(TestErrors.accessDenied())).toBe(false);
|
|
366
|
+
expect(isNotFoundError(TestErrors.internalError())).toBe(false);
|
|
367
|
+
});
|
|
368
|
+
test("handles edge cases", ()=>{
|
|
369
|
+
expect(isNotFoundError(null)).toBe(false);
|
|
370
|
+
expect(isNotFoundError(void 0)).toBe(false);
|
|
371
|
+
expect(isNotFoundError("string")).toBe(false);
|
|
372
|
+
expect(isNotFoundError({})).toBe(false);
|
|
373
|
+
expect(isNotFoundError(new Error("Regular error"))).toBe(false);
|
|
374
|
+
});
|
|
375
|
+
test("works with any error type by converting to EnhancedS3Error", ()=>{
|
|
376
|
+
const regularError = new Error("Some error");
|
|
377
|
+
const result = isNotFoundError(regularError);
|
|
378
|
+
expect(result).toBe(false);
|
|
379
|
+
});
|
|
380
|
+
});
|
|
343
381
|
describe("Integration Tests", ()=>{
|
|
344
382
|
test("complete error processing workflow", ()=>{
|
|
345
383
|
const testCases = [
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const BUCKET_TAG_VEEAM_APPLICATION = "X-Scality-Veeam-Application";
|
|
2
|
+
export declare const BUCKET_TAG_APPLICATION = "X-Scality-Application";
|
|
3
|
+
export declare const VEEAM_BACKUP_REPLICATION = "Veeam Backup & Replication";
|
|
4
|
+
export declare const VEEAM_IMMUTABLE_POLICY_NAME = "Scality-Veeam-Immutable-Policy";
|
|
5
|
+
/** Generic identifier for Veeam Backup for Microsoft 365 (VBO) */
|
|
6
|
+
export declare const VEEAM_VBO_APPLICATION = "Veeam Backup for Microsoft 365";
|
|
7
|
+
/** Generic identifier for Veeam Backup for Microsoft 365 (v6, v7) */
|
|
8
|
+
export declare const VEEAM_OFFICE_365 = "Veeam Backup for Microsoft 365 (v6, v7)";
|
|
9
|
+
/** Generic identifier for Veeam Backup for Microsoft 365 (v8+) */
|
|
10
|
+
export declare const VEEAM_OFFICE_365_V8 = "Veeam Backup for Microsoft 365 (v8+)";
|
|
11
|
+
/** Generic identifier for Commvault */
|
|
12
|
+
export declare const COMMVAULT_APPLICATION = "Commvault";
|
|
@@ -0,0 +1,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
|
+
export { 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 };
|
|
@@ -52,3 +52,12 @@ export declare function createS3OperationError(error: unknown, operation: string
|
|
|
52
52
|
* Implements unified retry policy for all S3 operations.
|
|
53
53
|
*/
|
|
54
54
|
export declare function shouldRetryError(error: unknown, failureCount: number, maxRetries?: number): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Checks if an error indicates that a resource was not found (404).
|
|
57
|
+
* This is useful for distinguishing between "resource doesn't exist" (normal state)
|
|
58
|
+
* and actual errors (permissions, network issues, etc.).
|
|
59
|
+
*
|
|
60
|
+
* @param error - The error to check
|
|
61
|
+
* @returns true if the error category is NOT_FOUND
|
|
62
|
+
*/
|
|
63
|
+
export declare function isNotFoundError(error: unknown): boolean;
|
|
@@ -76,4 +76,9 @@ function shouldRetryError(error, failureCount, maxRetries = 3) {
|
|
|
76
76
|
if (failureCount >= maxRetries) return false;
|
|
77
77
|
return isEnhancedS3Error(error) ? error.shouldRetry() : createS3Error(error).shouldRetry();
|
|
78
78
|
}
|
|
79
|
-
|
|
79
|
+
function isNotFoundError(error) {
|
|
80
|
+
if (!error) return false;
|
|
81
|
+
const enhancedError = isEnhancedS3Error(error) ? error : createS3Error(error);
|
|
82
|
+
return "NOT_FOUND" === enhancedError.category;
|
|
83
|
+
}
|
|
84
|
+
export { EnhancedS3Error, errorHandling_ErrorCategory as ErrorCategory, createS3Error, createS3OperationError, isEnhancedS3Error, isNotFoundError, isS3ServiceException, shouldRetryError };
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const AWS_RULE_LIMITS: {
|
|
2
|
+
RULE_ID_MAX_LENGTH: number;
|
|
3
|
+
TAG_KEY_MAX_LENGTH: number;
|
|
4
|
+
TAG_VALUE_MAX_LENGTH: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const STATUS_OPTIONS: readonly [{
|
|
7
|
+
readonly value: "Enabled";
|
|
8
|
+
readonly label: "Enabled";
|
|
9
|
+
}, {
|
|
10
|
+
readonly value: "Disabled";
|
|
11
|
+
readonly label: "Disabled";
|
|
12
|
+
}];
|
|
13
|
+
export type FilterType = "none" | "prefix" | "tags" | "and";
|
|
14
|
+
/**
|
|
15
|
+
* Filter data for S3 rules. All fields are present for form handling,
|
|
16
|
+
* but only certain fields are used based on filterType.
|
|
17
|
+
*/
|
|
18
|
+
export interface FilterData {
|
|
19
|
+
filterType: FilterType;
|
|
20
|
+
prefix: string;
|
|
21
|
+
tags: Array<{
|
|
22
|
+
key: string;
|
|
23
|
+
value: string;
|
|
24
|
+
}>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Type-safe filter specification for S3 rule building.
|
|
28
|
+
* Each variant only includes the fields relevant to that filter type.
|
|
29
|
+
*/
|
|
30
|
+
export type FilterSpec = {
|
|
31
|
+
type: "none";
|
|
32
|
+
} | {
|
|
33
|
+
type: "prefix";
|
|
34
|
+
prefix: string;
|
|
35
|
+
} | {
|
|
36
|
+
type: "tags";
|
|
37
|
+
tags: Array<{
|
|
38
|
+
key: string;
|
|
39
|
+
value: string;
|
|
40
|
+
}>;
|
|
41
|
+
} | {
|
|
42
|
+
type: "and";
|
|
43
|
+
prefix: string;
|
|
44
|
+
tags: Array<{
|
|
45
|
+
key: string;
|
|
46
|
+
value: string;
|
|
47
|
+
}>;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Converts form FilterData to type-safe FilterSpec.
|
|
51
|
+
*/
|
|
52
|
+
export declare function toFilterSpec(data: FilterData): FilterSpec;
|
|
53
|
+
export declare function buildS3Filter(data: FilterData): Record<string, unknown>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const AWS_RULE_LIMITS = {
|
|
2
|
+
RULE_ID_MAX_LENGTH: 255,
|
|
3
|
+
TAG_KEY_MAX_LENGTH: 128,
|
|
4
|
+
TAG_VALUE_MAX_LENGTH: 256
|
|
5
|
+
};
|
|
6
|
+
const STATUS_OPTIONS = [
|
|
7
|
+
{
|
|
8
|
+
value: "Enabled",
|
|
9
|
+
label: "Enabled"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
value: "Disabled",
|
|
13
|
+
label: "Disabled"
|
|
14
|
+
}
|
|
15
|
+
];
|
|
16
|
+
function toFilterSpec(data) {
|
|
17
|
+
switch(data.filterType){
|
|
18
|
+
case "none":
|
|
19
|
+
return {
|
|
20
|
+
type: "none"
|
|
21
|
+
};
|
|
22
|
+
case "prefix":
|
|
23
|
+
return {
|
|
24
|
+
type: "prefix",
|
|
25
|
+
prefix: data.prefix
|
|
26
|
+
};
|
|
27
|
+
case "tags":
|
|
28
|
+
return {
|
|
29
|
+
type: "tags",
|
|
30
|
+
tags: data.tags
|
|
31
|
+
};
|
|
32
|
+
case "and":
|
|
33
|
+
return {
|
|
34
|
+
type: "and",
|
|
35
|
+
prefix: data.prefix,
|
|
36
|
+
tags: data.tags
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function buildS3Filter(data) {
|
|
41
|
+
const spec = toFilterSpec(data);
|
|
42
|
+
switch(spec.type){
|
|
43
|
+
case "none":
|
|
44
|
+
return {};
|
|
45
|
+
case "prefix":
|
|
46
|
+
return {
|
|
47
|
+
Prefix: spec.prefix
|
|
48
|
+
};
|
|
49
|
+
case "tags":
|
|
50
|
+
if (0 === spec.tags.length) return {};
|
|
51
|
+
if (1 === spec.tags.length) return {
|
|
52
|
+
Tag: {
|
|
53
|
+
Key: spec.tags[0].key,
|
|
54
|
+
Value: spec.tags[0].value
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
And: {
|
|
59
|
+
Tags: spec.tags.map((tag)=>({
|
|
60
|
+
Key: tag.key,
|
|
61
|
+
Value: tag.value
|
|
62
|
+
}))
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
case "and":
|
|
66
|
+
{
|
|
67
|
+
const hasPrefix = spec.prefix && "" !== spec.prefix.trim();
|
|
68
|
+
const hasTags = spec.tags.length > 0;
|
|
69
|
+
if (!hasTags && !hasPrefix) return {};
|
|
70
|
+
if (!hasTags && hasPrefix) return {
|
|
71
|
+
Prefix: spec.prefix
|
|
72
|
+
};
|
|
73
|
+
if (hasTags && !hasPrefix) {
|
|
74
|
+
if (1 === spec.tags.length) return {
|
|
75
|
+
Tag: {
|
|
76
|
+
Key: spec.tags[0].key,
|
|
77
|
+
Value: spec.tags[0].value
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
return {
|
|
81
|
+
And: {
|
|
82
|
+
Tags: spec.tags.map((tag)=>({
|
|
83
|
+
Key: tag.key,
|
|
84
|
+
Value: tag.value
|
|
85
|
+
}))
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
And: {
|
|
91
|
+
Prefix: spec.prefix,
|
|
92
|
+
Tags: spec.tags.map((tag)=>({
|
|
93
|
+
Key: tag.key,
|
|
94
|
+
Value: tag.value
|
|
95
|
+
}))
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export { AWS_RULE_LIMITS, STATUS_OPTIONS, buildS3Filter, toFilterSpec };
|
package/package.json
CHANGED