@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.
Files changed (287) hide show
  1. package/dist/components/DataBrowserUI.d.ts +12 -0
  2. package/dist/components/DataBrowserUI.js +99 -0
  3. package/dist/components/Editor.d.ts +1 -1
  4. package/dist/components/Editor.js +3 -3
  5. package/dist/components/__tests__/BucketAccessor.test.js +214 -0
  6. package/dist/components/__tests__/BucketCorsPage.test.d.ts +1 -0
  7. package/dist/components/__tests__/BucketCorsPage.test.js +263 -0
  8. package/dist/components/__tests__/BucketCreate.test.js +271 -105
  9. package/dist/components/__tests__/BucketDetails.test.d.ts +1 -0
  10. package/dist/components/__tests__/BucketDetails.test.js +421 -0
  11. package/dist/components/__tests__/BucketLifecycleFormPage.test.d.ts +13 -0
  12. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +178 -178
  13. package/dist/components/__tests__/BucketLifecycleList.test.js +85 -85
  14. package/dist/components/__tests__/BucketList.test.js +463 -239
  15. package/dist/components/__tests__/BucketNotificationFormPage.test.d.ts +1 -0
  16. package/dist/components/__tests__/BucketNotificationFormPage.test.js +348 -0
  17. package/dist/components/__tests__/BucketNotificationList.test.d.ts +1 -0
  18. package/dist/components/__tests__/BucketNotificationList.test.js +379 -0
  19. package/dist/components/__tests__/BucketOverview.test.js +281 -266
  20. package/dist/components/__tests__/BucketPolicyPage.test.js +151 -99
  21. package/dist/components/__tests__/BucketReplicationFormPage.test.d.ts +15 -0
  22. package/dist/components/__tests__/BucketReplicationFormPage.test.js +544 -544
  23. package/dist/components/__tests__/BucketReplicationList.test.js +106 -106
  24. package/dist/components/__tests__/CreateFolderButton.test.js +56 -56
  25. package/dist/components/__tests__/DeleteBucketButton.test.js +64 -64
  26. package/dist/components/__tests__/DeleteBucketConfigRuleButton.test.js +47 -47
  27. package/dist/components/__tests__/DeleteObjectButton.test.js +64 -64
  28. package/dist/components/__tests__/EmptyBucketButton.test.js +59 -59
  29. package/dist/components/__tests__/MetadataSearch.test.js +65 -65
  30. package/dist/components/__tests__/ObjectList.test.js +741 -240
  31. package/dist/components/__tests__/UploadButton.test.js +45 -45
  32. package/dist/components/breadcrumb/Breadcrumb.d.ts +6 -0
  33. package/dist/components/breadcrumb/Breadcrumb.js +37 -0
  34. package/dist/components/breadcrumb/DataBrowserBreadcrumb.d.ts +1 -0
  35. package/dist/components/breadcrumb/DataBrowserBreadcrumb.js +10 -0
  36. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.d.ts +1 -0
  37. package/dist/components/breadcrumb/__tests__/Breadcrumb.test.js +196 -0
  38. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.d.ts +1 -0
  39. package/dist/components/breadcrumb/__tests__/DataBrowserBreadcrumb.test.js +153 -0
  40. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.d.ts +1 -0
  41. package/dist/components/breadcrumb/__tests__/useBreadcrumbPaths.test.js +134 -0
  42. package/dist/components/breadcrumb/index.d.ts +8 -0
  43. package/dist/components/breadcrumb/index.js +4 -0
  44. package/dist/components/breadcrumb/useBreadcrumbPaths.d.ts +2 -0
  45. package/dist/components/breadcrumb/useBreadcrumbPaths.js +82 -0
  46. package/dist/components/buckets/BucketAccessor.d.ts +2 -0
  47. package/dist/components/buckets/BucketAccessor.js +125 -0
  48. package/dist/components/buckets/BucketConfigEditButton.d.ts +8 -0
  49. package/dist/components/buckets/{BucketPolicyButton.js → BucketConfigEditButton.js} +9 -5
  50. package/dist/components/buckets/BucketCorsPage.d.ts +1 -0
  51. package/dist/components/buckets/BucketCorsPage.js +234 -0
  52. package/dist/components/buckets/BucketCreate.d.ts +3 -2
  53. package/dist/components/buckets/BucketCreate.js +93 -47
  54. package/dist/components/buckets/BucketDetails.d.ts +42 -0
  55. package/dist/components/buckets/BucketDetails.js +249 -85
  56. package/dist/components/buckets/BucketLifecycleFormPage.js +225 -191
  57. package/dist/components/buckets/BucketLifecycleList.d.ts +2 -2
  58. package/dist/components/buckets/BucketLifecycleList.js +59 -61
  59. package/dist/components/buckets/BucketList.d.ts +7 -8
  60. package/dist/components/buckets/BucketList.js +158 -101
  61. package/dist/components/buckets/BucketLocation.js +4 -4
  62. package/dist/components/buckets/BucketOverview.d.ts +22 -2
  63. package/dist/components/buckets/BucketOverview.js +394 -187
  64. package/dist/components/buckets/BucketPage.js +43 -21
  65. package/dist/components/buckets/BucketPolicyPage.js +155 -127
  66. package/dist/components/buckets/BucketReplicationFormPage.js +134 -133
  67. package/dist/components/buckets/BucketReplicationList.d.ts +2 -2
  68. package/dist/components/buckets/BucketReplicationList.js +48 -45
  69. package/dist/components/buckets/BucketVersioning.d.ts +4 -0
  70. package/dist/components/buckets/BucketVersioning.js +76 -0
  71. package/dist/components/buckets/DeleteBucketButton.js +8 -8
  72. package/dist/components/buckets/DeleteBucketConfigRuleButton.d.ts +2 -2
  73. package/dist/components/buckets/DeleteBucketConfigRuleButton.js +2 -2
  74. package/dist/components/buckets/EmptyBucketButton.js +24 -24
  75. package/dist/components/buckets/EmptyBucketSummary.d.ts +2 -2
  76. package/dist/components/buckets/EmptyBucketSummary.js +1 -1
  77. package/dist/components/buckets/EmptyBucketSummaryList.d.ts +1 -1
  78. package/dist/components/buckets/EmptyBucketSummaryList.js +22 -22
  79. package/dist/components/buckets/__tests__/BucketVersioning.test.d.ts +1 -0
  80. package/dist/components/buckets/__tests__/BucketVersioning.test.js +163 -0
  81. package/dist/components/buckets/notifications/BucketNotificationFormPage.d.ts +1 -0
  82. package/dist/components/buckets/notifications/BucketNotificationFormPage.js +316 -0
  83. package/dist/components/buckets/notifications/BucketNotificationList.d.ts +10 -0
  84. package/dist/components/buckets/notifications/BucketNotificationList.js +267 -0
  85. package/dist/components/buckets/notifications/EventsSection.js +145 -29
  86. package/dist/components/buckets/notifications/__tests__/events.test.d.ts +1 -0
  87. package/dist/components/buckets/notifications/__tests__/events.test.js +56 -0
  88. package/dist/components/buckets/notifications/events.d.ts +71 -7
  89. package/dist/components/buckets/notifications/events.js +98 -16
  90. package/dist/components/index.d.ts +27 -20
  91. package/dist/components/index.js +17 -10
  92. package/dist/components/layouts/ArrowNavigation.d.ts +3 -0
  93. package/dist/components/layouts/ArrowNavigation.js +28 -0
  94. package/dist/components/layouts/BrowserPageLayout.d.ts +5 -1
  95. package/dist/components/layouts/BrowserPageLayout.js +10 -5
  96. package/dist/components/objects/CreateFolderButton.d.ts +2 -2
  97. package/dist/components/objects/CreateFolderButton.js +12 -12
  98. package/dist/components/objects/DeleteObjectButton.d.ts +1 -1
  99. package/dist/components/objects/DeleteObjectButton.js +19 -21
  100. package/dist/components/objects/GetPresignedUrlButton.d.ts +7 -0
  101. package/dist/components/objects/GetPresignedUrlButton.js +255 -0
  102. package/dist/components/objects/ObjectDetails/ObjectMetadata.d.ts +2 -2
  103. package/dist/components/objects/ObjectDetails/ObjectMetadata.js +289 -230
  104. package/dist/components/objects/ObjectDetails/ObjectSummary.d.ts +2 -2
  105. package/dist/components/objects/ObjectDetails/ObjectSummary.js +540 -138
  106. package/dist/components/objects/ObjectDetails/ObjectTags.d.ts +2 -2
  107. package/dist/components/objects/ObjectDetails/ObjectTags.js +103 -123
  108. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.d.ts +1 -0
  109. package/dist/components/objects/ObjectDetails/__tests__/ObjectDetails.test.js +516 -0
  110. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.d.ts +1 -0
  111. package/dist/components/objects/ObjectDetails/__tests__/ObjectSummary.test.js +1064 -0
  112. package/dist/components/objects/ObjectDetails/formUtils.d.ts +15 -0
  113. package/dist/components/objects/ObjectDetails/formUtils.js +7 -0
  114. package/dist/components/objects/ObjectDetails/index.d.ts +18 -2
  115. package/dist/components/objects/ObjectDetails/index.js +152 -40
  116. package/dist/components/objects/ObjectList.d.ts +12 -10
  117. package/dist/components/objects/ObjectList.js +590 -263
  118. package/dist/components/objects/ObjectLock/EditRetentionButton.js +4 -4
  119. package/dist/components/objects/ObjectLock/ObjectLockRetentionSettings.js +15 -15
  120. package/dist/components/objects/ObjectLock/ObjectLockSettings.d.ts +1 -1
  121. package/dist/components/objects/ObjectLock/ObjectLockSettings.js +32 -31
  122. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.d.ts +1 -1
  123. package/dist/components/objects/ObjectLock/ObjectLockSettingsUtils.js +6 -6
  124. package/dist/components/objects/ObjectLock/__tests__/EditRetentionButton.test.js +51 -51
  125. package/dist/components/objects/ObjectLock/__tests__/ObjectLockSettings.test.js +78 -78
  126. package/dist/components/objects/ObjectPage.js +12 -8
  127. package/dist/components/objects/UploadButton.d.ts +3 -3
  128. package/dist/components/objects/UploadButton.js +10 -10
  129. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.d.ts +1 -0
  130. package/dist/components/objects/__tests__/GetPresignedUrlButton.test.js +531 -0
  131. package/dist/components/providers/DataBrowserProvider.d.ts +23 -12
  132. package/dist/components/providers/DataBrowserProvider.js +60 -38
  133. package/dist/components/providers/QueryProvider.d.ts +9 -0
  134. package/dist/components/providers/QueryProvider.js +21 -0
  135. package/dist/components/search/MetadataSearch.js +29 -28
  136. package/dist/components/search/SearchHints.js +1 -1
  137. package/dist/components/ui/ArrayFieldActions.js +12 -7
  138. package/dist/components/ui/ConfirmDeleteRuleModal.d.ts +2 -2
  139. package/dist/components/ui/ConfirmDeleteRuleModal.js +6 -1
  140. package/dist/components/ui/DeleteObjectModalContent.d.ts +1 -1
  141. package/dist/components/ui/DeleteObjectModalContent.js +12 -12
  142. package/dist/components/ui/FilterFormSection.d.ts +2 -2
  143. package/dist/components/ui/FilterFormSection.js +29 -29
  144. package/dist/components/ui/Search.elements.d.ts +2 -2
  145. package/dist/components/ui/Search.elements.js +7 -7
  146. package/dist/components/ui/Table.elements.d.ts +2 -1
  147. package/dist/components/ui/Table.elements.js +18 -12
  148. package/dist/config/__tests__/factory.test.d.ts +1 -0
  149. package/dist/config/__tests__/factory.test.js +311 -0
  150. package/dist/config/factory.d.ts +10 -56
  151. package/dist/config/factory.js +23 -71
  152. package/dist/config/types.d.ts +212 -34
  153. package/dist/contexts/DataBrowserUICustomizationContext.d.ts +27 -0
  154. package/dist/contexts/DataBrowserUICustomizationContext.js +13 -0
  155. package/dist/hooks/__tests__/useAccessibleBuckets.test.d.ts +1 -0
  156. package/dist/hooks/__tests__/useAccessibleBuckets.test.js +145 -0
  157. package/dist/hooks/__tests__/useISVBucketDetection.test.js +45 -45
  158. package/dist/hooks/__tests__/useIsBucketEmpty.test.js +27 -27
  159. package/dist/hooks/__tests__/useLoginMutation.test.d.ts +1 -0
  160. package/dist/hooks/__tests__/useLoginMutation.test.js +194 -0
  161. package/dist/hooks/bucketConfiguration.d.ts +8 -1
  162. package/dist/hooks/bucketConfiguration.js +52 -51
  163. package/dist/hooks/bucketOperations.d.ts +10 -1
  164. package/dist/hooks/bucketOperations.js +10 -9
  165. package/dist/hooks/factories/__tests__/useCreateS3FunctionMutationHook.test.js +80 -80
  166. package/dist/hooks/factories/__tests__/useCreateS3InfiniteQueryHook.test.js +80 -80
  167. package/dist/hooks/factories/__tests__/useCreateS3LoginHook.test.js +44 -44
  168. package/dist/hooks/factories/__tests__/useCreateS3MutationHook.test.js +63 -63
  169. package/dist/hooks/factories/__tests__/useCreateS3QueryHook.test.js +65 -65
  170. package/dist/hooks/factories/index.d.ts +4 -4
  171. package/dist/hooks/factories/index.js +2 -2
  172. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.d.ts +2 -2
  173. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +16 -13
  174. package/dist/hooks/factories/useCreateS3LoginHook.d.ts +2 -2
  175. package/dist/hooks/factories/useCreateS3LoginHook.js +1 -1
  176. package/dist/hooks/factories/useCreateS3MutationHook.d.ts +3 -3
  177. package/dist/hooks/factories/useCreateS3MutationHook.js +7 -2
  178. package/dist/hooks/factories/useCreateS3QueryHook.d.ts +2 -2
  179. package/dist/hooks/factories/useCreateS3QueryHook.js +11 -6
  180. package/dist/hooks/index.d.ts +19 -12
  181. package/dist/hooks/index.js +16 -9
  182. package/dist/hooks/loginOperations.d.ts +1 -1
  183. package/dist/hooks/loginOperations.js +1 -1
  184. package/dist/hooks/objectOperations.d.ts +2 -2
  185. package/dist/hooks/objectOperations.js +50 -49
  186. package/dist/hooks/presignedOperations.d.ts +4 -4
  187. package/dist/hooks/presignedOperations.js +5 -5
  188. package/dist/hooks/useAccessibleBuckets.d.ts +11 -0
  189. package/dist/hooks/useAccessibleBuckets.js +115 -0
  190. package/dist/hooks/useBatchObjectLegalHold.d.ts +11 -0
  191. package/dist/hooks/useBatchObjectLegalHold.js +48 -0
  192. package/dist/hooks/useBucketConfigEditor.d.ts +31 -0
  193. package/dist/hooks/useBucketConfigEditor.js +82 -0
  194. package/dist/hooks/useDataBrowserNavigate.d.ts +28 -0
  195. package/dist/hooks/useDataBrowserNavigate.js +24 -0
  196. package/dist/hooks/useDeleteBucketConfigRule.d.ts +2 -2
  197. package/dist/hooks/useDeleteBucketConfigRule.js +4 -4
  198. package/dist/hooks/useEmptyBucket.js +11 -11
  199. package/dist/hooks/useFeatures.d.ts +7 -0
  200. package/dist/hooks/useFeatures.js +8 -0
  201. package/dist/hooks/useISVBucketDetection.js +6 -6
  202. package/dist/hooks/useIsBucketEmpty.js +4 -4
  203. package/dist/hooks/useLimitedAccessFlow.d.ts +48 -0
  204. package/dist/hooks/useLimitedAccessFlow.js +23 -0
  205. package/dist/hooks/useS3Client.d.ts +6 -0
  206. package/dist/hooks/useS3Client.js +3 -2
  207. package/dist/hooks/useS3ConfigSwitch.d.ts +11 -0
  208. package/dist/hooks/useS3ConfigSwitch.js +37 -0
  209. package/dist/hooks/useSupportedNotificationEvents.d.ts +6 -0
  210. package/dist/hooks/useSupportedNotificationEvents.js +8 -0
  211. package/dist/index.d.ts +6 -6
  212. package/dist/index.js +2 -2
  213. package/dist/schemas/bucketPolicySchema.json +3 -13
  214. package/dist/test/msw/handlers/deleteBucket.d.ts +1 -1
  215. package/dist/test/msw/handlers/deleteBucket.js +20 -10
  216. package/dist/test/msw/handlers/getBucketAcl.d.ts +1 -1
  217. package/dist/test/msw/handlers/getBucketAcl.js +29 -17
  218. package/dist/test/msw/handlers/getBucketLocation.d.ts +1 -1
  219. package/dist/test/msw/handlers/getBucketLocation.js +29 -15
  220. package/dist/test/msw/handlers/getBucketPolicy.d.ts +1 -1
  221. package/dist/test/msw/handlers/getBucketPolicy.js +52 -32
  222. package/dist/test/msw/handlers/headObject.d.ts +1 -1
  223. package/dist/test/msw/handlers/headObject.js +31 -13
  224. package/dist/test/msw/handlers/listBuckets.d.ts +1 -1
  225. package/dist/test/msw/handlers/listBuckets.js +5 -3
  226. package/dist/test/msw/handlers/listObjectVersions.d.ts +1 -1
  227. package/dist/test/msw/handlers/listObjectVersions.js +38 -26
  228. package/dist/test/msw/handlers/listObjects.d.ts +1 -1
  229. package/dist/test/msw/handlers/listObjects.js +35 -23
  230. package/dist/test/msw/handlers/objectLegalHold.d.ts +1 -1
  231. package/dist/test/msw/handlers/objectLegalHold.js +32 -17
  232. package/dist/test/msw/handlers/objectRetention.d.ts +1 -1
  233. package/dist/test/msw/handlers/objectRetention.js +31 -17
  234. package/dist/test/msw/handlers/putBucketAcl.d.ts +1 -1
  235. package/dist/test/msw/handlers/putBucketAcl.js +29 -14
  236. package/dist/test/msw/handlers/putObject.d.ts +1 -1
  237. package/dist/test/msw/handlers/putObject.js +27 -12
  238. package/dist/test/msw/handlers.d.ts +3 -3
  239. package/dist/test/msw/handlers.js +77 -54
  240. package/dist/test/msw/index.d.ts +2 -2
  241. package/dist/test/msw/index.js +1 -1
  242. package/dist/test/msw/server.d.ts +1 -1
  243. package/dist/test/msw/server.js +1 -1
  244. package/dist/test/msw/utils.js +2 -2
  245. package/dist/test/setup.d.ts +1 -1
  246. package/dist/test/setup.js +13 -30
  247. package/dist/test/testUtils.d.ts +85 -33
  248. package/dist/test/testUtils.js +176 -111
  249. package/dist/test/utils/errorHandling.test.js +119 -119
  250. package/dist/types/index.d.ts +50 -37
  251. package/dist/types/monaco.d.ts +13 -0
  252. package/dist/types/monaco.js +0 -0
  253. package/dist/utils/__tests__/proxyMiddleware.test.d.ts +1 -0
  254. package/dist/utils/__tests__/proxyMiddleware.test.js +579 -0
  255. package/dist/utils/__tests__/s3Client.test.d.ts +1 -0
  256. package/dist/utils/__tests__/s3Client.test.js +340 -0
  257. package/dist/utils/__tests__/s3ConfigIdentifier.test.d.ts +1 -0
  258. package/dist/utils/__tests__/s3ConfigIdentifier.test.js +437 -0
  259. package/dist/utils/constants.d.ts +10 -0
  260. package/dist/utils/constants.js +19 -9
  261. package/dist/utils/deletion/index.d.ts +2 -2
  262. package/dist/utils/deletion/index.js +1 -1
  263. package/dist/utils/deletion/messages.d.ts +1 -1
  264. package/dist/utils/deletion/messages.js +4 -4
  265. package/dist/utils/errorHandling.d.ts +3 -3
  266. package/dist/utils/errorHandling.js +6 -6
  267. package/dist/utils/hooks.js +8 -8
  268. package/dist/utils/index.d.ts +5 -4
  269. package/dist/utils/index.js +4 -2
  270. package/dist/utils/proxyMiddleware.d.ts +32 -13
  271. package/dist/utils/proxyMiddleware.js +90 -36
  272. package/dist/utils/s3Client.d.ts +14 -4
  273. package/dist/utils/s3Client.js +5 -26
  274. package/dist/utils/s3ConfigIdentifier.d.ts +79 -0
  275. package/dist/utils/s3ConfigIdentifier.js +57 -0
  276. package/dist/utils/s3RuleUtils.d.ts +5 -5
  277. package/dist/utils/s3RuleUtils.js +17 -17
  278. package/package.json +10 -8
  279. package/dist/components/__tests__/BucketNotificationCreatePage.test.js +0 -316
  280. package/dist/components/buckets/BucketPolicyButton.d.ts +0 -7
  281. package/dist/components/buckets/notifications/BucketNotificationCreatePage.d.ts +0 -1
  282. package/dist/components/buckets/notifications/BucketNotificationCreatePage.js +0 -234
  283. package/dist/hooks/useLoginMutation.d.ts +0 -21
  284. package/dist/hooks/useLoginMutation.js +0 -9
  285. package/dist/utils/useFeatures.d.ts +0 -1
  286. package/dist/utils/useFeatures.js +0 -7
  287. /package/dist/components/__tests__/{BucketNotificationCreatePage.test.d.ts → BucketAccessor.test.d.ts} +0 -0
