@verdaccio/ui-components 4.0.0-next-8.4 → 4.0.0-next-8.6
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/CHANGELOG.md +19 -0
- package/build/components/CopyClipboard/CopyToClipBoard.js +2 -2
- package/build/components/HeaderInfoDialog/HeaderInfoDialog.js +2 -2
- package/build/components/Heading/Heading.js +2 -2
- package/build/components/Help/Help.js +1 -1
- package/build/components/Icons/SvgIcon.js +2 -2
- package/build/components/Label/Label.js +2 -2
- package/build/components/LinkExternal/LinkExternal.js +2 -2
- package/build/components/NoItems/NoItems.js +2 -2
- package/build/components/Package/styles.js +13 -13
- package/build/components/Readme/Readme.spec.js +4 -2
- package/build/components/Readme/Readme.spec.js.map +1 -1
- package/build/components/Readme/utils.js +1 -1
- package/build/components/Search/Search.js +13 -2
- package/build/components/Search/SearchItem.js +2 -2
- package/build/components/TextField/TextField.js +2 -2
- package/build/components/Versions/HistoryList.js +6 -1
- package/build/components/Versions/__partials__/unsorted-versions.json +37 -0
- package/build/sections/Header/HeaderSettingsDialog.js +2 -2
- package/build/src/AppTest/App.stories.d.ts +9 -8
- package/build/src/components/Author/Author.stories.d.ts +1 -1
- package/build/src/components/Engines/Engines.stories.d.ts +1 -1
- package/build/src/components/Search/Search.d.ts +3 -1
- package/build/src/components/Search/Search.stories.d.ts +6 -8
- package/build/src/sections/Detail/Detail.stories.d.ts +8 -7
- package/build/src/sections/Header/Header.stories.d.ts +6 -5
- package/build/src/sections/Home/Home.stories.d.ts +6 -5
- package/build/src/sections/SideBar/Sidebar.stories.d.ts +7 -7
- package/build/src/store/api.d.ts +3 -0
- package/build/src/utils/token-generate.d.ts +4 -0
- package/build/store/api.js +1 -1
- package/build/store/models/routes.js +1 -1
- package/build/utils/token-generate.js +33 -0
- package/build/utils/url.js +19 -9
- package/package.json +37 -31
- package/src/AppTest/App.stories.tsx +81 -24
- package/src/AppTest/AppRoute.test.tsx +6 -2
- package/src/components/ActionBar/ActionBar.test.tsx +68 -29
- package/src/components/Author/Author.stories.tsx +1 -1
- package/src/components/Engines/Engines.stories.tsx +12 -12
- package/src/components/Help/Help.tsx +1 -1
- package/src/components/Package/Package.test.tsx +9 -0
- package/src/components/Package/styles.ts +1 -2
- package/src/components/Readme/Readme.spec.tsx +2 -2
- package/src/components/Readme/utils.ts +2 -2
- package/src/components/Search/Search.stories.tsx +24 -2
- package/src/components/Search/Search.tsx +7 -3
- package/src/components/Versions/HistoryList.tsx +10 -2
- package/src/components/Versions/Versions.test.tsx +11 -0
- package/src/components/Versions/__partials__/unsorted-versions.json +37 -0
- package/src/layouts/Version/Version.stories.tsx +26 -0
- package/src/sections/Detail/Detail.stories.tsx +52 -21
- package/src/sections/Header/Header.stories.tsx +33 -10
- package/src/sections/Home/Home.stories.tsx +25 -8
- package/src/sections/SideBar/Sidebar.stories.tsx +53 -28
- package/src/store/api.test.ts +4 -2
- package/src/store/api.ts +1 -1
- package/src/store/models/login.test.ts +25 -19
- package/src/utils/token.test.ts +2 -3
- package/src/utils/url.ts +25 -9
- package/tsconfig.build.json +2 -2
- package/tsconfig.json +3 -2
- package/vitest.config.mjs +2 -1
- package/vitest/api/glob-sidebar.json +0 -12520
- package/vitest/api/got-sidebar.json +0 -23346
- package/vitest/api/home-packages.json +0 -40
- package/vitest/api/jquery-readme.js +0 -3
- package/vitest/api/jquery-sidebar.json +0 -5908
- package/vitest/api/search-verdaccio.json +0 -1192
- package/vitest/api/storybook-readme.js +0 -3
- package/vitest/api/storybook-sidebar.json +0 -53782
- package/vitest/api/storybook-v.json +0 -53782
- package/vitest/identity.js +0 -29
- package/vitest/react-markdown.tsx +0 -7
- package/vitest/server-handlers.ts +0 -82
- package/vitest/server.ts +0 -6
- package/vitest/setup-env.ts +0 -33
- package/vitest/setup.ts +0 -40
- package/vitest/unit/empty-string.ts +0 -1
- package/vitest/unit/empty.ts +0 -1
- package/vitest/vitestSerializer.ts +0 -31
- /package/{vitest/unit/components/__mocks__/token.ts → src/utils/token-generate.ts} +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { HttpResponse, http } from 'msw';
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import { MemoryRouter, Route } from 'react-router';
|
|
3
5
|
|
|
@@ -5,10 +7,14 @@ import { HeaderInfoDialog } from '../../';
|
|
|
5
7
|
import { VersionProvider } from '../../providers';
|
|
6
8
|
import Header from './Header';
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
type Story = StoryObj<typeof Header>;
|
|
11
|
+
const meta: Meta<typeof Header> = {
|
|
9
12
|
title: 'Sections/Header',
|
|
13
|
+
component: Header,
|
|
10
14
|
};
|
|
11
15
|
|
|
16
|
+
export default meta;
|
|
17
|
+
|
|
12
18
|
function CustomInfoDialog({ onCloseDialog, title, isOpen }) {
|
|
13
19
|
return (
|
|
14
20
|
<HeaderInfoDialog
|
|
@@ -25,12 +31,29 @@ function CustomInfoDialog({ onCloseDialog, title, isOpen }) {
|
|
|
25
31
|
);
|
|
26
32
|
}
|
|
27
33
|
|
|
28
|
-
export const HeaderAll:
|
|
29
|
-
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
export const HeaderAll: Story = {
|
|
35
|
+
render: () => (
|
|
36
|
+
<MemoryRouter initialEntries={[`/-/web/detail/storybook`]}>
|
|
37
|
+
<Route exact={true} path="/-/web/detail/:package">
|
|
38
|
+
<VersionProvider>
|
|
39
|
+
<Header HeaderInfoDialog={CustomInfoDialog} />
|
|
40
|
+
</VersionProvider>
|
|
41
|
+
</Route>
|
|
42
|
+
</MemoryRouter>
|
|
43
|
+
),
|
|
44
|
+
parameters: {
|
|
45
|
+
msw: {
|
|
46
|
+
handlers: [
|
|
47
|
+
http.get('https://my-registry.org/-/verdaccio/data/sidebar/storybook', () => {
|
|
48
|
+
return HttpResponse.json(require('../../../vitest/api/storybook-sidebar.json'));
|
|
49
|
+
}),
|
|
50
|
+
http.get('https://my-registry.org/-/verdaccio/data/package/readme/storybook', () => {
|
|
51
|
+
return HttpResponse.json(require('../../../vitest/api/storybook-readme')());
|
|
52
|
+
}),
|
|
53
|
+
http.get('https://my-registry.org/-/verdaccio/data/search/*', () => {
|
|
54
|
+
return HttpResponse.json(require('../../../vitest/api/search-verdaccio.json'));
|
|
55
|
+
}),
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
@@ -1,16 +1,33 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { HttpResponse, http } from 'msw';
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import { MemoryRouter, Route } from 'react-router';
|
|
3
5
|
|
|
4
6
|
import Home from './Home';
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
type Story = StoryObj<typeof Home>;
|
|
9
|
+
const meta: Meta<typeof Home> = {
|
|
7
10
|
title: 'Sections/Home',
|
|
11
|
+
component: Home,
|
|
8
12
|
};
|
|
9
13
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
export default meta;
|
|
15
|
+
|
|
16
|
+
export const HomeDefault: Story = {
|
|
17
|
+
render: () => (
|
|
18
|
+
<MemoryRouter initialEntries={[`/`]}>
|
|
19
|
+
<Route exact={true} path="/">
|
|
20
|
+
<Home />
|
|
21
|
+
</Route>
|
|
22
|
+
</MemoryRouter>
|
|
23
|
+
),
|
|
24
|
+
parameters: {
|
|
25
|
+
msw: {
|
|
26
|
+
handlers: [
|
|
27
|
+
http.get('https://my-registry.org/-/verdaccio/data/packages', () => {
|
|
28
|
+
return HttpResponse.json([...require('../../../vitest/api/home.json')]);
|
|
29
|
+
}),
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -1,39 +1,64 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { HttpResponse, http } from 'msw';
|
|
1
3
|
import React from 'react';
|
|
2
4
|
import { MemoryRouter, Route } from 'react-router';
|
|
3
5
|
|
|
4
6
|
import { VersionProvider } from '../../providers';
|
|
5
7
|
import DetailSidebar from './Sidebar';
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
const meta: Meta<typeof DetailSidebar> = {
|
|
8
10
|
title: 'Sections/Sidebar',
|
|
11
|
+
component: DetailSidebar,
|
|
9
12
|
};
|
|
10
13
|
|
|
11
|
-
export
|
|
12
|
-
<MemoryRouter initialEntries={[`/-/web/detail/storybook`]}>
|
|
13
|
-
<Route exact={true} path="/-/web/detail/:package">
|
|
14
|
-
<VersionProvider>
|
|
15
|
-
<DetailSidebar />
|
|
16
|
-
</VersionProvider>
|
|
17
|
-
</Route>
|
|
18
|
-
</MemoryRouter>
|
|
19
|
-
);
|
|
14
|
+
export default meta;
|
|
20
15
|
|
|
21
|
-
|
|
22
|
-
<MemoryRouter initialEntries={[`/-/web/detail/storybook/v/6.0.26`]}>
|
|
23
|
-
<Route exact={true} path="/-/web/detail/:package/v/:version">
|
|
24
|
-
<VersionProvider>
|
|
25
|
-
<DetailSidebar />
|
|
26
|
-
</VersionProvider>
|
|
27
|
-
</Route>
|
|
28
|
-
</MemoryRouter>
|
|
29
|
-
);
|
|
16
|
+
type Story = StoryObj<typeof DetailSidebar>;
|
|
30
17
|
|
|
31
|
-
export const
|
|
32
|
-
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
18
|
+
export const SidebarLatestPackage: Story = {
|
|
19
|
+
render: () => (
|
|
20
|
+
<MemoryRouter initialEntries={[`/-/web/detail/storybook`]}>
|
|
21
|
+
<Route exact={true} path="/-/web/detail/:package">
|
|
22
|
+
<VersionProvider>
|
|
23
|
+
<DetailSidebar />
|
|
24
|
+
</VersionProvider>
|
|
25
|
+
</Route>
|
|
26
|
+
</MemoryRouter>
|
|
27
|
+
),
|
|
28
|
+
parameters: {
|
|
29
|
+
msw: {
|
|
30
|
+
handlers: [
|
|
31
|
+
http.get('https://my-registry.org/-/verdaccio/data/sidebar/storybook', () => {
|
|
32
|
+
return HttpResponse.json(require('../../../vitest/api/storybook-sidebar.json'));
|
|
33
|
+
}),
|
|
34
|
+
http.get('https://my-registry.org/-/verdaccio/data/package/readme/storybook', () => {
|
|
35
|
+
return HttpResponse.json(require('../../../vitest/api/storybook-readme')());
|
|
36
|
+
}),
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const SidebarPackageVersion: Story = {
|
|
43
|
+
render: () => (
|
|
44
|
+
<MemoryRouter initialEntries={[`/-/web/detail/storybook/v/6.0.26`]}>
|
|
45
|
+
<Route exact={true} path="/-/web/detail/:package/v/:version">
|
|
46
|
+
<VersionProvider>
|
|
47
|
+
<DetailSidebar />
|
|
48
|
+
</VersionProvider>
|
|
49
|
+
</Route>
|
|
50
|
+
</MemoryRouter>
|
|
51
|
+
),
|
|
52
|
+
parameters: {
|
|
53
|
+
msw: {
|
|
54
|
+
handlers: [
|
|
55
|
+
http.get('https://my-registry.org/-/verdaccio/data/sidebar/storybook', () => {
|
|
56
|
+
return HttpResponse.json(require('../../../vitest/api/storybook-sidebar.json'));
|
|
57
|
+
}),
|
|
58
|
+
http.get('https://my-registry.org/-/verdaccio/data/package/readme/storybook', () => {
|
|
59
|
+
return HttpResponse.json(require('../../../vitest/api/storybook-readme')());
|
|
60
|
+
}),
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
package/src/store/api.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import api, { handleResponseType } from './api';
|
|
3
|
+
import api, { CustomError, handleResponseType } from './api';
|
|
4
4
|
|
|
5
5
|
describe('api', () => {
|
|
6
6
|
describe('handleResponseType', () => {
|
|
@@ -142,7 +142,9 @@ describe('api', () => {
|
|
|
142
142
|
})
|
|
143
143
|
);
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
const error = new CustomError('Unknown error');
|
|
146
|
+
error.code = 500;
|
|
147
|
+
await expect(api.request('/resource')).rejects.toThrow(error);
|
|
146
148
|
});
|
|
147
149
|
|
|
148
150
|
test('when api returns an error 5.x.x', async () => {
|
package/src/store/api.ts
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { generateTokenWithTimeRange } from '../../utils/token-generate';
|
|
4
4
|
|
|
5
5
|
describe('getDefaultUserState', (): void => {
|
|
6
6
|
const username = 'xyz';
|
|
7
7
|
|
|
8
8
|
beforeEach(() => {
|
|
9
9
|
vi.resetModules();
|
|
10
|
+
vi.resetAllMocks();
|
|
10
11
|
});
|
|
11
12
|
|
|
12
13
|
test('should return state with empty user', async () => {
|
|
13
14
|
const token = 'token-xx-xx-xx';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
|
|
16
|
+
vi.doMock('../storage', () => ({
|
|
17
|
+
default: {
|
|
18
|
+
getItem: (key: string) => (key === 'token' ? token : username),
|
|
19
|
+
},
|
|
17
20
|
}));
|
|
21
|
+
|
|
18
22
|
const Login = await import('./login');
|
|
19
23
|
const { getDefaultUserState } = Login;
|
|
20
24
|
const result = {
|
|
@@ -24,19 +28,21 @@ describe('getDefaultUserState', (): void => {
|
|
|
24
28
|
expect(getDefaultUserState()).toEqual(result);
|
|
25
29
|
});
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
test('should return state with user from storage', async () => {
|
|
32
|
+
const token = generateTokenWithTimeRange(24);
|
|
33
|
+
|
|
34
|
+
vi.doMock('../storage', () => ({
|
|
35
|
+
default: {
|
|
36
|
+
getItem: (key: string) => (key === 'token' ? token : username),
|
|
37
|
+
},
|
|
38
|
+
}));
|
|
39
|
+
|
|
40
|
+
const Login = await import('./login');
|
|
41
|
+
const { getDefaultUserState } = Login;
|
|
42
|
+
const result = {
|
|
43
|
+
token,
|
|
44
|
+
username,
|
|
45
|
+
};
|
|
46
|
+
expect(getDefaultUserState()).toEqual(result);
|
|
47
|
+
});
|
|
42
48
|
});
|
package/src/utils/token.test.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import { isTokenExpire } from './token';
|
|
4
4
|
import {
|
|
5
5
|
generateInvalidToken,
|
|
6
6
|
generateTokenWithExpirationAsString,
|
|
7
7
|
generateTokenWithOutExpiration,
|
|
8
8
|
generateTokenWithTimeRange,
|
|
9
|
-
} from '
|
|
10
|
-
import { isTokenExpire } from './token';
|
|
9
|
+
} from './token-generate';
|
|
11
10
|
|
|
12
11
|
/* eslint-disable no-console */
|
|
13
12
|
console.error = vi.fn();
|
package/src/utils/url.ts
CHANGED
|
@@ -45,13 +45,29 @@ export function downloadFile(fileStream: Blob, fileName: string): void {
|
|
|
45
45
|
fileLink.href = objectURL;
|
|
46
46
|
fileLink.download = fileName;
|
|
47
47
|
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
48
|
+
// Skip actual download in test environment to avoid JSDOM navigation error
|
|
49
|
+
// Check if we're in a test environment (JSDOM)
|
|
50
|
+
const isTestEnvironment =
|
|
51
|
+
(typeof window !== 'undefined' &&
|
|
52
|
+
window.navigator &&
|
|
53
|
+
window.navigator.userAgent &&
|
|
54
|
+
window.navigator.userAgent.includes('Node.js')) ||
|
|
55
|
+
window.navigator.userAgent.includes('jsdom');
|
|
56
|
+
|
|
57
|
+
if (!isTestEnvironment) {
|
|
58
|
+
// Without appending to an HTML Element, download dialog does not show up on Firefox
|
|
59
|
+
// https://github.com/verdaccio/ui/issues/119
|
|
60
|
+
document.documentElement.appendChild(fileLink);
|
|
61
|
+
fileLink.click();
|
|
62
|
+
// firefox requires remove the object url
|
|
63
|
+
setTimeout(() => {
|
|
64
|
+
URL.revokeObjectURL(objectURL);
|
|
65
|
+
document.documentElement.removeChild(fileLink);
|
|
66
|
+
}, 150);
|
|
67
|
+
} else {
|
|
68
|
+
// In test environment, just clean up without triggering navigation
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
URL.revokeObjectURL(objectURL);
|
|
71
|
+
}, 150);
|
|
72
|
+
}
|
|
57
73
|
}
|
package/tsconfig.build.json
CHANGED
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"rootDir": ".",
|
|
11
11
|
"outDir": "./build",
|
|
12
12
|
"skipLibCheck": true,
|
|
13
|
-
"jsx": "react"
|
|
13
|
+
"jsx": "react",
|
|
14
|
+
"types": ["node", "@testing-library/jest-dom"]
|
|
14
15
|
},
|
|
15
16
|
"include": ["src/**/*", "./src/types/index.d.ts"],
|
|
16
|
-
"types": ["node", "@testing-library/jest-dom"],
|
|
17
17
|
"typedocOptions": {
|
|
18
18
|
"categoryOrder": ["Model", "Component", "Provider", "*"],
|
|
19
19
|
"defaultCategory": "Component",
|
package/tsconfig.json
CHANGED
|
@@ -10,9 +10,10 @@
|
|
|
10
10
|
"outDir": "./build",
|
|
11
11
|
"preserveSymlinks": true,
|
|
12
12
|
"jsx": "react",
|
|
13
|
-
"allowJs": true
|
|
13
|
+
"allowJs": true,
|
|
14
|
+
"types": ["node", "jest", "@testing-library/jest-dom"]
|
|
14
15
|
},
|
|
15
|
-
"
|
|
16
|
+
"include": ["src/**/*", "vitest/**/*", "src/test/**/*"],
|
|
16
17
|
"references": [
|
|
17
18
|
{
|
|
18
19
|
"path": "../core/types"
|
package/vitest.config.mjs
CHANGED
|
@@ -7,7 +7,7 @@ export default defineConfig({
|
|
|
7
7
|
environment: 'jsdom',
|
|
8
8
|
globals: true,
|
|
9
9
|
setupFiles: ['./vitest/setup.ts', './vitest/setup-env.ts'],
|
|
10
|
-
exclude: ['node_modules', '
|
|
10
|
+
exclude: ['**/node_modules/**', '**/build/**'],
|
|
11
11
|
snapshotFormat: {
|
|
12
12
|
escapeString: true,
|
|
13
13
|
printBasicPrototype: true,
|
|
@@ -22,6 +22,7 @@ export default defineConfig({
|
|
|
22
22
|
'\\.(jpg)$': './vitest/unit/empty.ts',
|
|
23
23
|
'\\.(md)$': './vitest/unit/empty-string.ts',
|
|
24
24
|
},
|
|
25
|
+
testTimeout: 20000,
|
|
25
26
|
},
|
|
26
27
|
plugins: [
|
|
27
28
|
react({
|