@scality/data-browser-library 1.0.7 → 1.0.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.
Files changed (44) hide show
  1. package/dist/components/__tests__/BucketCorsPage.test.js +67 -9
  2. package/dist/components/__tests__/BucketDetails.test.js +1 -0
  3. package/dist/components/__tests__/BucketLifecycleFormPage.test.js +16 -11
  4. package/dist/components/__tests__/BucketNotificationFormPage.test.js +45 -0
  5. package/dist/components/__tests__/BucketOverview.test.js +92 -2
  6. package/dist/components/__tests__/BucketPolicyPage.test.js +70 -51
  7. package/dist/components/__tests__/BucketReplicationFormPage.test.js +18 -24
  8. package/dist/components/__tests__/ObjectList.test.js +43 -2
  9. package/dist/components/buckets/BucketConfigEditButton.d.ts +2 -0
  10. package/dist/components/buckets/BucketConfigEditButton.js +9 -3
  11. package/dist/components/buckets/BucketCorsPage.js +57 -20
  12. package/dist/components/buckets/BucketDetails.js +27 -2
  13. package/dist/components/buckets/BucketLifecycleFormPage.js +310 -270
  14. package/dist/components/buckets/BucketOverview.js +21 -18
  15. package/dist/components/buckets/BucketPolicyPage.js +119 -83
  16. package/dist/components/buckets/BucketReplicationFormPage.js +39 -29
  17. package/dist/components/buckets/BucketVersioning.js +16 -10
  18. package/dist/components/buckets/__tests__/BucketVersioning.test.js +76 -23
  19. package/dist/components/buckets/notifications/BucketNotificationFormPage.js +13 -5
  20. package/dist/components/objects/ObjectList.js +22 -25
  21. package/dist/components/objects/ObjectLock/EditRetentionButton.js +2 -2
  22. package/dist/components/objects/UploadButton.js +25 -15
  23. package/dist/config/__tests__/resolveBrandingTheme.test.d.ts +1 -0
  24. package/dist/config/__tests__/resolveBrandingTheme.test.js +96 -0
  25. package/dist/config/resolveBrandingTheme.d.ts +16 -0
  26. package/dist/config/resolveBrandingTheme.js +23 -0
  27. package/dist/config/types.d.ts +36 -0
  28. package/dist/hooks/factories/useCreateS3InfiniteQueryHook.js +2 -0
  29. package/dist/hooks/index.d.ts +1 -1
  30. package/dist/hooks/objectOperations.d.ts +3 -3
  31. package/dist/hooks/objectOperations.js +3 -3
  32. package/dist/hooks/useBucketConfigEditor.d.ts +4 -4
  33. package/dist/hooks/useBucketConfigEditor.js +16 -31
  34. package/dist/index.d.ts +1 -0
  35. package/dist/index.js +1 -0
  36. package/dist/test/mocks/esmOnlyModules.js +4 -0
  37. package/dist/types/index.d.ts +0 -1
  38. package/dist/utils/__tests__/proxyMiddleware.test.js +34 -0
  39. package/dist/utils/proxyMiddleware.js +2 -0
  40. package/package.json +4 -4
  41. package/dist/components/Editor.d.ts +0 -12
  42. package/dist/components/Editor.js +0 -28
  43. package/dist/types/monaco.d.ts +0 -13
  44. package/dist/types/monaco.js +0 -0
@@ -1,4 +1,4 @@
1
- import type { BeforeMount } from '@monaco-editor/react';
1
+ import type { JSONSchema7 } from 'json-schema';
2
2
  import { useForm } from 'react-hook-form';