@@ -0,0 +1,579 @@
1
+ import { HttpRequest } from "@aws-sdk/protocol-http";
2
+ import { createProxyMiddleware, resolveProxyEndpoint } from "../proxyMiddleware.js";
3
+ describe('resolveProxyEndpoint', ()=>{
4
+ it('should return full URL unchanged', ()=>{
5
+ expect(resolveProxyEndpoint('http://localhost:3000/api/s3')).toBe('http://localhost:3000/api/s3');
6
+ expect(resolveProxyEndpoint('https://proxy.example.com:8443/s3')).toBe('https://proxy.example.com:8443/s3');
7
+ });
8
+ it('should resolve origin-relative path using window.location.origin', ()=>{
9
+ const resolved = resolveProxyEndpoint('/zenko/s3');
10
+ expect(resolved).toContain('/zenko/s3');
11
+ expect(resolved.startsWith('http')).toBe(true);
12
+ });
13
+ it('should resolve "origin" keyword using window.location.origin', ()=>{
14
+ const resolved = resolveProxyEndpoint('origin');
15
+ expect(resolved.startsWith('http')).toBe(true);
16
+ expect(resolved.split('://')[1]).not.toContain('/');
17
+ });
18
+ });
19
+ describe('createProxyMiddleware', ()=>{
20
+ describe('Configuration validation', ()=>{
21
+ it('should create middleware with https target endpoint', ()=>{
22
+ const middleware = createProxyMiddleware({
23
+ enabled: true,
24
+ endpoint: 'http://localhost:3000/api/s3',
25
+ target: 'https://s3.amazonaws.com'
26
+ });
27
+ expect(middleware).toBeDefined();
28
+ expect(middleware.applyToStack).toBeInstanceOf(Function);
29
+ });
30
+ it('should create middleware with custom port in target endpoint', ()=>{
31
+ const middleware = createProxyMiddleware({
32
+ enabled: true,
33
+ endpoint: 'http://localhost:8080/proxy',
34
+ target: 'https://s3.amazonaws.com:9000'
35
+ });
36
+ expect(middleware).toBeDefined();
37
+ expect(middleware.applyToStack).toBeInstanceOf(Function);
38
+ });
39
+ it('should create middleware with path in proxy endpoint', ()=>{
40
+ const middleware = createProxyMiddleware({
41
+ enabled: true,
42
+ endpoint: 'http://localhost:3000/api/s3',
43
+ target: 'https://s3.amazonaws.com'
44
+ });
45
+ expect(middleware).toBeDefined();
46
+ expect(middleware.applyToStack).toBeInstanceOf(Function);
47
+ });
48
+ it('should create middleware with hostname-only target', ()=>{
49
+ const middleware = createProxyMiddleware({
50
+ enabled: true,
51
+ endpoint: 'http://localhost:3000/api/s3',
52
+ target: 's3.pod-choco.local'
53
+ });
54
+ expect(middleware).toBeDefined();
55
+ expect(middleware.applyToStack).toBeInstanceOf(Function);
56
+ });
57
+ });
58
+ describe('Middleware stack integration', ()=>{
59
+ it('should add two middlewares to the stack', ()=>{
60
+ const mockStack = {
61
+ add: jest.fn()
62
+ };
63
+ const middleware = createProxyMiddleware({
64
+ enabled: true,
65
+ endpoint: 'http://localhost:3000/api/s3',
66
+ target: 'https://s3.amazonaws.com'
67
+ });
68
+ middleware.applyToStack(mockStack);
69
+ expect(mockStack.add).toHaveBeenCalledTimes(2);
70
+ expect(mockStack.add).toHaveBeenNthCalledWith(1, expect.any(Function), expect.objectContaining({
71
+ step: 'build',
72
+ name: 'proxyPreSigningMiddleware',
73
+ priority: 'high'
74
+ }));
75
+ expect(mockStack.add).toHaveBeenNthCalledWith(2, expect.any(Function), expect.objectContaining({
76
+ step: 'finalizeRequest',
77
+ name: 'proxyPostSigningMiddleware',
78
+ priority: 'high'
79
+ }));
80
+ });
81
+ });
82
+ describe('Pre-signing middleware', ()=>{
83
+ it('should modify request to use real S3 host for signing', async ()=>{
84
+ const mockNext = jest.fn().mockResolvedValue({
85
+ output: {}
86
+ });
87
+ const mockStack = {
88
+ add: jest.fn((middleware, config)=>{
89
+ if ('build' === config.step) mockStack.preSigningMiddleware = middleware;
90
+ }),
91
+ preSigningMiddleware: null
92
+ };
93
+ const middleware = createProxyMiddleware({
94
+ enabled: true,
95
+ endpoint: 'http://localhost:3000/api/s3',
96
+ target: 'https://s3.amazonaws.com'
97
+ });
98
+ middleware.applyToStack(mockStack);
99
+ const preSigningMiddleware = mockStack.preSigningMiddleware(mockNext);
100
+ const mockRequest = new HttpRequest({
101
+ hostname: 'localhost',
102
+ port: 3000,
103
+ path: '/api/s3/bucket/key',
104
+ protocol: 'http:',
105
+ headers: {
106
+ host: 'localhost:3000'
107
+ },
108
+ query: {
109
+ param: 'value'
110
+ }
111
+ });
112
+ await preSigningMiddleware({
113
+ request: mockRequest,
114
+ input: {}
115
+ });
116
+ expect(mockRequest.hostname).toBe('s3.amazonaws.com');
117
+ expect(mockRequest.port).toBe(443);
118
+ expect(mockRequest.protocol).toBe('https:');
119
+ expect(mockRequest.headers.host).toBe('s3.amazonaws.com');
120
+ expect(mockRequest.query).toEqual({
121
+ param: 'value'
122
+ });
123
+ expect(mockNext).toHaveBeenCalledTimes(1);
124
+ expect(mockNext).toHaveBeenCalledWith({
125
+ request: mockRequest,
126
+ input: {}
127
+ });
128
+ });
129
+ it('should remove proxy path prefix from request path before signing', async ()=>{
130
+ const mockNext = jest.fn().mockResolvedValue({
131
+ output: {}
132
+ });
133
+ const mockStack = {
134
+ add: jest.fn((middleware, config)=>{
135
+ if ('build' === config.step) mockStack.preSigningMiddleware = middleware;
136
+ }),
137
+ preSigningMiddleware: null
138
+ };
139
+ const middleware = createProxyMiddleware({
140
+ enabled: true,
141
+ endpoint: 'http://localhost:3000/api/s3',
142
+ target: 'https://s3.amazonaws.com'
143
+ });
144
+ middleware.applyToStack(mockStack);
145
+ const preSigningMiddleware = mockStack.preSigningMiddleware(mockNext);
146
+ const mockRequest = new HttpRequest({
147
+ hostname: 'localhost',
148
+ path: '/api/s3/mybucket/mykey',
149
+ protocol: 'http:',
150
+ headers: {
151
+ host: 'localhost'
152
+ }
153
+ });
154
+ await preSigningMiddleware({
155
+ request: mockRequest,
156
+ input: {}
157
+ });
158
+ expect(mockRequest.path).toBe('/mybucket/mykey');
159
+ });
160
+ it('should ensure path starts with slash after removing prefix', async ()=>{
161
+ const mockNext = jest.fn().mockResolvedValue({
162
+ output: {}
163
+ });
164
+ const mockStack = {
165
+ add: jest.fn((middleware, config)=>{
166
+ if ('build' === config.step) mockStack.preSigningMiddleware = middleware;
167
+ }),
168
+ preSigningMiddleware: null
169
+ };
170
+ const middleware = createProxyMiddleware({
171
+ enabled: true,
172
+ endpoint: 'http://localhost:3000/api/s3',
173
+ target: 'https://s3.amazonaws.com'
174
+ });
175
+ middleware.applyToStack(mockStack);
176
+ const preSigningMiddleware = mockStack.preSigningMiddleware(mockNext);
177
+ const mockRequest = new HttpRequest({
178
+ hostname: 'localhost',
179
+ path: '/api/s3mybucket',
180
+ protocol: 'http:',
181
+ headers: {
182
+ host: 'localhost'
183
+ }
184
+ });
185
+ await preSigningMiddleware({
186
+ request: mockRequest,
187
+ input: {}
188
+ });
189
+ expect(mockRequest.path).toMatch(/^\//);
190
+ });
191
+ it('should preserve query parameters during pre-signing', async ()=>{
192
+ const mockNext = jest.fn().mockResolvedValue({
193
+ output: {}
194
+ });
195
+ const mockStack = {
196
+ add: jest.fn((middleware, config)=>{
197
+ if ('build' === config.step) mockStack.preSigningMiddleware = middleware;
198
+ }),
199
+ preSigningMiddleware: null
200
+ };
201
+ const middleware = createProxyMiddleware({
202
+ enabled: true,
203
+ endpoint: 'http://localhost:3000/api/s3',
204
+ target: 'https://s3.amazonaws.com'
205
+ });
206
+ middleware.applyToStack(mockStack);
207
+ const preSigningMiddleware = mockStack.preSigningMiddleware(mockNext);
208
+ const originalQuery = {
209
+ 'list-type': '2',
210
+ prefix: 'folder/',
211
+ delimiter: '/'
212
+ };
213
+ const mockRequest = new HttpRequest({
214
+ hostname: 'localhost',
215
+ path: '/api/s3/bucket',
216
+ protocol: 'http:',
217
+ headers: {
218
+ host: 'localhost'
219
+ },
220
+ query: originalQuery
221
+ });
222
+ await preSigningMiddleware({
223
+ request: mockRequest,
224
+ input: {}
225
+ });
226
+ expect(mockRequest.query).toEqual(originalQuery);
227
+ });
228
+ it('should handle custom port in real S3 endpoint', async ()=>{
229
+ const mockNext = jest.fn().mockResolvedValue({
230
+ output: {}
231
+ });
232
+ const mockStack = {
233
+ add: jest.fn((middleware, config)=>{
234
+ if ('build' === config.step) mockStack.preSigningMiddleware = middleware;
235
+ }),
236
+ preSigningMiddleware: null
237
+ };
238
+ const middleware = createProxyMiddleware({
239
+ enabled: true,
240
+ endpoint: 'http://localhost:3000/api/s3',
241
+ target: 'http://s3.local:9000'
242
+ });
243
+ middleware.applyToStack(mockStack);
244
+ const preSigningMiddleware = mockStack.preSigningMiddleware(mockNext);
245
+ const mockRequest = new HttpRequest({
246
+ hostname: 'localhost',
247
+ path: '/api/s3/bucket/key',
248
+ protocol: 'http:',
249
+ headers: {
250
+ host: 'localhost'
251
+ }
252
+ });
253
+ await preSigningMiddleware({
254
+ request: mockRequest,
255
+ input: {}
256
+ });
257
+ expect(mockRequest.hostname).toBe('s3.local');
258
+ expect(mockRequest.port).toBe(9000);
259
+ expect(mockRequest.protocol).toBe('http:');
260
+ });
261
+ it('should not modify requests not targeting proxy', async ()=>{
262
+ const mockNext = jest.fn().mockResolvedValue({
263
+ output: {}
264
+ });
265
+ const mockStack = {
266
+ add: jest.fn((middleware, config)=>{
267
+ if ('build' === config.step) mockStack.preSigningMiddleware = middleware;
268
+ }),
269
+ preSigningMiddleware: null
270
+ };
271
+ const middleware = createProxyMiddleware({
272
+ enabled: true,
273
+ endpoint: 'http://localhost:3000/api/s3',
274
+ target: 'https://s3.amazonaws.com'
275
+ });
276
+ middleware.applyToStack(mockStack);
277
+ const preSigningMiddleware = mockStack.preSigningMiddleware(mockNext);
278
+ const mockRequest = new HttpRequest({
279
+ hostname: 'different-host.com',
280
+ path: '/bucket/key',
281
+ protocol: 'https:',
282
+ headers: {
283
+ host: 'different-host.com'
284
+ }
285
+ });
286
+ const originalHostname = mockRequest.hostname;
287
+ const originalPath = mockRequest.path;
288
+ await preSigningMiddleware({
289
+ request: mockRequest,
290
+ input: {}
291
+ });
292
+ expect(mockRequest.hostname).toBe(originalHostname);
293
+ expect(mockRequest.path).toBe(originalPath);
294
+ });
295
+ });
296
+ describe('Post-signing middleware', ()=>{
297
+ it('should route signed request through proxy with correct parameters', async ()=>{
298
+ const mockNext = jest.fn().mockResolvedValue({
299
+ output: {}
300
+ });
301
+ const mockStack = {
302
+ add: jest.fn((middleware, config)=>{
303
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
304
+ }),
305
+ postSigningMiddleware: null
306
+ };
307
+ const middleware = createProxyMiddleware({
308
+ enabled: true,
309
+ endpoint: 'http://localhost:3000/api/s3',
310
+ target: 'https://s3.amazonaws.com'
311
+ });
312
+ middleware.applyToStack(mockStack);
313
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
314
+ const mockRequest = new HttpRequest({
315
+ hostname: 's3.amazonaws.com',
316
+ port: 443,
317
+ path: '/bucket/key',
318
+ protocol: 'https:',
319
+ headers: {
320
+ host: 's3.amazonaws.com',
321
+ authorization: 'AWS4-HMAC-SHA256 Credential=...'
322
+ },
323
+ query: {
324
+ param: 'value'
325
+ }
326
+ });
327
+ await postSigningMiddleware({
328
+ request: mockRequest,
329
+ input: {}
330
+ });
331
+ expect(mockRequest.hostname).toBe('localhost');
332
+ expect(mockRequest.port).toBe(3000);
333
+ expect(mockRequest.protocol).toBe('http:');
334
+ expect(mockRequest.path).toBe('/api/s3/bucket/key');
335
+ expect(mockRequest.headers.host).toBe('localhost:3000');
336
+ expect(mockRequest.query).toEqual({
337
+ param: 'value'
338
+ });
339
+ expect(mockRequest.headers.authorization).toBe('AWS4-HMAC-SHA256 Credential=...');
340
+ expect(mockNext).toHaveBeenCalledTimes(1);
341
+ });
342
+ it('should preserve authorization header when routing through proxy', async ()=>{
343
+ const mockNext = jest.fn().mockResolvedValue({
344
+ output: {}
345
+ });
346
+ const mockStack = {
347
+ add: jest.fn((middleware, config)=>{
348
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
349
+ }),
350
+ postSigningMiddleware: null
351
+ };
352
+ const middleware = createProxyMiddleware({
353
+ enabled: true,
354
+ endpoint: 'http://localhost:3000/api/s3',
355
+ target: 'https://s3.amazonaws.com'
356
+ });
357
+ middleware.applyToStack(mockStack);
358
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
359
+ const authHeader = 'AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20230101/us-east-1/s3/aws4_request';
360
+ const mockRequest = new HttpRequest({
361
+ hostname: 's3.amazonaws.com',
362
+ path: '/bucket/key',
363
+ protocol: 'https:',
364
+ headers: {
365
+ host: 's3.amazonaws.com',
366
+ authorization: authHeader
367
+ }
368
+ });
369
+ await postSigningMiddleware({
370
+ request: mockRequest,
371
+ input: {}
372
+ });
373
+ expect(mockRequest.headers.authorization).toBe(authHeader);
374
+ });
375
+ it('should correctly format host header for non-standard proxy port', async ()=>{
376
+ const mockNext = jest.fn().mockResolvedValue({
377
+ output: {}
378
+ });
379
+ const mockStack = {
380
+ add: jest.fn((middleware, config)=>{
381
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
382
+ }),
383
+ postSigningMiddleware: null
384
+ };
385
+ const middleware = createProxyMiddleware({
386
+ enabled: true,
387
+ endpoint: 'http://localhost:8080/proxy',
388
+ target: 'https://s3.amazonaws.com'
389
+ });
390
+ middleware.applyToStack(mockStack);
391
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
392
+ const mockRequest = new HttpRequest({
393
+ hostname: 's3.amazonaws.com',
394
+ path: '/bucket/key',
395
+ protocol: 'https:',
396
+ headers: {
397
+ host: 's3.amazonaws.com'
398
+ }
399
+ });
400
+ await postSigningMiddleware({
401
+ request: mockRequest,
402
+ input: {}
403
+ });
404
+ expect(mockRequest.hostname).toBe('localhost');
405
+ expect(mockRequest.port).toBe(8080);
406
+ expect(mockRequest.headers.host).toBe('localhost:8080');
407
+ });
408
+ it('should omit port from host header for http port 80', async ()=>{
409
+ const mockNext = jest.fn().mockResolvedValue({
410
+ output: {}
411
+ });
412
+ const mockStack = {
413
+ add: jest.fn((middleware, config)=>{
414
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
415
+ }),
416
+ postSigningMiddleware: null
417
+ };
418
+ const middleware = createProxyMiddleware({
419
+ enabled: true,
420
+ endpoint: 'http://proxy.example.com/api',
421
+ target: 'https://s3.amazonaws.com'
422
+ });
423
+ middleware.applyToStack(mockStack);
424
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
425
+ const mockRequest = new HttpRequest({
426
+ hostname: 's3.amazonaws.com',
427
+ path: '/bucket/key',
428
+ protocol: 'https:',
429
+ headers: {
430
+ host: 's3.amazonaws.com'
431
+ }
432
+ });
433
+ await postSigningMiddleware({
434
+ request: mockRequest,
435
+ input: {}
436
+ });
437
+ expect(mockRequest.headers.host).toBe('proxy.example.com');
438
+ expect(mockRequest.headers.host).not.toContain(':80');
439
+ });
440
+ it('should omit port from host header for https port 443', async ()=>{
441
+ const mockNext = jest.fn().mockResolvedValue({
442
+ output: {}
443
+ });
444
+ const mockStack = {
445
+ add: jest.fn((middleware, config)=>{
446
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
447
+ }),
448
+ postSigningMiddleware: null
449
+ };
450
+ const middleware = createProxyMiddleware({
451
+ enabled: true,
452
+ endpoint: 'https://proxy.example.com/api',
453
+ target: 'https://s3.amazonaws.com'
454
+ });
455
+ middleware.applyToStack(mockStack);
456
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
457
+ const mockRequest = new HttpRequest({
458
+ hostname: 's3.amazonaws.com',
459
+ path: '/bucket/key',
460
+ protocol: 'https:',
461
+ headers: {
462
+ host: 's3.amazonaws.com'
463
+ }
464
+ });
465
+ await postSigningMiddleware({
466
+ request: mockRequest,
467
+ input: {}
468
+ });
469
+ expect(mockRequest.headers.host).toBe('proxy.example.com');
470
+ expect(mockRequest.headers.host).not.toContain(':443');
471
+ });
472
+ it('should prepend proxy pathname to request path', async ()=>{
473
+ const mockNext = jest.fn().mockResolvedValue({
474
+ output: {}
475
+ });
476
+ const mockStack = {
477
+ add: jest.fn((middleware, config)=>{
478
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
479
+ }),
480
+ postSigningMiddleware: null
481
+ };
482
+ const middleware = createProxyMiddleware({
483
+ enabled: true,
484
+ endpoint: 'http://localhost:3000/my/proxy/path',
485
+ target: 'https://s3.amazonaws.com'
486
+ });
487
+ middleware.applyToStack(mockStack);
488
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
489
+ const mockRequest = new HttpRequest({
490
+ hostname: 's3.amazonaws.com',
491
+ path: '/bucket/key',
492
+ protocol: 'https:',
493
+ headers: {
494
+ host: 's3.amazonaws.com'
495
+ }
496
+ });
497
+ await postSigningMiddleware({
498
+ request: mockRequest,
499
+ input: {}
500
+ });
501
+ expect(mockRequest.path).toBe('/my/proxy/path/bucket/key');
502
+ });
503
+ it('should preserve complex query parameters', async ()=>{
504
+ const mockNext = jest.fn().mockResolvedValue({
505
+ output: {}
506
+ });
507
+ const mockStack = {
508
+ add: jest.fn((middleware, config)=>{
509
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
510
+ }),
511
+ postSigningMiddleware: null
512
+ };
513
+ const middleware = createProxyMiddleware({
514
+ enabled: true,
515
+ endpoint: 'http://localhost:3000/api/s3',
516
+ target: 'https://s3.amazonaws.com'
517
+ });
518
+ middleware.applyToStack(mockStack);
519
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
520
+ const complexQuery = {
521
+ 'list-type': '2',
522
+ prefix: 'folder/subfolder/',
523
+ delimiter: '/',
524
+ 'max-keys': '1000',
525
+ 'continuation-token': 'ABC123=='
526
+ };
527
+ const mockRequest = new HttpRequest({
528
+ hostname: 's3.amazonaws.com',
529
+ path: '/bucket',
530
+ protocol: 'https:',
531
+ headers: {
532
+ host: 's3.amazonaws.com'
533
+ },
534
+ query: complexQuery
535
+ });
536
+ await postSigningMiddleware({
537
+ request: mockRequest,
538
+ input: {}
539
+ });
540
+ expect(mockRequest.query).toEqual(complexQuery);
541
+ });
542
+ it('should not modify requests not targeting real S3 endpoint', async ()=>{
543
+ const mockNext = jest.fn().mockResolvedValue({
544
+ output: {}
545
+ });
546
+ const mockStack = {
547
+ add: jest.fn((middleware, config)=>{
548
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
549
+ }),
550
+ postSigningMiddleware: null
551
+ };
552
+ const middleware = createProxyMiddleware({
553
+ enabled: true,
554
+ endpoint: 'http://localhost:3000/api/s3',
555
+ target: 'https://s3.amazonaws.com'
556
+ });
557
+ middleware.applyToStack(mockStack);
558
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
559
+ const mockRequest = new HttpRequest({
560
+ hostname: 'other-service.com',
561
+ path: '/api/endpoint',
562
+ protocol: 'https:',
563
+ headers: {
564
+ host: 'other-service.com'
565
+ }
566
+ });
567
+ const originalHostname = mockRequest.hostname;
568
+ const originalPath = mockRequest.path;
569
+ const originalPort = mockRequest.port;
570
+ await postSigningMiddleware({
571
+ request: mockRequest,
572
+ input: {}
573
+ });
574
+ expect(mockRequest.hostname).toBe(originalHostname);
575
+ expect(mockRequest.path).toBe(originalPath);
576
+ expect(mockRequest.port).toBe(originalPort);
577
+ });
578
+ });
579
+ });
@@ -0,0 +1 @@
1
+ export {};