@scality/data-browser-library 1.0.0-preview.2
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/Editor.d.ts +12 -0
- package/dist/components/Editor.js +28 -0
- package/dist/components/__tests__/BucketList.test.d.ts +1 -0
- package/dist/components/__tests__/BucketList.test.js +225 -0
- package/dist/components/__tests__/BucketOverview.test.d.ts +1 -0
- package/dist/components/__tests__/BucketOverview.test.js +479 -0
- package/dist/components/__tests__/BucketPolicyPage.test.d.ts +1 -0
- package/dist/components/__tests__/BucketPolicyPage.test.js +213 -0
- package/dist/components/__tests__/CreateFolderButton.test.d.ts +1 -0
- package/dist/components/__tests__/CreateFolderButton.test.js +147 -0
- package/dist/components/__tests__/DeleteBucketButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteBucketButton.test.js +272 -0
- package/dist/components/__tests__/DeleteObjectButton.test.d.ts +1 -0
- package/dist/components/__tests__/DeleteObjectButton.test.js +302 -0
- package/dist/components/__tests__/MetadataSearch.test.d.ts +1 -0
- package/dist/components/__tests__/MetadataSearch.test.js +201 -0
- package/dist/components/__tests__/ObjectList.test.d.ts +1 -0
- package/dist/components/__tests__/ObjectList.test.js +283 -0
- package/dist/components/__tests__/UploadButton.test.d.ts +1 -0
- package/dist/components/__tests__/UploadButton.test.js +144 -0
- package/dist/components/buckets/BucketDetails.d.ts +1 -0
- package/dist/components/buckets/BucketDetails.js +51 -0
- package/dist/components/buckets/BucketList.d.ts +12 -0
- package/dist/components/buckets/BucketList.js +136 -0
- package/dist/components/buckets/BucketLocation.d.ts +3 -0
- package/dist/components/buckets/BucketLocation.js +16 -0
- package/dist/components/buckets/BucketOverview.d.ts +14 -0
- package/dist/components/buckets/BucketOverview.js +209 -0
- package/dist/components/buckets/BucketPage.d.ts +2 -0
- package/dist/components/buckets/BucketPage.js +47 -0
- package/dist/components/buckets/BucketPolicyButton.d.ts +7 -0
- package/dist/components/buckets/BucketPolicyButton.js +18 -0
- package/dist/components/buckets/BucketPolicyPage.d.ts +1 -0
- package/dist/components/buckets/BucketPolicyPage.js +205 -0
- package/dist/components/buckets/DeleteBucketButton.d.ts +8 -0
- package/dist/components/buckets/DeleteBucketButton.js +78 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/components/index.js +13 -0
- package/dist/components/layouts/BrowserPageLayout.d.ts +9 -0
- package/dist/components/layouts/BrowserPageLayout.js +46 -0
- package/dist/components/objects/CreateFolderButton.d.ts +29 -0
- package/dist/components/objects/CreateFolderButton.js +118 -0
- package/dist/components/objects/DeleteObjectButton.d.ts +8 -0
- package/dist/components/objects/DeleteObjectButton.js +191 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -0
- package/dist/components/objects/ObjectDetails/ObjectMetadata.js +323 -0
- package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +3 -0
- package/dist/components/objects/ObjectDetails/ObjectSummary.js +193 -0
- package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +3 -0
- package/dist/components/objects/ObjectDetails/ObjectTags.js +300 -0
- package/dist/components/objects/ObjectDetails/index.d.ts +9 -0
- package/dist/components/objects/ObjectDetails/index.js +49 -0
- package/dist/components/objects/ObjectList.d.ts +40 -0
- package/dist/components/objects/ObjectList.js +407 -0
- package/dist/components/objects/ObjectPage.d.ts +1 -0
- package/dist/components/objects/ObjectPage.js +43 -0
- package/dist/components/objects/UploadButton.d.ts +34 -0
- package/dist/components/objects/UploadButton.js +229 -0
- package/dist/components/providers/DataBrowserProvider.d.ts +20 -0
- package/dist/components/providers/DataBrowserProvider.js +42 -0
- package/dist/components/search/MetadataSearch.d.ts +5 -0
- package/dist/components/search/MetadataSearch.js +162 -0
- package/dist/components/search/SearchHints.d.ts +8 -0
- package/dist/components/search/SearchHints.js +21 -0
- package/dist/components/ui/DeleteObjectModalContent.d.ts +5 -0
- package/dist/components/ui/DeleteObjectModalContent.js +71 -0
- package/dist/components/ui/Search.elements.d.ts +17 -0
- package/dist/components/ui/Search.elements.js +59 -0
- package/dist/components/ui/Table.elements.d.ts +36 -0
- package/dist/components/ui/Table.elements.js +87 -0
- package/dist/config/factory.d.ts +52 -0
- package/dist/config/factory.js +70 -0
- package/dist/config/types.d.ts +46 -0
- package/dist/config/types.js +0 -0
- package/dist/hooks/__tests__/useIsBucketEmpty.test.d.ts +1 -0
- package/dist/hooks/__tests__/useIsBucketEmpty.test.js +122 -0
- package/dist/hooks/bucketConfiguration.d.ts +147 -0
- package/dist/hooks/bucketConfiguration.js +59 -0
- package/dist/hooks/bucketOperations.d.ts +36 -0
- package/dist/hooks/bucketOperations.js +12 -0
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +276 -0
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +259 -0
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +166 -0
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +200 -0
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.d.ts +1 -0
- package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +136 -0
- package/dist/hooks/factories/index.d.ts +18 -0
- package/dist/hooks/factories/index.js +5 -0
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +13 -0
- package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +76 -0
- package/dist/hooks/factories/useCreateS3LoginHook.d.ts +8 -0
- package/dist/hooks/factories/useCreateS3LoginHook.js +22 -0
- package/dist/hooks/factories/useCreateS3MutationHook.d.ts +5 -0
- package/dist/hooks/factories/useCreateS3MutationHook.js +50 -0
- package/dist/hooks/factories/useCreateS3QueryHook.d.ts +3 -0
- package/dist/hooks/factories/useCreateS3QueryHook.js +30 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.js +8 -0
- package/dist/hooks/loginOperations.d.ts +21 -0
- package/dist/hooks/loginOperations.js +9 -0
- package/dist/hooks/objectOperations.d.ts +190 -0
- package/dist/hooks/objectOperations.js +66 -0
- package/dist/hooks/presignedOperations.d.ts +73 -0
- package/dist/hooks/presignedOperations.js +72 -0
- package/dist/hooks/useIsBucketEmpty.d.ts +7 -0
- package/dist/hooks/useIsBucketEmpty.js +36 -0
- package/dist/hooks/useLoginMutation.d.ts +21 -0
- package/dist/hooks/useLoginMutation.js +9 -0
- package/dist/hooks/useS3Client.d.ts +1 -0
- package/dist/hooks/useS3Client.js +13 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/schemas/bucketPolicySchema.json +321 -0
- package/dist/test/msw/handlers/deleteBucket.d.ts +1 -0
- package/dist/test/msw/handlers/deleteBucket.js +14 -0
- package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -0
- package/dist/test/msw/handlers/getBucketAcl.js +96 -0
- package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -0
- package/dist/test/msw/handlers/getBucketLocation.js +23 -0
- package/dist/test/msw/handlers/getBucketPolicy.d.ts +11 -0
- package/dist/test/msw/handlers/getBucketPolicy.js +72 -0
- package/dist/test/msw/handlers/headObject.d.ts +1 -0
- package/dist/test/msw/handlers/headObject.js +17 -0
- package/dist/test/msw/handlers/listBuckets.d.ts +1 -0
- package/dist/test/msw/handlers/listBuckets.js +24 -0
- package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -0
- package/dist/test/msw/handlers/listObjectVersions.js +83 -0
- package/dist/test/msw/handlers/listObjects.d.ts +1 -0
- package/dist/test/msw/handlers/listObjects.js +66 -0
- package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -0
- package/dist/test/msw/handlers/objectLegalHold.js +24 -0
- package/dist/test/msw/handlers/objectRetention.d.ts +1 -0
- package/dist/test/msw/handlers/objectRetention.js +27 -0
- package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -0
- package/dist/test/msw/handlers/putBucketAcl.js +18 -0
- package/dist/test/msw/handlers/putObject.d.ts +1 -0
- package/dist/test/msw/handlers/putObject.js +16 -0
- package/dist/test/msw/handlers.d.ts +4 -0
- package/dist/test/msw/handlers.js +109 -0
- package/dist/test/msw/index.d.ts +2 -0
- package/dist/test/msw/index.js +3 -0
- package/dist/test/msw/server.d.ts +4 -0
- package/dist/test/msw/server.js +20 -0
- package/dist/test/msw/utils.d.ts +2 -0
- package/dist/test/msw/utils.js +13 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +82 -0
- package/dist/test/testUtils.d.ts +82 -0
- package/dist/test/testUtils.js +236 -0
- package/dist/test/utils/errorHandling.test.d.ts +1 -0
- package/dist/test/utils/errorHandling.test.js +385 -0
- package/dist/types/index.d.ts +48 -0
- package/dist/types/index.js +0 -0
- package/dist/utils/deletion/index.d.ts +2 -0
- package/dist/utils/deletion/index.js +2 -0
- package/dist/utils/deletion/messages.d.ts +5 -0
- package/dist/utils/deletion/messages.js +29 -0
- package/dist/utils/deletion/types.d.ts +11 -0
- package/dist/utils/deletion/types.js +0 -0
- package/dist/utils/errorHandling.d.ts +54 -0
- package/dist/utils/errorHandling.js +79 -0
- package/dist/utils/hooks.d.ts +2 -0
- package/dist/utils/hooks.js +26 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/proxyMiddleware.d.ts +18 -0
- package/dist/utils/proxyMiddleware.js +56 -0
- package/dist/utils/s3Client.d.ts +5 -0
- package/dist/utils/s3Client.js +35 -0
- package/dist/utils/useFeatures.d.ts +1 -0
- package/dist/utils/useFeatures.js +7 -0
- package/package.json +79 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
2
|
+
import { useCreateS3LoginHook } from "../useCreateS3LoginHook.js";
|
|
3
|
+
import { createS3Client } from "../../../utils/s3Client.js";
|
|
4
|
+
import { createS3OperationError } from "../../../utils/errorHandling.js";
|
|
5
|
+
import { createQueryWrapper, validateFactoryHook, validateHookResult } from "../../../test/testUtils.js";
|
|
6
|
+
jest.mock("../../../utils/s3Client");
|
|
7
|
+
jest.mock("../../../utils/errorHandling");
|
|
8
|
+
const mockCreateS3Client = createS3Client;
|
|
9
|
+
const mockCreateS3OperationError = createS3OperationError;
|
|
10
|
+
class MockLoginCommand {
|
|
11
|
+
input;
|
|
12
|
+
constructor(input){
|
|
13
|
+
this.input = input;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const mockS3Client = {
|
|
17
|
+
send: jest.fn()
|
|
18
|
+
};
|
|
19
|
+
describe("useCreateS3LoginHook - Login Factory Specific", ()=>{
|
|
20
|
+
const mockLoginConfig = {
|
|
21
|
+
endpoint: "https://s3.amazonaws.com",
|
|
22
|
+
region: "us-east-1",
|
|
23
|
+
forcePathStyle: false,
|
|
24
|
+
credentials: {
|
|
25
|
+
accessKeyId: "test-access-key",
|
|
26
|
+
secretAccessKey: "test-secret-key"
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
beforeEach(()=>{
|
|
30
|
+
jest.clearAllMocks();
|
|
31
|
+
mockCreateS3Client.mockReturnValue(mockS3Client);
|
|
32
|
+
});
|
|
33
|
+
it("should create a functioning login mutation hook", ()=>{
|
|
34
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
35
|
+
validateFactoryHook(useLoginMutation, "S3 Authentication");
|
|
36
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
37
|
+
wrapper: createQueryWrapper()
|
|
38
|
+
});
|
|
39
|
+
validateHookResult(result.current, "mutation");
|
|
40
|
+
});
|
|
41
|
+
it("should authenticate successfully with valid credentials", async ()=>{
|
|
42
|
+
mockS3Client.send.mockResolvedValueOnce({});
|
|
43
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
44
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
45
|
+
wrapper: createQueryWrapper()
|
|
46
|
+
});
|
|
47
|
+
result.current.mutate(mockLoginConfig);
|
|
48
|
+
await waitFor(()=>{
|
|
49
|
+
expect(result.current.isSuccess).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
expect(result.current.data).toEqual({
|
|
52
|
+
config: mockLoginConfig,
|
|
53
|
+
authenticated: true
|
|
54
|
+
});
|
|
55
|
+
expect(mockCreateS3Client).toHaveBeenCalledWith(mockLoginConfig);
|
|
56
|
+
});
|
|
57
|
+
it("should handle authentication failure", async ()=>{
|
|
58
|
+
const mockError = new Error("Access Denied");
|
|
59
|
+
const enhancedError = new Error("Enhanced S3 Authentication Error");
|
|
60
|
+
mockS3Client.send.mockRejectedValueOnce(mockError);
|
|
61
|
+
mockCreateS3OperationError.mockReturnValueOnce(enhancedError);
|
|
62
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
63
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
64
|
+
wrapper: createQueryWrapper()
|
|
65
|
+
});
|
|
66
|
+
result.current.mutate(mockLoginConfig);
|
|
67
|
+
await waitFor(()=>{
|
|
68
|
+
expect(result.current.isError).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
expect(result.current.error).toBe(enhancedError);
|
|
71
|
+
expect(mockCreateS3OperationError).toHaveBeenCalledWith(mockError, "S3 Authentication");
|
|
72
|
+
});
|
|
73
|
+
it("should create its own S3 client instead of using context client", async ()=>{
|
|
74
|
+
mockS3Client.send.mockResolvedValueOnce({});
|
|
75
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
76
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
77
|
+
wrapper: createQueryWrapper()
|
|
78
|
+
});
|
|
79
|
+
result.current.mutate(mockLoginConfig);
|
|
80
|
+
await waitFor(()=>{
|
|
81
|
+
expect(result.current.isSuccess).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
expect(mockCreateS3Client).toHaveBeenCalledWith(mockLoginConfig);
|
|
84
|
+
expect(mockCreateS3Client).toHaveBeenCalledTimes(1);
|
|
85
|
+
});
|
|
86
|
+
it("should handle mutation callbacks correctly", async ()=>{
|
|
87
|
+
const onSuccess = jest.fn();
|
|
88
|
+
const onError = jest.fn();
|
|
89
|
+
const onSettled = jest.fn();
|
|
90
|
+
mockS3Client.send.mockResolvedValueOnce({});
|
|
91
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
92
|
+
const { result } = renderHook(()=>useLoginMutation({
|
|
93
|
+
onSuccess,
|
|
94
|
+
onError,
|
|
95
|
+
onSettled
|
|
96
|
+
}), {
|
|
97
|
+
wrapper: createQueryWrapper()
|
|
98
|
+
});
|
|
99
|
+
result.current.mutate(mockLoginConfig);
|
|
100
|
+
await waitFor(()=>{
|
|
101
|
+
expect(result.current.isSuccess).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
const expectedResult = {
|
|
104
|
+
config: mockLoginConfig,
|
|
105
|
+
authenticated: true
|
|
106
|
+
};
|
|
107
|
+
expect(onSuccess).toHaveBeenCalledWith(expectedResult, mockLoginConfig, void 0, expect.any(Object));
|
|
108
|
+
expect(onError).not.toHaveBeenCalled();
|
|
109
|
+
expect(onSettled).toHaveBeenCalledWith(expectedResult, null, mockLoginConfig, void 0, expect.any(Object));
|
|
110
|
+
});
|
|
111
|
+
it("should handle network errors during authentication", async ()=>{
|
|
112
|
+
const networkError = new Error("Network timeout");
|
|
113
|
+
const enhancedError = new Error("Enhanced Network Error");
|
|
114
|
+
mockS3Client.send.mockRejectedValueOnce(networkError);
|
|
115
|
+
mockCreateS3OperationError.mockReturnValueOnce(enhancedError);
|
|
116
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
117
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
118
|
+
wrapper: createQueryWrapper()
|
|
119
|
+
});
|
|
120
|
+
result.current.mutate(mockLoginConfig);
|
|
121
|
+
await waitFor(()=>{
|
|
122
|
+
expect(result.current.isError).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
expect(result.current.error).toBe(enhancedError);
|
|
125
|
+
expect(mockCreateS3OperationError).toHaveBeenCalledWith(networkError, "S3 Authentication");
|
|
126
|
+
});
|
|
127
|
+
it("should work with credentials containing session token", async ()=>{
|
|
128
|
+
const configWithToken = {
|
|
129
|
+
...mockLoginConfig,
|
|
130
|
+
credentials: {
|
|
131
|
+
...mockLoginConfig.credentials,
|
|
132
|
+
sessionToken: "test-session-token"
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
mockS3Client.send.mockResolvedValueOnce({});
|
|
136
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
137
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
138
|
+
wrapper: createQueryWrapper()
|
|
139
|
+
});
|
|
140
|
+
result.current.mutate(configWithToken);
|
|
141
|
+
await waitFor(()=>{
|
|
142
|
+
expect(result.current.isSuccess).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
expect(mockCreateS3Client).toHaveBeenCalledWith(configWithToken);
|
|
145
|
+
expect(result.current.data).toEqual({
|
|
146
|
+
config: configWithToken,
|
|
147
|
+
authenticated: true
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
it("should handle custom endpoint configurations", async ()=>{
|
|
151
|
+
const customEndpointConfig = {
|
|
152
|
+
...mockLoginConfig,
|
|
153
|
+
endpoint: "https://custom-s3.example.com"
|
|
154
|
+
};
|
|
155
|
+
mockS3Client.send.mockResolvedValueOnce({});
|
|
156
|
+
const useLoginMutation = useCreateS3LoginHook(MockLoginCommand, "S3 Authentication");
|
|
157
|
+
const { result } = renderHook(()=>useLoginMutation(), {
|
|
158
|
+
wrapper: createQueryWrapper()
|
|
159
|
+
});
|
|
160
|
+
result.current.mutate(customEndpointConfig);
|
|
161
|
+
await waitFor(()=>{
|
|
162
|
+
expect(result.current.isSuccess).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
expect(mockCreateS3Client).toHaveBeenCalledWith(customEndpointConfig);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
2
|
+
import { useCreateS3MutationHook } from "../useCreateS3MutationHook.js";
|
|
3
|
+
import { useS3Client } from "../../useS3Client.js";
|
|
4
|
+
import { createS3OperationError } from "../../../utils/errorHandling.js";
|
|
5
|
+
import { createQueryWrapper, validateFactoryHook, validateHookResult } from "../../../test/testUtils.js";
|
|
6
|
+
jest.mock("../../useS3Client");
|
|
7
|
+
jest.mock("../../../utils/errorHandling");
|
|
8
|
+
const mockUseS3Client = useS3Client;
|
|
9
|
+
const mockCreateS3OperationError = createS3OperationError;
|
|
10
|
+
class MockCommand {
|
|
11
|
+
input;
|
|
12
|
+
constructor(input){
|
|
13
|
+
this.input = input;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const mockS3Client = {
|
|
17
|
+
send: jest.fn()
|
|
18
|
+
};
|
|
19
|
+
describe("useCreateS3MutationHook - Factory Specific", ()=>{
|
|
20
|
+
beforeEach(()=>{
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
mockUseS3Client.mockReturnValue(mockS3Client);
|
|
23
|
+
});
|
|
24
|
+
it("should create a functioning mutation hook", ()=>{
|
|
25
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "testMutation");
|
|
26
|
+
validateFactoryHook(useMutation, "testMutation");
|
|
27
|
+
const { result } = renderHook(()=>useMutation(), {
|
|
28
|
+
wrapper: createQueryWrapper()
|
|
29
|
+
});
|
|
30
|
+
validateHookResult(result.current, "mutation");
|
|
31
|
+
});
|
|
32
|
+
it("should accept invalidation keys parameter", ()=>{
|
|
33
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "testMutation", [
|
|
34
|
+
"ListObjects",
|
|
35
|
+
"TestQuery"
|
|
36
|
+
]);
|
|
37
|
+
validateFactoryHook(useMutation, "testMutation");
|
|
38
|
+
const { result } = renderHook(()=>useMutation(), {
|
|
39
|
+
wrapper: createQueryWrapper()
|
|
40
|
+
});
|
|
41
|
+
validateHookResult(result.current, "mutation");
|
|
42
|
+
});
|
|
43
|
+
it("should execute mutation successfully", async ()=>{
|
|
44
|
+
const mockResponse = {
|
|
45
|
+
success: true,
|
|
46
|
+
key: "uploaded-file.txt"
|
|
47
|
+
};
|
|
48
|
+
mockS3Client.send.mockResolvedValue(mockResponse);
|
|
49
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "PutObject");
|
|
50
|
+
const { result } = renderHook(()=>useMutation(), {
|
|
51
|
+
wrapper: createQueryWrapper()
|
|
52
|
+
});
|
|
53
|
+
result.current.mutate({
|
|
54
|
+
Bucket: "test-bucket",
|
|
55
|
+
Key: "test-file.txt",
|
|
56
|
+
Body: "content"
|
|
57
|
+
});
|
|
58
|
+
await waitFor(()=>{
|
|
59
|
+
expect(result.current.isSuccess).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
expect(result.current.data).toEqual(mockResponse);
|
|
62
|
+
expect(mockS3Client.send).toHaveBeenCalledWith(expect.objectContaining({
|
|
63
|
+
input: {
|
|
64
|
+
Bucket: "test-bucket",
|
|
65
|
+
Key: "test-file.txt",
|
|
66
|
+
Body: "content"
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
it("should handle mutation errors with proper context", async ()=>{
|
|
71
|
+
const mockError = new Error("Access Denied");
|
|
72
|
+
const enhancedError = new Error("Enhanced Access Denied");
|
|
73
|
+
mockS3Client.send.mockRejectedValue(mockError);
|
|
74
|
+
mockCreateS3OperationError.mockReturnValue(enhancedError);
|
|
75
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "PutObject");
|
|
76
|
+
const { result } = renderHook(()=>useMutation(), {
|
|
77
|
+
wrapper: createQueryWrapper()
|
|
78
|
+
});
|
|
79
|
+
result.current.mutate({
|
|
80
|
+
Bucket: "test-bucket",
|
|
81
|
+
Key: "test-file.txt"
|
|
82
|
+
});
|
|
83
|
+
await waitFor(()=>{
|
|
84
|
+
expect(result.current.isError).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
expect(result.current.error).toBe(enhancedError);
|
|
87
|
+
expect(mockCreateS3OperationError).toHaveBeenCalledWith(mockError, "PutObject", "test-bucket");
|
|
88
|
+
});
|
|
89
|
+
it("should handle mutation callbacks correctly", async ()=>{
|
|
90
|
+
const mockResponse = {
|
|
91
|
+
success: true
|
|
92
|
+
};
|
|
93
|
+
const onSuccess = jest.fn();
|
|
94
|
+
const onError = jest.fn();
|
|
95
|
+
const onSettled = jest.fn();
|
|
96
|
+
mockS3Client.send.mockResolvedValue(mockResponse);
|
|
97
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "PutObject");
|
|
98
|
+
const { result } = renderHook(()=>useMutation({
|
|
99
|
+
onSuccess,
|
|
100
|
+
onError,
|
|
101
|
+
onSettled
|
|
102
|
+
}), {
|
|
103
|
+
wrapper: createQueryWrapper()
|
|
104
|
+
});
|
|
105
|
+
const variables = {
|
|
106
|
+
Bucket: "test-bucket",
|
|
107
|
+
Key: "test-file.txt"
|
|
108
|
+
};
|
|
109
|
+
result.current.mutate(variables);
|
|
110
|
+
await waitFor(()=>{
|
|
111
|
+
expect(result.current.isSuccess).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
expect(onSuccess).toHaveBeenCalledWith(mockResponse, variables, void 0, expect.any(Object));
|
|
114
|
+
expect(onError).not.toHaveBeenCalled();
|
|
115
|
+
expect(onSettled).toHaveBeenCalledWith(mockResponse, null, variables, void 0, expect.any(Object));
|
|
116
|
+
});
|
|
117
|
+
it("should handle mutation with invalidation keys", async ()=>{
|
|
118
|
+
const mockResponse = {
|
|
119
|
+
success: true
|
|
120
|
+
};
|
|
121
|
+
mockS3Client.send.mockResolvedValue(mockResponse);
|
|
122
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "PutObject", [
|
|
123
|
+
"ListObjects",
|
|
124
|
+
"TestQuery"
|
|
125
|
+
]);
|
|
126
|
+
const { result } = renderHook(()=>useMutation(), {
|
|
127
|
+
wrapper: createQueryWrapper()
|
|
128
|
+
});
|
|
129
|
+
result.current.mutate({
|
|
130
|
+
Bucket: "test-bucket",
|
|
131
|
+
Key: "test-file.txt"
|
|
132
|
+
});
|
|
133
|
+
await waitFor(()=>{
|
|
134
|
+
expect(result.current.isSuccess).toBe(true);
|
|
135
|
+
});
|
|
136
|
+
expect(result.current.data).toEqual(mockResponse);
|
|
137
|
+
});
|
|
138
|
+
it("should handle concurrent mutations correctly", async ()=>{
|
|
139
|
+
const mockResponse1 = {
|
|
140
|
+
success: true,
|
|
141
|
+
id: 1
|
|
142
|
+
};
|
|
143
|
+
const mockResponse2 = {
|
|
144
|
+
success: true,
|
|
145
|
+
id: 2
|
|
146
|
+
};
|
|
147
|
+
let callCount = 0;
|
|
148
|
+
mockS3Client.send.mockImplementation(()=>{
|
|
149
|
+
callCount++;
|
|
150
|
+
return Promise.resolve(1 === callCount ? mockResponse1 : mockResponse2);
|
|
151
|
+
});
|
|
152
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "PutObject");
|
|
153
|
+
const { result: result1 } = renderHook(()=>useMutation(), {
|
|
154
|
+
wrapper: createQueryWrapper()
|
|
155
|
+
});
|
|
156
|
+
const { result: result2 } = renderHook(()=>useMutation(), {
|
|
157
|
+
wrapper: createQueryWrapper()
|
|
158
|
+
});
|
|
159
|
+
result1.current.mutate({
|
|
160
|
+
Bucket: "test-bucket",
|
|
161
|
+
Key: "file1.txt"
|
|
162
|
+
});
|
|
163
|
+
result2.current.mutate({
|
|
164
|
+
Bucket: "test-bucket",
|
|
165
|
+
Key: "file2.txt"
|
|
166
|
+
});
|
|
167
|
+
await waitFor(()=>{
|
|
168
|
+
expect(result1.current.isSuccess).toBe(true);
|
|
169
|
+
expect(result2.current.isSuccess).toBe(true);
|
|
170
|
+
});
|
|
171
|
+
expect(result1.current.data).toEqual(mockResponse1);
|
|
172
|
+
expect(result2.current.data).toEqual(mockResponse2);
|
|
173
|
+
expect(mockS3Client.send).toHaveBeenCalledTimes(2);
|
|
174
|
+
});
|
|
175
|
+
it("should pass command correctly for mutations", async ()=>{
|
|
176
|
+
let capturedCommand;
|
|
177
|
+
mockS3Client.send.mockImplementation((command)=>{
|
|
178
|
+
capturedCommand = command;
|
|
179
|
+
return Promise.resolve({
|
|
180
|
+
success: true
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
const useMutation = useCreateS3MutationHook(MockCommand, "PutObject");
|
|
184
|
+
const { result } = renderHook(()=>useMutation(), {
|
|
185
|
+
wrapper: createQueryWrapper()
|
|
186
|
+
});
|
|
187
|
+
result.current.mutate({
|
|
188
|
+
Bucket: "test-bucket",
|
|
189
|
+
Key: "test-file.txt"
|
|
190
|
+
});
|
|
191
|
+
await waitFor(()=>{
|
|
192
|
+
expect(result.current.isSuccess).toBe(true);
|
|
193
|
+
});
|
|
194
|
+
expect(capturedCommand).toBeInstanceOf(MockCommand);
|
|
195
|
+
expect(capturedCommand.input).toEqual({
|
|
196
|
+
Bucket: "test-bucket",
|
|
197
|
+
Key: "test-file.txt"
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
2
|
+
import { useCreateS3QueryHook } from "../useCreateS3QueryHook.js";
|
|
3
|
+
import { useS3Client } from "../../useS3Client.js";
|
|
4
|
+
import { createS3OperationError } from "../../../utils/errorHandling.js";
|
|
5
|
+
import { createQueryWrapper, validateFactoryHook, validateHookResult } from "../../../test/testUtils.js";
|
|
6
|
+
jest.mock("../../useS3Client");
|
|
7
|
+
jest.mock("../../../utils/errorHandling");
|
|
8
|
+
const mockUseS3Client = useS3Client;
|
|
9
|
+
const mockCreateS3OperationError = createS3OperationError;
|
|
10
|
+
class MockCommand {
|
|
11
|
+
input;
|
|
12
|
+
constructor(input){
|
|
13
|
+
this.input = input;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const mockS3Client = {
|
|
17
|
+
send: jest.fn()
|
|
18
|
+
};
|
|
19
|
+
describe("useCreateS3QueryHook - Factory Specific", ()=>{
|
|
20
|
+
beforeEach(()=>{
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
mockUseS3Client.mockReturnValue(mockS3Client);
|
|
23
|
+
});
|
|
24
|
+
it("should create a functioning query hook", ()=>{
|
|
25
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
26
|
+
validateFactoryHook(useTestQuery, "testOperation");
|
|
27
|
+
const { result } = renderHook(()=>useTestQuery({
|
|
28
|
+
testParam: "value"
|
|
29
|
+
}), {
|
|
30
|
+
wrapper: createQueryWrapper()
|
|
31
|
+
});
|
|
32
|
+
validateHookResult(result.current, "query");
|
|
33
|
+
});
|
|
34
|
+
it("should accept and forward query options correctly", ()=>{
|
|
35
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
36
|
+
const customOptions = {
|
|
37
|
+
enabled: false,
|
|
38
|
+
staleTime: 5000,
|
|
39
|
+
refetchOnWindowFocus: false
|
|
40
|
+
};
|
|
41
|
+
const { result } = renderHook(()=>useTestQuery({
|
|
42
|
+
testParam: "value"
|
|
43
|
+
}, customOptions), {
|
|
44
|
+
wrapper: createQueryWrapper()
|
|
45
|
+
});
|
|
46
|
+
expect(result.current.fetchStatus).toBe("idle");
|
|
47
|
+
expect(result.current.isLoading).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
it("should handle successful query execution", async ()=>{
|
|
50
|
+
const mockResponse = {
|
|
51
|
+
data: "test-response",
|
|
52
|
+
status: "success"
|
|
53
|
+
};
|
|
54
|
+
mockS3Client.send.mockResolvedValue(mockResponse);
|
|
55
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
56
|
+
const { result } = renderHook(()=>useTestQuery({
|
|
57
|
+
Bucket: "test-bucket",
|
|
58
|
+
Key: "test-key"
|
|
59
|
+
}), {
|
|
60
|
+
wrapper: createQueryWrapper()
|
|
61
|
+
});
|
|
62
|
+
await waitFor(()=>{
|
|
63
|
+
expect(result.current.isSuccess).toBe(true);
|
|
64
|
+
});
|
|
65
|
+
expect(result.current.data).toEqual(mockResponse);
|
|
66
|
+
expect(mockS3Client.send).toHaveBeenCalledWith(expect.any(MockCommand), expect.objectContaining({
|
|
67
|
+
abortSignal: expect.any(AbortSignal)
|
|
68
|
+
}));
|
|
69
|
+
});
|
|
70
|
+
it("should handle query errors with proper context", async ()=>{
|
|
71
|
+
const mockError = new Error("S3 Service Error");
|
|
72
|
+
const enhancedError = new Error("Enhanced S3 Service Error");
|
|
73
|
+
mockS3Client.send.mockRejectedValue(mockError);
|
|
74
|
+
mockCreateS3OperationError.mockReturnValue(enhancedError);
|
|
75
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
76
|
+
const { result } = renderHook(()=>useTestQuery({
|
|
77
|
+
Bucket: "test-bucket",
|
|
78
|
+
Key: "test-key"
|
|
79
|
+
}), {
|
|
80
|
+
wrapper: createQueryWrapper()
|
|
81
|
+
});
|
|
82
|
+
await waitFor(()=>{
|
|
83
|
+
expect(result.current.isError).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
expect(result.current.error).toBe(enhancedError);
|
|
86
|
+
expect(mockCreateS3OperationError).toHaveBeenCalledWith(mockError, "testOperation", "test-bucket");
|
|
87
|
+
});
|
|
88
|
+
it("should handle parameter validation correctly", ()=>{
|
|
89
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
90
|
+
const { result: invalidResult } = renderHook(()=>useTestQuery({
|
|
91
|
+
Bucket: "test",
|
|
92
|
+
Key: void 0
|
|
93
|
+
}), {
|
|
94
|
+
wrapper: createQueryWrapper()
|
|
95
|
+
});
|
|
96
|
+
expect(invalidResult.current.fetchStatus).toBe("idle");
|
|
97
|
+
const { result: validResult } = renderHook(()=>useTestQuery({
|
|
98
|
+
Bucket: "test",
|
|
99
|
+
Key: "valid-key"
|
|
100
|
+
}), {
|
|
101
|
+
wrapper: createQueryWrapper()
|
|
102
|
+
});
|
|
103
|
+
expect(validResult.current.fetchStatus).not.toBe("idle");
|
|
104
|
+
});
|
|
105
|
+
it("should handle empty string parameters correctly", ()=>{
|
|
106
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
107
|
+
const { result: emptyResult } = renderHook(()=>useTestQuery({
|
|
108
|
+
Bucket: "test",
|
|
109
|
+
Key: ""
|
|
110
|
+
}), {
|
|
111
|
+
wrapper: createQueryWrapper()
|
|
112
|
+
});
|
|
113
|
+
expect(emptyResult.current.fetchStatus).not.toBe("idle");
|
|
114
|
+
});
|
|
115
|
+
it("should pass AbortSignal correctly to S3 client", async ()=>{
|
|
116
|
+
let capturedAbortSignal;
|
|
117
|
+
mockS3Client.send.mockImplementation((_command, options)=>{
|
|
118
|
+
capturedAbortSignal = options?.abortSignal;
|
|
119
|
+
return Promise.resolve({
|
|
120
|
+
success: true
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
const useTestQuery = useCreateS3QueryHook(MockCommand, "testOperation");
|
|
124
|
+
const { result } = renderHook(()=>useTestQuery({
|
|
125
|
+
Bucket: "test",
|
|
126
|
+
Key: "test"
|
|
127
|
+
}), {
|
|
128
|
+
wrapper: createQueryWrapper()
|
|
129
|
+
});
|
|
130
|
+
await waitFor(()=>{
|
|
131
|
+
expect(result.current.isSuccess).toBe(true);
|
|
132
|
+
});
|
|
133
|
+
expect(capturedAbortSignal).toBeInstanceOf(AbortSignal);
|
|
134
|
+
expect(capturedAbortSignal?.aborted).toBe(false);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S3 Hook Factory Functions
|
|
3
|
+
*
|
|
4
|
+
* These factory functions provide a standardized way to create React Query hooks
|
|
5
|
+
* for S3 operations, eliminating code duplication and ensuring consistent patterns
|
|
6
|
+
* across all S3 hooks.
|
|
7
|
+
*
|
|
8
|
+
* The factories handle:
|
|
9
|
+
* - Standard error handling with EnhancedS3Error
|
|
10
|
+
* - Consistent query key patterns
|
|
11
|
+
* - Automatic query invalidation for mutations
|
|
12
|
+
* - AbortSignal support for cancellation
|
|
13
|
+
* - Bucket/object context extraction for errors
|
|
14
|
+
*/
|
|
15
|
+
export { useCreateS3QueryHook } from "./useCreateS3QueryHook";
|
|
16
|
+
export { useCreateS3MutationHook, useCreateS3FunctionMutationHook, } from "./useCreateS3MutationHook";
|
|
17
|
+
export { useCreateS3InfiniteQueryHook } from "./useCreateS3InfiniteQueryHook";
|
|
18
|
+
export { useCreateS3LoginHook } from "./useCreateS3LoginHook";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { useCreateS3QueryHook } from "./useCreateS3QueryHook.js";
|
|
2
|
+
import { useCreateS3FunctionMutationHook, useCreateS3MutationHook } from "./useCreateS3MutationHook.js";
|
|
3
|
+
import { useCreateS3InfiniteQueryHook } from "./useCreateS3InfiniteQueryHook.js";
|
|
4
|
+
import { useCreateS3LoginHook } from "./useCreateS3LoginHook.js";
|
|
5
|
+
export { useCreateS3FunctionMutationHook, useCreateS3InfiniteQueryHook, useCreateS3LoginHook, useCreateS3MutationHook, useCreateS3QueryHook };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { UseInfiniteQueryOptions, UseInfiniteQueryResult } from "@tanstack/react-query";
|
|
2
|
+
import { EnhancedS3Error } from "../../utils/errorHandling";
|
|
3
|
+
/**
|
|
4
|
+
* Factory function for creating S3 infinite query hooks
|
|
5
|
+
*
|
|
6
|
+
* This factory handles S3 operations that return paginated results and need
|
|
7
|
+
* infinite scroll support. It automatically handles:
|
|
8
|
+
* - Error handling with enhanced S3 errors
|
|
9
|
+
* - Standard query key patterns
|
|
10
|
+
* - AbortSignal support for cancellation
|
|
11
|
+
* - Pagination parameters and logic
|
|
12
|
+
*/
|
|
13
|
+
export declare function useCreateS3InfiniteQueryHook<TInput extends object, TOutput>(Command: new (input: TInput) => any, operationName: string): (params: TInput, options?: Partial<UseInfiniteQueryOptions<TOutput, EnhancedS3Error, TOutput, (string | TInput)[], string | undefined>>) => UseInfiniteQueryResult<TOutput, EnhancedS3Error>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
2
|
+
import { useS3Client } from "../useS3Client.js";
|
|
3
|
+
import { createS3OperationError, shouldRetryError } from "../../utils/errorHandling.js";
|
|
4
|
+
function useCreateS3InfiniteQueryHook(Command, operationName) {
|
|
5
|
+
return (params, options)=>{
|
|
6
|
+
const s3Client = useS3Client();
|
|
7
|
+
const queryOptions = {
|
|
8
|
+
queryKey: [
|
|
9
|
+
operationName,
|
|
10
|
+
params
|
|
11
|
+
],
|
|
12
|
+
queryFn: async ({ pageParam, signal })=>{
|
|
13
|
+
try {
|
|
14
|
+
const command = new Command({
|
|
15
|
+
...params,
|
|
16
|
+
...pageParam ? getPaginationParams(operationName, pageParam) : {}
|
|
17
|
+
});
|
|
18
|
+
const response = await s3Client.send(command, {
|
|
19
|
+
abortSignal: signal
|
|
20
|
+
});
|
|
21
|
+
return response;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
const bucketName = "Bucket" in params ? params.Bucket : void 0;
|
|
24
|
+
throw createS3OperationError(error, operationName, bucketName);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
retry: options?.retry ?? ((failureCount, error)=>shouldRetryError(error, failureCount)),
|
|
28
|
+
initialPageParam: void 0,
|
|
29
|
+
getNextPageParam: (lastPage)=>getNextPageToken(operationName, lastPage),
|
|
30
|
+
enabled: params ? Object.entries(params).every(([key, value])=>{
|
|
31
|
+
if ("Prefix" === key) return void 0 !== value;
|
|
32
|
+
return void 0 !== value && "" !== value;
|
|
33
|
+
}) : true,
|
|
34
|
+
...options
|
|
35
|
+
};
|
|
36
|
+
return useInfiniteQuery(queryOptions);
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function getPaginationParams(operationName, pageParam) {
|
|
40
|
+
switch(operationName){
|
|
41
|
+
case "ListObjects":
|
|
42
|
+
return {
|
|
43
|
+
ContinuationToken: pageParam
|
|
44
|
+
};
|
|
45
|
+
case "ListObjectVersions":
|
|
46
|
+
if (pageParam.includes("|")) {
|
|
47
|
+
const [keyMarker, versionIdMarker] = pageParam.split("|");
|
|
48
|
+
return {
|
|
49
|
+
...keyMarker && "" !== keyMarker ? {
|
|
50
|
+
KeyMarker: keyMarker
|
|
51
|
+
} : {},
|
|
52
|
+
...versionIdMarker && "" !== versionIdMarker ? {
|
|
53
|
+
VersionIdMarker: versionIdMarker
|
|
54
|
+
} : {}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
KeyMarker: pageParam
|
|
59
|
+
};
|
|
60
|
+
default:
|
|
61
|
+
return {
|
|
62
|
+
ContinuationToken: pageParam
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function getNextPageToken(operationName, lastPage) {
|
|
67
|
+
switch(operationName){
|
|
68
|
+
case "ListObjects":
|
|
69
|
+
return lastPage.IsTruncated ? lastPage.NextContinuationToken : void 0;
|
|
70
|
+
case "ListObjectVersions":
|
|
71
|
+
return lastPage.IsTruncated && (lastPage.NextKeyMarker || lastPage.NextVersionIdMarker) ? `${lastPage.NextKeyMarker || ""}|${lastPage.NextVersionIdMarker || ""}` : void 0;
|
|
72
|
+
default:
|
|
73
|
+
return lastPage.IsTruncated ? lastPage.NextContinuationToken : void 0;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export { useCreateS3InfiniteQueryHook };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { UseMutationOptions, UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
import { EnhancedS3Error } from "../../utils/errorHandling";
|
|
3
|
+
/**
|
|
4
|
+
* Factory function for creating S3 login mutation hooks
|
|
5
|
+
* This factory handles the special authentication case where we need
|
|
6
|
+
* to create a new S3 client with the provided credentials
|
|
7
|
+
*/
|
|
8
|
+
export declare function useCreateS3LoginHook<TInput extends object, TOutput>(_Command: new (input: TInput) => any, operationName: string): (options?: Omit<UseMutationOptions<TOutput, EnhancedS3Error, TInput>, "mutationFn">) => UseMutationResult<TOutput, EnhancedS3Error, TInput>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useMutation } from "@tanstack/react-query";
|
|
2
|
+
import { ListBucketsCommand } from "@aws-sdk/client-s3";
|
|
3
|
+
import { createS3OperationError } from "../../utils/errorHandling.js";
|
|
4
|
+
import { createS3Client } from "../../utils/s3Client.js";
|
|
5
|
+
function useCreateS3LoginHook(_Command, operationName) {
|
|
6
|
+
return (options)=>useMutation({
|
|
7
|
+
mutationFn: async (params)=>{
|
|
8
|
+
try {
|
|
9
|
+
const loginS3Client = createS3Client(params);
|
|
10
|
+
await loginS3Client.send(new ListBucketsCommand({}));
|
|
11
|
+
return {
|
|
12
|
+
config: params,
|
|
13
|
+
authenticated: true
|
|
14
|
+
};
|
|
15
|
+
} catch (error) {
|
|
16
|
+
throw createS3OperationError(error, operationName);
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
...options
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export { useCreateS3LoginHook };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { UseMutationOptions, UseMutationResult } from "@tanstack/react-query";
|
|
2
|
+
import { EnhancedS3Error } from "../../utils/errorHandling";
|
|
3
|
+
import { S3Client } from "@aws-sdk/client-s3";
|
|
4
|
+
export declare function useCreateS3MutationHook<TInput extends object, TOutput>(Command: new (input: TInput) => any, operationName: string, invalidationKeys?: string[]): (options?: Omit<UseMutationOptions<TOutput, EnhancedS3Error, TInput>, "mutationFn">) => UseMutationResult<TOutput, EnhancedS3Error, TInput>;
|
|
5
|
+
export declare function useCreateS3FunctionMutationHook<TInput, TOutput>(operation: (s3Client: S3Client, input: TInput) => Promise<TOutput>, invalidationKeys?: string[]): (options?: Omit<UseMutationOptions<TOutput, EnhancedS3Error, TInput>, "mutationFn">) => UseMutationResult<TOutput, EnhancedS3Error, TInput>;
|