3
3
  type FormValues = {
4
4
  content: string;
@@ -13,10 +13,9 @@ export type BucketConfigEditorConfig = {
13
13
  initialContent: string | undefined;
14
14
  defaultTemplate: string;
15
15
  isLoading: boolean;
16
- notFoundErrorNames: string[];
17
16
  errorInstance: Error | null;
18
17
  validate: (content: string) => ValidationResult;
19
- monacoSchema?: unknown;
18
+ jsonSchema?: JSONSchema7;
20
19
  };
21
20
  export type BucketConfigEditorResult = {
22
21
  bucketName: string;
@@ -24,8 +23,9 @@ export type BucketConfigEditorResult = {
24
23
  content: string;
25
24
  isCreateMode: boolean;
26
25
  isValidFormat: boolean;
27
- handleBeforeMount: BeforeMount;
26
+ jsonSchema?: JSONSchema7;
28
27
  navigateToBucket: () => void;
28
+ loadTemplate: () => void;
29
29
  };
30
30
  export declare const useBucketConfigEditor: (config: BucketConfigEditorConfig) => BucketConfigEditorResult;
31
31
  export {};
@@ -1,5 +1,6 @@
1
1
  import { useCallback, useEffect, useMemo } from "react";
2
2
  import { useForm } from "react-hook-form";
3
+ import { isNotFoundError } from "../utils/errorHandling.js";
3
4
  import { useDataBrowserNavigate } from "./useDataBrowserNavigate.js";
4
5
  const useBucketConfigEditor = (config)=>{
5
6
  const navigate = useDataBrowserNavigate();
@@ -12,12 +13,8 @@ const useBucketConfigEditor = (config)=>{
12
13
  });
13
14
  const { watch, reset } = form;
14
15
  const content = watch('content');
15
- const isCreateMode = useMemo(()=>{
16
- if (!config.errorInstance) return false;
17
- return config.notFoundErrorNames.some((name)=>config.errorInstance?.name === name);
18
- }, [
19
- config.errorInstance,
20
- config.notFoundErrorNames
16
+ const isCreateMode = useMemo(()=>isNotFoundError(config.errorInstance), [
17
+ config.errorInstance
21
18
  ]);
22
19
  const initialValue = useMemo(()=>{
23
20
  if (config.initialContent) try {
@@ -26,10 +23,9 @@ const useBucketConfigEditor = (config)=>{
26
23
  } catch {
27
24
  return config.initialContent;
28
25
  }
29
- return config.defaultTemplate;
26
+ return '';
30
27
  }, [
31
- config.initialContent,
32
- config.defaultTemplate
28
+ config.initialContent
33
29
  ]);
34
30
  useEffect(()=>{
35
31
  reset({
@@ -43,40 +39,29 @@ const useBucketConfigEditor = (config)=>{
43
39
  content,
44
40
  config.validate
45
41
  ]);
46
- const handleBeforeMount = useCallback((monaco)=>{
47
- const jsonLanguage = monaco.languages.json;
48
- if (jsonLanguage?.jsonDefaults) if (config.monacoSchema) jsonLanguage.jsonDefaults.setDiagnosticsOptions({
49
- validate: true,
50
- schemas: [
51
- {
52
- uri: 'http://myserver/schema.json',
53
- fileMatch: [
54
- '*'
55
- ],
56
- schema: config.monacoSchema
57
- }
58
- ]
59
- });
60
- else jsonLanguage.jsonDefaults.setDiagnosticsOptions({
61
- validate: true
62
- });
63
- }, [
64
- config.monacoSchema
65
- ]);
66
42
  const navigateToBucket = useCallback(()=>{
67
43
  navigate(`/buckets/${bucketName}`);
68
44
  }, [
69
45
  navigate,
70
46
  bucketName
71
47
  ]);
48
+ const loadTemplate = useCallback(()=>{
49
+ form.setValue('content', config.defaultTemplate, {
50
+ shouldDirty: true
51
+ });
52
+ }, [
53
+ form,
54
+ config.defaultTemplate
55
+ ]);
72
56
  return {
73
57
  bucketName,
74
58
  form,
75
59
  content,
76
60
  isCreateMode,
77
61
  isValidFormat,
78
- handleBeforeMount,
79
- navigateToBucket
62
+ jsonSchema: config.jsonSchema,
63
+ navigateToBucket,
64
+ loadTemplate
80
65
  };
81
66
  };
82
67
  export { useBucketConfigEditor };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './components';
2
2
  export * from './config/factory';
3
+ export * from './config/resolveBrandingTheme';
3
4
  export * from './config/types';
4
5
  export * from './hooks';
5
6
  export * from './types';
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from "./components/index.js";
2
2
  export * from "./config/factory.js";
3
+ export * from "./config/resolveBrandingTheme.js";
3
4
  export * from "./config/types.js";
4
5
  export * from "./hooks/index.js";
5
6
  export * from "./types/index.js";
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ createHighlighterCore: ()=>Promise.resolve({}),
3
+ fromHighlighter: ()=>()=>{}
4
+ };
@@ -2,7 +2,6 @@ import type { S3ClientConfig } from '@aws-sdk/client-s3';
2
2
  import type { AwsCredentialIdentity } from '@aws-sdk/types';
3
3
  import type { ProxyConfiguration, S3EventType } from '../config/types';
4
4
  export type { _Object, Bucket, BucketCannedACL, BucketLocationConstraint, CopyObjectCommandInput, CopyObjectCommandOutput, CreateBucketCommandInput, CreateBucketCommandOutput, DeleteBucketCommandInput, DeleteBucketCommandOutput, DeleteBucketCorsCommandOutput, DeleteBucketLifecycleCommandOutput, DeleteBucketPolicyCommandOutput, DeleteBucketReplicationCommandOutput, DeleteBucketTaggingCommandOutput, DeleteMarkerEntry, DeleteObjectCommandInput, DeleteObjectCommandOutput, DeleteObjectsCommandInput, DeleteObjectsCommandOutput, DeleteObjectTaggingCommandOutput, GetBucketAclCommandOutput, GetBucketCorsCommandOutput, GetBucketEncryptionCommandOutput, GetBucketLifecycleConfigurationCommandOutput, GetBucketLocationCommandInput, GetBucketLocationCommandOutput, GetBucketNotificationConfigurationCommandOutput, GetBucketPolicyCommandOutput, GetBucketReplicationCommandOutput, GetBucketTaggingCommandOutput, GetBucketVersioningCommandOutput, GetObjectAclCommandOutput, GetObjectAttributesCommandInput, GetObjectAttributesCommandOutput, GetObjectCommandInput, GetObjectCommandOutput, GetObjectLegalHoldCommandOutput, GetObjectLockConfigurationCommandOutput, GetObjectRetentionCommandOutput, GetObjectTaggingCommandOutput, GetObjectTorrentCommandOutput, HeadObjectCommandInput, HeadObjectCommandOutput, ListBucketsCommandOutput, ListMultipartUploadsCommandInput, ListMultipartUploadsCommandOutput, ListObjectsV2CommandInput, ListObjectsV2CommandOutput, ListObjectVersionsCommandInput, ListObjectVersionsCommandOutput, ObjectCannedACL, ObjectVersion, Owner, PutBucketAclCommandInput, PutBucketCorsCommandInput, PutBucketEncryptionCommandInput, PutBucketLifecycleConfigurationCommandInput, PutBucketNotificationConfigurationCommandInput, PutBucketPolicyCommandInput, PutBucketReplicationCommandInput, PutBucketTaggingCommandInput, PutBucketTaggingCommandOutput, PutBucketVersioningCommandInput, PutObjectAclCommandInput, PutObjectCommandInput, PutObjectCommandOutput, PutObjectLegalHoldCommandInput, PutObjectLockConfigurationCommandInput, PutObjectRetentionCommandInput, PutObjectTaggingCommandInput, RestoreObjectCommandInput, RestoreObjectCommandOutput, SelectObjectContentCommandInput, SelectObjectContentCommandOutput, Tag, } from '@aws-sdk/client-s3';
5
- export type { MonacoJsonDefaults, MonacoLanguagesJson } from './monaco';
6
5
  /**
7
6
  * S3 backend capabilities configuration.
8
7
  */
@@ -333,12 +333,45 @@ describe('createProxyMiddleware', ()=>{
333
333
  expect(mockRequest.protocol).toBe('http:');
334
334
  expect(mockRequest.path).toBe('/api/s3/bucket/key');
335
335
  expect(mockRequest.headers.host).toBe('localhost:3000');
336
+ expect(mockRequest.headers['x-s3-target-endpoint']).toBe('https://s3.amazonaws.com');
336
337
  expect(mockRequest.query).toEqual({
337
338
  param: 'value'
338
339
  });
339
340
  expect(mockRequest.headers.authorization).toBe('AWS4-HMAC-SHA256 Credential=...');
340
341
  expect(mockNext).toHaveBeenCalledTimes(1);
341
342
  });
343
+ it('should set X-S3-Target-Endpoint header with custom port', async ()=>{
344
+ const mockNext = jest.fn().mockResolvedValue({
345
+ output: {}
346
+ });
347
+ const mockStack = {
348
+ add: jest.fn((middleware, config)=>{
349
+ if ('finalizeRequest' === config.step) mockStack.postSigningMiddleware = middleware;
350
+ }),
351
+ postSigningMiddleware: null
352
+ };
353
+ const middleware = createProxyMiddleware({
354
+ enabled: true,
355
+ endpoint: 'http://localhost:3000/api/s3',
356
+ target: 'http://s3.local:9000'
357
+ });
358
+ middleware.applyToStack(mockStack);
359
+ const postSigningMiddleware = mockStack.postSigningMiddleware(mockNext);
360
+ const mockRequest = new HttpRequest({
361
+ hostname: 's3.local',
362
+ port: 9000,
363
+ path: '/bucket/key',
364
+ protocol: 'http:',
365
+ headers: {
366
+ host: 's3.local:9000'
367
+ }
368
+ });
369
+ await postSigningMiddleware({
370
+ request: mockRequest,
371
+ input: {}
372
+ });
373
+ expect(mockRequest.headers['x-s3-target-endpoint']).toBe('http://s3.local:9000');
374
+ });
342
375
  it('should preserve authorization header when routing through proxy', async ()=>{
343
376
  const mockNext = jest.fn().mockResolvedValue({
344
377
  output: {}
@@ -574,6 +607,7 @@ describe('createProxyMiddleware', ()=>{
574
607
  expect(mockRequest.hostname).toBe(originalHostname);
575
608
  expect(mockRequest.path).toBe(originalPath);
576
609
  expect(mockRequest.port).toBe(originalPort);
610
+ expect(mockRequest.headers['x-s3-target-endpoint']).toBeUndefined();
577
611
  });
578
612
  });
579
613
  });
@@ -52,6 +52,7 @@ const createProxyMiddleware = (config)=>{
52
52
  const resolvedProxyEndpoint = resolveProxyEndpoint(config.endpoint);
53
53
  const target = parseEndpoint(config.target);
54
54
  const proxy = parseEndpoint(resolvedProxyEndpoint);
55
+ const targetEndpointUrl = `${target.protocol}//${target.hostname}${80 !== target.port && 443 !== target.port ? `:${target.port}` : ''}`;
55
56
  return {
56
57
  applyToStack: (clientStack)=>{
57
58
  const preSigningMiddleware = (next)=>async (args)=>{
@@ -90,6 +91,7 @@ const createProxyMiddleware = (config)=>{
90
91
  request.protocol = proxy.protocol;
91
92
  request.path = '' === proxy.pathname || '/' === proxy.pathname ? request.path : proxy.pathname + request.path;
92
93
  request.headers.host = proxy.port && 80 !== proxy.port && 443 !== proxy.port ? `${proxy.hostname}:${proxy.port}` : proxy.hostname;
94
+ request.headers['x-s3-target-endpoint'] = targetEndpointUrl;
93
95
  request.query = queryParams;
94
96
  }
95
97
  return next(args);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scality/data-browser-library",
3
- "version": "1.0.7",
3
+ "version": "1.0.9",
4
4
  "description": "A modular React component library for browsing S3 buckets and objects",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -30,8 +30,7 @@
30
30
  "@aws-sdk/s3-presigned-post": "^3.983.0",
31
31
  "@aws-sdk/s3-request-presigner": "^3.983.0",
32
32
  "@hookform/resolvers": "^5.2.2",
33
- "@monaco-editor/react": "^4.7.0",
34
- "@scality/zenkoclient": "^2.0.0-preview.1",
33
+ "@scality/cloudserverclient": "^1.0.4",
35
34
  "@tanstack/react-query": "^5.8.0",
36
35
  "@tanstack/react-query-devtools": "^5.8.0",
37
36
  "@testing-library/user-event": "^14.6.1",
@@ -40,7 +39,7 @@
40
39
  "react-hook-form": "^7.48.0"
41
40
  },
42
41
  "peerDependencies": {
43
- "@scality/core-ui": ">=0.197.0",
42
+ "@scality/core-ui": ">=0.202.0",
44
43
  "react": ">=18.0.0",
45
44
  "react-dom": ">=18.0.0",
46
45
  "react-router": ">=7.1.3",
@@ -54,6 +53,7 @@
54
53
  "@testing-library/react": "^15.0.6",
55
54
  "@testing-library/user-event": "^14.6.1",
56
55
  "@types/jest": "^30.0.0",
56
+ "@types/json-schema": "^7.0.15",
57
57
  "@types/react": "^18.2.0",
58
58
  "@types/react-dom": "^18.2.0",
59
59
  "@types/styled-components": "^5.1.34",
@@ -1,12 +0,0 @@
1
- import { type BeforeMount, type EditorProps } from '@monaco-editor/react';
2
- interface EditorComponentProps {
3
- value: string;
4
- onChange: (value: string | undefined) => void;
5
- readOnly?: boolean;
6
- language?: string;
7
- height?: string;
8
- width?: string;
9
- beforeMount?: BeforeMount;
10
- }
11
- export declare const Editor: React.FC<EditorComponentProps & EditorProps>;
12
- export {};
@@ -1,28 +0,0 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import react from "@monaco-editor/react";
3
- const Editor = ({ value, onChange, readOnly = false, language = 'json', height = '400px', width = '100%', beforeMount, ...rest })=>{
4
- const editorTheme = 'vs-dark';
5
- return /*#__PURE__*/ jsx(react, {
6
- height: height,
7
- width: width,
8
- language: language,
9
- value: value,
10
- theme: editorTheme,
11
- onChange: onChange,
12
- options: {
13
- readOnly,
14
- scrollBeyondLastLine: false,
15
- minimap: {
16
- enabled: false
17
- },
18
- fontSize: 12,
19
- lineNumbers: 'on',
20
- automaticLayout: true,
21
- formatOnPaste: true,
22
- formatOnType: true
23
- },
24
- beforeMount: beforeMount,
25
- ...rest
26
- });
27
- };
28
- export { Editor };
@@ -1,13 +0,0 @@
1
- export interface MonacoJsonDefaults {
2
- setDiagnosticsOptions(options: {
3
- validate: boolean;
4
- schemas?: Array<{
5
- uri: string;
6
- fileMatch: string[];
7
- schema: unknown;
8
- }>;
9
- }): void;
10
- }
11
- export interface MonacoLanguagesJson {
12
- jsonDefaults: MonacoJsonDefaults;
13
- }
File without changes